2回答

0收藏

[评测分享] 【灵动Motor-DK电机控制板】-03串口shell移植

#板卡评测 #板卡评测 3994 人阅读 | 2 人回复 | 2023-07-25

   上期实现了串口的发送接收数据,本次就利用串口的发送接收移植一些开源的shell框架。
本次移植的是nr_micro_shell和letter_shell这2种,以前也在其他MCU平台移植过,所以本次移植就很容易了。
下面先移植nr_micro_shell.
首先添加nr_micro_shell源码到工程中。添加头文件路径。

然后修改nr_micro_shell的配置文件nr_micro_shell_config.h.主要移植配置如下2个,其他项按需配置。
一个串口printf输出打印,一个串口单字节输出。


先在串口初始化后初始化shell。直接调用nr_micro_shell的初始化函数。
    shell_init();
然后在串口接收处处理串口接收的数据。
  1. void shell_usart_loop(void)
  2. {
  3.     if(shell_uart_rx.read_i != shell_uart_rx.write_i)
  4.     {
  5.         shell(shell_uart_rx.buff[shell_uart_rx.read_i++]);
  6.         shell_uart_rx.read_i &= 0x7f;
  7.     }
  8. }
复制代码
编译成功

下载程序到板上,连接串口。


打开串口助手输入命令查看效果




2、移植letter_shell.
和上面移植差不多,首先下载letter_shell源码,加入到工程中,添加源码的头文件路径。

下面是移植的接口文件代码:
首先是配置文件:
  1. /**
  2. * @file shell_cfg_user.h
  3. * @author Letter (nevermindzzt@gmail.com)
  4. * @brief shell config
  5. * @version 3.0.0
  6. * @date 2019-12-31
  7. *
  8. * @copyright (c) 2019 Letter
  9. *
  10. */

  11. #ifndef __SHELL_CFG_USER_H__
  12. #define __SHELL_CFG_USER_H__

  13. #include "stdlib.h"
  14. #include "main.h"

  15. #if 0
  16. #define     SHELL_TASK_WHILE                //是否使用默认shell任务while循环
  17. #define     SHELL_USING_CMD_EXPORT          //是否使用命令导出方式
  18. #define     SHELL_USING_COMPANION           //是否使用shell伴生对象功能
  19. #define     SHELL_SUPPORT_END_LINE          //是否支持shell尾行模式
  20. #define     SHELL_HELP_LIST_USER            //是否在输入命令列表中列出用户
  21. #define     SHELL_HELP_LIST_VAR             //是否在输入命令列表中列出变量
  22. #define     SHELL_HELP_LIST_KEY             //是否在输入命令列表中列出按键
  23. #define     SHELL_ENTER_LF                  //使用LF作为命令行回车触发
  24. #define     SHELL_ENTER_CR                  //使用CR作为命令行回车触发
  25. #define     SHELL_ENTER_CRLF                //使用CRLF作为命令行回车触发
  26. #define     SHELL_EXEC_UNDEF_FUNC           //使用执行未导出函数的功能
  27. #define     SHELL_COMMAND_MAX_LENGTH        //shell命令最大长度
  28. #define     SHELL_PARAMETER_MAX_NUMBER      //shell命令参数最大数量
  29. #define     SHELL_HISTORY_MAX_NUMBER        //历史命令记录数量
  30. #define     SHELL_DOUBLE_CLICK_TIME         //双击间隔(ms)
  31. #define     SHELL_QUICK_HELP                //快速帮助
  32. #define     SHELL_MAX_NUMBER                //管理的最大shell数量
  33. #define     SHELL_GET_TICK()                //获取系统时间(ms)
  34. #define     SHELL_USING_LOCK                //是否使用锁
  35. #define     SHELL_MALLOC(size)              //内存分配函数(shell本身不需要)
  36. #define     SHELL_FREE(obj)                 //内存释放函数(shell本身不需要)
  37. #define     SHELL_SHOW_INFO                 //是否显示shell信息
  38. #define     SHELL_CLS_WHEN_LOGIN            //是否在登录后清除命令行
  39. #define     SHELL_DEFAULT_USER              //shell默认用户
  40. #define     SHELL_DEFAULT_USER_PASSWORD     //默认用户密码
  41. #define     SHELL_LOCK_TIMEOUT              //shell自动锁定超时

  42. #endif

  43. /**
  44. * @brief 是否使用shell伴生对象
  45. *        一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
  46. */
  47. #define     SHELL_USING_COMPANION       1


  48. /**
  49. * @brief 支持shell尾行模式
  50. */
  51. #define     SHELL_SUPPORT_END_LINE      1


  52. /**
  53. * @brief 使用LF作为命令行回车触发
  54. *        可以和SHELL_ENTER_CR同时开启
  55. */
  56. #define     SHELL_ENTER_LF              1

  57. /**
  58. * @brief 使用CR作为命令行回车触发
  59. *        可以和SHELL_ENTER_LF同时开启
  60. */
  61. #define     SHELL_ENTER_CR              1

  62. /**
  63. * @brief 使用CRLF作为命令行回车触发
  64. *        不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启
  65. */
  66. #define     SHELL_ENTER_CRLF            0

  67. /**
  68. * @brief shell格式化输入的缓冲大小
  69. *        为0时不使用shell格式化输入
  70. * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用
  71. */
  72. //#define     SHELL_SCAN_BUFFER          0

  73. /**
  74. * @brief 获取系统时间(ms)
  75. *        定义此宏为获取系统Tick,如`HAL_GetTick()`
  76. * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
  77. */
  78. //#define     SHELL_GET_TICK()            HAL_GetTick()

  79. /**
  80. * @brief 使用锁
  81. * @note 使用shell锁时,需要对加锁和解锁进行实现
  82. */
  83. //#define     SHELL_USING_LOCK            0

  84. /**
  85. * @brief shell内存分配
  86. *        shell本身不需要此接口,若使用shell伴生对象,需要进行定义
  87. */
  88. #define     SHELL_MALLOC(size)          malloc(size)

  89. /**
  90. * @brief shell内存释放
  91. *        shell本身不需要此接口,若使用shell伴生对象,需要进行定义
  92. */
  93. #define     SHELL_FREE(obj)             free(obj)




  94. #endif



