FreeRTOS 队列结构 C

Posted

技术标签:

【中文标题】FreeRTOS 队列结构 C【英文标题】:FreeRTOS Queue Struct C 【发布时间】:2017-06-08 22:10:57 【问题描述】:

我不明白如何声明可用于在 FreeRTOS 中的两个线程之间发送数据的结构。

我有两个线程,一个应该用数据填充结构,另一个应该从结构中读取数据,这些数据是通过消息队列发送的。

数据可以复制也可以通过指针复制,不是大量数据。

在我的 main.c 文件中,我声明了结构并声明了队列和队列句柄: 在 int main(void) 之前:

xQueueHandle LED_Queue_Handle, ChannelFreqQueue;

    struct AMessage

        uint8_t channelID;
        float channelFreq;
;

在 main 我创建队列

ChannelFreqQueue = xQueueCreate(2, sizeof(struct AMessage *));

在需要向队列发送数据的任务中:

static void StopCompThread(void const *argument)

    uint32_t count=0;
    uint8_t ActiveChannel =0;
    uint16_t uartcount =0;
    const float period = 0.0085;
    static float frequency = 0;

    for (;;)
  
        struct AMessage txIdrisData;

        if(xSemaphoreTake(OscStopSem, portMAX_DELAY))       // Timer 17 Callback 8.5ms
        
                    HAL_TIM_Base_Stop_IT(&htim17);
                    __HAL_TIM_SET_COUNTER(&htim17,0);       
                    count = __HAL_TIM_GetCounter(&htim3);
                    uartcount++;


                            uint16_t pinstatus = (uint16_t)GPIOB->ODR & 0x2000;
                            if (pinstatus == 0)
                            
                                ActiveChannel = 0x01;
                            
                            else ActiveChannel = 0x02;

                            if (uartcount == 525)
                            
                                txIdrisData.channelID = ActiveChannel;
                                txIdrisData.channelFreq = frequency;

                                xQueueSend(ChannelFreqQueue, (void *) &txIdrisData,portMAX_DELAY); 

                            

        

     //FORever

 // StopCompThread

然后是需要从队列中接收数据的任务:

static void IDRISThread(void const *argument)
    
        struct AMessage rxIdrisData;    

        float temp = 0.0;
        uint8_t channel = 0;
        char IdrisDataBuf[11] = 0; // 3 Bytes x 4 channels = 12 Bytes
        uint8_t IdrisStatusByte = 0;

        for (;;)
      
          xQueueReceive( ChannelFreqQueue, &( rxIdrisData ), portMAX_DELAY );

            temp = rxIdrisData.channelFreq;
            channel = rxIdrisData.channelID;

            temp = temp * 1000;

            snprintf(IdrisDataBuf, 2, "%.0f",temp); // Channel Data - Counts/Frequency

            if (channel == 0x00)
            
                IdrisDataBuf[2] = 0x00;
            
            if (channel == 0x01)
            
                IdrisDataBuf[2] = 0x01;
            

            uart_send(IdrisDataBuf, 12);


         //FORever

     // IDRISThread

我确信我对如何声明和使用结构有误解,而且我混淆了指针和非指针。我尝试使用此 API 文档作为参考:http://www.freertos.org/a00118.html

如果有人能指出我的错误或帮助我理解可能有助于我理解的伪代码,将不胜感激。

【问题讨论】:

如果将struct AMessage推入队列,为什么在创建队列时使用sizeof(struct AMessage *)?类型不匹配。 【参考方案1】:

为什么不只是对结构进行排队,而不是指向结构的指针,它会简单得多。阅读FreeRTOS Queues documentation page 上的简介,并查看Queue Sets 页面下方的“使用队列集的替代方法”部分。

【讨论】:

【参考方案2】:

您没有空间在队列中存储元素

ChannelFreqQueue = xQueueCreate(2, sizeof(struct AMessage *));

创建 2 个指向 struct AMessage 结构的指针元素。 你需要的是struct AMessage的2个元素数组

ChannelFreqQueue = xQueueCreate(2, sizeof(struct AMessage));

【讨论】:

假设您有一个 32 位系统,您的队列将有 2 个条目长,每个条目有 4 个字节。当您将某些内容发送到队列时,只会将结构的前 4 个字节复制到队列中。当您从队列中接收时,只会将 4 个字节复制回您的结构中。假设没有填充您的结构可能是 5 个字节长。所以LP上面说的就是你需要做的。

以上是关于FreeRTOS 队列结构 C的主要内容,如果未能解决你的问题,请参考以下文章

FreeRTOSFreeRTOS学习笔记(14)— FreeRTOS的消息队列(原生API)

FreeRTOS 通信方式

STM32CubeMX学习笔记(29)——FreeRTOS实时操作系统使用(消息队列)

基于STM32与FreeRTOS的消息传递详解(HAL库)

基于STM32与FreeRTOS的消息传递详解(HAL库)

基于STM32与FreeRTOS的消息传递详解(HAL库)