四、代码编写
基于“freertos_hello_cm4”参考例程,在此基础上完成三个线程的编码。
首先是硬件初始化函数“void BOARD_InitHardware(void)”中的“BOARD_InitBootPins();”中,需要增加RGB灯的GPIO口、UART1复用关系的设定。
void BOARD_InitPins(void)
{
/* Clock Gate Control: Clock enabled. The current clock selection and divider options are locked. */
CLOCK_EnableClock(kCLOCK_PortA);
/* Clock Gate Control: Clock enabled. The current clock selection and divider options are locked. */
CLOCK_EnableClock(kCLOCK_PortC);
/* PORTA24 (pin D6) is configured as PTA24 */
PORT_SetPinMux(PORTA, 24U, kPORT_MuxAsGpio);
PORT_SetPinMux(PORTA, 23U, kPORT_MuxAsGpio);
PORT_SetPinMux(PORTA, 22U, kPORT_MuxAsGpio);
/* PORTC7 (pin N2) is configured as LPUART0_RX */
PORT_SetPinMux(PORTC, 7U, kPORT_MuxAlt3);
/* PORTA25 (pin B5) is configured as LPUART1_RX */
PORT_SetPinMux(PORTA, 25U, kPORT_MuxAlt2);
/* PORTC8 (pin P3) is configured as LPUART0_TX */
PORT_SetPinMux(PORTC, 8U, kPORT_MuxAlt3);
/* PORTA26 (pin A5) is configured as LPUART1_TX */
PORT_SetPinMux(PORTA, 26U, kPORT_MuxAlt2);
}
当然后续还要对输出PWM管脚的复用关系进行定义,然后接着是串口1的初始化。
/**
* @brief 初始化uart配置参数
* @param 无
* @retval 无
*/
void UART_ModeConfig(void)
{
/*定义串口配置参数结构体变量,用于保存串口的配置信息*/
lpuart_config_t config;
/*调用固件库函数得到默认的串口配置参数,在默认的配置参数基础上修改*/
LPUART_GetDefaultConfig(&config);
config.baudRate_Bps = BOARD_CONN_UART_BAUDRATE; //波特率
config.enableRx = true; //是否允许接收数据
config.enableTx = true; //是否允许发送数据
/*调用固件库函数,将修改好的配置信息写入到串口的配置寄存器中*/
LPUART_Init(BOARD_CONN_UART, &config, BOARD_DEBUG_UART_CLK_FREQ);
/*允许接收中断*/
LPUART_EnableInterrupts(BOARD_CONN_UART, kLPUART_RxDataRegFullInterruptEnable);
/*设置中断优先级,*/
NVIC_SetPriority(BOARD_CONN_UART_IRQ, 5);
/*使能中断*/
EnableIRQ(BOARD_CONN_UART_IRQ);
}
main函数中创建三个线程
/*!
* @brief Application entry point.
*/
int main(void)
{
/* Init board hardware. */
BOARD_InitHardware();
Uart_xMutex = xSemaphoreCreateMutex();
xSemaphoreGive(Uart_xMutex);
UART_SendQueHandle = xQueueCreate(2, sizeof(u8 *)); // 创建发送队列
UARTProQueHandle = xQueueCreate(2, UART_BUF_SIZE);
/* Define the init structure for the output LED pin*/
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
/* Init output LED GPIO. */
GPIO_PinInit(BOARD_LED1_GPIO, BOARD_LED1_GPIO_PIN, &led_config);
GPIO_PinInit(BOARD_LED2_GPIO, BOARD_LED2_GPIO_PIN, &led_config);
GPIO_PinInit(BOARD_LED3_GPIO, BOARD_LED3_GPIO_PIN, &led_config);
taskENTER_CRITICAL();
if (xTaskCreate(led_task, "Led_task", configMINIMAL_STACK_SIZE + 100, NULL, led_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
if (xTaskCreate(send_task, "Send_task", configMINIMAL_STACK_SIZE + 100, NULL, send_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
if (xTaskCreate(recv_task, "Recv_task", configMINIMAL_STACK_SIZE + 100, NULL, recv_task_PRIORITY, NULL) !=
pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
taskEXIT_CRITICAL();
vTaskStartScheduler();
for (;;)
;
}
头文件包含
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "semphr.h"
/* Freescale includes. */
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_lpuart.h"
#include "board.h"
#include "app.h"
#include "bsp_uart.h"
任务优先级定义
/* Task priorities. */
#define led_task_PRIORITY 14
#define send_task_PRIORITY 12
#define recv_task_PRIORITY 13
三个线程具体功能代码
static void led_task(void *pvParameters)
{
while(1)
{
vTaskDelay(100U);
GPIO_PortToggle(BOARD_LED1_GPIO, 1u << BOARD_LED1_GPIO_PIN);
vTaskDelay(100U);
GPIO_PortToggle(BOARD_LED2_GPIO, 1u << BOARD_LED2_GPIO_PIN);
vTaskDelay(100U);
GPIO_PortToggle(BOARD_LED3_GPIO, 1u << BOARD_LED3_GPIO_PIN);
PRINTF("-one thread.\r\n");
vTaskDelay(100U);
}
}
static void send_task(void *pvParameters)
{
u8 *pMsg, msgCnt;
while (1)
{
pMsg = NULL;
msgCnt = uxQueueMessagesWaiting(UART_SendQueHandle);
PRINTF("--second thread..\r\n");
if(msgCnt > 0)
{
PRINTF("send queue is %2d\r\n", msgCnt);
if(xQueueReceive(UART_SendQueHandle, &pMsg, portMAX_DELAY)==pdTRUE)
{
if (pMsg != NULL)
{
UART_SendPack(pMsg);
vPortFree(pMsg);
}
}
}
vTaskDelay(100U);
}
}
static void recv_task(void *pvParameters)
{
u8 rcvDat = 0;
u16 len;
u8 tmpBuf[UART_RCV_SIZE]={0};
while (1)
{
PRINTF("---third thread...\r\n");
if (xQueueReceive(UARTProQueHandle, &tmpBuf, 0xff) == pdTRUE)
{
PRINTF("recv data %2d\r\n", tmpBuf[0]);
len = MTH_ARR_WRD(tmpBuf);
if(UARTRcvPro(tmpBuf+2 , &len, rcvDat)) // 获取一帧数据
{
GPIO_PinWrite(BOARD_LED3_GPIO,BOARD_LED3_GPIO_PIN,1);
vTaskDelay(20U);
GPIO_PinWrite(BOARD_LED3_GPIO,BOARD_LED3_GPIO_PIN,0);
vTaskDelay(20U);
}
}
vTaskDelay(100U);
}
}