MessageQ模块支持可变长度消息的结构化发送和接收。此模块可用于同构(如DSP到DSP)或异构(如ARM到DSP)多处理器消息传递。MessageQ提供了比其他模块更复杂的消息传递。它通常用于复杂的情况,如多处理器消息传递。
以下是MessageQ模块的关键特性:
- 消息的writers和readers可以被重新定位到另一个处理器,而不需要更改运行时代码。
- 接收消息时允许超时。
- readers可以确定writers并回复。
- 当超时为0时,接收消息是确定的。
- 消息可以驻留在任何消息队列上。
- 支持零拷贝转移。
- 可以从任何类型的线程发送和接收。
- 通知机制由应用程序指定。
- 在消息缓冲池上允许QoS(服务质量)。例如,为特定的消息队列使用特定的缓冲池。
消息的发送和接收是通过放置在消息队列上或从消息队列中删除消息来完成的。读取器是一个从消息队列获取(读取)消息的线程。写入器是将消息放入(写入)消息队列的线程。每个消息队列有一个读取器,可以有多个写入器。一个线程可以读写多个消息队列。从概念上讲,读取线程拥有一个消息队列。读取线程创建一个消息队列。写入线程打开一个已创建的消息队列以访问它们。
消息队列由系统范围的惟一名称标识。在内部,MessageQ使用NameServer模块来管理这些名称。这些名称用于打开消息队列。消息必须从MessageQ模块中分配。一旦消息被分配,它就可以被发送到任何消息队列。消息一旦发送,作者就失去了对消息的所有权,不应该试图修改消息。一旦读者收到消息,它就拥有消息。它可以释放消息,也可以重用消息。
消息队列中的消息可以是可变长度的。唯一的要求是消息定义中的第一个字段必须是MessageQ_MsgHeader结构。例如:
typedef struct MyMsg {
MessageQ_MsgHeader header;
...
} MyMsg;
MessageQ API在内部使用MessageQ_MsgHeader。应用程序不应该修改或直接访问MessageQ_MsgHeader中的字段。所有通过MessageQ模块发送的消息都必须从堆中分配。堆还可以用于与MessageQ无关的其他内存分配。一个应用程序可以使用多个堆。拥有多个堆的目的是允许应用程序管理其消息使用。例如,应用程序可以从一个快速片上内存堆中分配关键消息,从另一个较慢的外部备忘录堆中分配非关键消息
MessageQ_registerHeap() API用于将MessageQ堆id分配给堆。在分配消息时,使用的是heapId,而不是堆句柄。这个heapId实际上被放置到消息中(MessageQ_MsgHeader的一部分)。在分配堆ids时必须小心。
MessageQ还支持使用未通过MessageQ_alloc()函数分配的消息。请参考MessageQ_staticMsgInit()函数描述以了解更多细节。
MessageQ支持读/写不同的线程模型。让消息队列的创建者通过MessageQ_Params.synchronizer配置参数来实现。无论何时调用MessageQ_put(),同步器都会收到信号。如果调用MessageQ_get()且没有消息,同步器将等待。
因为ISyncs是二进制的,读取器在等待另一个信号之前必须清空消息队列中的所有消息。例如,如果读取器是SYS/BIOS Swi,那么同步器实例可以是SyncSwi。如果调用了MessageQ_put(),则会调用Swi_post()。Swi将运行,并且它必须调用MessageQ_get(),直到没有消息返回为止。
MessageQ头应该如下所示包含在应用程序中:
#include <ti/ipc/MessageQ.h>