移植FreerRTOS_PLUS_CLI

一,简介

        最近使用了FreerRTOS_PLUS_CLI 的库,在移植过程中参考了:FreeRTOS-Plus-CLI使用笔记_顶点元的博客-CSDN博客   ,不过还发现了一点需要修改的地方,在这里写一篇记录,方便自己回来查看,也帮助一下正在学习CLI库的人。

官网链接:FreeRTOS Plus CLI - Enable your FreeRTOS application to process command line input

二,准备工作

1,使用STM32CubeIDE,新建一个工程

2,打开FreerRTOS

3,打开USART1 添加DMA传输,可以不打开串口中断

4,准备FreerRTOS_PLUS_CLI库源文件,添加至工程

FreeRTOS-Plus/Source/FreeRTOS-Plus-CLI文件夹下的FreeRTOS_CLI.c/h文件。
FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos文件夹下的Sample-CLI-commands.c和UARTCommandConsole.c文件。
FreeRTOS/Demo/Common/include文件夹下的serial.h文件和FreeRTOS\Demo\CORTEX_STM32F103_Keil\serial文件夹下的serial.c文件
 

 注:Demo使用的是标准库,STM32CubeIDE生成的代码使用HAL库

三,修改代码

1,修改串口中断函数,将收到的数据放入队列

#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

uint8_t usart1_rx_buffer_len;
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

extern uint8_t  usart1_rx_buffer_data[256];
extern QueueHandle_t xRxedChars;

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
 
	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) { //IDLE中断(说明接收到了一帧数据)
	    __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除IDLE中断标志位
	    HAL_UART_DMAStop(&huart1);
	    //usart1_rx_buffer.finish_flag = 1;
	    usart1_rx_buffer_len = 256 - __HAL_DMA_GET_COUNTER(huart1.hdmarx);//hdma_usart1_rx.Instance->NDTR;

	    for(uint16_t i = 0; i < usart1_rx_buffer_len; ++i) {
	      xQueueSendFromISR(xRxedChars, &usart1_rx_buffer_data[i], &pxHigherPriorityTaskWoken);
	    }
	    HAL_UART_Receive_DMA(&huart1, usart1_rx_buffer_data, 256);
	  }

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  
  /* USER CODE END USART1_IRQn 1 */
}

2,修改serial底层代码,这里面主要放的是串口的初始化,传入队列的处理,输出队列的处理

对于初始化队列,main()函数中已经有了,可以直接注释掉,而且它是标准库写的

xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
xComPortHandle xReturn;
//USART_InitTypeDef USART_InitStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
//GPIO_InitTypeDef GPIO_InitStructure;

	/* 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 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
	{
		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;
}

2,对输出函数修改,它是标准库,换成HAL库

signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
{
	signed portBASE_TYPE xReturn;

	if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
	{
		xReturn = pdPASS;
		//USART_ITConfig( USART1, USART_IT_TXE, ENABLE );

	    /*修改:发送队列中有数据,通过轮询方式发送出去 */
		 uint8_t rxChar;
	    if(xQueueReceive(xCharsForTx, &rxChar, 0) == pdTRUE) {
	      if((HAL_UART_GetState(&huart1) & HAL_UART_STATE_BUSY_TX) != HAL_UART_STATE_BUSY_TX) {
	        HAL_UART_Transmit(&huart1, &rxChar, 1, 0xff); //轮询方式将数据发送出去
	      }
	    }
	}else
	{
		xReturn = pdFAIL;
	}

	return xReturn;

}


3,对输入中断函数修改

void vUARTInterruptHandler( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
char cChar;

	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) != RESET )
	{
		/* 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 );
			HAL_UART_Transmit(&huart1, (uint8_t*)&cChar, 1,0xff);

		}
		else
		{
			//USART_ITConfig( USART1, USART_IT_TXE, DISABLE );
			__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);

		}
	}

	if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)
	{
		//cChar = USART_ReceiveData( USART1 );
		cChar = (uint8_t)(huart1.Instance->DR & 0xFF);

		xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
	}

	portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

4,FreeRTOSConfig.h文件添加configCOMMAND_INT_MAX_OUTPUT_SIZE宏的定义

/****************************************************************
            FreeRTOS Plus CLI相关的配置                         
****************************************************************/
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1024


5,修改main()函数

#include "FreeRTOS_CLI.h"
#include "serial.h"

uint8_t  usart1_rx_buffer_data[256];

//在main()中添加

void main(void){

//************//
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
  HAL_UART_Receive_DMA(&huart1, usart1_rx_buffer_data, 256);
  vRegisterSampleCLICommands();
  vUARTCommandConsoleStart( 512, 1 );

}

四,使用

通过串口助手发送指令就可以了,记得指令要加\r\n

下一次出如何添加指令

以上提到的源代码:CSDN

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我小何就行了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值