大家好,又见面了,我是你们的朋友全栈君。
FinSH 控制台
1.初始化 时序
模块初始函数
int finsh_system_init(void)
初始化函数通过 INIT_APP_EXPORT(finsh_system_init) 宏定义加入到系统组建初始化
main_thread_entry 会调用 rt_components_init(); 从而去执行”.rti_fn.” level section下的函数入口地址。
RT thread 隐式调用封装的核心机制。
一般来说会创建一个cmd.c迎来存放我们各种添加的命令函数
命令函数需要在cmd.c中声明这样连接器才能找到函数的位置,一般我们会通过包含头文件。这样cmd.c会变得臃肿。
使用MSH_CMD_EXPORT 宏定义,就会把命令执行函数的入口放到相应的section下。类似一个命令向量表。
2.Finsh架构
FinSH 是控制台,控制台主要作用是
1:接收指定端口的信息
2:解析端口信息(命令)
3:执行命令
FinSH 主体为finsh_thread_entry 线程。
线程结构为
while(1)
{
1:接收指定端口的信息: getchr()
2:解析端口信息(命令) :if字符比较 ,字符串比较
3:执行命令 :执行函数指针
}
1.接收端口信息为了减少对资源的占用使用了,等待信号量的方式
2.解析命令端口 为查询命令列表方式
3.执行命令 通过命令函数指针执行函数
3.FinSH初始化
finsh_system_init
控制台的初始需要解决几个问题,
1.命令行列表的确定
finsh_system_function_init(&FSymTabKaTeX parse error: Expected ‘EOF’, got ‘&’ at position 7: Base, &̲FSymTabLimit);
2.主处理流程(thread)finsh_thread_entry的创建
tid = rt_thread_create(FINSH_THREAD_NAME,
finsh_thread_entry, RT_NULL,
FINSH_THREAD_STACK_SIZE, FINSH_THREAD_PRIORITY, 10);
3.任务控制信号量的创建 rt_sem_init
rt_sem_init(&(shell->rx_sem), "shrx", 0, 0);
在任务死循环中等待 输入端口接收数据,接收端口接收数据后释放信号量唤醒FinSH函数处理字符
4.明确控制台输入输出对应的物理端口
finsh_set_device(console->parent.name);
4.线程通信和收发
finsh_set_device(console->parent.name);
设置console为FinSH为其输入输出设备
设定console 设备的接收回调函数,当console设备接收中断进入后会执行回调函数
finsh_set_device->rt_device_set_rx_indicate(dev, finsh_rx_ind);
回调函数的意义是发送信号量到 finsh_getchar(); 使得FinSH获得输入
/* release semaphore to let finsh thread rx data */
rt_sem_release(&shell->rx_sem);
finsh_getchar()得到信号量得以基础运行。
while (rt_device_read(device, -1, &ch, 1) != 1)
rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER);
rt_device_read 判断底层是否有接收到数据,没有的话,FinSH线程进入信号量等待。直到isr接收数据回调函数释放信号量
这里的回调机制是没接收一个字符就会产生一次中断,就会发送一次信号量,下个章节说明
5.添加一个自己的命令
如果命令函数没有使用会被编译器优化 , 加入 attribute((used))
#include “finsh.h”
__attribute__((used)) int LED_state4(void)
{
rt_kprintf("LED 4 \r\n");
rt_pin_write(LED0_PIN,0);
rt_pin_write(LED1_PIN,0);
rt_pin_write(LED2_PIN,0);
return 0;
}MSH_CMD_EXPORT(LED_state4, Led all blink);
6.FinSH 字符解析
首先对操作字符解析,使用方向按键可以实时在控制台中进行操作
键盘的输入量是单个字符,为了识别和相应用户的单次按键键入,所以采用单个字符。
/* * handle control key * up key : 0x1b 0x5b 0x41 * down key: 0x1b 0x5b 0x42 * right key:0x1b 0x5b 0x43 * left key: 0x1b 0x5b 0x44 */
if (ch == '\r' || ch == '\n')
当检测到回车按键和换行的时候,表示用户输入完成一条信息。对信息进行分析
1.输入信息保存入,历史信息列表
2.查找命令列表,命中后执行
6.总结
核心部分为 finsh_thread_entry
1:解析端口信息(命令)
2:执行命令
这步分可以进行移植
配置部分为RT Thread 设备驱动架构,移植过程较为复杂。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143335.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...