【RT-Thread學習】一:導出自己的命令到MSH命令列表中


RT-Thread簡介,摘自RT-Thread官網www.rt-thread.org:

RT-Thread是一個集實時操作系統(RTOS)內核、中間件組件和開發者社區於一體的技術平台,由熊譜翔先生帶領並集合開源社區力量開發而成,RT-Thread也是一個組件完整豐富、高度可伸縮、簡易開發、超低功耗、高安全性的物聯網操作系統。RT-Thread具備一個IoT OS平台所需的所有關鍵組件,例如GUI、網絡協議棧、安全傳輸、低功耗組件等等。經過11年的累積發展,RT-Thread已經擁有一個國內最大的嵌入式開源社區,同時被廣泛應用於能源、車載、醫療、消費電子等多個行業,累積裝機量超過兩千萬台,成為國人自主開發、國內最成熟穩定和裝機量最大的開源RTOS。

RT-Thread擁有良好的軟件生態,支持市面上所有主流的編譯工具如GCC、Keil、IAR等,工具鏈完善、友好,支持各類標准接口,如POSIX、CMSIS、C++應用環境、Javascript執行環境等,方便開發者移植各類應用程序。商用支持所有主流MCU架構,如ARM Cortex-M/R/A, MIPS, X86, Xtensa, C-Sky, RISC-V,幾乎支持市場上所有主流的MCU和Wi-Fi芯片。

 RT-Thread的學習基於正點原子的潘多拉IoT Board物聯網開發板STM32L475,板上集成了ST-Link V2.1調試器,方便程序下載和調試。同時具有豐富的外設,如SDIO WIFI模塊,TFT顯示屏,音頻解碼芯片,六軸傳感器,溫濕度傳感器,貼片電機等。可用於物聯網及RT-Thread的入門學習。板子的上手指南可以參考https://www.rt-thread.org/document/site/tutorial/quick-start/iot_board/quick-start/。

FinSH是 RT-Thread 的命令行組件(shell),通過RT-Thread配置使用MSH(module shell)模式時,FinSH 與傳統 shell(dos/bash)執行方式一致,例如,可以通過 cd / 命令將目錄切換至根目錄。

msh 通過解析,將輸入字符分解成以空格區分開的命令和參數。其命令執行格式如下所示:

command [arg1] [arg2] [...]

其中 command 既可以是 RT-Thread 內置的命令,也可以是可執行的文件。

FinSH 內置命令

在 RT-Thread 中默認內置了一些 FinSH 命令,在 FinSH 中輸入 help 后回車或者直接按下 Tab 鍵,就可以打印當前系統支持的所有命令。C-Style 和 msh 模式下的內置命令基本一致,這里就以 msh 為例。

msh 模式下,按下 Tab 鍵后可以列出當前支持的所有命令。默認命令的數量不是固定的,RT-Thread 的各個組件會向 FinSH 輸出一些命令。例如,當打開 DFS 組件時,就會把 ls,cp,cd 等命令加到 FinSH 中,方便開發者調試。

以下為按下 Tab 鍵后打印出來的當前支持的所有顯示 RT-Thread 內核狀態信息的命令,左邊是命令名稱,右邊是關於命令的描述:

RT-Thread shell commands:
version - show RT-Thread version information
list_thread - list thread
list_sem - list semaphore in system
list_event - list event in system
list_mutex - list mutex in system
list_mailbox - list mail box in system
list_msgqueue - list message queue in system
list_timer - list timer in system
list_device - list device in system
exit - return to RT-Thread shell mode.
help - RT-Thread shell help.
ps - List threads in the system.
time - Execute command with time.
free - Show the memory usage in the system.
這里列出輸入常用命令后返回的字段信息,方便開發者理解返回的信息內容。

自定義 msh 命令

自定義的 msh 命令,可以在 msh 模式下被運行,將一個命令導出到 msh 模式可以使用如下宏接口:

MSH_CMD_EXPORT(name, desc);

參數 描述
name 要導出的命令
desc 導出命令的描述
這個命令可以導出有參數的命令,也可以導出無參數的命令。導出無參數命令時,函數的入參為 void,示例如下:

void hello(void)
{
rt_kprintf("hello RT-Thread!\n");
}

MSH_CMD_EXPORT(hello , say hello to RT-Thread);
導出有參數的命令時,函數的入參為 int argc 和 char**argv。argc 表示參數的個數,argv 表示命令行參數字符串指針數組指針。導出有參數命令示例如下:

