第7章 任务间的同步与通讯之消息队列
嵌入式实时操作系统试题

1、目前使用的嵌入式操作系统主要有那些?请举出六种常用的。
Windwos CE、Windows Mobile、VxWork、Linux、uCos、Symbian、QNX2、一般而言,嵌入式系统的架构可以分为4个部分,分别是(处理器)、存储器、输入输出和软件,一般软件分为(操作系统)和应用软件两个主要部分。
3、从嵌入式操作系统特点可以将嵌入式操作系统分为(实时操作系统)和分时操作系统,其中实时系统可分为(硬实时系统)和软实时系统4、uc/os操作系统不包括以下哪集中状态A、运行B、挂起C、退出D、休眠5、0x70&0x11的运算结果是A、0x1B、0x11C、0x17D、0x76、下列哪种方式不是ucos操作系统中任务之间的通信方式A、信号量B、消息队列C、邮件D、邮箱7、在将ucos操作系统移植到ARM处理器上时,以下那些文件不需要修改A、OS_CORE.CB、include.hC、OS_CPU.HD、OSTaskInit设计实时操作系统时,首先应该考虑系统的()。
A.可靠性和灵活性B.实时性和可靠性C.分配性和可靠性D.灵活性和实时性2. 大多数嵌入式实时操作系统中,为了让操作系统能够在有突发状态时迅速取得控制权,以作出反映,大都采用()的功能。
A:抢占式任务调度B:时间片轮转调度C:单调速率调度D:FIFO调度8、所有的电子设备都属于嵌入式设备简单题:1、根据嵌入式系统的特点、写出嵌入式系统的定义答:以应用为中心,以计算机技术为基础,软硬件可裁剪、功能、可靠性、成本、体积、功耗严格要求的专用计算机系统2、试分析实时操作系统的工作特点及相互之间的转换运行:获得CPU的控制权就绪:进入任务等待队列,通过调度中转为运行状态挂起:由于系统函数调用而被设置成挂起状态,任务发生阻塞,等待系统实时事件的发生而被唤醒,从而转为就绪或运行。
休眠:任务完成或者错误被清除的任务,该任务此时不具有任务控制块。
消息队列同步和异步

消息队列同步和异步消息队列是一种常用的通信模式,可以实现系统间的数据传输和交互。
在消息队列中,消息的发送和接收可以有两种模式:同步和异步。
同步模式下,消息的发送方需要等待消息的接收方对消息进行处理后才能继续执行后续的操作。
这种模式下,消息发送方会阻塞并等待接收方的响应。
在同步模式中,发送方和接收方之间的交互是实时的,消息的发送和接收是一一对应的。
同步模式可以保证消息的可靠性,但是在处理大量消息时,可能会造成发送方的等待时间变长,影响系统的性能。
异步模式下,消息的发送方不需要等待消息的接收方对消息进行处理,而是可以继续执行后续的操作。
这种模式下,消息发送方发送完消息后就不再关心消息的处理情况,而是继续执行自己的任务。
接收方则可以在自己的时间内对消息进行处理。
异步模式下,发送方和接收方之间的交互是非实时的,消息的发送和接收是解耦的。
异步模式可以提高系统的并发性能,但是在消息的可靠性上需要额外的机制来保证。
消息队列的同步和异步模式各有优缺点,可以根据具体的业务需求来选择使用。
在一些对实时性要求较高的场景中,可以选择使用同步模式,以保证消息的及时处理和可靠性。
而在一些对性能要求较高的场景中,可以选择使用异步模式,以提高系统的并发能力。
在实际应用中,消息队列的同步和异步模式有着广泛的应用。
例如,在电商平台中,订单的生成和支付是一个常见的场景。
在同步模式下,当用户下单后,订单系统会等待支付系统对订单进行支付确认,然后才能继续执行后续的操作。
这样可以保证订单的可靠性,避免用户支付后订单状态不一致的情况。
而在异步模式下,订单系统可以在用户下单后立即返回成功的响应,而支付系统则可以在自己的时间内对订单进行支付处理。
这样可以提高系统的并发性能,减少用户等待的时间。
除了订单支付场景,消息队列的同步和异步模式还可以应用在其他许多场景中。
例如,日志系统可以使用异步模式来提高日志的写入性能;邮件系统可以使用异步模式来提高邮件的发送速度;任务调度系统可以使用异步模式来提高任务的并发处理能力等等。
消息队列的工作原理

