1.前言
参考:https://blog.csdn.net/sinat_3... ,本文详细介绍了如何将FreeRTOS的命令行接口(CLI)组件移植到Mini-F5375-OB开发板上,通过串口中断实现命令交互。内容包括下载参考源码、移植CLI组件、实现串口初始化及中断,到注册并执行自定义命令(如hello、led控制和sum计算)的全过程。CLI的使用大大方便了单片机的调试和维护。
2. 下载参考代码
为了实现类似RT-Thread类似的控制台功能,在FreeRTOS下有一个cli组件,根据参考文献是移植到GD32F107单片机上,本文直接将从https://gitee.com/yvany/gd_fr...下载源码,直接复制cli目录下的几个文件,在此基础上进行cli组件的移植。
将上述文件下载下来,放到上一篇帖子提到的FreeRTOS_Blinky工程下,新建一个cli目录,将6个文件放入该文件夹。在MDK下增加组,更名为cli.
然后将cli目录下的源文件添加到工程中。
3.移植代码
打开serial.c,修改其中的与串口相关代码。修改xSerialPortInitMinimal函数,使用开发板上的USART3串口。并开启接收中断。修改后的代码如下:
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
xComPortHandle xReturn;
/* Create the queues used to hold Rx/Tx characters. */
xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
/* If the queue/semaphore was created correctly then setup the serial port
hardware. */
if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) )
{
/* Enable USART3 */
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
USART_InitTypeDef USART_InitStruct;
// 1. 先使能GPIO时钟 (AHB总线)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
// 2. 配置TX引脚(PC10)
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_7); // PC10复用为UART3_TX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStruct);
// 3. 配置RX引脚(PC11)
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_7); // PC11复用为UART3_RX
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_FLOATING; // 复用输入模式
GPIO_Init(GPIOC, &GPIO_InitStruct);
// 4. 使能UART3时钟 (APB1总线)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
USART_StructInit(&USART_InitStruct);
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStruct);
// 配置USART3中断优先级
NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 只使能USART3接收中断,不使能发送中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// USART_ITConfig(USART3, USART_IT_TXE, ENABLE); // 不使能发送中断
}
else
{
xReturn = ( xComPortHandle ) 0;
}
/* This demo file only supports a single port but we have to return
something to comply with the standard demo header file. */
return xReturn;
}
然后修改USART3串口中断函数,处理接收中断
void USART3_IRQHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
uint8_t RxData = 0;
// 处理接收中断
if (RESET != USART_GetITStatus(USART3, USART_IT_RXNE))
{
RxData = USART_ReceiveData(USART3);
xQueueSendFromISR(xRxedChars, &RxData, &xHigherPriorityTaskWoken);
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
同时,也需要修改串口发送函数为使用USART3
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
{
signed portBASE_TYPE xReturn;
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
{
xReturn = pdPASS;
uint8_t cChar;
/*修改:发送队列中有数据,通过轮询方式发送出去 */
if(xQueueReceive(xCharsForTx, &cChar, 0) == pdTRUE) {
USART_SendData(USART3, (uint8_t)cChar);
while (RESET == USART_GetFlagStatus(USART3, USART_FLAG_TC));
}
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
修改后,编译代码
4. 增加通过命令行开关LED的命令
在Sample-CLI-command.c中,有2个控制led的外部函数,需要修改为对应开发板上的LED控制
打开platform.c,在其中增加2个函数,并在platform.h中进行声明
编译通过后,下载到开发板。打开串口中断MobaXterm,选择对应串口,可以看到FreeRTOS的Clit提示信息,输入help回车,会打印已有命令。
输入led on 回车,可以看到2个LED同时亮起,输入led off 回车,2个LED同时熄灭
增加TAB键显示帮助的功能
仿照RT-Thread控制台,按下Tab键后可以显示帮助信息,显示当前可用命令的方式,添加功能。打开UARTCommandConsole.c,在prvUARTCommandConsoleTask的代码中增加对Tab键的处理:else if( cRxedChar == '\t' ) { /* 按下Tab时,回显help与>在同一行,tab键本身不显示 */ vSerialPutString( xPort, "\bhelp", 5 ); strcpy(cInputString, "help"); ucInputIndex = strlen("help"); BaseType_t xReturnedTab; do { xReturnedTab = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE ); vSerialPutString( xPort, pcOutputString, ( unsigned short ) strlen( pcOutputString ) ); } while( xReturnedTab != pdFALSE ); strcpy( cLastInputString, cInputString ); ucInputIndex = 0; memset( cInputString, 0x00, cmdMAX_INPUT_SIZE ); vSerialPutString( xPort, pcEndOfOutputMessage, ( unsigned short ) strlen( pcEndOfOutputMessage ) ); }
编译重新下载,通过控制台测试tab键功能。
6. 结束语
通过参考网络资料,移植了FreeRTOS的cli命令行处理组件到Mini-F5375-OB开发板,测试控制led开关的命令,增加了Tab键显示帮助的命令。通过命令行控制台,可以帮助我们更好的调试代码,增加软件灵活性。