嵌入式实时操作系统原理与创新实践 课件 第四章-消息队列_第1页
嵌入式实时操作系统原理与创新实践 课件 第四章-消息队列_第2页
嵌入式实时操作系统原理与创新实践 课件 第四章-消息队列_第3页
嵌入式实时操作系统原理与创新实践 课件 第四章-消息队列_第4页
嵌入式实时操作系统原理与创新实践 课件 第四章-消息队列_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

RT-ThreadIPC通信、等待机制与队列操作第4章消息队列1、消息队列基础概念2、控制块与消息池3、消息发送机制4、消息接收、控制与实验目录CONTENTS结构初始化发送机制接收应用基础概念消息队列在IPC中的位置03基础概念消息队列是本书介绍的第一个IPC模块,服务于线程与中断之间的信息传递。01线程与线程发送者把消息写入队列,接收者按队列顺序取出02线程与中断中断可发送消息,线程负责后续处理03消息长度每个队列规定最大消息大小,实际发送长度可以不同结构初始化发送机制接收应用基础概念消息队列与线程状态04基础概念01队列有消息接收线程取得消息后继续运行02队列为空接收线程按timeout选择立即返回、限时等待或阻塞03消息到达等待线程从挂起态恢复为就绪态04等待超时线程恢复,并获得超时错误码消息队列把数据传递与线程调度联系在一起结构初始化发送机制接收应用基础概念等待线程的两种排序方式05基础概念FIFO模式按线程开始等待的先后顺序排列。最早挂起的线程最先获得消息。PRIO模式按线程优先级排列。优先级最高的等待线程最先获得消息。两种模式都作用于suspend_thread等待链表结构初始化发送机制接收应用基础概念消息队列提供的操作06基础概念01创建与删除支持静态初始化、动态创建及对应的删除方式02消息发送支持立即发送、限时等待和永久阻塞03消息接收队列为空时可立即返回,也可挂起等待04紧急发送把消息插入有效消息链表的头部05等待排序等待线程可按FIFO或优先级排列结构初始化发送机制接收应用基础概念消息队列模块开关07基础概念消息队列属于可裁剪模块。使用前需在rtconfig.h中启用宏定义。#defineRT_USING_MESSAGEQUEUE关闭该宏后,相关函数不会参与内核编译结构初始化发送机制接收应用基础概念消息队列控制块08结构初始化structrt_messagequeue{structrt_ipc_objectparent;void*msg_pool;rt_uint16_tmsg_size;rt_uint16_tmax_msgs;rt_uint16_tentry;void*msg_queue_head;void*msg_queue_tail;void*msg_queue_free;rt_list_tsuspend_sender_thread;};控制块继承IPC对象保存消息池地址与容量信息维护有效消息和空闲消息链表管理等待发送消息的线程结构初始化发送机制接收应用基础概念控制块字段:消息池与容量09结构初始化01parent继承rt_ipc_object,包含内核对象信息与接收等待链表02msg_pool消息池的首地址03msg_size每条消息允许的最大内容大小04max_msgs消息池能够容纳的消息节点数量05entry当前有效消息数量结构初始化发送机制接收应用基础概念控制块字段:有效消息链表10结构初始化msg_queue_head指向有效消息链表头部。接收操作从这里取走下一条消息。msg_queue_tail指向有效消息链表尾部。普通发送把新消息接到这里。队列为空时,head与tail都指向RT_NULL结构初始化发送机制接收应用基础概念空闲链表与发送等待链表11结构初始化msg_queue_free指向空闲消息节点链表。发送消息前必须先取得一个空闲节点。suspend_sender_thread队列已满时,等待发送的线程挂入该双向链表。接收线程释放节点后可唤醒其中的线程。一个管理空闲存储,一个管理等待存储的线程结构初始化发送机制接收应用基础概念两条线程挂起链表12结构初始化structrt_ipc_object{structrt_objectparent;rt_list_tsuspend_thread;};suspend_thread挂载因队列为空而等待消息的接收线程suspend_sender_thread挂载因队列已满而等待空闲节点的发送线程。结构初始化发送机制接收应用基础概念消息队列的存储结构13结构初始化图4.1消息队列大致结构结构初始化发送机制接收应用基础概念rt_mq_init()接口14结构初始化rt_err_trt_mq_init(rt_mq_tmq,constchar*name,void*msgpool,rt_size_tmsg_size,rt_size_tpool_size,rt_uint8_tflag);参数含义mq消息队列控制块地址name消息队列名称msgpool消息池首地址msg_size每条消息内容的最大大小pool_size消息池总大小flag等待线程按FIFO或优先级排列结构初始化发送机制接收应用基础概念初始化对象与等待策略15结构初始化rt_object_init(&mq->parent.parent,RT_Object_Class_MessageQueue,name);mq->parent.parent.flag=flag;rt_ipc_object_init(&mq->parent);等待线程排列方式#defineRT_IPC_FLAG_FIFO0x00#defineRT_IPC_FLAG_PRIO0x01FIFO选择最早等待的线程,PRIO选择优先级最高的线程。结构初始化发送机制接收应用基础概念消息池容量计算16结构初始化消息内容按RT_ALIGN_SIZE对齐后,再计算消息池能容纳的节点数。mq->msg_pool=msgpool;mq->msg_size=RT_ALIGN(msg_size,RT_ALIGN_SIZE);mq->max_msgs=pool_size/(mq->msg_size+sizeof(structrt_mq_message));每个节点由消息头和定长内容区组成结构初始化发送机制接收应用基础概念空闲消息链表初始化17结构初始化mq->msg_queue_head=RT_NULL;mq->msg_queue_tail=RT_NULL;mq->msg_queue_free=RT_NULL;for(temp=0;temp<mq->max_msgs;temp++){head=(structrt_mq_message*)(...);head->next=mq->msg_queue_free;mq->msg_queue_free=head;}mq->entry=0;rt_list_init(&mq->suspend_sender_thread);01有效链表头、尾均置空02逐个格式化消息池节点03节点依次接入空闲单向链表04有效消息数置零,并初始化发送等待链表结构初始化发送机制接收应用基础概念初始化后的消息队列18结构初始化图4.2初始化后的消息队列结构结构初始化发送机制接收应用基础概念rt_mq_create()与静态初始化19结构初始化rt_mq_init()用于静态消息队列。控制块和消息池由用户预先分配。rt_mq_create()用于动态消息队列。内核动态申请控制块和消息池空间。选择方式与静态线程、动态线程一致结构初始化发送机制接收应用基础概念rt_mq_detach():删除静态消息队列20结构初始化rt_err_trt_mq_detach(rt_mq_tmq){RT_ASSERT(rt_object_is_systemobject(&mq->parent.parent));rt_ipc_list_resume_all(&mq->parent.suspend_thread);rt_ipc_list_resume_all(&mq->suspend_sender_thread);rt_object_detach(&mq->parent.parent);returnRT_EOK;}参数mq静态消息队列控制块地址删除前恢复接收等待与发送等待链表中的全部线程结构初始化发送机制接收应用基础概念rt_mq_delete():删除动态消息队列21结构初始化rt_mq_delete()完成与rt_mq_detach()相同的线程恢复和对象清理,并释放动态申请的内存。01共同操作恢复两条挂起链表中的线程,清除消息队列对象信息02主要区别delete还要释放create时动态申请的内存03使用原则嵌入式内存有限,动态对象不用时及时删除结构初始化发送机制接收应用基础概念rt_mq_send_wait()接口22发送机制rt_err_trt_mq_send_wait(rt_mq_tmq,constvoid*buffer,rt_size_tsize,rt_int32_ttimeout);参数含义mq目标消息队列控制块buffer消息内容所在内存的首地址size本次发送的消息长度timeout等待空闲节点的超时时间发送流程可分为等待空闲节点和插入有效链表两部分结构初始化发送机制接收应用基础概念发送等待:参数与满队列判断23发送机制RT_ASSERT(mq!=RT_NULL);RT_ASSERT(buffer!=RT_NULL);RT_ASSERT(size!=0);if(size>mq->msg_size)return-RT_ERROR;msg=mq->msg_queue_free;if(msg==RT_NULL&&timeout==0)return-RT_EFULL;消息长度不得超过msg_size检查free与取得节点必须处于同一临界区队列已满且不等待时立即返回-RT_EFULL结构初始化发送机制接收应用基础概念发送等待:挂起发送线程24发送机制while((msg=mq->msg_queue_free)==RT_NULL){thread->error=RT_EOK;if(timeout==0)return-RT_EFULL;rt_ipc_list_suspend(&mq->suspend_sender_thread,thread,mq->parent.parent.flag);...}没有空闲节点发送线程挂入suspend_sender_thread,并按FIFO或PRIO排列。被唤醒不代表已经取得节点,代码会回到while重新检查free,再决定发送或继续等待。结构初始化发送机制接收应用基础概念发送等待:定时器与剩余时间25发送机制if(timeout>0){tick_delta=rt_tick_get();rt_timer_control(&thread->thread_timer,RT_TIMER_CTRL_SET_TIME,&timeout);rt_timer_start(&thread->thread_timer);}rt_schedule();tick_delta=rt_tick_get()-tick_delta;timeout-=tick_delta;if(timeout<0)timeout=0;01启动线程内置定时器02重新调度,让出CPU03线程恢复后检查错误码04扣除已等待时间后回到while重新检查free结构初始化发送机制接收应用基础概念发送操作:取得空闲节点26发送机制mq->msg_queue_free=msg->next;msg->next=RT_NULL;rt_memcpy(msg+1,buffer,size);01脱离空闲链表free指针移动到下一个空闲节点02形成游离节点当前节点next置为RT_NULL03复制消息内容buffer数据写入消息头之后的内容区结构初始化发送机制接收应用基础概念发送操作:接入有效消息链表27发送机制if(mq->msg_queue_tail!=RT_NULL)mq->msg_queue_tail->next=msg;mq->msg_queue_tail=msg;if(mq->msg_queue_head==RT_NULL)mq->msg_queue_head=msg;mq->entry++;01旧表尾连接新节点02tail指向新节点03原队列为空时同步设置head04有效消息数量entry加一结构初始化发送机制接收应用基础概念发送操作:唤醒接收线程28发送机制rt_inlinert_err_trt_ipc_list_resume(rt_list_t*list){structrt_thread*thread;thread=rt_list_entry(list->next,structrt_thread,tlist);rt_thread_resume(thread);returnRT_EOK;}参数list需要从挂起链表中恢复的线程节点发送成功后若suspend_thread非空,恢复首个接收线程并立即调度结构初始化发送机制接收应用基础概念rt_mq_send():无等待发送29发送机制rt_err_trt_mq_send(rt_mq_tmq,constvoid*buffer,rt_size_tsize){returnrt_mq_send_wait(mq,buffer,size,0);}参数含义mq目标消息队列控制块buffer消息内容所在内存的首地址size消息长度timeout固定为0,队列已满时立即返回错误结构初始化发送机制接收应用基础概念rt_mq_urgent():紧急消息发送30发送机制msg->next=mq->msg_queue_head;mq->msg_queue_head=msg;if(mq->msg_queue_tail==RT_NULL)mq->msg_queue_tail=msg;mq->entry++;参数含义mq目标消息队列控制块buffer消息内容所在内存的首地址size消息长度队列已满时不等待,直接返回-RT_EFULL新节点插入有效消息链表头部接收线程会优先取到这条紧急消息结构初始化发送机制接收应用基础概念普通发送与紧急发送31发送机制普通发送新消息接到msg_queue_tail。队列满时,send_wait可根据timeout挂起等待。紧急发送新消息插入msg_queue_head。队列满时直接返回,不进入等待循环。二者都会增加entry,并唤醒等待接收的线程结构初始化发送机制接收应用基础概念rt_mq_recv()接口32接收应用rt_err_trt_mq_recv(rt_mq_tmq,void*buffer,rt_size_tsize,rt_int32_ttimeout);参数含义mq目标消息队列控制块buffer接收消息的目标内存首地址size接收缓冲区大小timeout等待有效消息的超时时间结构初始化发送机制接收应用基础概念接收等待:空队列判断33接收应用if(mq->entry==0&&timeout==0)return-RT_ETIMEOUT;while(mq->entry==0){thread->error=RT_EOK;if(timeout==0)return-RT_ETIMEOUT;...}判断依据entry表示有效消息数量。entry为0且不等待时,立即返回-RT_ETIMEOUT。结构初始化发送机制接收应用基础概念接收等待:挂起与超时34接收应用rt_ipc_list_suspend(&mq->parent.suspend_thread,thread,mq->parent.parent.flag);if(timeout>0){tick_delta=rt_tick_get();rt_timer_control(&thread->thread_timer,RT_TIMER_CTRL_SET_TIME,&timeout);rt_timer_start(&thread->thread_timer);}rt_schedule();01挂入接收等待链表02限时等待时启动线程定时器03执行系统调度04恢复后更新剩余timeout结构初始化发送机制接收应用基础概念接收操作:取出有效消息35接收应用msg=mq->msg_queue_head;mq->msg_queue_head=msg->next;if(mq->msg_queue_tail==msg)mq->msg_queue_tail=RT_NULL;if(mq->entry>0)mq->entry--;接收始终从head取消息。取走唯一节点后,tail也必须置为RT_NULL。结构初始化发送机制接收应用基础概念接收操作:释放节点并唤醒发送线程36接收应用rt_memcpy(buffer,msg+1,size>mq->msg_size?mq->msg_size:size);msg->next=mq->msg_queue_free;mq->msg_queue_free=msg;if(!rt_list_isempty(&mq->suspend_sender_thread)){rt_ipc_list_resume(&mq->suspend_sender_thread);rt_schedule();}复制长度取size与msg_size的较小值把用完的节点放回空闲链表节点归还后再恢复等待发送的线程恢复中断后执行一次调度结构初始化发送机制接收应用基础概念发送与接收的对称关系37接收应用发送操作空闲链表减少一个节点。有效链表尾部增加一个节点。entry加一。可能唤醒接收线程。接收操作有效链表头部减少一个节点。空闲链表增加一个节点。entry减一。可能唤醒发送线程。两类操作都在修改链表时关闭中断,保证结构一致结构初始化发送机制接收应用基础概念rt_mq_control():重置消息队列38接收应用rt_mq_control(mq,RT_IPC_CMD_RESET,arg);//恢复全部等待

温馨提示

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

评论

0/150

提交评论