消息队列的工作原理消息队列(Message Queue),简称MQ,是一种在分布式系统中应用广泛的通信模型,用于实现异步通信和解耦系统组件之间的关系。
它能够将消息发送方和接收方解耦,并能够提供高度可靠的消息传输机制。
在现代应用开发中,消息队列已成为构建可扩展性和弹性的重要组件之一首先,消息生产者将消息发送到消息队列中,称为将消息入队。
消息队列将消息保存在其中,直到消息被消费者接收和处理。
消息传输是消息队列的核心过程。
消息传输包括两个阶段:将消息从生产者发送到消息队列,和将消息从消息队列发送到消费者。
消息生产者发送消息到消息队列时,可以采用两种方式:发到消息队列的内存中或者写入到磁盘文件中。
这两种方式有各自的优缺点。
如果消息先写入到内存中,速度很快,但是一旦消息队列宕机,消息会丢失。
为了解决这个问题,可以将消息持久化到磁盘文件中。
这种方式可以确保消息的持久性和可靠性,但是会引入磁盘IO开销,降低性能。
当消息到达消息队列后,它会根据一定的策略进行存储和管理。
消息队列通常采用队列(FIFO)的方式进行消息管理。
先发送的消息先被消费,保证消息的顺序性。
消费者在实际处理阶段消费消息。
消费者在注册消息队列时,可以选择两种方式接收消息:主动拉取和被动推送。
主动拉取方式,消费者需要主动地从消息队列中拉取消息,然后进行处理。
这种方式对于消费者来说更加灵活,可以按照自身的处理速度去拉取消息,但需要不断地发送拉取请求,可能会造成额外的网络开销。
被动推送方式,消息队列主动将消息推送给消费者。
消费者在注册时提供一个接收消息的地址,当有消息到达时,消息队列会将消息推送给消费者。
这种方式对于业务量大、实时性要求高的场景更加合适,消费者无需频繁发送拉取请求。
在处理消息过程中,消息队列还提供了一些重要的机制,例如消息持久化、事务消息和消息确认机制。
消息持久化指在消息到达消息队列后,将消息持久化到磁盘文件中。
这样即使消息队列宕机,消息也不会丢失。
消息队列介绍及原理

消息队列介绍及原理消息队列(Message Queue)是一种进程间通信的方式,通过消息的方式进行数据传输和交互。
它将消息按照一定的顺序存放在队列中,接收方可以按照一定的规则从队列中取出消息进行处理。
消息队列常用于分布式系统或异步处理的场景中,它能够实现异步解耦、削峰填谷、异步处理等功能。
同时,消息队列还具有高可用、可靠性强等特点,使得它成为了当前分布式系统中不可或缺的重要组件。
下面将介绍消息队列的原理及其基本特点。
一、消息队列的基本原理消息队列的基本原理可以归纳为三个关键组成部分:生产者、队列和消费者。
1. 生产者(Producer):消息的生产者负责将需要传递的消息发送到队列中。
生产者只负责把消息发送到队列,不需要知道消息被谁接收。
2. 队列(Queue):消息队列是消息传递的媒介,它负责存储所有发送过来的消息。
消息队列通常是基于先进先出(FIFO)原则进行消息的存储和处理。
3. 消费者(Consumer):消费者从队列中获取消息并进行处理。
消费者需要从消息队列中主动获取消息,因此消费者和队列之间是解耦的。
消息队列的基本原理可以表示为:生产者将消息发送到队列,消费者从队列中获取消息进行处理。
生产者和消费者之间通过消息队列实现了解耦,生产者和消费者之间并不直接通信。
二、消息队列的基本特点消息队列具有以下的基本特点,使得它成为了一种重要的分布式系统通信方式。
1.异步解耦:生产者和消费者之间通过消息队列进行通信,生产者发送消息后即可继续其他逻辑处理,而不需要等待消费者的处理结果。
这样能够实现异步解耦,提高系统的响应速度和吞吐量。
2.削峰填谷:队列作为中间媒介,能够将消息暂时存储起来。
当消费者无法及时处理消息时,消息可以在队列中排队等待处理。
这样能够避免突发流量对系统的影响,平滑处理请求,达到平均请求速率。
3.可靠性:消息队列通常具备持久化机制,可以确保消息不会丢失。
即使在生产者发送消息后,但在消费者接收消息之前,如果发生系统故障,消息也不会丢失。
什么是消息队列

