实时操作系统应用开发技术 课件 第4章LiteOS同步与通信技术_第1页
实时操作系统应用开发技术 课件 第4章LiteOS同步与通信技术_第2页
实时操作系统应用开发技术 课件 第4章LiteOS同步与通信技术_第3页
实时操作系统应用开发技术 课件 第4章LiteOS同步与通信技术_第4页
实时操作系统应用开发技术 课件 第4章LiteOS同步与通信技术_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第4章

LiteOS同步与通信技术主讲人:王宜怀时间:2025.6实时操作系统应用开发技术目录CONTENTRTOS中同步与通信基本概念4.1消息队列4.3事件4.2信号量4.4互斥量4.5RTOS中同步与通信基本概念4.1PART-实时操作系统应用开发技术1、同步的含义2、实现同步的通信手段RTOS提供多种通信手段,如事件、消息队列、信号量、互斥量等,适用于不同场合。从是否需要通信数据角度看,事件、信号量、互斥量适用于无需数据传输的同步;消息队列适用于既有同步功能又能传输数据的场景。从产生与使用数据速度角度看,消息队列适用于产生数据速度快于处理速度的情况,但需保证平均处理速度不低于产生速度。线程间配合称为同步,由条件触发。控制方发出信息,被控制方接收后进入就绪状态。线程间的同步过程通常由某种条件触发,称为条件同步。控制方发出信息,被控制方接收后状态改变,实现同步。4.1.1同步的含义与通信手段4/46中断服务例程产生同步信号,线程等待信号,信号发出后线程变为就绪状态。例如,小灯线程与串口接收中断相关联,串口接收中断收到完整数据帧时发出事件信号,小灯线程收到信号后进行灯的亮暗切换。两个线程之间的同步分为单向同步和双向同步。单向同步时,控制方线程发出信息后,被控制方线程进入就绪状态。若控制方优先级低于被控制方,瞬时同步效果较好;反之则较差。双向同步中,通信双方相互制约,生产者通过提供消息同步消费者,消费者通过回复消息同步生产者,达到产销平衡。3.两个以上线程同步一个线程采用事件按“逻辑与”实现,被同步线程的执行次数不超过各个同步线程中发出信号最少的线程的执行次数。“逻辑与”的控制功能具有安全控制的特点,可用来保障一个重要线程必须在万事俱备的前提下才可以执行。若干相关线程的运行频度保持一致,每个相关线程在运行到同步点时都必须等待其他线程,全部到达后按优先级顺序离开。多个线程相互同步保证在任何情况下各个线程的有效执行次数都相同,而且等于运行速度最低的线程的执行次数,具有团队作战的特点,适用于多线程配合的循环作业。4.多个线程相互同步2.两个线程之间的同步1.中断和线程之间的同步4.1.2同步类型5/46事件4.2PART-实时操作系统应用开发技术4.2.1事件的含义及应用场合事件是RTOS中用于协调线程间或中断与线程间同步的机制,不传送数据,只发同步信号,常用于线程需等待另一线程或中断信号才能继续工作的情况。事件适用于需多个信号逻辑运算后同步的场景,如串口接收完整数据帧后通知线程处理,实现中断服务例程与线程的高效协作。事件的定义应用场景7/461.创建事件变量函数event_create在使用事件之前必须调用创建事件函数创建一个事件控制块结构体变量。4.2.2事件的常用函数8/46当调用事件获取函数时,线程进入阻塞状态,等待32位事件字指定的一位或几位置位后退出阻塞状态。2.获取事件函数event_recv4.2.2事件的常用函数9/46发送事件函数用于发送事件字的指定事件位,事件位被置位后,因执行获取事件函数而进入阻塞列表的线程会退出阻塞状态,进入就绪列表,接受调度。3.发送事件函数event_send4.2.2事件的常用函数10/464.2.3事件的编程实例1.事件样例程序的功能(1)用户串口中断为收到一个字节产生中断,在“isr.c”文件的中断服务例程UART_User_Handler中,进行接收组帧。(2)当串口接收到一个完整的数据帧(帧头3A+四位数据+帧尾0D0A),发送一个事件(起名为红灯事件)。(3)在红灯线程中,有等待红灯事件的语句,没有红灯事件时,该线程进入阻塞队列,一旦有红灯事件发生,运行随后的程序,红灯状态反转。11/464.2.3事件的编程实例(1)声明事件字全局变量并创建事件字G_VAR_PREFIXevent_tg_EventWord;(3)创建事件字实例g_EventWord=event_create("g_EventWord",IPC_FLAG_PRIO);(2)确定要用的事件名称、使用事件字的哪儿一位#defineRED_LIGHT_EVENT(1<<3)2.准备阶段12/464.2.3事件的编程实例等待事件发生在线程中使用event_recv函数等待事件位被置位,根据参数选项选择“逻辑与”或“逻辑或”方式等待。设置事件位在触发事件的线程或中断服务例程中使用event_send函数对事件位置位,通知等待线程事件发生。event_recv(g_EventWord,RED_LIGHT_EVENT,EVENT_FLAG_OR|EVENT_FLAG_CLEAR,WAITING_FOREVER,&recvedstate);uart_send_string(UART_User,(void*)"在红灯线程中,收到红灯事件,红灯反转\r\n");gpio_reverse(LIGHT_RED);//反转红灯event_send(g_EventWord,RED_LIGHT_EVENT);//设置红灯事件3.应用阶段13/464.2.3事件的编程实例红灯线程代码展示了红灯线程等待事件触发后反转红灯状态的完整代码,包括线程初始化和主循环部分。用户串口中断服务例程代码展示了串口接收完整数据帧后发送事件的中断服务例程代码,实现中断与线程的通信。4.样例程序源码14/464.2.3事件的编程实例5.运行结果15/46消息队列4.3PART-实时操作系统应用开发技术消息队列是RTOS中用于线程间或线程与中断间传送数据的同步与通信手段。它是一种容器,用于保存消息,实现线程间的同步和大量数据交换。消息队列允许消息发送方在队列未满时发送消息,接收方在队列非空时取出消息。消息队列具有缓冲功能,可解决消息堆积问题。适用于消息产生周期短、处理周期长,或消息产生随机、处理速度与内容有关的情况。这两种情况均可把产生与处理分在两个程序主体进行编程,它们之间通过消息队列通信。例如,消息的产生是随机的,某些消息的处理时间可能较长,通过消息队列可以实现消息的缓冲和同步传递。0102消息队列的含义消息队列的应用场合4.3.1消息队列的含义及应用场合17/461.创建消息队列变量函数mq_create在使用消息队列之前必须调用创建消息队列变量函数创建一个消息队列结构体指针变量,并分配内存空间。函数功能为创建一个消息队列结构体指针变量,参数包括消息队列名称、消息大小(单位为字节)、消息队列中最多能容纳的消息数以及消息队列标志位。消息队列标志位可选择IPC_FLAG_PRIO(优先级高的线程优先)或IPC_FLAG_FIFO(先进先出顺序)。4.3.2消息队列的常用函数18/462.发送消息函数mq_send将消息放入消息队列,若消息阻塞队列中有等待消息的线程,RTOS内核将其移出放入就绪队列。参数包括消息队列控制块、消息内容和消息的大小,函数返回成功或错误代码。4.3.2消息队列的常用函数19/463.获取消息函数mq_recv运行到此函数,若消息队列为空,则线程阻塞,直到消息队列中有消息,阻塞解除,运行其后代码。参数包括消息队列控制块、接收消息的地址、接收缓冲区的大小以及等待的超时时间,函数返回状态代码值。4.3.2消息队列的常用函数//==================================================================//函数名称:mq_send//功能概要:发送消息(即将消息放入消息队列)//参数说明:mq-消息队列控制块//buffer-消息内容//size-消息的大小(即一条消息的字节数)//函数返回:返回成功或错误代码//==================================================================err_tmq_send(mq_tmq,void*buffer,size_tsize);

