【国民技术N32G457评测】三、移植小型嵌入式shell工具 nr_micro_shell
[复制链接]
【移植准备】
在进行调试和维护时,常常需要与单片机进行交互,获取、设置某些参数或执行某些操作,nr_micro_shell 正是为满足这一需求,针对资源较少的MCU编写的基本命令行工具。虽然RT_Thread组件中已经提供了强大的 finsh 命令行交互工具,但对于ROM、RAM资源较少的单片机,finsh 还是略显的庞大,在这些平台上,若仍想保留基本的命令行交互功能,nr_micro_shell是一个不错的选择。
nr_micro_shell具有以下优点
1.占用资源少,使用简单,灵活方便。使用过程只涉及两个shell_init()和shell()两个函数,无论是使用RTOS还是裸机都可以方便的应用该工具,不需要额外的编码工作。
2.交互体验好。完全类似于linux shell命令行,当串口终端支持ANSI(如Hypertrm终端)时,其不仅支持基本的命令行交互,还提供Tab键命令补全,查询历史命令,方向键移动光标修改功能。
3.扩展性好。nr_micro_shell为用户提供自定义命令的标准函数原型,只需要按照命令编写命令函数,并注册命令函数,即可使用命令。
nr_micro_shell和相同配置下的 finsh (finsh不使用msh)占用资源对比:
可以通过 git 链接下载获取源码 。
【移植步骤】
Step 1. 获取到源码包后,添加到之前创建好的 模板工程中的第三方组件目录下,如下图:
Step 2. 打开Project.uvprojx ,将shell 源码添加进工程中
Step 3. 打开魔术棒配置工程 ,将shell 源码的头文件路径添加进来
Step 4. 打开串口1的底层驱动源文件,改写 log_init(),使能串口的接收中断,并且添加 shell_init(); 发送的话仍旧需要重定向 shell_printf 为 printf ;在接收中断中需要做如下处理:
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] This function handles USARTy global interrupt request.
*/
void LOG_USARTx_IRQHandler(void)
{
if (USART_GetIntStatus(LOG_USARTx, USART_INT_RXDNE) != RESET)
{
/* Read one byte from the receive data register */
shell(USART_ReceiveData(LOG_USARTx));
}
}
Step 5. 最重要的一步,需要自定义和注册命令,可以直接在 const static_cmd_st static_cmd[] 中添加,其中 {"\0", NULL} 不能去除 ,也可以使用 NR_SHELL_CMD_EXPORT 方式添加,本次实验中添加如下3条自定义命令,用于查询 nr_micro_shell 版本信息和控制板载LED灯的状态
/**
* @brief ls command
*/
void shell_ls_cmd(char argc, char *argv)
{
unsigned int i = 0;
if (argc > 1)
{
if (!strcmp("cmd", &argv[argv[1]]))
{
for (i = 0; nr_shell.static_cmd[i].fp != NULL; i++)
{
shell_printf("%s", nr_shell.static_cmd[i].cmd);
shell_printf("\r\n");
}
}
else if (!strcmp("-v", &argv[argv[1]]))
{
shell_printf("ls version 1.0.\r\n");
}
else if (!strcmp("-h", &argv[argv[1]]))
{
shell_printf("useage: ls [options]\r\n");
shell_printf("options: \r\n");
shell_printf("\t -h \t: show help\r\n");
shell_printf("\t -v \t: show version\r\n");
shell_printf("\t cmd \t: show all commands\r\n");
}
}
else
{
shell_printf("ls need more arguments!\r\n");
}
}
/**
* @brief test command
*/
void shell_test_cmd(char argc, char *argv)
{
unsigned int i;
shell_printf("test command:\r\n");
for (i = 0; i < argc; i++)
{
shell_printf("paras %d: %s\r\n", i, &(argv[argv[i]]));
}
}
/**
* @brief blink_led_cmd
* blink 0 turn off the led
* blink 1 turn on the led
*/
void blink_led_cmd(char argc, char *argv)
{
if(!strcmp("1", &argv[argv[1]]))
{
LedOn(PORT_GROUP1, LED1_PIN);
LedOn(PORT_GROUP2, LED2_PIN);
LedOn(PORT_GROUP2, LED3_PIN);
shell_printf("leds are ON\r\n");
}
else if(!strcmp("0", &argv[argv[1]]))
{
LedOff(PORT_GROUP1, LED1_PIN);
LedOff(PORT_GROUP2, LED2_PIN);
LedOff(PORT_GROUP2, LED3_PIN);
shell_printf("leds are OFF\r\n");
}
}
#ifdef NR_SHELL_USING_EXPORT_CMD
NR_SHELL_CMD_EXPORT(ls, shell_ls_cmd);
NR_SHELL_CMD_EXPORT(test, shell_test_cmd);
#else
const static_cmd_st static_cmd[] =
{
{"ls", shell_ls_cmd},
{"test", shell_test_cmd},
{"blink", blink_led_cmd},
{"\0", NULL}
};
#endif
Step 6. 最后编译下载到开发板,使用j-link cdc 串口时按照如下接口定义方式与开发板连接:
开启串口工具或者shell终端助手,使用自定义命令进行调试,可以正常使用shell来切换板载LED状态
本次移植实验结束,具体可以参照附件包内容。
2. N32G45x_Nr_Micro_Shell.zip
(1.18 MB, 下载次数: 42)
|