复制代码
下面是接口代码及测试命令:
  1. /**
  2. * @file shell_port.c
  3. * @author Letter (NevermindZZT@gmail.com)
  4. * @brief
  5. * @version 0.1
  6. * @date 2019-02-22
  7. *
  8. * @copyright (c) 2019 Letter
  9. *
  10. */

  11. #include "shell_cfg_user.h"
  12. #include "platform.h"
  13. #include "shell.h"


  14. Shell shell;
  15. char shellBuffer[512];


  16. /**
  17. * @brief 用户shell写
  18. *
  19. * @param data 数据
  20. * @param len 数据长度
  21. *
  22. * @return short 实际写入的数据长度
  23. */
  24. short userShellWrite(char *data, unsigned short len)
  25. {
  26.     for(uint32_t i=0;i<len;i++)
  27.         stdout_putchar(data[i]);
  28.     return len;
  29. }


  30. /**
  31. * @brief 用户shell读
  32. *
  33. * @param data 数据
  34. * @param len 数据长度
  35. *
  36. * @return short 实际读取到
  37. */
  38. short userShellRead(char *data, unsigned short len)
  39. {
  40.     uint32_t rlen = 0;
  41.     for(uint32_t i=0;i<len;i++)
  42.     {
  43.         if(shell_uart_rx.read_i != shell_uart_rx.write_i)
  44.         {
  45.             data[rlen++] = shell_uart_rx.buff[shell_uart_rx.read_i++];
  46.             shell_uart_rx.read_i &= 0x7f;
  47.         }
  48.     }
  49.     return rlen;
  50. }

  51. /**
  52. * @brief 用户shell上锁
  53. *
  54. * @param shell shell
  55. *
  56. * @return int 0
  57. */
  58. int userShellLock(Shell *shell)
  59. {
  60.     return 0;
  61. }

  62. /**
  63. * @brief 用户shell解锁
  64. *
  65. * @param shell shell
  66. *
  67. * @return int 0
  68. */
  69. int userShellUnlock(Shell *shell)
  70. {
  71.     return 0;
  72. }

  73. /**
  74. * @brief 用户shell初始化
  75. *
  76. */
  77. void userShellInit(void)
  78. {
  79.     shell.write = userShellWrite;
  80.     shell.read = userShellRead;
  81. //    shell.lock = userShellLock;
  82. //    shell.unlock = userShellUnlock;
  83.     shellInit(&shell, shellBuffer, 512);

  84. }

  85. //测试添加用户:
  86. SHELL_EXPORT_USER(SHELL_CMD_PERMISSION(0x01), root, 123456, add user);


  87. //测试添加mian命令
  88. int func(int argc, char *argv[])
  89. {
  90.     printf("%d parameter(s)\r\n", argc);
  91.     for (char i = 1; i < argc; i++)
  92.     {
  93.         printf("%s\r\n", argv[i]);
  94.     }
  95.     return  0;
  96. }
  97. SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0x01)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func, func, test1);
  98. //letter:/$ func "hello world"
  99. //2 parameter(s)
  100. //hello world
  101. SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0x02)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func2, func, test2);



  102. //测试添加func命令
  103. int func1(int i, char ch, char *str)
  104. {
  105.     printf("input int: %d, char: %c, string: %s\r\n", i, ch, str);
  106.     return  0;
  107. }
  108. SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), func1, func1, test3);
  109. //letter:/$ func1 666 'A' "hello world"
  110. //input int: 666, char: A, string: hello world



复制代码


接口初始化shell


主循环处理串口接收的数据:


编译下载查看串口数据:


GPIO_LED_Toggle.zip (3.14 MB, 下载次数: 3)

分享到:
回复

使用道具 举报

回答|共 2 个

倒序浏览

沙发

meiyao

发表于 2023-7-30 22:43:05 | 只看该作者

不简单,大佬就是大佬,写个串口都这么秀
回复 支持 反对

使用道具 举报

板凳

yangjiaxu

发表于 2023-7-31 13:26:02 | 只看该作者

看着还挺有意思的啊,哈哈,这个micro shell是一般应用在哪儿啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条