移植

finsh完全采用ANSI C编写,具备极好的移植性;内存占用少,如果不使用前面章节中介绍的函数方式动态地向finsh添加符号,finsh将不会动态申请内存。finsh源码位于 components/finsh 目录下。移植finsh需要注意以下几个方面:

  • finsh shell线程:
    每次的命令执行都是在finsh shell线程的上下文中完成的。当定义RT_USING_FINSH宏时,就可以在初始化线程中调用finsh_system_init()初始化finsh shell线程。RT-Thread 1.2.0之后的版本中可以不使用 finsh_set_device(const char device_name) 函数去显式指定使用的设备,而是会自动调用 rt_console_get_device() 函数去使用console设备(RT-Thread 1.1.x及以下版本中必须使用 finsh_set_device(const char device_name) 指定finsh shell使用的设备)。finsh shell线程在函数 finsh_system_init() 函数中被创建,它将一直等待rx_sem信号量。

  • finsh的输出:
    finsh的输出依赖于系统的输出,在RT-Thread中依赖rt_kprintf输出。在启动函数 rt_hw_board_init() 中, rt_console_set_device(const char* name) 函数设置了finsh的打印输出设备。

  • finsh的输入:
    finsh shell线程在获得了rx_sem信号量后,调用 rt_device_read() 函数从设备(选用串口设备)中获得一个字符然后处理。所以finsh的移植需要 rt_device_read() 函数的实现。而rx_sem信号量的释放通过调用 rx_indicate() 函数以完成对finsh shell线程的输入通知。通常的过程是,当串口接收中断发生是(即串口有输入),接受中断服务例程调用 rx_indicate() 函数通知finsh shelli线程有输入:而后finsh shell线程获取串口输入最后做相应的命令处理。