打印
[MM32软件]

【EV Board (MM32L0136C7P)测评】+ 简易SHELL实现

[复制链接]
977|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aple0807|  楼主 | 2022-12-15 18:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 aple0807 于 2022-12-15 18:36 编辑

开发MCU软件最常用的调试方式就是利用调试工具在线调试,打断点观察程序运行数据。但在部分场合不方便一直连接调试工具,特别是产测阶段或者现场维护等操作。此时为程序添加SHELL接口可以极大改善调试速度。
本次使用MM32L0136开发板的串口实现SHELL功能。
本程序SHELL的原理主要借助与编译工具 section 属性特征实现,即链接器会按照section属性值的字符顺序来排列变量。

SHELL核心宏如下:
typedef struct
{
        const char *name;
        int (*func)(int, void *[]);
} func_info_type;

#define DBG_FUN_BASE_EXPORT(fn, level)                                                \
        extern int fn(int argc, void *argv[]);                                            \
        OBJ_USED const func_info_type __dbg_func_##fn OBJ_SECTION(".app_fn.dbg." level) = \
                {                                                                             \
                        #fn,                                                                      \
                        (void *)fn,                                                               \
        }

#if DBG_EN > 0
#define DBG_FUN_EXPORT(fn) DBG_FUN_BASE_EXPORT(fn, "2." #fn)
#else
#define DBG_FUN_EXPORT(...)
#endif

#define SHELL_FUN_EXPORT(fn) DBG_FUN_BASE_EXPORT(fn, "2." #fn)
使用SHELL_FUN_EXPORT处理的函数,会创建一个结构,包括函数地址和函数名。串口接收到一行数据后会搜索函数名,命中则使用绝对地址调用该函数。

/*******************************************************************************
* [url=home.php?mod=space&uid=247401]@brief[/url] 搜索指令索引
* @param cmd
* [url=home.php?mod=space&uid=266161]@return[/url] 目标索引,-1标示未搜索到
******************************************************************************/
int dbg_fun_list_find(const char *cmd)
{
        int low, high, mid, des = -1;
        volatile const func_info_type *volatile funlist_start = &__dbg_func_dbg_fun_list_start;
        volatile const func_info_type *volatile funlist_end = &__dbg_func_dbg_fun_list_end;

        low = 1;
        high = (funlist_end - funlist_start);

        while (low <= high)
        {
                ii8 cval;

                mid = (low + high) >> 1;
                cval = comp_string(cmd, (funlist_start + mid)->name, 256);
                if (cval > 0)
                {
                        low = mid + 1;
                }
                else if (cval < 0)
                {
                        high = mid - 1;
                }
                else
                {
                        des = mid;
                        break;
                }
        }

        return des;
}

/*******************************************************************************
* @brief: 执行命令
* @param *cmd
* [url=home.php?mod=space&uid=266161]@return[/url] {*}
******************************************************************************/
int dbg_fun_list_exe(const char *cmd)
{
        int argc, site;
        char *argv[10];
        char cbuff[256];
        volatile const func_info_type *volatile funlist_start = &__dbg_func_dbg_fun_list_start;

        copy_str(cmd, cbuff, sizeof(cbuff) - 1);
        str_remove_l20_ascii(cbuff);

        argc = str_split(cbuff, ' ', argv, arr_len(argv));

        site = dbg_fun_list_find(argv[0]);

        if (site > 0)
        {
                (funlist_start + site)->func(argc, (void **)argv);
        }

        return site;
}
经过以上处理后,如下书写函数就可以在串口助手调用程序的函数了:
int sh_func1(int argc, void *argv[])
{
        printf("shell fun1 is called\n");
        return 0;
}
SHELL_FUN_EXPORT(sh_func1);

int sh_func2(int argc, void *argv[])
{
        printf("shell fun2 is called\n");
        return 0;
}
SHELL_FUN_EXPORT(sh_func2);


下面附上工程,有兴趣的小伙伴可以一起研究,改善功能!
L0136DEMO.rar (1.43 MB)

示例程序使用UART2作为SHELL串口,演示如下:


使用特权

评论回复
沙发
tpgf| | 2023-1-5 10:16 | 只看该作者
在计算机科学中,Shell俗称壳(用来区别于核),是指"为使用者提供操作界面"的软件(command interpreter,命令解析器)。它类似于DOS下的COMMAND.COM和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。

使用特权

评论回复
板凳
木木guainv| | 2023-1-5 10:37 | 只看该作者
传统意义上的shell指的是命令行式的shell,以后如果不特别注明,shell是指命令行式的shell。

使用特权

评论回复
地板
晓伍| | 2023-1-5 10:48 | 只看该作者
文字操作系统与外部最主要的接口就叫做shell。shell是操作系统最外面的一层。shell管理与操作系统之间的交互:等待你输入,向操作系统解释你的输入,并且处理各种各样的操作系统的输出结果。

使用特权

评论回复
5
八层楼| | 2023-1-5 11:23 | 只看该作者
Shell基本上是一个命令解释器,类似于DOS下的COMMAND.COM。它接收用户输入的命令(如ls等),然后调用相应的应用程序。较为通用的shell有标准的Bourne shell和C Shell。

使用特权

评论回复
6
guanjiaer| | 2023-1-5 12:47 | 只看该作者
交互式模式就是shell等待用户的输入,并且执行用户提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当用户签退后,shell也终止了。

使用特权

评论回复
7
heimaojingzhang| | 2023-1-5 12:55 | 只看该作者
shell也可以运行在另外一种模式:非交互式模式。在这种模式下,shell不与用户进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。

使用特权

评论回复
8
Jacquetry| | 2023-1-5 17:07 | 只看该作者
一个可以嵌入在程序中的嵌入式shell

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

328

帖子

2

粉丝