41//timeout-设置等待的超时时间,一般为WAITING_FOREVER:永久等待//功能概要:将消息从消息队列中取出//==================================================================err_tmq_recv(mq_tmq,void*buffer,size_tsize,int32_ttimeout)20/461.消息队列样例程序的功能(1)用户串口中断为收到一个字节产生中断,在“isr.c”文件的中断服务例程UART_User_Handler中,进行接收组帧。(2)当串口接收到一个完整的数据帧(帧头3A+8字节数据+帧尾0D0A),发送一个消息,每个消息就是数据帧中的8字节数据。注意每个消息的字节数是在创建消息队列时确定的,且为定长。(3)在等待消息的线程(thread_message_recv)中,有等待消息的语句,若消息队列中没有消息,该线程进入消息阻塞队列,一旦消息队列中有消息,运行随后的程序,通过串口(波特率为115200)打印出消息,以及消息队列中剩余消息的个数。4.3.3消息队列的编程实例21/462.准备阶段(1)声明消息队列变量。在使用消息队列之前,首先在07_AppPrg文件夹下的工程总头文件(includes.h文件)中声明一个全局消息队列变量g_mq。G_VAR_PREFIXmq_tg_mq;//声明一个全局消息变量111111111111111111111(2)创建消息队列实例。在threadauto_appinit.c文件的thread_auto函数中创建消息队列实例,实参为:消息变量名字为g_mq,每个消息8个字节,最大消息个数4个。//创建消息队列,参数为:名字、单个消息字节数、消息个数、进出方式(先进先出)g_mq=mq_create("g_mq",8,4,IPC_FLAG_FIFO);111111111111111111111111111111111114.3.3消息队列的编程实例22/46(1)等待消息。即通过mq_recv函数获取消息队列中存放的消息。例如在本节样例程序中,thread_messagerecv.c文件中,有如下语句,该语句之后的程序,等待消息队列中有消息时才会被运行。(2)发送消息(将消息放入消息队列)。通过mq_send函数将消息放入消息队列中,若消息队列中存放的消息数已满,则会直接舍弃该条消息。例如在本节样例程序的中断服务例程UART_User_Handler中,将收到的消息放入消息队列。3.应用阶段4.3.3消息队列的编程实例23/464.样例程序源码4.3.3消息队列的编程实例1等待消息的线程代码展示了等待消息的线程代码,包括线程初始化和主循环部分,详细说明了消息接收和处理过程。2用户串口中断服务例程代码展示了用户串口中断服务例程代码,详细说明了如何接收完整数据帧并发送消息。24/465.运行结果4.3.3消息队列的编程实例25/46信号量4.4PART-实时操作系统应用开发技术信号量是一个非负整型变量,用于确保线程在访问共享资源时不会发生冲突。利用信号量机制访问共享资源时,线程必须获取对应的信号量。如果信号量不为0,则表示还有资源可以使用,线程可使用该资源,并将信号量减1;如果信号量为0,则表示资源已被用完,线程进入信号量阻塞列表,排队等候其他线程使用完资源后释放信号量。信号量的最大值为1时,信号量就变成了互斥量。1.信号量的含义用于实现线程之间的有序操作、互斥执行以及控制线程的并发数等。例如,在停车场车位管理中,信号量初始值为停车场可用车辆数量,车辆进入停车场前先申请信号量,若信号量大于0,车辆可以进入并占用一个车位,信号量减1;若信号量为0,车辆进入阻塞状态等待。当有车辆离开停车场时,信号量加1,等待的车辆可以进入。这种有序的特性使信号量在计算机中有较多的应用场合。2.信号量的应用场合4.4.1信号量的含义及应用场合27/461.创建信号量变量函数sem_create在使用信号量之前必须调用创建信号量变量函数创建一个信号量结构体指针变量,并设置可用资源的最大数。4.4.2信号量的常用函数28/462.等待获取信号量函数sem_take在获取共享资源之前,需要等待获取信号量。若可用信号量个数大于0,则获取一个信号量,并将可用信号量个数减1;若可用信号量个数为0,则阻塞线程,直到其他线程释放信号量。4.4.2信号量的常用函数29/463.释放信号量函数sem_release当线程使用完共享资源后,需要释放占用的共享资源,使可用信号量值加1。4.4.2信号量的常用函数30/46以三辆车进只有两个停车位的停车场为例,通过信号量实现车辆的有序进场停车。该工程模拟的功能是:车辆1、车辆2和车辆3分别停随机的3-13秒,通过信号量来管理停车场的空车位,实现车辆的有序进场和出场。1.信号量样例程序的功能4.4.3信号量的编程实例31/46通过sem_create函数初始化信号量结构体指针变量,设置最大可用资源数。例如在本节样例程序中,在thread_auto中初始化信号量结构体指针变量,为了模拟演示设置最大可用停车位为2。2.准备阶段4.4.3信号量的编程实例32/46(1)等待信号量。在线程访问资源前,通过sem_take函数等待信号量;若无可用信号量时,则线程进入信号量阻塞列表,等待可用信号量的到来。例如在本节样例程序中,在对应线程中获取信号量,代码如下:sem_take(g_sp,WAITING_FOREVER);//等待信号量1111111111(2)释放信号量。在线程使用完资源后,通过sem_release函数释放信号量。例如在本节样例程序中,在对应线程中释放信号量,代码如下:sem_release(g_sp);//释放信号量111111111111111111111111111111

