Rt-Thread系统,提供了一个命令行组件----FinSH,通过FinSH能够提供一个串口控制台。
在上位机上,可与串口监听工具,或者使用Putty,来连接到该串口控制台。
发送help指令(勾选回车),可以看到系统自带的一些指令:
在工程根目录下面的rtconfig.h,有关于FinSH的配置选项:
上述配置,具体的作用如下:
- /* 开启 FinSH */
- #define RT_USING_FINSH
- /* 将线程名称定义为 tshell */
- #define FINSH_THREAD_NAME "tshell"
- /* 开启历史命令 */
- #define FINSH_USING_HISTORY
- /* 记录 5 行历史命令 */
- #define FINSH_HISTORY_LINES 5
- /* 开启使用 Tab 键 */
- #define FINSH_USING_SYMTAB
- /* 开启描述功能 */
- #define FINSH_USING_DESCRIPTION
- /* 定义 FinSH 线程优先级为 20 */
- #define FINSH_THREAD_PRIORITY 20
- /* 定义 FinSH 线程的栈大小为 4KB */
- #define FINSH_THREAD_STACK_SIZE 4096
- /* 定义命令字符长度为 80 字节 */
- #define FINSH_CMD_SIZE 80
- /* 开启 msh 功能 */
- #define FINSH_USING_MSH
- /* 默认使用 msh 功能 */
- #define FINSH_USING_MSH_DEFAULT
- /* 最大输入参数数量为 10 个 */
- #define FINSH_ARG_MAX 10
除了FinSH自带的系统指令,我们也可以自定义新的指令。
通过下面的宏:
- MSH_CMD_EXPORT(name, desc);
- command [arg1] [arg2] [...]
下面以一个简单的实例说明:
- void <b style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 11px;">helloworld</b>(void)
- {
- rt_kprintf("hello RT-Thread!\n");
- }
- MSH_CMD_EXPORT(<b style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 11px;">helloworld</b> , say hello to RT-Thread);
编译下载后,输入helloworld,就能够执行调用了。
根据模板建立的代码,提供了一个led指令,我们可以写一个test指令,能够输出参数信息,如果指令后面的参数是led,还可以调用这个led指令对应的函数:
- /*********************************************************************
- * @fn led
- *
- * @brief gpio operation by pins driver.
- *
- * @return none
- */
- int led(void)
- {
- rt_uint8_t count;
- rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
- rt_kprintf("led_SP:%08x\r\n",__get_SP());
- for(count = 0 ; count < 10 ;count++)
- {
- rt_pin_write(LED0_PIN, PIN_LOW);
- rt_kprintf("led on, count : %d\r\n", count);
- rt_thread_mdelay(500);
- rt_pin_write(LED0_PIN, PIN_HIGH);
- rt_kprintf("led off\r\n");
- rt_thread_mdelay(500);
- }
- return 0;
- }
- static void test(int argc, char**argv)
- {
- if (argc < 2)
- {
- rt_kprintf("Please input'test param'\n");
- return;
- }
- for(int i=1;i<argc;i++) {
- rt_kprintf("param%d is %s\n", i, argv[i]);
- }
- if (rt_strcmp(argv[1], "led")==0)
- {
- rt_kprintf("run LED command!\n");
- led();
- }
- }
- MSH_CMD_EXPORT(test, test command: test param);
- MSH_CMD_EXPORT(led, led sample by using I/O drivers);
编译下载后,执行test,会提示要输入参数;
输入test 参数1 参数2 。。。,则会打印出参数信息;
如果输入test led,则会调用led指令对应的函数,使得对应的LED点亮。
通过上面的test指令,我们可以接收到参数了,但是这些参数,都是字符串形式的,我们可以从中提取需要的数据。
例如,下面在test指令中,如果第一个参数是led_set,则顺位读取第二个参数为led的序号,第三个参数为0和1表示关闭或者开启led
- /*********************************************************************
- * @fn led_set
- *
- * @brief use pins driver to set gpio
- *
- * @return none
- */
- int led_set(int index, int value)
- {
- rt_base_t pin = index==1 ? 1 : 0;
- rt_base_t val = value == 1 ? PIN_LOW : PIN_HIGH;
- rt_pin_mode(pin, PIN_MODE_OUTPUT);
- rt_pin_write(pin, val);
- return 0;
- }
- static void test(int argc, char**argv)
- {
- if (argc < 2)
- {
- rt_kprintf("Please input'test param'\n");
- return;
- }
- for(int i=1;i<argc;i++) {
- rt_kprintf("param%d is %s\n", i, argv[i]);
- }
- if (rt_strcmp(argv[1], "led")==0)
- {
- rt_kprintf("run LED command!\n");
- led();
- }
- if (rt_strcmp(argv[1], "led_set")==0 && argc==4)
- {
- int index = 0;
- int value = 0;
- sscanf(argv[2], "%d", &index);
- sscanf(argv[3], "%d", &value);
- rt_kprintf("led_set %d %d\n", index, value);
- led_set(index, value);
- }
- }
- MSH_CMD_EXPORT(test, test command: test param);
在上述代码中,使用了sscanf,来从对应的参数中,获取输入的数值,再去调用led_set(int index, int value),从而控制LED对应的GPIO。
需要注意的是,ch32v307的板载的LED1、LED2是低电平触发的,所以设置值value为1的时候,实际使用PIN_LOW,反之则用PIN_HIGH。
通过上面的实例,我们参考来构建自己需要的指令,以及合适的参数。
在串口终端中调试好了,还可以使用其他设备,通过串口来连接,并根据指令格式发送数据,就能够调用和执行对应的指令了。