大家好,又见面了,我是你们的朋友全栈君。
接上一章剖析RT-Thread中finsh组件实现(1),rt_device 具体定义如下:
其中内核基类定义如下:
所以刚才串口1初始化后名称被初始化为了 “usart1” ,与刚才设置终端时入参刚好可以匹配。而这个标志是类型标志,串口类型即为 RT_Object_Class_Device ,同时也是一个静态类,所以会或上0x80
其实 rt_device 中最重要的是传入了设备回调与操作函数指针,这些指针此时指向的是串口1的一系列操作函数。这些函数被初始化在串口1初始化的 rt_hw_serial_register 函数里
当得到返回的 rt_device 后,紧接着是打开这个设备,然后把当前控制台设置为新开打的设备:
到这里控制台初始化结束,然后后面就一直运行到main函数里。而shell的设置很容易想到,和之前串口初始化一样,还有一部分也被设置在自动化初始化的段里。 在文件shell.c里最后一句话
这里把finsh的初始化放在了应用初始化里,即段后缀.6里。初始化具体内容如下:
tips
代码语言:javascript复制段名 $$Base或$$Limit是MDK里用法,配合keep链接时保留一个段内的数据
a$$Base代表段名为a的首地址
a$$Limit代表段名为a的结尾
可以看到MDK链接选项卡参数是:
官方文档解释 而 finsh_system_function_init 函数也很简单,直接设置两个全局变量:
shell结构体定义如下:
我们先看一下信号量初始化:
最后finsh接收与发送其实都在finsh线程里完成:(删除掉了一些没有通过预编译的代码)
代码语言:javascript复制void finsh_thread_entry(void *parameter)
{
char ch;
/* normal is echo mode */
#ifndef FINSH_ECHO_DISABLE_DEFAULT
shell->echo_mode = 1; //开启回显,即能看到输入的cmd
#else
shell->echo_mode = 0;
#endif
#ifndef RT_USING_POSIX
/* set console device as shell device */
if (shell->device == RT_NULL)
{
rt_device_t console = rt_console_get_device(); //获取到之前设置的终端,即usart1
if (console)
{
finsh_set_device(console->parent.name);
}
}
#endif
rt_kprintf(FINSH_PROMPT);
while (1)
{
ch = finsh_getchar();
/* * 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 == 0x1b)
{
shell->stat = WAIT_SPEC_KEY;
continue;
}
else if (shell->stat == WAIT_SPEC_KEY)
{
if (ch == 0x5b)
{
shell->stat = WAIT_FUNC_KEY;
continue;
}
shell->stat = WAIT_NORMAL;
}
else if (shell->stat == WAIT_FUNC_KEY)
{
shell->stat = WAIT_NORMAL;
if (ch == 0x41) /* up key */
{
#ifdef FINSH_USING_HISTORY //显示历史cmd,完成↑翻看历史记录功能
/* prev history */
if (shell->current_history > 0)
shell->current_history --;
else
{
shell->current_history = 0;
continue;
}
/* copy the history command */
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x42) /* down key */
{
#ifdef FINSH_USING_HISTORY //显示历史cmd,完成↓翻看历史记录功能
/* next history */
if (shell->current_history < shell->history_count - 1)
shell->current_history ;
else
{
/* set to the end of history */
if (shell->history_count != 0)
shell->current_history = shell->history_count - 1;
else
continue;
}
memcpy(shell->line, &shell->cmd_history[shell->current_history][0],
FINSH_CMD_SIZE);
shell->line_curpos = shell->line_position = strlen(shell->line);
shell_handle_history(shell);
#endif
continue;
}
else if (ch == 0x44) /* left key */ //←功能
{
if (shell->line_curpos)
{
rt_kprintf("b");
shell->line_curpos --;
}
continue;
}
else if (ch == 0x43) /* right key */ //→功能
{
if (shell->line_curpos < shell->line_position)
{
rt_kprintf("%c", shell->line[shell->line_curpos]);
shell->line_curpos ;
}
continue;
}
}
/* received null or error */
if (ch == '