ARM Cortex-M3嵌入式开发及应用教与学 课件 第13章 消息邮箱与消息队列_第1页
ARM Cortex-M3嵌入式开发及应用教与学 课件 第13章 消息邮箱与消息队列_第2页
ARM Cortex-M3嵌入式开发及应用教与学 课件 第13章 消息邮箱与消息队列_第3页
ARM Cortex-M3嵌入式开发及应用教与学 课件 第13章 消息邮箱与消息队列_第4页
ARM Cortex-M3嵌入式开发及应用教与学 课件 第13章 消息邮箱与消息队列_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ARMCortex-M3嵌入式控制技术

——基于STM32F103RCT6

嵌入式实时操作系统μC/OS-II第十三章

消息邮箱与消息队列

消息邮箱和消息队列是µC/OS-II系统中非常重要的两个组件。信号量主要用于任务间的同步,而消息邮箱和消息队列不仅可以实现任务间的同步,而且可用于任务间相互通信。本章将详细介绍消息邮箱和消息队列的概念和用法。

本章的学习目标:

了解消息邮箱的工作原理;

熟悉消息邮箱与队列的系统函数;

掌握消息邮箱与队列的应用方法。

1μC/OS-II消息邮箱2μC/OS-II多任务工程实例3

统计任务实例4系统定时器13.1μC/OS-II消息邮箱消息邮箱不仅能实现任务间的同步,而且还可用于任务间相互通信。在µC/OS-II中,与消息邮箱管理相关的函数有8个,位于µC/OS-II内核文件os_mbox.c中,如表所示。函数原型功能OS_EVENT*OSMboxCreate(void*msg);创建并初始化一个消息邮箱。如果参数不为空,则新建的邮箱将包含消息void*OSMboxPend(OS_EVENT*pevent,INT16Utimeout,INT8U*perr);向邮箱请求消息,如果邮箱中有消息,则消息传递到任务中,邮箱清空;如果邮箱中没有消息,当前任务挂起等待,直到邮箱中有消息或等待超时。如果有多个任务等待同一个消息,则该消息到来时,µC/OS-II使优先级最高的任务获得消息并运行(中断服务程序不能调用该函数)INT8UOSMboxPost(OS_EVENT*pevent,void*pmsg);向邮箱传入消息(可理解为向邮箱释放消息),如果有任务在等待该消息,则高优先级的任务将会:(1)如果此任务优先级低于调用该函数的任务,则在调用该函数的任务执行完后,立即得到消息并执行;(2)如果此任务优先级高于调用该函数的任务,则此任务立即执行,调用该函数的任务被挂起等待。pmsg不允许传递空指针INT8UOSMboxPostOpt(OS_EVENT*pevent,void*pmsg,INT8Uopt);向邮箱中释放消息。opt可取:(1)OS_POST_OPT_BROADCAST,消息将广播给所有请求该消息邮箱的任务;(2)OS_POST_OPT_NONE,此时与OSMboxPost含义相同;(3)OS_POST_OPT_NO_SCHED,释放消息后不进行任务调度,可用于一次性地释放多个消息后,再进行任务调度OS_EVENT*OSMboxDel(OS_EVENT*pevent,INT8Uopt,INT8U*perr);删除一个消息邮箱。通常,在删除邮箱前,应删除那些请求该邮箱的任务(中断服务程序不能调用该函数)INT8UOSMboxQuery(OS_EVENT*pevent,OS_MBOX_DATA*p_mbox_data);查询邮箱当前的消息及等待该消息的事件列表INT8UOSMboxPendAbort(OS_EVENT*pevent,INT8Uopt,INT8U*perr);中止任务对消息邮箱的请求,使等待该消息的任务继续执行(中断服务程序不能调用该函数)void*OSMboxAccept(OS_EVENT*pevent);向指定的邮箱请求消息,如果没有消息,则调用该函数的任务不挂起等待;如果有消息,则消息传递到任务中,然后清空邮箱。可被任务或中断服务程序调用,多用于中断服务程序中消息邮箱的工作情况消息邮箱的用法如下:(1)定义事件,如“OS_EVENT*mbox01;”。(2)定义全局一维数组保存消息,如“INT8Umsgbx[80];”。(3)创建消息邮箱,如“mbox01=OSMboxCreate(NULL);”,NULL参数表示创建的邮箱中没有消息。(4)在某一个任务A中释放消息,如:“OSMboxPost(mbox01,(void*)msgbx);”,如果发送的消息为“Msg:A-X”,则需要事先将该消息存在msgbx中,可以使用语句“strcpy((char*)msgbx,“Msg:A-X”);”。(5)在另一个任务X中请求消息,如“pmsg=OSMboxPend(mbox01,0,&err);”,这里的pmsg为“void*”类型的任务局部变量,这样,消息“Msg:A-X”就从任务A传递到任务X中了。13.2μC/OS-II消息队列消息队列可以视为消息邮箱的数组形式,消息邮箱一次只能传递一则消息,而消息队列可以一次传递多则消息。因此,消息邮箱是消息队列的一种特例。消息队列的工作情况如图所示。任务和中断服务程序可以向消息队列中释放消息,只有任务才能从消息队列中请求消息,任务可以始终请求消息,也可周期性地请求消息。消息队列具有一定的长度,其长度为可包含的消息个数,如果向队列中释放消息的速度大于从队列中请求消息的速度,那么消息队列将溢出。在μC/OS-II中,消息队列相关的管理函数约有10个,列于表中,这些函数位于μC/OS-II内核文件os_q.c中函数原型功能OS_EVENT*OSQCreate(void**start,INT16Usize);创建一个消息队列,允许任务或中断服务程序发送一些指针类型的变量(消息)给一个或多个任务,消息内容由应用程序指定void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*perr);向消息队列请求消息。如果队列中有消息,则该消息传递给任务,并从队列中清除该消息;如果队列中没有消息,则调用该函数的任务被挂起等待,直到有消息或等待超时。当有多个任务请求到同一消息队列时,µC/OS-II进行任务调度,使优先级最高的任务得到消息(中断服务程序不能调用该函数)INT8UOSQPost(OS_EVENT*pevent,void*pmsg);向消息队列送入消息(即向队列释放消息),消息队列为先进先出(FIFO)方式。如果队列已满,则消息不会进入队列,OSQPost立即返回;否则,消息进入队列,如果有任务在请求该消息队列,则µC/OS-II进行任务调度,当前任务和所有请求该消息队列的任务中最高优先级的任务得到执行权INT8UOSQPostFront(OS_EVENT*pevent,void*pmsg);向消息队列送入消息(即向队列释放消息),消息插入到队列前端,消息队列为后进先出(LIFO)方式。如果队列已满,则消息不会插入队列,OSQPostFront立即返回;否则,消息插入队列,如果有任务在请求该消息队列,则µC/OS-II进行任务调度,当前任务和所有请求该消息队列的任务中最高优先级的任务得到执行权INT8UOSQPostOpt(OS_EVENT*pevent,void*pmsg,INT8Uopt);向队列中释放消息。opt可取以下值:(1)OS_POST_OPT_NONE,与OSQPost相同;(2)OS_POST_OPT_FRONT,与OSQPostFront相同;(3)OS_POST_OPT_BROADCAST,每个消息均广播给所有请求队列的任务;(4)OS_POST_OPT_NO_SCHED,释放消息后不进行任务调度,借助该参数可以一次性向队列中释放多个消息,在释放完最后一个消息时,不使用该参数,进行任务调度。OS_EVENT*OSQDel(OS_EVENT*pevent,INT8Uopt,INT8U*perr);删除一个消息队列。通常,删除消息队列前,应删除所有请求该消息队列的任务(中断服务程序不能调用该函数)void*OSQAccept(OS_EVENT*pevent,INT8U*perr);向消息队列请求消息。与OSQPend不同的是,如果队列中没有消息,调用该函数的任务并不挂起等待,主要用于中断服务程序中。如果队列中有消息,该消息传递到任务中,在OSQAccept返回前,该消息从队列中移除INT8UOSQPendAbort(OS_EVENT*pevent,INT8Uopt,INT8U*perr);放弃请求消息队列,继续执行当前任务(中断服务程序不能调用该函数)INT8UOSQQuery(OS_EVENT*pevent,OS_Q_DATA*p_q_data);查询消息队列信息。INT8UOSQFlush(OS_EVENT*pevent);清空消息队列消息队列的使用方法如下:(1)定义事件,如“OS_EVENT*q01;”。(2)定义一维指针数组,如“void*ptq[10];”;定义全局二维数组存放队列中的消息,如“INT8Umsgq[10][80];”。(3)创建消息队列,如“q01=OSQCreate(&ptq[0],10);”,这里创建了一个长度为10的消息队列。(4)在某一任务A中,向队列中释放消息,如“OSQPost(q01,(void*)&msgq[0][0]);”。(5)在另一任务X中,向队列请求消息,如“pmsg=OSQPend(q01,0,&err);”,这里pmsg为“void*”类型的局部变量,指向请求到的消息。13.3消息邮箱与消息队列实例在工程PRJ31的基础上,新建工程“PRJ32”,保存在“D:\STM32F103RCT6PRJ\PRJ32”目录下,此时的工程PRJ32与工程PRJ31完全相同。拟使工程PRJ32实现的功能与PRJ31也完全相同,但是,在实现手段上采取了如表所示的变化。序号功能工程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论