STM32F103移植FreeRTOS-CLI
Posted 旧年不在666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103移植FreeRTOS-CLI相关的知识,希望对你有一定的参考价值。
STM32F103移植FreeRTOS-CLI
一、平台
-
芯片:STM32F103RDT6
-
FreeRTOS版本:FreeRTOS V10.0.1
-
开发工具:stm32cubemx V6.1.2 + keil MDK V5.27.1.0
-
开发所用的库:HAL库
二、源码
三、串口配置
四、文件移植
五、接口适配(以下只列出需要修改的地方)
#define __FreeRTOS_CLI_DEF_H__
#include "usart.h"
#include "log.h"
#include "FreeRTOS.h"
//FreeRTOS-CLI修改控制宏
#ifndef __FreeRTOS_CLI_RESTORE_EN__
#define __FreeRTOS_CLI_RESTORE_EN__ 0
#endif
//定义输出缓存大小
#ifndef configCOMMAND_INT_MAX_OUTPUT_SIZE
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1024
#endif
#ifndef FreeRTOS_CLI_NEW_LINE
#define FreeRTOS_CLI_NEW_LINE "\\033[32mKavabot#\\033[0m"
#endif
#endif
//定义FreeRTOS-CLI全局串口接收缓存
uint8_t cli_rx_buff;
//定义FreeRTOS-CLI串口句柄
UART_HandleTypeDef *cli_com_handle = &huart1;
#if __FreeRTOS_CLI_RESTORE_EN__
/*-----------------------------------------------------------*/
/* UART interrupt handler. */
void vUARTInterruptHandler( void );
/*-----------------------------------------------------------*/
#endif
/*
* See the serial2.h header file.
*/
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
xComPortHandle xReturn;
#if __FreeRTOS_CLI_RESTORE_EN__
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
#endif
/* 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 ) )
{
#if __FreeRTOS_CLI_RESTORE_EN__
/* Enable USART1 clock */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );
/* Configure USART1 Rx (PA10) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
USART_InitStructure.USART_BaudRate = ulWantedBaud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Clock = USART_Clock_Disable;
USART_InitStructure.USART_CPOL = USART_CPOL_Low;
USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_InitStructure.USART_LastBit = USART_LastBit_Disable;
USART_Init( USART1, &USART_InitStructure );
USART_ITConfig( USART1, USART_IT_RXNE, ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
USART_Cmd( USART1, ENABLE );
#else
HAL_UART_Receive_IT(cli_com_handle, &cli_rx_buff, 1);
#endif
}
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;
}
signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
{
signed portBASE_TYPE xReturn;
//定义FreeRTOS-CLI串口发送缓存
uint8_t cli_tx_buff;
if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
{
xReturn = pdPASS;
#if __FreeRTOS_CLI_RESTORE_EN__
USART_ITConfig( USART1, USART_IT_TXE, ENABLE );
#else
if (xQueueReceive(xCharsForTx, &cli_tx_buff, 0) == pdTRUE)
{
while(HAL_UART_Transmit_IT(cli_com_handle, &cli_tx_buff, 1) != HAL_OK);
}
#endif
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
#if __FreeRTOS_CLI_RESTORE_EN__
void vUARTInterruptHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
char cChar;
if( USART_GetITStatus( USART1, USART_IT_TXE ) == SET )
{
/* The interrupt was caused by the THR becoming empty. Are there any
more characters to transmit? */
if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* A character was retrieved from the queue so can be sent to the
THR now. */
USART_SendData( USART1, cChar );
}
else
{
USART_ITConfig( USART1, USART_IT_TXE, DISABLE );
}
}
if( USART_GetITStatus( USART1, USART_IT_RXNE ) == SET )
{
cChar = USART_ReceiveData( USART1 );
xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
#else
/******************************************************************************
* @Function: FreeRTOS_CLI_USART_RXNE_Callback
* @Description: CLI串口接收中断回调函数
* @Input: void
* @Output: None
* @Return: void
* @Others: 此函数需要在USART1接收中断回调函数中调用
* @param {UART_HandleTypeDef} *huart
*******************************************************************************/
void FreeRTOS_CLI_USART_RXNE_Callback(UART_HandleTypeDef *huart)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(xRxedChars, &cli_rx_buff, &xHigherPriorityTaskWoken);
HAL_UART_Receive_IT(huart, &cli_rx_buff, 1);
}
#endif
//添加FreeRTOS-CLI公共头文件
#include "FreeRTOS_CLI_def.h"
//声明FreeRTOS-CLI串口接收中断回调函数
void FreeRTOS_CLI_USART_RXNE_Callback(UART_HandleTypeDef *huart);
#if __FreeRTOS_CLI_RESTORE_EN__
/*-----------------------------------------------------------*/
/*
* The task that implements the command console processing.
*/
static void prvUARTCommandConsoleTask( void *pvParameters );
void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority );
/*-----------------------------------------------------------*/
#endif
#if __FreeRTOS_CLI_RESTORE_EN__
/*-----------------------------------------------------------*/
void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority )
{
/* Create the semaphore used to access the UART Tx. */
xTxMutex = xSemaphoreCreateMutex();
configASSERT( xTxMutex );
/* Create that task that handles the console itself. */
xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */
"CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */
usStackSize, /* The size of the stack allocated to the task. */
NULL, /* The parameter is not used, so NULL is passed. */
uxPriority, /* The priority allocated to the task. */
NULL ); /* A handle is not required, so just pass NULL. */
}
/*-----------------------------------------------------------*/
#endif
#if __FreeRTOS_CLI_RESTORE_EN__
static void prvUARTCommandConsoleTask( void *pvParameters )
#else
void prvUARTCommandConsoleTask( void *pvParameters )
#endif
{
/* Create the semaphore used to access the UART Tx. */
xTxMutex = xSemaphoreCreateMutex();
configASSERT( xTxMutex );
六、使用
/******************************************************************************
* @Function: task_shell_run
* @Description: SHELL任务函数入口
* @Input: void
* @Output: None
* @Return: void
* @Others: None
* @param {void} *pvParameters
*******************************************************************************/
void task_shell_run(void *pvParameters)
{
//这里会把示例命令注册
vRegisterSampleCLICommands();
while(1)
{
//这里会不断接收中断输入的命令进行处理
prvUARTCommandConsoleTask(NULL);
osDelay(2);
}
}
七、至于如何添加自己的命令,后面再讲
以上是关于STM32F103移植FreeRTOS-CLI的主要内容,如果未能解决你的问题,请参考以下文章
GD32F103学习笔记——在GD32F103移植STM32F103代码