【DigiKey&NXP】NXP FRDM-K32L3A6开发板-FreeRTOS系统篇(二)

四、代码编写

基于“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);
    }
}