什么是消息队列?消息队列是一种在应用程序之间传递消息的通信模式。
它提供了一种异步的、解耦的方式来处理消息的发送和接收。
消息队列通常被用于解决分布式系统中的通信和数据交换问题。
以下是消息队列的一些关键概念和特性:1. 生产者和消费者:消息队列中的消息生产者负责发送消息到队列,而消息消费者则负责从队列中接收和处理消息。
生产者和消费者可以是独立的应用程序,它们通过消息队列实现解耦和异步通信。
2. 消息:消息是生产者发送到消息队列的数据单元。
它可以是任意格式的数据,如文本、JSON、XML等。
消息通常包含一些元数据,如标识符、时间戳等,以帮助消费者处理和识别消息。
3. 队列:队列是消息的存储和传递机制。
它可以是内存中的数据结构或持久化存储。
消息队列通常支持先进先出(FIFO)的消息传递顺序,确保消息按照发送的顺序进行处理。
4. 可靠性:消息队列通常提供可靠性保证,确保消息的可靠传递和处理。
它可以通过持久化消息和确认机制来确保消息不会丢失或重复处理。
消息队列还可以提供消息的持久化存储,以防止系统故障导致消息丢失。
5. 异步通信:消息队列采用异步通信模式,生产者和消费者可以独立地进行操作,不需要直接的即时响应。
这种异步模式可以提高系统的可伸缩性和性能,允许生产者和消费者在不同的速率下运行。
6. 解耦和削峰:消息队列可以实现系统组件之间的解耦,使得系统更加灵活和可维护。
通过将消息发送到队列中,生产者和消费者可以独立地演化和扩展,而不会相互影响。
此外,消息队列还可以用于削峰填谷,即在高峰期缓冲请求,以平稳处理流量。
7. 多模式通信:消息队列通常支持多种通信模式,如点对点(Point-to-Point)和发布/订阅(Publish/Subscribe)。
点对点模式中,消息从一个生产者发送到一个特定的消费者;而发布/订阅模式中,消息被广播到多个订阅者。
消息队列在许多应用场景中得到广泛应用,特别是在分布式系统和微服务架构中。
消息队列的原理

消息队列的原理
消息队列是一种在应用程序之间实现异步通信的机制。
它是基于生产者-消费者模式的,即一个或多个生产者将消息放入队
列中,一个或多个消费者从队列中获取消息进行处理。
消息队列的原理如下:
1. 生产者发送消息:生产者将消息发送到消息队列中。
消息可以是任何形式的数据,如文本、图像、音频等。
2. 消息队列存储消息:消息队列是一个存储消息的缓冲区,它可以按照先进先出(FIFO)的顺序存储消息。
消息队列一般
基于内存或者持久化存储。
3. 消费者获取消息:消费者可以在任何时候从消息队列中获取消息。
消费者可以单个或批量获取消息,具体取决于实现方式。
4. 消费者处理消息:消费者获取到消息后,将对消息进行处理。
处理方式可以是执行特定的业务逻辑、将消息写入数据库、发送到其他系统等。
5. 消息确认和删除:消费者在处理完消息后,可以向消息队列发送确认消息,告知消息队列该消息已经成功处理。
消息队列接收到确认消息后,将删除该消息。
6. 处理失败的消息:如果消费者在处理消息时发生错误,可以进行相应的错误处理,例如记录日志、重试处理、发送到死信队列等。
消息队列的好处包括解耦、削峰填谷、提高系统可伸缩性、提高系统可靠性等。
它常用于处理高并发、异步处理、系统解耦等场景。
消息队列原理