static void atcmd(int argc, char**argv)
{
……
}

MSH_CMD_EXPORT(atcmd, atcmd sample: atcmd <server|client>);
 

更為詳細的FINSH和MSH介紹可參考官方文檔https://www.rt-thread.org/document/site/programming-manual/finsh/finsh/。

知道了怎么添加自定義的MSH命令后,我們試着添加一個命令,如打印cpu時鍾信息的命令:

/* 系統時鍾信息查看 */
void clockinfo(void)
{
volatile uint32_t rcc_cr = RCC->CR; //讀取RCC_CR寄存器值
rt_kprintf("RCC_CR:%#X.\r\n",rcc_cr);

/* System Clock source */
if(__HAL_RCC_GET_SYSCLK_SOURCE()==RCC_SYSCLKSOURCE_STATUS_MSI)
{
rt_kprintf("SYSCKL source: MSI.\r\n");
}
else if(__HAL_RCC_GET_SYSCLK_SOURCE()==RCC_SYSCLKSOURCE_STATUS_HSI)
{
rt_kprintf("SYSCKL source: HSI.\r\n");
}
else if(__HAL_RCC_GET_SYSCLK_SOURCE()==RCC_SYSCLKSOURCE_STATUS_HSE)
{
rt_kprintf("SYSCKL source: HSE.\r\n");
}
else if(__HAL_RCC_GET_SYSCLK_SOURCE()==RCC_SYSCLKSOURCE_STATUS_PLLCLK)
{
rt_kprintf("SYSCKL source: PLL.\r\n");
}

/* PLL Clock source */
if (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)
{
/* PLL source is HSI oscillator */
rt_kprintf("PLL source:HSI oscillator.\r\n");
}
else if (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)
{
/* PLL source is HSE bypass oscillator */
rt_kprintf("PLL source:HSE bypass oscillator.\r\n");
}
else if (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
{
/* PLL source is MSI oscillator */
rt_kprintf("PLL source:MSI oscillator.\r\n");
}

/* Clock Frequency */
rt_kprintf("SystemClockFreq:%lu.\r\n",HAL_RCC_GetSysClockFreq());
rt_kprintf("HCLKFreq:%lu.\r\n",HAL_RCC_GetHCLKFreq());
rt_kprintf("PCLK1Freq:%lu.\r\n",HAL_RCC_GetPCLK1Freq());
rt_kprintf("PCLK2Freq:%lu.\r\n",HAL_RCC_GetPCLK2Freq());

/* Peripheral Clock Frequency */ //各個外設時鍾頻率
rt_kprintf("RTC\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC)); //RTC
rt_kprintf("ADC\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)); //ADC
rt_kprintf("I2C1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C1));//I2C1
rt_kprintf("I2C2\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C2));//I2C2
rt_kprintf("I2C3\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2C3));//I2C3
rt_kprintf("LPTIM1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_LPTIM1)); //LPTIM1
rt_kprintf("LPTIM2\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_LPTIM2)); //LPTIM2
rt_kprintf("LPUART1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_LPUART1));//LPUART1
rt_kprintf("RGN\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RNG)); //RNG
rt_kprintf("SAI1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1));//SAI1
rt_kprintf("SDMMC1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1)); //SDMMC1
rt_kprintf("SWPMI1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SWPMI1)); //SWPMI1
rt_kprintf("USART1\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_USART1)); //USART1
rt_kprintf("USART2\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_USART2)); //USART2
rt_kprintf("USART3\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_USART3)); //USART3
rt_kprintf("UART4\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_UART4)); //UART4
rt_kprintf("UART5\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_UART5)); //UART5
rt_kprintf("USB\tClockFreq:%lu.\r\n",HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_USB)); //USB
}
/* 導出到 msh 命令列表中 */
MSH_CMD_EXPORT(clockinfo, display system clock info);
 也可以使用別名導出,這樣函數名和命令名可以不一致:

MSH_CMD_EXPORT_ALIAS(clockinfo,showclock, display system clock info.);
這樣導出后可以使用命令showclock執行時鍾信息查看命令。在MSH命令行界面按TAB鍵查看命令列表,可以看到導出的命令及其幫助信息。
————————————————
版權聲明:本文為CSDN博主「yangsmithcool123」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yangsmithcool123/java/article/details/88022647


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM