STM32使用FreeRTOS CLI

这是FreeRTOS带有的命令行形式的操作。

使用HAL库的串口传输。在CubeMX里打开串口的中断,打开FreeRTOS的USE_TRACE_FACILITY和USE_STATS_FORMATTING_FUNCTIONS,这两个用于任务基本信息查询,Sample-CLI-commands里的一个命令示例函数需要用到。

STM32使用FreeRTOS CLI_第1张图片

STM32使用FreeRTOS CLI_第2张图片GENERATE...这个暂时可以不用,在扩展的时候用。

从源码中得到以下6个文件:

FreeRTOSv10.2.1\FreeRTOS\Demo\CORTEX_STM32F103_Keil\serial\serial.c

FreeRTOSv10.2.1\FreeRTOS\Demo\Common\include\serial.h

FreeRTOSv10.2.1\FreeRTOS-Plus\Source\FreeRTOS-Plus-CLI\FreeRTOS_CLI.c和FreeRTOS_CLI.h

FreeRTOSv10.2.1\FreeRTOS-Plus\Demo\Common\FreeRTOS_Plus_CLI_Demos\UARTCommandConsole.c和Sample-CLI-commands.c

STM32使用FreeRTOS CLI_第3张图片注:这里我改成了c++文件,其实是不用改的,原本就是c文件

1、在FreeRTOS_CLI头文件里加上#define configCOMMAND_INT_MAX_OUTPUT_SIZE 500,这是用来定义输出缓存的大小,命令会将数据一次性全部复制到这里面,300起步。太小会因为数组不够导致只能回显一部分。

STM32使用FreeRTOS CLI_第4张图片

 

2、

(1)、在serial源文件里添加:

#include "main.h"

extern UART_HandleTypeDef huart1;

uint8_t aRxBuffer;

STM32使用FreeRTOS CLI_第5张图片

(2)、将xSerialPortInitMinimal函数里的开头的部分结构体定义删掉。再把if ((xRxedChars != serINVALID_QUEUE) && (xCharsForTx != serINVALID_QUEUE)){}里的内容替换为HAL_UART_Receive_IT(&huart1, &aRxBuffer, 1);,因为串口初始化已经自动被CubeMX配置好了,这条函数的作用是当接收到1字节后就调用HAL_UART_RxCpltCallback函数。

STM32使用FreeRTOS CLI_第6张图片

(3)、将xSerialPutChar函数里的if (xQueueSend(xCharsForTx, &cOutChar, xBlockTime) == pdPASS){}里的内容替换为:

xReturn = pdPASS;

uint8_t cChar;

if (xQueueReceive(xCharsForTx, &cChar, 0) == pdTRUE) { while(HAL_UART_Transmit_IT(&huart1, &cChar, 1) != HAL_OK); }。这里不能用阻塞式的函数,否则在回显的时候有问题,还导致接收也有问题。很可能是HAL库的问题,有看到过讨论这种问题的文章,可能和__HAL_LOCK有关。

STM32使用FreeRTOS CLI_第7张图片

(4)、删掉vUARTInterruptHandler函数。再添加:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

    if (huart->Instance == USART1)

    {

        portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

        xQueueSendFromISR(xRxedChars, &aRxBuffer, &xHigherPriorityTaskWoken);

        HAL_UART_Receive_IT(&huart1, &aRxBuffer, 1);

    }

}

STM32使用FreeRTOS CLI_第8张图片

3、在UARTCommandConsole源文件里,将

static void prvUARTCommandConsoleTask( void *pvParameters );

void vUARTCommandConsoleStart( uint16_t usStackSize, UBaseType_t uxPriority );这两条函数声明去掉。

添加extern void vRegisterSampleCLICommands( void );,这个用于添加cli的命令。

STM32使用FreeRTOS CLI_第9张图片

注:extern "C"的作用是将函数从C++接口改为C接口,只用C就就只要添加extern void vRegisterSampleCLICommands( void );。

将vUARTCommandConsoleStart函数里的:

xTxMutex = xSemaphoreCreateMutex();

configASSERT( xTxMutex );

移到下面的prvUARTCommandConsoleTask函数里面的for( ;; )的前面,再删掉vUARTCommandConsoleStart函数。

把vRegisterSampleCLICommands函数放到prvUARTCommandConsoleTask的for( ;; )前面。

STM32使用FreeRTOS CLI_第10张图片

4、在main源文件里添加extern void prvUARTCommandConsoleTask( void *pvParameters );,再将该函数作为任务函数来配置,栈用128 * 8的大小。

STM32使用FreeRTOS CLI_第11张图片

STM32使用FreeRTOS CLI_第12张图片

现在在单片机每次开机就会从串口输出一段话。\n和\r都可以作为回车。发送help\n,会将已经添加的命令都发送回来。

STM32使用FreeRTOS CLI_第13张图片

注:在Sample-CLI-commands源文件里有两处strncat( pcWriteBuffer, "\r\n", strlen( "\r\n" ));,这个函数不对,需要在strlen( "\r\n" )后面写+1,因为需要将最后面的空字符也拼接上去。即使不改,在使时也没发现有问题。

 

扩展:

说明:打开Sample-CLI-commands源文件的prvRunTimeStatsCommand函数,这样可以查询每个任务的运行时间的占空比。

方法:在CubeMX里打开FreeRTOS的USE_TRACE_FACILITY、USE_STATS_FORMATTING_FUNCTIONS和GENERATE_RUN_TIME_STATS。

在FreeRTOSConfig头文件里的最下面有两个宏定义:

#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats

#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue

这两个都是函数名,是自带的弱函数。configureTimerForRunTimeStats函数是一个用于初始化的函数,可以不用。getRunTimeCounterValue函数则是关键,它返回一个值,这个值必须是不断累加的,用于计算任务执行时间的占比。例:

unsigned long getRunTimeCounterValue(void)

{

return xTaskGetTickCount(); //返回当前滴答数

}。在任意文件的任意位置定义这个函数即可。

你可能感兴趣的:(MCU)