ThreadX学习(9)——消息队列

学习参考

消息队列

消息队列是ThreadX中线程间(以及线程和中断间)通信的主要手段。

tx_queue_send服务将消息放置在队列的后面,tx_queue_ receive服务将消息从队列的前面移除。

作用

为什么需要消息队列,而不直接使用全局数组?

在裸机编程时,使用全局数组的确比较方便,但是在加上 RTOS 后就是另一种情况了。

相比消息队列,使用全局数组主要有如下四个问题:

  • 使用消息队列可以有效管理线程,而全局数组无法做到,线程的超时机制需要用户自己去实现。
  • 使用全局数组要防止多线程的访问冲突,而使用消息队列则处理好了这个问题,用户无需担心。
  • 使用消息队列可以有效地解决中断服务程序与线程之间消息传递的问题。
  • FIFO 机制更有利于数据的处理。

消息流向

消息发送端将消息复制到队列中,然后队列将消息复制到消息接收端。

如果消息队列为空,消息接收端等待并挂起,那么当消息发送端准备发送时,该消息会绕过队列,直接复制到接收端。

队列缓存

队列用于缓冲消息的内存区域在队列创建期间指定。

它可以位于目标地址空间的任何位置。这是一个重要的特性,因为它为应用程序提供了相当大的灵活性。

例如,应用程序可以在高速RAM中定位一个非常重要的队列的内存区域,以提高性能。

线程挂起

当线程向一个满的队列发送消息,或者从一个空的队列接收消息时,会被挂起。

消息大小

创建队列时指定消息大小,消息大小为1-16个32位字(4-64B)。

也就是说,每次调用tx_queue_send函数,只能发送最多64B的消息。因此,消息队列不适合传输大量数据。

有一种说法是可以发送数据的指针,已完成大量数据的传输,那么就需要提前把指针的空间分配好,然后还要提供数据的大小。

或者直接在_txe_queue_create函数中修改消息大小的限制。

队列大小

用户创建消息队列时,需要自己设置队列的总大小和每个消息的大小,以此来得出队列可容纳的消息数量。

可容纳消息数量 = 队列的总大小 / 每个消息大小

如果不能整除,则不会使用剩余字节。

API

1.tx_queue_create

TX_QUEUE queue_ptr;//先定义再创建

UINT  tx_queue_create(	TX_QUEUE *queue_ptr, 
						CHAR *name_ptr, 
						UINT message_size, 
						VOID *queue_start, 
						ULONG queue_size)

创建消息队列:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 第 2 个参数 name_ptr 是消息队列名称字符串。
  • 第 3 个参数 message_size 是每个消息的大小。
  • 第 4 个参数 queue_start 是消息队列缓冲区的起始地址。起始地址必须与ULONG数据类型的大小对齐。
  • 第 5 个参数 queue_size 是消息队列的总大小。
  • 返回值:
    • TX_SUCCESS:(0x00)成功创建消息队列。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。要么指针是NULL,要么队列已经创建。
    • TX_PTR_ERROR: (0x03)无效的消息队列起始地址。
    • TX_SIZE_ERROR: (0x05)消息队列大小无效。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。

2.tx_queue_send

UINT  tx_queue_send(TX_QUEUE *queue_ptr, 
					VOID *source_ptr, 
					ULONG wait_option)

发送消息:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 第 2 个参数 source_ptr 是需发送消息的指针。
  • 第 3 个参数 wait_option 是等待选项:
    • TX_NO_WAIT (0x00000000),表示不管消息队列是否满,立即返回。如果在定时器组,初始
      化或中断里面调用,必须要设置成这个参数。
    • TX_WAIT_FOREVER (0xFFFFFFFF),表示永久等待,直到消息队列有空间可用。
    • 等待时间,范围 0x00000001 到 0xFFFFFFFE,单位为系统时钟节拍。
  • 返回值:
    • TX_SUCCESS: (0x00)消息发送成功。
    • TX_DELETED: (0x01)线程挂起时消息队列被删除。
    • TX_QUEUE_FULL: (0x0B)在指定的等待时间内队列已满。
    • TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、计时器或中断中止。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。
    • TX_PTR_ERROR:(0x03)消息的源指针无效。
    • TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。

3.tx_queue_receive

UINT tx_queue_receive(TX_QUEUE *queue_ptr,
                      VOID *destination_ptr, 
                      ULONG wait_option);

