【RT-Thread学习】⼀:导出⾃⼰的命令到MSH命令列表中RT-Thread简介,摘⾃RT-Thread官⽹:
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芯⽚。
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");
}thread技术
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>);
知道了怎么添加⾃定义的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)
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键查看命令列表,可以看到导出的命令及其帮助信息。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论