RTT之FinSH組件添加(含啓動流程分析)

FinSH,類似於linux的shell,對於調試階段還是很有用的,可以在完成整個程序時再關上,就是了。

常用的就是msh()模式,即shell模式,另一個C-Style模式,類似於調用C函數名的方式,不常用。

Fish的執行過程:

1、每次命令的執行都是在FinSH(tshell線程)的上下文中完成的。

在rtconfig.h中#define RT_USING_FINSH,即可以初始化FinSH線程,通過函數finsh_system_init() 完成。追蹤下此函數可以發現,在shell.c文件下。並且是通過INIT_APP_EXPORT(finsh_system_init);這種自動初始化機制來調用的。

注:

這些自動初始化的函數,何時被調用呢?

從內核的啓動流程上看,主要是通過rt_components_board_init()和rt_componets_init()來調用。

其中rt_hw_board_init()下rt_componets_init()這個函數會遍歷所有INIT_BOARD_EXPORT聲明的函數。默認只開啓了串口和Pin設備。

rt_comonents_init()是在componets.c文件下void main_thread_entry(void *parameter),main線程啓動時調用。

在rtdef.h中定義了6種的自動初始化類型:

 

FinSH的命令輸入的實現:

FinSH命令也是在rtdef.h中實現,緊接着就是:

仿真可知,FinSH線程也是在main線程裏調用rt_comonents_init()時實現,調用shell.c裏的int finsh_system_init(void)創建FinSH線程。

在FinSH線程實現,接收字符,在shell.c中void finsh_thread_entry(void *parameter),調用以下函數:

static char finsh_getchar(void)
{
#ifdef RT_USING_POSIX
    return getchar();
#else
    char ch;

    RT_ASSERT(shell != RT_NULL);
    while (rt_device_read(shell->device, -1, &ch, 1) != 1)
        rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER);

    return ch;
#endif
}

一直等待信號量。

然後,接收中斷服務調用rx_indicate(),通知FinSH線程有輸入。可以看到在drv_usart.c中,調用了中斷函數,

通過uart_isr()函數又調用了serial.c中的void rt_hw_serial_isr(struct rt_serial_device *serial, int event),這裏面調用了rx_indicate()表明已經接收到了數據。然後放到FinSH線程中解析就可以了。

瞭解這些,其實一定可以實現FinSH的。可能遇到問題是用普通的串口工具是無法實現交互的,最好是用xshell或SecureCRT.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章