3.应用阶段4.4.3信号量的编程实例33/464.4.3信号量的编程实例展示了停车线程的完整代码,包括线程初始化和主循环部分,详细说明了信号量的获取和释放过程。4.样例程序源码4.样例程序源码34/464.4.3信号量的编程实例5.运行结果35/46互斥量4.5PART-实时操作系统应用开发技术STEP.01STEP.02STEP.03互斥量的概念互斥量是一种用于保护操作系统中的临界区或共享资源的同步工具,能够保证任何时刻只有一个线程能够操作临界区。互斥量的操作只有加锁和解锁两种,每个线程都可以对一个互斥量进行加锁和解锁操作,必须按照先加锁后解锁的顺序进行。一旦某个线程对互斥量加锁,在它对互斥量进行解锁操作之前,任何线程都无法再对该互斥量进行加锁,是一种独占资源的行为。互斥关系多个需求者为了争夺某个共用资源而产生的关系,竞争者之间可能彼此不认识,但为了竞争共用资源,产生了互斥关系。例如,食堂里几个人排队打饭,竞争者之间为了争夺共用资源(如打饭窗口)而产生互斥关系,没有竞争到资源的需求者都需要排队等待第一个需求者使用完资源后,才能开始使用资源。互斥应用场合在一个计算机系统中,有很多受限的资源,如串行通信接口、读卡器和打印机等硬件资源以及公用全局变量、队列和数据等软件资源需要互斥使用。4.5.1互斥量的含义及应用场合37/46创建互斥量变量函数mutex_create在使用互斥量之前必须调用创建互斥量变量函数创建一个互斥量结构体指针变量。014.5.2互斥量的常用函数38/46获取互斥量函数mutex_take调用获取互斥量函数将在指定的等待时间内获取指定的互斥量。024.5.2互斥量的常用函数39/46互斥量释放函数mutex_release调用互斥量释放函数将释放指定的互斥量。034.5.2互斥量的常用函数40/46通过互斥量实现线程对资源的独占访问,使红灯、绿灯、蓝灯线程按照一定时间间隔单独亮,不出现混合颜色。该工程实现的功能是:红灯线程每5秒闪烁一次、绿灯线程每10秒闪烁一次、蓝灯线程每20秒闪烁一次。通过单色灯互斥量使得每一时刻只有一个灯亮,不出现混合颜色情况。1.样例程序的功能4.5.3互斥量的编程实例41/46(1)在includes.h中定义互斥量。G_VAR_PREFI

温馨提示

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

评论

0/150

提交评论