美文网首页
FreeRTOS操作系统例程(8):消息队列

FreeRTOS操作系统例程(8):消息队列

作者: 闵许可 | 来源:发表于2019-05-28 18:01 被阅读0次

    安富莱电子 www.armfly.com

    安富莱_STM32-V5开发板_FreeRTOS教程(V1.0)

    static QueueHandle_t xQueue1 = NULL;

    static QueueHandle_t xQueue2 = NULL;

    typedef struct Msg

    {

    uint8_t ucMessageID;

    uint16_t usData[2];

    uint32_t ulData[2];

    }MSG_T;

    MSG_T g_tMsg;

    /*

    *********************************************************************************************************

    *  函 数 名: AppObjCreate

    *  功能说明: 创建任务通信机制

    *  形 参: 无

    *  返 回 值: 无

    *********************************************************************************************************

    */

    static void AppObjCreate (void)

    {

    /* 创建 10 个 uint8_t 型消息队列 */

    xQueue1 = xQueueCreate(10, sizeof(uint8_t));

    if( xQueue1 == 0 )

    {

    /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */

    }

    /* 创建 10 个存储指针变量的消息队列,由于 CM3/CM4 内核是 32 位机,一个指针变量占用 4 个字节 */

    xQueue2 = xQueueCreate(10, sizeof(struct Msg *));

    if( xQueue2 == 0 )

    {

    /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */

    }

    }

    /*向 xQueue1 发送数据 */

    //初始化定义

    uint8_t ucCount = 0;

    /* while循环里实现向 xQueue2 发送数据 */

    ucCount++;

    /* 向消息队列发数据,如果消息队列满了,等待 10 个时钟节拍 */

    if( xQueueSend(xQueue1,

                              (void *) &ucCount,

                              (TickType_t)10) != pdPASS )

    {

    /* 发送失败,即使等待了 10 个时钟节拍 */

    printf("向 xQueue1 发送数据失败,即使等待了 10 个时钟节拍\r\n");

    }

    else

    {

    /* 发送成功 */

    printf("向 xQueue1 发送数据成功\r\n");

    }

    /* 向 xQueue2 发送数据 */

    //初始化定义

    MSG_T *ptMsg;

    /* 初始化结构体指针 */

    ptMsg = &g_tMsg;

    /* 初始化数组 */

    ptMsg->ucMessageID = 0;

    ptMsg->ulData[0] = 0;

    ptMsg->usData[0] = 0;

    /* while循环里实现向 xQueue2 发送数据 */

    ptMsg->ucMessageID++;

    ptMsg->ulData[0]++;;

    ptMsg->usData[0]++;

    /* 使用消息队列实现指针变量的传递 */

    if(xQueueSend(xQueue2, /* 消息队列句柄 */

                             (void *) &ptMsg, /* 发送结构体指针变量 ptMsg 的地址 */

                             (TickType_t)10) != pdPASS )

    {

    /* 发送失败,即使等待了 10 个时钟节拍 */

    printf("向 xQueue2 发送数据失败,即使等待了 10 个时钟节拍\r\n");

    }

    else

    {

    /* 发送成功 */

    printf("向 xQueue2 发送数据成功\r\n");

    }

    xQueueReceive接收消息队列中的数据

    static QueueHandle_t xQueue1 = NULL;

    /*

    *********************************************************************************************************

    *  函 数 名: vTaskMsgPro

    *  功能说明: 使用函数 xQueueReceive 接收任务 vTaskTaskUserIF 发送的消息队列数据(xQueue1)

    *  形 参: pvParameters 是在创建该任务时传递的形参

    *  返 回 值: 无

    * 优 先 级: 3

    *********************************************************************************************************

    */

    static void vTaskMsgPro(void *pvParameters)

    {

    BaseType_t xResult;

    const TickType_t xMaxBlockTime = pdMS_TO_TICKS(300); /* 设置最大等待时间为 300ms */

    uint8_t ucQueueMsgValue;

    while(1)

    {

    xResult = xQueueReceive(xQueue1, /* 消息队列句柄 */

                                               (void *)&ucQueueMsgValue, /* 存储接收到的数据到变量 ucQueueMsgValue 中 */

                                               (TickType_t)xMaxBlockTime);/* 设置阻塞时间 */

    if(xResult == pdPASS)

    {

    /* 成功接收,并通过串口将数据打印出来 */

    printf("接收到消息队列数据 ucQueueMsgValue = %d\r\n", ucQueueMsgValue);

    }

    else

    {

    /* 超时 */

    bsp_LedToggle(1);

    bsp_LedToggle(4);

    }

    }

    }

    /*

    *********************************************************************************************************

    *  函 数 名: vTaskLED

    *  功能说明: 使用函数 xQueueReceive 接收任务 vTaskTaskUserIF 发送的消息队列数据(xQueue2)

    *  形 参: pvParameters 是在创建该任务时传递的形参

    *  返 回 值: 无

    * 优 先 级: 2

    *********************************************************************************************************

    */

    static void vTaskLED(void *pvParameters)

    {

    MSG_T *ptMsg;

    BaseType_t xResult;

    const TickType_t xMaxBlockTime = pdMS_TO_TICKS(200); /* 设置最大等待时间为 200ms */

    while(1)

    {

    xResult = xQueueReceive(xQueue2, /* 消息队列句柄 */

                                              (void *)&ptMsg, /* 这里获取的是结构体的地址 */

                                              (TickType_t)xMaxBlockTime);/* 设置阻塞时间 */

    if(xResult == pdPASS)

    {

    /* 成功接收,并通过串口将数据打印出来 */

    printf("接收到消息队列数据 ptMsg->ucMessageID = %d\r\n", ptMsg->ucMessageID);

    printf("接收到消息队列数据 ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0]);

    printf("接收到消息队列数据 ptMsg->usData[0] = %d\r\n", ptMsg->usData[0]);

    }

    else

    {

    /* 超时 */

    bsp_LedToggle(2);

    bsp_LedToggle(3);

    }

    }

    }

    中断方式 

     bsp_InitHardTimer(); /* 初始化 TIM2 定时器 */

    /*按键或什么外部触发启动定时器*/

    printf("启动单次定时器中断,50ms 后在定时器中断给任务 vTaskMsgPro 发送消息\r\n");

    bsp_StartHardTimer(1 ,50000, (void *)TIM_CallBack1);

    printf("启动单次定时器中断,50ms 后在定时器中断给任务 vTaskLED 发送消息\r\n");

    bsp_StartHardTimer(2 ,50000, (void *)TIM_CallBack2);

    函数 xQueueSendFromISR 在中断服务程序中的使用方法

    /*

    *********************************************************************************************************

    *  函 数 名: TIM_CallBack1 和 TIM_CallBack2

    *  功能说明: 定时器中断的回调函数,此函数被 bsp_StartHardTimer 所调用。

    *  形 参: 无

    *  返 回 值: 无

    *********************************************************************************************************

    */

    static uint32_t g_uiCount = 0; /* 设置为全局静态变量,方便数据更新 */

    static void TIM_CallBack1(void)

    {

    BaseType_t xResult;

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    /* 中断消息处理,此处省略 */

    ……

    g_uiCount++;

    /* 向消息队列发数据 */

    xQueueSendFromISR(xQueue1,

                                        (void *)&g_uiCount,

                                        &xHigherPriorityTaskWoken);

    /* 如果 xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

    }

    static void TIM_CallBack2 (void)

    {

    MSG_T *ptMsg;

    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    /* 中断消息处理,此处省略 */

    ……

    /* 初始化结构体指针 */

    ptMsg = &g_tMsg;

    /* 初始化数组 */

    ptMsg->ucMessageID++;

    ptMsg->ulData[0]++;

    ptMsg->usData[0]++;

    /* 向消息队列发数据 */

    xQueueSendFromISR(xQueue2,

                                        (void *)&ptMsg,

                                        &xHigherPriorityTaskWoken);

    /* 如果 xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */

    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

    }

    相关文章

      网友评论

          本文标题:FreeRTOS操作系统例程(8):消息队列

          本文链接:https://www.haomeiwen.com/subject/ztggzqtx.html