硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1558|回复: 17
收起左侧

[ThreadX全家桶] 突然发觉threadx的队列使用有很大的局限性

  [复制链接]

79

主题

191

回帖

428

积分

高级会员

积分
428
发表于 2023-6-4 10:28:15 | 显示全部楼层 |阅读模式
看到threadx所有的例程都是TX_1_ULONG发送4个字节为一个消息包。

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

使用道具 举报

4

主题

38

回帖

50

积分

初级会员

积分
50
发表于 2023-6-4 12:12:01 | 显示全部楼层
20个字节,算下来也就5个字,你用TX_8_ULONG不就多了3个字?
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2023-6-4 12:31:28 | 显示全部楼层
,其他操作系统一次最多只能发送 4 字节。大容量消息,可以发送指针就可以了。
回复

使用道具 举报

3

主题

56

回帖

65

积分

初级会员

积分
65
发表于 2023-6-4 15:05:54 来自手机 | 显示全部楼层
数据量大发地址,效率更高
回复

使用道具 举报

79

主题

191

回帖

428

积分

高级会员

积分
428
 楼主| 发表于 2023-6-4 19:00:24 | 显示全部楼层
结构体数据内部有读和写之分,多个任务可以修改结构体的数据和读写权限,,,每个消息都是一个独立的数据包,tx_queue_receive端收到消息就处理,用指针感觉不太方便。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2023-6-5 00:09:02 | 显示全部楼层
如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例,他的消息队列是数据的复制粘贴,FreeRTOS也是,区别的地方是ThreadX限制了最大复制粘贴数,因为数据量多了之后,复制粘贴比较耽误时间。

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

使用道具 举报

4

主题

160

回帖

172

积分

初级会员

积分
172
发表于 2023-6-5 08:38:52 | 显示全部楼层
freertos随便发,的确还是很好用的。
回复

使用道具 举报

3

主题

1222

回帖

1231

积分

至尊会员

积分
1231
发表于 2023-6-5 12:18:57 | 显示全部楼层
那是编程人员自己的应用场景比较轻量化,懒省事这么做,没啥毛病。 一旦你开始追求效率,‘’零拷贝‘’的需求,你就有了。然后,你必然导向硬汉大哥给你的建议。
回复

使用道具 举报

79

主题

191

回帖

428

积分

高级会员

积分
428
 楼主| 发表于 2023-6-5 12:45:49 来自手机 | 显示全部楼层
硬汉的建议给了我另一种解决问题的思路,值得一试,谢谢!各个系统的区别还是挺大的,要想玩转它,还得像硬汉那样整明白系统的原理才行。
回复

使用道具 举报

2

主题

10

回帖

16

积分

新手上路

积分
16
发表于 2023-6-18 11:13:09 | 显示全部楼层
表面上的使用方便,是以背后的复杂性为代价的。
回复

使用道具 举报

5

主题

95

回帖

110

积分

初级会员

积分
110
发表于 2023-12-3 18:58:29 | 显示全部楼层
eric2013 发表于 2023-6-5 00:09
如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例, ...

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

使用道具 举报

79

主题

191

回帖

428

积分

高级会员

积分
428
 楼主| 发表于 2023-12-4 09:28:57 来自手机 | 显示全部楼层
最近发现threadx最新版本的队列发送源代码跟以前旧版的不一样了,貌似改进了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2023-12-4 10:41:43 | 显示全部楼层
xiaomeng 发表于 2023-12-3 18:58
发送端申请内存,接收端释放内存;
有demo吗

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2023-12-4 10:41:59 | 显示全部楼层
天马行空 发表于 2023-12-4 09:28
最近发现threadx最新版本的队列发送源代码跟以前旧版的不一样了,貌似改进了。

最新的6.3.0 ? 改天我试试。
回复

使用道具 举报

1

主题

30

回帖

33

积分

新手上路

积分
33
发表于 2023-12-4 10:44:17 | 显示全部楼层
eric2013 发表于 2023-6-5 00:09
如果习惯了FreeRTOS那种玩法,使用ThreadX, uCOS-III,RTX等RTOS的消息队列确实会不顺手,以ThreadX为例, ...

正儿八经用法
回复

使用道具 举报

1

主题

92

回帖

100

积分

初级会员

积分
100
发表于 2024-2-21 15:30:36 | 显示全部楼层
FreeRTOS里的xQueueOverwrite()和xQueuePeek()这种覆写功能也很好,ThreadX里没有,我用全局变量加互斥信号实现了,还有其他好的方法吗?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 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)


[C] 纯文本查看 复制代码
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;
}


[C] 纯文本查看 复制代码
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;
}

回复

使用道具 举报

1

主题

92

回帖

100

积分

初级会员

积分
100
发表于 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 ...

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 16:06 , Processed in 0.391749 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表