天马行空 发表于 2023-6-4 10:28:15

突然发觉threadx的队列使用有很大的局限性

看到threadx所有的例程都是TX_1_ULONG发送4个字节为一个消息包。

如果想把一个总共20字节的结构体做为一个消息包一次性发送,用TX_4_ULONG不够,一次发不完;用TX_8_ULONG一发就死了,死掉的原因是queue内部复制结构体数据时超范围了。。。。
个人觉得threadX的队列用起来真不如FreeRTOS的方便。

The_One 发表于 2023-6-4 12:12:01

20个字节,算下来也就5个字,你用TX_8_ULONG不就多了3个字?

zhangjinxing 发表于 2023-6-4 12:31:28

;P,其他操作系统一次最多只能发送 4 字节。大容量消息,可以发送指针就可以了。

way2888 发表于 2023-6-4 15:05:54

数据量大发地址,效率更高

天马行空 发表于 2023-6-4 19:00:24

结构体数据内部有读和写之分,多个任务可以修改结构体的数据和读写权限,,,每个消息都是一个独立的数据包,tx_queue_receive端收到消息就处理,用指针感觉不太方便。

eric2013 发表于 2023-6-5 00:09:02

如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例,他的消息队列是数据的复制粘贴,FreeRTOS也是,区别的地方是ThreadX限制了最大复制粘贴数,因为数据量多了之后,复制粘贴比较耽误时间。

针对楼主的情况,其实用其它RTOS实现也非常简单。以ThreadX为例,他有个内存池的动态内存管理,你要做的是消息队列发送前申请你需要的动态内存并填充数据,然后传递地址即可。接收端获取数据地址后,提取数据,释放动态内存。其实FreeRTOS消息队列就是这种玩法实现的。

fyyxxm 发表于 2023-6-5 08:38:52

freertos随便发,的确还是很好用的。

morning_enr6U 发表于 2023-6-5 12:18:57

那是编程人员自己的应用场景比较轻量化,懒省事这么做,没啥毛病。 一旦你开始追求效率,‘’零拷贝‘’的需求,你就有了。然后,你必然导向硬汉大哥给你的建议。

天马行空 发表于 2023-6-5 12:45:49

硬汉的建议给了我另一种解决问题的思路,值得一试,谢谢!各个系统的区别还是挺大的,要想玩转它,还得像硬汉那样整明白系统的原理才行。

zxwhy2008 发表于 2023-6-18 11:13:09

表面上的使用方便,是以背后的复杂性为代价的。

xiaomeng 发表于 2023-12-3 18:58:29

eric2013 发表于 2023-6-5 00:09
如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例, ...

发送端申请内存,接收端释放内存;
有demo吗

天马行空 发表于 2023-12-4 09:28:57

最近发现threadx最新版本的队列发送源代码跟以前旧版的不一样了,貌似改进了。

eric2013 发表于 2023-12-4 10:41:43

xiaomeng 发表于 2023-12-3 18:58
发送端申请内存,接收端释放内存;
有demo吗

调用那个动态申请API,申请个空间给消息队列使用即可

eric2013 发表于 2023-12-4 10:41:59

天马行空 发表于 2023-12-4 09:28
最近发现threadx最新版本的队列发送源代码跟以前旧版的不一样了,貌似改进了。

最新的6.3.0 ? 改天我试试。

lililili 发表于 2023-12-4 10:44:17

eric2013 发表于 2023-6-5 00:09
如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例, ...

正儿八经用法{:8:}

nnqtdf 发表于 2024-2-21 15:30:36

FreeRTOS里的xQueueOverwrite()和xQueuePeek()这种覆写功能也很好,ThreadX里没有,我用全局变量加互斥信号实现了,还有其他好的方法吗?

eric2013 发表于 2024-2-22 09:20:20

nnqtdf 发表于 2024-2-21 15:30
FreeRTOS里的xQueueOverwrite()和xQueuePeek()这种覆写功能也很好,ThreadX里没有,我用全局变量加互斥信号 ...

threadx/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c at master · eclipse-threadx/threadx (github.com)


BaseType_t xQueueOverwrite(QueueHandle_t xQueue,
                           const void * pvItemToQueue)
{
    TX_INTERRUPT_SAVE_AREA;
    UINT ret;
    UINT read_post;
    uint8_t *p_write_temp;

    configASSERT(xQueue != NULL);
    configASSERT(pvItemToQueue != NULL);

    read_post = 0u;
    TX_DISABLE;

    if(xQueue->read_sem.tx_semaphore_count != 0u) {
      // Go back one message.
      p_write_temp = xQueue->p_write;
      if(p_write_temp == xQueue->p_mem) {
            p_write_temp = (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)));
      } else {
            p_write_temp -= xQueue->msg_size;
      }

      memcpy(p_write_temp, pvItemToQueue, xQueue->msg_size);
    } else {
      memcpy(xQueue->p_write, pvItemToQueue, xQueue->msg_size);
      if(xQueue->p_write >= (xQueue->p_mem + (xQueue->msg_size * (xQueue->queue_length - 1u)))) {
            xQueue->p_write = xQueue->p_mem;
      } else {
            xQueue->p_write += xQueue->msg_size;
      }
      read_post = 1u;
    }

    TX_RESTORE;

    if(read_post == 1u) {
      // Signal that there is an additional message available on the queue.
      ret = tx_semaphore_put(&xQueue->read_sem);
      if(ret != TX_SUCCESS) {
            TX_FREERTOS_ASSERT_FAIL();
            return pdFALSE;
      }
    }

    return pdPASS;
}

BaseType_t xQueuePeek(QueueHandle_t xQueue,
                      void *pvBuffer,
                      TickType_t xTicksToWait)
{
    TX_INTERRUPT_SAVE_AREA;
    UINT timeout;
    UINT ret;

    configASSERT(xQueue != NULL);
    configASSERT(pvBuffer != NULL);

    if(xTicksToWait ==portMAX_DELAY) {
      timeout = TX_WAIT_FOREVER;
    } else {
      timeout = (UINT)xTicksToWait;
    }

    // Wait for a message to be available on the queue.
    ret = tx_semaphore_get(&xQueue->read_sem, timeout);
    if(ret != TX_SUCCESS) {
      return pdFAIL;
    }

    // Retrieve the message.
    TX_DISABLE;
    _tx_thread_preempt_disable++;

    memcpy(pvBuffer, xQueue->p_read, xQueue->msg_size);

    // Restore the original space on the queue.
    ret = tx_semaphore_put(&xQueue->read_sem);
    if(ret != TX_SUCCESS) {
      TX_FREERTOS_ASSERT_FAIL();
      return pdFALSE;
    }

    _tx_thread_preempt_disable--;
    TX_RESTORE;

    return pdPASS;
}

nnqtdf 发表于 2024-2-22 14:32:36

eric2013 发表于 2024-2-22 09:20
threadx/utility/rtos_compatibility_layers/FreeRTOS/tx_freertos.c at master · eclipse-threadx/thre ...

{:8:}{:8:}{:8:}
页: [1]
查看完整版本: 突然发觉threadx的队列使用有很大的局限性