消息队列原理消息队列是一种在分布式系统中常用的通信方式,它可以在不同的组件之间传递消息,实现解耦和异步通信。
在实际应用中,消息队列被广泛应用于日志收集、事件驱动、任务调度等场景。
本文将介绍消息队列的原理及其应用。
首先,消息队列是一种基于生产者-消费者模型的通信方式。
生产者负责产生消息并将其发送到消息队列中,而消费者则从消息队列中获取消息并进行处理。
这种模型能够有效地解耦生产者和消费者,使它们能够独立地演化和扩展,提高系统的可靠性和可扩展性。
其次,消息队列通常由消息中间件来实现,消息中间件可以是开源的,也可以是商业化的。
消息中间件提供了消息存储、消息传递、消息路由等功能,能够保证消息的可靠性、顺序性和一致性。
常见的消息中间件包括RabbitMQ、Kafka、ActiveMQ等。
消息队列的原理包括消息的生产、消息的存储和消息的消费。
生产者将消息发送到消息队列中,消息队列将消息存储在其中,并将消息传递给消费者。
消费者从消息队列中获取消息并进行处理。
消息队列通常支持多种消息传递模式,包括点对点模式和发布-订阅模式。
在点对点模式中,消息队列将消息传递给一个消费者进行处理,消息在传递过程中只能被一个消费者接收。
而在发布-订阅模式中,消息队列将消息传递给多个消费者进行处理,消息在传递过程中可以被多个消费者接收。
这两种模式能够满足不同的业务需求,提高系统的灵活性和可扩展性。
消息队列的应用场景非常广泛。
在日志收集方面,消息队列能够帮助系统实时地收集和处理大量的日志数据,提高系统的监控和分析能力。
在事件驱动方面,消息队列能够帮助系统实现异步通信,提高系统的响应速度和吞吐量。
在任务调度方面,消息队列能够帮助系统实现任务的分发和执行,提高系统的任务处理能力。
总之,消息队列是一种在分布式系统中常用的通信方式,它能够帮助系统实现解耦和异步通信,提高系统的可靠性和可扩展性。
消息队列的原理包括消息的生产、消息的存储和消息的消费,它通常由消息中间件来实现。
详解linux进程间通信-消息队列