接收消息:

  • 第 1 个参数 queue_ptr 是消息队列的指针。
  • 第 2 个参数 destination_ptr 是接收消息存储的位置。
  • 第 3 个参数 wait_option 是等待选项:
    • TX_NO_WAIT:(0 x00000000)
    • TX_WAIT_FOREVER: (0xFFFFFFFF)
    • 等待时间:(0x00000001 ~ 0xFFFFFFFE)
  • 返回值
    • TX_SUCCESS: (0x00)成功接收消息。
    • TX_DELETED: (0x01)线程挂起时消息队列被删除。
    • TX_QUEUE_EMPTY: (0x0A)等待时间内队列为空。
    • TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、计时器或ISR中止。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。
    • TX_PTR_ERROR:(0x03)无效的接收消息存储指针。
    • TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。

4.tx_queue_info_get

UINT tx_queue_info_get( TX_QUEUE *queue_ptr, 
						CHAR **name,
						ULONG *enqueued, 
						ULONG *available_storage
						TX_THREAD **first_suspended, 
						ULONG *suspended_count,
						TX_QUEUE **next_queue);

获取消息队列信息:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 第 2 个参数 name 是消息队列名字符串,获取后存储的指针。
  • 第 3 个参数 enqueued 是消息队列中现有消息数量,所存储的指针。
  • 第 4 个参数 available_storage 是消息队列中剩余空间,所存储的指针。
  • 第 5 个参数 first_suspended 是消息队列挂起列表的第一个线程,所存储的指针。
  • 第 6 个参数 suspended_count 是消息队列挂起列表的线程数,所存储的指针。
  • 第 7 个参数 next_queue 是下一个消息队列,所存储的指针。
  • 返回值:
    • TX_SUCCESS: (0x00)成功获取队列信息。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。

参数输入TX_NULL(0x00)表示不需要该参数。

5.tx_queue_delete

UINT tx_queue_delete(TX_QUEUE *queue_ptr);

删除消息队列:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 返回值:
    • TX_SUCCESS: (0x00)成功删除消息队列。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。
    • TX_CALLER_ERROR:(0x13)无效的服务调用者。
  • 所有挂起等待此队列的线程都将恢复,并给出TX_DELETED返回状态。

6.tx_queue_flush

UINT tx_queue_flush(TX_QUEUE *queue_ptr);

清空消息队列:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 返回值:
    • TX_SUCCESS: (0x00)成功刷新消息队列。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。

如果队列已满,则丢弃所有挂起线程的消息,然后恢复每个挂起的线程,返回状态表明消息发送成功。如果队列为空,则此服务不执行任何操作。

7.tx_queue_front_send

UINT tx_queue_front_send(TX_QUEUE *queue_ptr,
                         VOID *source_ptr, 
                         ULONG wait_option);

发送紧急消息插队到队首:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 第 2 个参数 source_ptr 是需发送消息的指针。
  • 第 3 个参数 wait_option 是等待选项。
  • 返回值:
    • TX_SUCCESS: (0x00)消息发送成功。
    • TX_DELETED: (0x01)线程挂起时消息队列被删除。
    • TX_QUEUE_FULL: (0x0B)服务无法发送消息,因为在指定的等待时间内队列已满。
    • TX_WAIT_ABORTED: (0x1A)挂起被另一个线程、计时器或ISR中止。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。
    • TX_PTR_ERROR:(0x03)消息的源指针无效。
    • TX_WAIT_ERROR: (0x04)在非线程调用时指定了TX_NO_WAIT以外的等待选项。

8.tx_queue_prioritize

UINT tx_queue_prioritize(TX_QUEUE *queue_ptr);

挂起列表中最高优先级线程提到队首:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 返回值:
    • TX_SUCCESS:(0x00)成功。
    • TX_QUEUE_ERROR:(0x09)无效的消息队列指针。

9.tx_queue_send_notify

UINT  tx_queue_send_notify( TX_QUEUE *queue_ptr,
        					VOID (*queue_send_notify)(TX_QUEUE *));

发送通知回调:

  • 第 1 个参数 queue_ptr 是消息队列控制块指针。
  • 第 2 个参数 queue_send_notify 是队列发送通知函数的指针。如果该值为TX_NULL,则禁用通知。
  • 返回值:
    • TX_SUCCESS: (0x00)队列发送通知注册成功。
    • TX_QUEUE_ERROR:(0x09)无效的队列指针。
    • TX_FEATURE_NOT_ENABLED: (0xFF)系统编译时禁用了通知功能。

当消息被发送到指定队列时将调用queue_send_notify函数(自定义)。发送通知回调不允许调用任何带有挂起选项的 API。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值