详解linux进程间通信-消息队列前⾔:前⾯讨论了信号、管道的进程间通信⽅式,接下来将讨论消息队列。
⼀、系统V IPC 三种系统V IPC:消息队列、信号量以及共享内存(共享存储器)之间有很多相似之处。
每个内核中的 I P C结构(消息队列、信号量或共享存储段)都⽤⼀个⾮负整数的标识符( i d e n t i f i e r )加以引⽤。
⽆论何时创建I P C结构(调⽤m s g g e t、 s e m g e t或s h m g e t) ,都应指定⼀个关键字(k e y),关键字的数据类型由系统规定为 k e y _ t,通常在头⽂件< s y s / t y p e s . h >中被规定为长整型。
关键字由内核变换成标识符。
以上简单介绍了IPC,对接下来介绍的消息队列、信号量和共享内存有助于理解。
⼆、消息队列 1、简介 消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。
我们将称消息队列为“队列”,其标识符为“队列 I D”。
m s g g e t⽤于创建⼀个新队列或打开⼀个现存的队列。
m s g s n d⽤于将新消息添加到队列尾端。
每个消息包含⼀个正长整型类型字段,⼀个⾮负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给 m s g s n d。
m s g r c v⽤于从队列中取消息。
我们并不⼀定要以先进先出次序取消息,也可以按消息的类型字段取消息。
2、函数介绍ftok函数#include <sys/types.h>#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'功能:⽣成⼀个key(键值)msgget函数#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int msgflg);功能:创建或取得⼀个消息队列对象返回:消息队列对象的id 同⼀个key得到同⼀个对象格式:msgget(key,flag|mode);flag:可以是0或者IPC_CREAT(不存在就创建)mode:同⽂件权限⼀样msgsnd函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);功能:将msgp消息写⼊标识为msgid的消息队列msgp:struct msgbuf {long mtype; /* message type, must be > 0 */消息的类型必须>0char mtext[1]; /* message data */长度随意};msgsz:要发送的消息的⼤⼩不包括消息的类型占⽤的4个字节msgflg:如果是0 当消息队列为满 msgsnd会阻塞如果是IPC_NOWAIT 当消息队列为满时不阻塞⽴即返回返回值:成功返回id 失败返回-1msgrcv函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);功能:从标识符为msgid的消息队列⾥接收⼀个指定类型的消息并存储于msgp中读取后把消息从消息队列中删除msgtyp:为 0 表⽰⽆论什么类型都可以接收msgp:存放消息的结构体msgsz:要接收的消息的⼤⼩不包含消息类型占⽤的4字节msgflg:如果是0 标识如果没有指定类型的消息就⼀直等待如果是IPC_NOWAIT 则表⽰不等待msgctl函数int msgctl(int msqid, int cmd, struct msqid_ds *buf);msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象 程序2-2将简单演⽰消息队列: --- snd.c ---#include "my.h"typedef struct{long type;char name[20];int age;}Msg;int main(){key_t key = ftok("/home/liudw",'6');printf("key:%x\n",key);int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);if(msgid<0){perror("msgget error!");exit(-1);}Msg m;puts("please input your type name age:");scanf("%ld%s%d",&m.type,,&m.age);msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);return0;} --- rcv.c ---#include "my.h"typedef struct{long type;char name[20];int age;}Msg;int main(){key_t key = ftok("/home/liudw",'6');printf("key:%x\n",key);int msgid = msgget(key,O_RDONLY);if(msgid<0){perror("msgget error!");exit(-1);}Msg rcv;long type;puts("please input type you want!");scanf("%ld",&type);msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);printf("rcv--name:%s age:%d\n",,rcv.age);msgctl(msgid,IPC_RMID,NULL);return0;} 运⾏演⽰: 三、详解ftok函数 ftok根据路径名,提取⽂件信息,再根据这些⽂件信息及project ID合成key,该路径可以随便设置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
pevent:指向即将接收消息的队列的指针。
timeout:允许一个任务在经过了指定数目的时钟节拍后还没有得到需 要的消息时恢复运行状态。
err:指向包含错误码的变量的指针。OSQPend()函数返回的错误码可 能为下述几种:
OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()
等待消息队列中的消息 向消息队列发送消息 FIFO 向消息队列发送消息 LIFO 以可选方式向消息队列发送消息 FIFO 或 LIFO 无等待地从消息队列中获得消息 清空消息队列 查询消息队列的状态
删除消息队列——OSQDel()
函数原型
OS_EVENT *OSQDel(OS_EVENT *pevent,INT8U opt,INT8U *err)
参数:
(1) pevent:指向即将接收消息的队列的指针,其值在建立该队列时可以得 到。 (2) opt:定义消息队列删除条件的选项。它有如下两种选择: ① OS_DEL_NO_PEND:只能在没有任何任务等待该消息队列的消息时,才 能删除消息队列。 ② OS_DEL_ALWAYS:不管有没有任务在等待消息队列的消息,都立即删除消 息队列。删除后,所有等待消息的任务立即进入就绪状态。 (3) err: ① OS_NO_ERR:调用成功,消息队列已被删除。 ② OS_ERR_DEL_ISR:试图在中断服务子程序中删除消息队列。 ③ OS_ERR_INVALID_OPT:无效的opt参数,用户没有将opt定义为正确的选择。 ④ OS_ERR_EVENT_TYPE:pevent不是指向消息队列的指针。 ⑤ OS_ERR_PEVENT_NULL:已经没有OS_EVENT数据结构可以使用。
第七章 任务间的同步与通讯
消息队列
什么是消息队列: 消息队列数据结构 消息队列的操作函数使用
什么是消息队列
用来传递多个消息
可定义一个指针数组。让数组的每个元素都存放一个消 息缓冲区指针,那么任务就可通过传递这个指针数组指针的 方法来传递多个消息了。这种可以传递多个消息的数据结构 叫做消息队列。
向消息队列发送一个消息(LIFO),OSQPostFront()
函数OSQPostFront()以LIFO(后进先出)的方式组织消息队列。 OSQPostFront()函数的原型如下: INT8U OSQPostFront(OS_EVENT *pevent, void *msg);
• 参数:
pevent:指向即将接收消息的消息队列的指针。 msg:即将实际发送给任务的消息。消息是一个指针长度的变量,在不同 的程序中消息的使用也可能不同。不允许传递一个空指针。 • 返回值: OS_NO_ERR:消息成功的放到消息队列中。 OS_Q_FULL:消息队列已满。 OS_ERR_EVENT_TYPE:pevent 不是指向消息队列的指针。 OS_ERR_PEVENT_NULL:pevent是空指针。 OS_ERR_POST_NULL_PTR:发出空指针。
OSQPost()的函数原型如下: INT8U OSQPost(OS_EVENT *pevent, void *msg); • 参数:
pevent:指向即将接收消息的消息队列的指针。该指针的值在建立该队 列时可以得到。(参考OSQCreate()函数)。
msg:即将实际发送给任务的消息。消息是一个指针长度的变量,在不 同的程序中消息的使用也可能不同。不允许传递一个空指针。
息被返回给OSQPend()函数的调用者,队列中清除该消息。 如果调用OSQPend()函数时队列中没有需要的消息,OSQPend()
函数挂起当前任务直到得到需要的消息或超出定义的超时时间。
如果同时有多个任务等待同一个消息,μC/OS-Ⅱ默认最高优先级的任 务取得消息并且任务恢复执行。 一个由OSTaskSuspend()函数挂起的任务也可以接受消息,但这个 任务将一直保持挂起状态直到通过调用OSTaskResume()函数恢复任 务的运行。
该函数有如下三个参数: (1) pevent:指向接收消息的消息队列的指针。 (2) msg:发送给任务的消息。消息是用指针表示的变量,不允许传递空指针。 (3) opt:定义消息发送方式的选项。它有如下几种选择: ① OS_POST_OPT_NONE:发消息给一个任务,仿真OSQPost()函数。 ② OS_POST_OPT_BROADCAST:给等待消息的任务广播发送消息。 ③ OS_POST_OPT_FRONT:以LIFO方式发送消息,同于OSQPostFront()函数。 ④ OS_POST_OPT_FRONT + OS_POST_OPT_ BROADCAST:仿真OSQPostFront()函数, 且广播消息。
消息队列的操作
• • • • • • • • • OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()
向消息队列发送一个消息(FIFO),OSQPost()
消息队列配置常量一览表
队列函数 配置常数 OS_Q_EN 系统配置 OS_MAX_QS OS_MAX_EVENTS OSQCreate() OSQPend() OSQDel() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery() OS_Q_DEL_EN OS_Q_POST_EN OS_Q_FRONT_EN OS_Q_POST_OPT_EN OS_Q_ACCEPT_EN OS_Q_FLUSH_EN OS_Q_QUERY_EN 这三个函数至少要选择其中的一个 说 明 该常量为 0 时,屏蔽所有消息队列函数 决定消息队列的最大数目, 为 0 时, 屏蔽所有 消息队列函数 决定消息队列的最大数目 消息队列必须支持这两个函数,不能单独屏 蔽,所以无配置常量
msg = OSQPend(TaskQ, 100, &err);
if (err else { /*在指定的时间内没有接收到指定的消息 要做的事情 */ } } }
= = OS_NO_ERR) {
. /*在指定时间内接收到消息 要做的事情*/}
说明
如果调用OSQPend()函数时队列中已经存在需要的消息,那么该消
• 返回值:
OS_NO_ERR :消息成功的放到消息队列中。 OS_MBOX_FULL :消息队列已满。 OS_ERR_EVENT_TYPE :pevent 不是指向消息队列的指针。
示例
OS_EVENT *TaskQ;
INT8U RxBuf[50];
void TaskRx(void *pdata){ INT8U err; pdata = pdata; for (;;) { .
消息队列的操作
• • • • • • • • • OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()
等待一个消息队列中的消息,OSQPend()
OS_NO_ERR :消息被正确的接受。 OS_TIMEOUT :消息没有在指定的周期数内送到。 OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断调用该函数,但 μC/OS-Ⅱ仍然包含了检测这种情况的功能。 OS_ERR_EVENT_TYPE :pevent 不是指向消息队列的指针。
示例
事件
OS_EVENT *Semaphore;
消息队列
void *Msg_Group[10];
消息
char Msg_Arr[10][30];
Semaphore = OSQCreate(Msg_Group,10);
消息队列的操作
• • • • • • • • • OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()
OS_EVENT_TYPE_Q
OS_Q结构
typedef struct os_q {
struct os_q *OSQPtr void **OSQStart; void **OSQEnd; void **OSQIn; void **OSQOut; INT16U OSQSize; INT16U OSQEntries;
err = OSQPost(TaskQ, (void *)& RxBuf[0]);
if (err == OS_NO_ERR) { . } else { } } } .
消息队列的操作
• • • • • • • • • OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()
示例
OS_EVENT *TaskQ;
INT8U RxBuf[50];
void Task (void *pdata){ INT8U err; pdata = pdata; for (; ;) { .
err
if (err = . } else { . } } }
= OSQPostFront(TaskQ, (void *)&RxBuf[0]);