UCOSII信号量的理解
- 格式:pdf
- 大小:83.29 KB
- 文档页数:3
转:⼀步⼀步教你使⽤uCOS-II第⼀篇 UCOS介绍第⼀篇 UCOS介绍这个⼤家都知道。
呵呵。
考虑到咱们学习的完整性还是在这⾥唠叨⼀下。
让⼤家再熟悉⼀下。
⾼⼿们忍耐⼀下吧! uC/OS II(Micro Control Operation System Two)是⼀个可以基于ROM运⾏的、可裁减的、抢占式、实时多任务内核,具有⾼度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。
为了提供最好的移植性能,uC/OS II最⼤程度上使⽤ANSI C语⾔进⾏开发,并且已经移植到近40多种处理器体系上,涵盖了从8位到64位各种CPU(包括DSP)。
uC/OS II可以简单的视为⼀个多任务调度器,在这个任务调度器之上完善并添加了和多任务操作系统相关的系统服务,如信号量、邮箱等。
其主要特点有公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好,可裁剪,可固化。
内核属于抢占式,最多可以管理60个任务。
µC/OS-II 的前⾝是µC/OS,最早出⾃于1992 年美国嵌⼊式系统专家Jean brosse 在《嵌⼊式系统编程》杂志的5 ⽉和6 ⽉刊上刊登的⽂章连载,并把µC/OS 的源码发布在该杂志的B B S 上。
µC/OS 和µC/OS-II 是专门为计算机的嵌⼊式应⽤设计的,绝⼤部分代码是⽤C语⾔编写的。
CPU 硬件相关部分是⽤汇编语⾔编写的、总量约200⾏的汇编语⾔部分被压缩到最低限度,为的是便于移植到任何⼀种其它的CPU 上。
⽤户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件⼯具,就可以将µC/OS-II嵌⼈到开发的产品中。
µC/OS-II 具有执⾏效率⾼、占⽤空间⼩、实时性能优良和可扩展性强等特点,最⼩内核可编译⾄ 2KB 。
µC/OS-II 已经移植到了⼏乎所有知名的CPU 上。
UCOS-II/II、FreeRTOS、RTX四大RTOS系统性能对比大家好,感谢社区提供的板卡。
这次的使用对象是安富莱的STM32-V6板卡。
由于之前用过安富莱的V4板卡,所以安富莱给我留下了很深的印象,他们开发板的资料很过硬,售后完善,线上QQ技术支持也很给力,作为学习,确实是一款很不错的板卡。
唯一的是,安富莱很少出视频,其主要是编写PDF教学手册和程序例程。
另外他们的按键检测代码,很紧凑,有单发、连发、长按、短按、上升沿触发、下降沿触发等功能,是我见到最棒的按键检测代码。
STM32-V6是一款基于STM32F429单片机的开发板,整板采用4层板设计,本次选择它的目的,除了测试其能做常用外设开发驱动,安富莱还对它做了一个示波器的例程。
虽然示波器的性能不强,但是去十分有意思。
另外其支持VNC虚拟屏幕功能。
开发者可以不用LCD显示屏幕,直接使用PC屏幕作为自己的开发板屏幕,十分方便。
所以这个板子真的很强大。
拿到板子,在我查看他们的网络示波器例程后,发现安富莱只做了基于RTX的例程,并没有做基于uCOS、FreeRTOS的例程,这样我感到很奇怪。
因为安富莱的每个例程都会做三个OS版本,唯独这个例程却只制作了一个基于RTX的。
他们的技术支持回复是:“FreeRTOS的性能不行,所以对这个网络示波器的的应用来说,没有制作这方面的例程”,这让我感到很疑惑,FreeRTOS作为一款开源RTOS,性能真有这么差么?到底他们之间的差距又有多大?所以才有这次做UCOS-II、UCOS-III、FreeRTOS、RTX系统性能对比测试,本次我只是站在一个使用者的角度,测试四个RTOS单一的系统调度性能。
尽量使4个RTOS处在同一水平上测试:l 使用相同的硬件平台和相同的资源l 单片机都使用相同的主频,只是单片机的Uart资源。
实验一、任务创建与删除1、uC/OS-II介绍对于操作系统的学习,创建任务和删除任务是最为基础的工作,uC/OS-II以源代码的形式发布,是开源软件, 但并不意味着它是免费软件。
可以将其用于教学和私下研究;但是如果将其用于商业用途,那么必须通过Micrium获得商用许可。
uC/OS-II属于抢占式内核,最多可以支持64个任务,分别对应优先级0~63,每个任务只能对应唯一的优先级,其中0为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整型变量做累加运算;另一个是系统任务,它的优先级为次低,该任务负责统计当前cpu的利用率。
μC/OS-II可管理多达63个应用任务,并可以提供如下服务,本章将针对以下服务分别以例程的方式来介绍1)信号量2)互斥信号量3)事件标识4)消息邮箱5)消息队列6)任务管理7)固定大小内存块管理8)时间管理2、任务创建与删除想让uC/OS-II管理用户的任务,用户必须要先建立任务,在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。
uC/OS-II提供了两个函数来创建任务:OSTask Create()或OSTaskCreateExt()。
可以使用其中任意一个即可,其函数原型如下:INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U pri o)INT8U OSTaskCreateExt (void(*task)(void *pd),void *pdata,SD_STK *ptos,INT8U prio, INT16U id,OS_STK *pbos,INT32U stk_size, void *pext,INT16U opt)task:任务代码指针pdata:任务的参数指针ptos:任务的堆栈的栈顶指针prio:任务优先级id:任务特殊的标识符(uC/OS-II中还未使用)pbos:任务的堆栈栈底的指针(用于堆栈检验)stk_size:堆栈成员数目的容量(宽度为4字节)pext:指向用户附加的数据域的指针opt:是否允许堆栈检验,是否将堆栈清零,任务是否要进行浮点操作等等删除任务,是说任务将返回并处于休眠状态,任务的代码不再被uC/OS-II调用,而不是删除任务代码。
ucosii 互斥信号量创建条件摘要:1.ucosii 简介2.互斥信号量的概念3.互斥信号量的创建条件4.互斥信号量在ucosii 中的应用正文:【1.ucosii 简介】ucosii是一款基于μC/OS-II实时操作系统的嵌入式软件开发平台。
μC/OS-II是一个源代码公开的实时操作系统内核,其主要特点是可移植性强、占用资源少、实时性能优越,适用于各种嵌入式系统。
ucosii在μC/OS-II的基础上,提供了丰富的组件和工具,便于开发者快速构建嵌入式系统。
【2.互斥信号量的概念】互斥信号量(Mutex)是一种同步原语,用于实现多任务之间的互斥访问。
互斥信号量有一个计数器,用于表示当前有多少任务正在访问共享资源。
当一个任务要访问共享资源时,需要先请求互斥信号量。
如果计数器为零,表示当前没有其他任务访问共享资源,请求信号量后计数器加一,任务可以访问共享资源;如果计数器大于零,表示其他任务正在访问共享资源,请求信号量后计数器加一,任务需要等待其他任务访问完成后才能访问共享资源。
任务访问完共享资源后,释放互斥信号量,计数器减一,表示可以有其他任务访问共享资源。
【3.互斥信号量的创建条件】在ucosii 中,创建互斥信号量需要满足以下条件:1.互斥信号量对象需要分配在用户空间,不能分配在内核空间。
2.互斥信号量对象的初始化需要保证计数器为零,表示没有任务访问共享资源。
3.互斥信号量对象需要关联一个等待队列,用于存放等待访问共享资源的任务。
【4.互斥信号量在ucosii 中的应用】在ucosii 中,互斥信号量可以用于保护共享资源,避免多任务同时访问导致的数据不一致问题。
以下是一个简单的互斥信号量使用示例:```c#include "ucosii.h"#include "ucosii_os.h"// 定义共享资源int32_t g_data;// 创建互斥信号量MUTEX_T g_mutex;// 初始化互斥信号量void init_mutex() {mutex_init(&g_mutex, 0);}// 访问共享资源void access_data() {int32_t i;for (i = 0; i < 10; i++) {// 获取互斥信号量mutex_lock(&g_mutex);// 访问共享资源g_data = i;// 释放互斥信号量mutex_unlock(&g_mutex);}}// 任务入口void app_main() {init_mutex();// 启动多个任务访问共享资源while (1) {task_create(1, access_data, NULL);}}```在这个示例中,我们定义了一个共享资源g_data,并创建了一个互斥信号量g_mutex。
ucos信号量用法一、引言在嵌入式系统的开发中,ucos作为一个开源的实时操作系统,被广泛应用于各种嵌入式设备中。
信号量是ucos中一种重要的同步机制,用于解决多任务环境下资源竞争的问题。
本文将介绍ucos中信号量的用法和注意事项。
二、信号量的概念信号量是一种用于多任务同步和资源管理的机制。
在ucos中,信号量是一种计数型变量,用于实现任务的互斥访问和同步操作。
信号量可以有两个操作:等待(wait)和释放(signal)。
三、信号量的创建和初始化在ucos中,信号量的创建和初始化是通过调用相应的API函数实现的。
首先需要定义一个信号量的变量,然后通过调用API函数对其进行初始化。
例如,可以使用以下代码创建一个信号量并初始化为1:SEM_HANDLE sem;sem = OSSemCreate(1);在上述代码中,SEM_HANDLE是信号量的句柄类型,OSSemCreate()是ucos提供的一个用于创建和初始化信号量的函数。
四、信号量的等待操作信号量的等待操作是任务在使用共享资源之前进行的操作。
如果资源已被占用,则任务需要等待,直到资源可用。
在ucos中,可以通过调用OSSemPend()函数来完成等待操作。
以下是一个示例代码,展示了任务如何进行信号量等待操作:void Task1(void *arg){while(1){// 等待信号量OSSemPend(sem, 0, &err);// 使用共享资源// 释放信号量OSSemPost(sem);}}在上述代码中,任务会在OSSemPend()函数处等待信号量。
参数sem表示待等待的信号量句柄,0表示最大等待时间,&err用于记录等待的结果。
五、信号量的释放操作信号量的释放操作是任务在使用完共享资源后进行的操作。
通过调用OSSemPost()函数来释放信号量,使其他任务可以继续访问该资源。
以下是一个示例代码,展示了任务如何进行信号量释放操作:void Task2(void *arg){while(1){// 使用共享资源// 释放信号量OSSemPost(sem);}}在上述代码中,任务会在OSSemPost()函数处释放信号量,以便其他任务可以继续访问该资源。
μCOS-II互斥信号量Application NoteAN-1002Jean J. Labrossebrosse@概述:使用互斥信号(Mutual Exclusion Semaphores)或者简单的互斥(mutexes)实现对资源的独占访问,互斥信号本身是一种二进制信号,具有超出μCOS-II提供的一般信号机制的特性。
本手册描述了C/OS-II V2.04增加的mutex一系列服务。
简介:在应用程序中使用互斥信号是为了减少优先级翻转问题(priority inversion problem),如μC/OS-II, The Real-Time kernel (ISBN 0-87930-543-6), section 2.16, page 47中描述的。
当一个高优先级的任务需要的资源被一个低优先级的任务使用是,就会发生优先级翻转问题。
为了减少优先级翻转问题,内核可以提高低优先级任务的优先级,先于高优先级的任务运行,释放占用的资源。
为了实现互斥,实时内核需要具有支持在同一优先级具有多个任务的能力。
不幸的是,μC/OS-II不允许在相同的优先级有多个任务,必须只有一个任务。
但是我们有另外的方法解决这个问题。
可以把需要资源的高优先级任务上面的一个任务使用Mutex保留,允许提高低优先级任务的优先级。
举一个mutexes信号工作的例子,如listing1所示。
Listing 1中有三个任务可以使用共同的资源,为了访问这个资源,每个任务必须在互斥信号ResourceMutex上等待(pend),任务#1有最高优先级10,任务#2优先级为15,任务#3优先级为20,一个没有使用的正好在最高优先级之上的优先级#9用来作为优先级继承优先级(Priority Inheritance Priority-PIP)。
如main()所示,L1(1)进行μC/OS-II初始化,并通过调用OSMutexCreate() L1(2)创建了一个互斥信号。
uCOS-II中关于信号量的使用总结
在ucos-II中,为了实现任务之间的同步,用到的同步机制有:信号量,邮箱和消息队列。
其中这里我主要说下对信号量的使用经验。
信号量在创建时,调用OSSemCreate(INT16U cnt)函数。
cnt为信号量的初始值。
对cnt赋予不同的值,所起到的作用不同。
如果Semp = OSSemCreate(0), 该信号量表示等待一个事件或者多个事件的发生。
例如:我们现在想实现这样一个功能:当有按键按下时,PWM蜂鸣器响起;无按键时,蜂鸣器不响。
这是我们就可以分别建立两个任务,Task1和Task2,在Task1中处理按键的按下与否,一旦按下,则调用OSSemPost(Semp)发送这里信号量。
在Task2中调用OSSemPend(Semp,0,&err)请求此信号量,如果信号量可用,则调用蜂鸣器程序蜂鸣,否则无限等待,任务自动进行切换。
如果我们想对一个公共资源进行互斥访问,例如:如果我们想让两个任务Task1和Task2都可以调用Fun()函数,但不能同时调用,最好定义Semp = OSSemCreate(1),同理在各自的任务中都需要调用OSSemPend(Semp,0,&err)请求此信号量,如果可用,则调用Fun(),然后再调用OSSemPost(Semp)释放该信号量。
这里就实现了一个资源的互斥访问。
同理,如果一个任务要等待n个事件发生后才能执行,则应定义为Semp = OSSemCreate(n)。
然后在这n 个任务分别运行时调用OSSemPost(Semp),直到这n个事件均发生后,这个任务才能运行。
详解UCOS中的互斥信号量二值信号量主要用于进行共享资源的独占式访问,比如我们用一个变量来标志一个资源是否可用,当这个变量为1的时候表示资源可用,当这个资源为0的时候表示资源不可用,但是二值信号量容易产生优先级反转,影响系统的实时性。
互斥信号量一般用于降解优先级反转,优先级反转就是高优先级的任务的优先级被拉低了。
具体如下:我们有三个任务Task1,Task2,Task3,三个任务的优先级依次降低。
void Task1(){while(1){OSSemPend();//获取信号量......OSSemPost();//释放信号量}}void Task2(){while(1){//注意任务2不需要信号量}}void Task3(){while(1){OSSemPend();//获取信号量OSSemPost();//释放信号量}}void main(){OSInit();CreateTask(Task1);//1最高CreateTask(Task2);//2CreateTask(Task3);OSStart();}如上图所示:在任务2获得信号量的时候,任务1恢复就绪态之后因为没有获得信号量而挂起,所以任务3继续执行,直到任务3执行完毕之后,任务1才开始执行。
虽然任务1的优先级最高,但是因为信号量的原因而是任务1的优先级降到任务3的优先级水平。
而且任务2加重了优先级反转的程度。
当我们使用了互斥信号量之后,就可以在某种程度上缓解优先级反转的问题了。
当高优先级的任务请求互斥信号量时,如果低优先级的任务占有该信号量,则先提升低优先级任务的优先级,使之尽快执行完以释放互斥信号量,这样高优先级的任务也能尽快执行,在某种程度上缓解了优先级反转问题。
使用了互斥信号量之后的运行图如下:如图所示,在任务3执行的过程中,任务1请求互斥信号量,提升任务3的优先级到最高,使任务3尽快执行完,任务3执行完后释放信号量,任务1开始执行。
ucosii互斥信号量的用法(实用版)目录1.互斥信号量的概念和作用2.uCOS II 中的信号量和互斥信号量3.互斥信号量在 uCOS II 中的应用实例4.使用互斥信号量的注意事项正文一、互斥信号量的概念和作用互斥信号量是一种用于实现多任务之间同步和互斥的信号量,主要应用于解决多任务对共享资源访问时的线程冲突问题。
互斥信号量可以保证在某一时刻,只有一个任务能够访问共享资源,其他任务需要等待信号量变为可用状态后才能访问。
二、uCOS II 中的信号量和互斥信号量在 uCOS II 操作系统中,信号量是一种重要的同步原语,用于实现任务之间的同步和通信。
信号量分为计数型信号量和互斥型信号量两种。
计数型信号量可以实现任务之间的有序执行,它是一个整数值,可以通过 P 操作(即等待信号量)和 V 操作(即发送信号量)来实现任务的同步。
当计数型信号量的值为 0 时,表示任务需要等待其他任务释放资源;当信号量的值大于 0 时,表示任务可以继续执行。
互斥型信号量主要用于解决多任务对共享资源的互斥访问问题。
互斥型信号量只有一个值,通过 P 操作(即等待信号量)和 V 操作(即发送信号量)来实现任务的同步。
与计数型信号量不同,互斥型信号量在任何时候都只能被一个任务访问,其他任务需要等待信号量变为可用状态后才能访问。
三、互斥信号量在 uCOS II 中的应用实例在 uCOS II 中,互斥信号量通常用于以下场景:1.保护共享资源:当多个任务需要访问共享资源时,可以通过互斥信号量来保证同一时刻只有一个任务能够访问资源。
2.实现任务之间的互斥:在多任务系统中,有些任务不能同时执行,可以通过互斥信号量来实现任务之间的互斥。
3.实现任务之间的有序执行:在特定场景下,需要保证多个任务按照一定的顺序执行,可以通过互斥信号量来实现任务之间的有序执行。
四、使用互斥信号量的注意事项在使用互斥信号量时,需要注意以下几点:1.互斥信号量应在任务开始执行前创建,并在任务结束时释放,避免资源泄漏。
ucosii互斥信号量的用法
ucosii是一个嵌入式操作系统,提供了互斥信号量(Mutex Semaphore)作为一种同步机制。
互斥信号量是一个二进制信号量,用
于在多任务环境中保护共享资源。
它可以用来解决并发访问共享资源
可能引起的数据竞争问题。
互斥信号量主要有两个状态:锁定和非锁定。
只有一个任务可以
拥有互斥信号量的锁定状态,其他任务在请求锁定时会被阻塞。
当任
务完成对共享资源的操作后,会释放互斥信号量的锁定状态,允许其
他任务获取锁。
在ucosii中,可以使用以下函数来创建、获取和释放互斥信号量:
1.函数OSMutexCreate():用于创建一个互斥信号量。
可以设置互斥信号量的初始状态,创建成功后返回一个信号量控制块(OS_MUTEX)的指针。
2.函数OSMutexPend():用于获取一个互斥信号量的锁。
如果互斥信号量的锁已被其他任务获取,则当前任务会被阻塞,直到互斥信号
量的锁可用并成功获取。
3.函数OSMutexPost():用于释放一个互斥信号量的锁。
只有拥有互斥信号量锁的任务才能调用该函数进行释放。
4.函数OSMutexDel():用于删除一个互斥信号量。
如果互斥信号
量的锁被多个任务同时获取,则删除操作可能引起不可预测的行为。
需要注意的是,对于一个互斥信号量的获取和释放应该成对出现,即当前任务在获取互斥信号量后,应该在不再需要共享资源时及时释
放锁,以避免死锁等问题。
除了ucosii中提供的互斥信号量,还可以通过使用其他同步机制
如信号量、事件标志等来实现资源的同步和互斥访问。
ucos II 任务间通信详解ucos II 任务间通信之一 :全局变量任务创建好了之后,只是完成了系统编程的一小步,更为重要的是任务间的通信。
比如在mcu21的项目里,有通信任务,有液晶显示任务,有控制任务。
控制任务需要用到通信任务接受到的数据,液晶显示任务也显示控制任务的数据。
这就需要用到任务间的通信了。
Mcu21总结了一下,在ucos II 里任务间通信可以采用以下几种方式。
z共享全局变量,这是最快捷有效的方式,实现这种通信可以采用以下两种方式:一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断,二是利用函数OSSchedLock()和OSSchedUnlock()对μC/OS‐II中的任务调度函数上锁和开锁.z使用信号量z使用邮箱z使用消息队列下面介绍下共享全局变量的实现过程。
(1)宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是在移植ucos II过程中由用户定义的。
在os_cpu.h这个文件中。
代码如下,这部分代码的作用是关,开中断,具体和CPU有关。
当我们调用OS_ENTER_CRITICAL()时,系统中断被关闭,我们知道,任务切换时基于定时器中断的,当系统中断别关闭时,其它中断,包括定时器中断也就被关闭,任务切换也不可能发生,所以确保在访问变量的时候,不会有其它的任务或中断也在同时访问这个变量。
这两个宏非常好用,在mcu21的项目里经常用到。
尤其在中断处理函数里面。
因为现在的很多CPU是支持中断嵌套的,为了防止中断执行的时候不被其它的中断打断,就可以调用这两个宏。
(2)第二种方法是给任务调度函数上锁,开锁。
这种方法和使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()最大的区别是:中断是可以执行的。
尽管不执行任务切换,变量依然有可以被中断函数访问。
给任务调度器上锁的函数如下void OSSchedLock (void){if (OSRunning == TRUE) {OS_ENTER_CRITICAL();OSLockNesting++;OS_EXIT_CRITICAL();}}给任务调度器解锁的函数如下void OSSchedUnlock (void){if (OSRunning == TRUE) {OS_ENTER_CRITICAL();if (OSLockNesting > 0) {OSLockNesting‐‐;if ((OSLockNesting | OSIntNesting) == 0) { (1)OS_EXIT_CRITICAL();OSSched(); (2)} else {OS_EXIT_CRITICAL();}} else {OS_EXIT_CRITICAL();}}}它实现的原理大致是这样的。
ucosii互斥信号量的用法在嵌入式系统中,互斥信号量是一种非常重要的同步机制,它可以用来保护对共享资源的访问,防止多个任务同时访问而造成的数据冲突。
ucosii实时操作系统就提供了这种机制,使用互斥信号量可以保证在任何时刻只有一个任务在访问共享资源。
一、什么是互斥信号量在ucosii中,互斥信号量是一种特殊的二进制信号量,它的值可以为0或1,用来表示该资源是否被占用。
如果该资源的所有者允许其他任务访问,则该信号量的值为1;否则为0。
在任何时刻,只有一个任务能够访问被保护的资源,因此互斥信号量也被称为互斥锁。
二、互斥信号量的使用在使用互斥信号量时,需要先定义一个信号量对象,然后在需要保护的临界区前面使用semop()函数来设置信号量的值。
当其他任务需要访问被保护的资源时,需要先获取该信号量,进入临界区后释放该信号量。
具体步骤如下:1.定义一个信号量对象semaphorelock;2.在需要保护的临界区前,使用semop()函数设置信号量的值为1;3.其他任务需要访问被保护的资源时,使用semop()函数获取该信号量;4.进入临界区后释放该信号量;5.避免在其他任务释放信号量之前访问临界区,否则可能会发生竞争条件(racecondition)。
三、使用示例下面是一个使用ucosii互斥信号量的示例代码:#include"os.h"#defineKEY1#defineNO_KEY0voidtask1(void*arg){while(1){//获取互斥锁if(semop(lock,&req,1)==-1){//获取失败,等待其他任务释放锁}else{//进入临界区//对共享资源进行操作}}}voidtask2(void*arg){while(1){//释放互斥锁semop(lock,&rel,1);}}在上面的代码中,task1和task2分别代表两个任务。
task1在访问共享资源之前需要获取互斥锁,否则会一直等待;task2则负责释放互斥锁,以便其他任务可以访问共享资源。
目前因项目开发要用到ucOSII,在网上查找到了一些资料,为方便其他同仁,把我个人认为写得很好的文档摘抄到一个文件中,并上传到百度空间,希望对初学都有所帮助。
UCOS事件标志组管理笔记Ⅰ说明:本文摘自网上,来源已忘记,望原作者见谅。
当某个任务需要与多个任务同步时,须要使用事件标志组。
1、弄清楚OS_FLAG_GRP、OS_FLAG_NODE和OS_TCB之间的关系。
当一个任务开始等待某些事件标志位时,就回建立一个事件标志节点OS_FLAG_NODE数据结构,并且将任务所要等待的事件标志位写入OS_FLAG_NODE的分量.OSFlagNodeFlags。
然后将该数据结构分量.OSFlagNodeFLagGrp指向事件标志组OS_FLAG_GRP,将.OSFlagNodeTCB 指向该任务的控制块OS_TCB,建立起任务与事件标志组之间的联系,说明该任务是等待该事件标志组中某些事件标志位的任务。
当有多个任务都需要等待某个事件标志组中某些事件标志位时,这些任务分别建立自己的事件标志节点。
并且将这些事件标志节点通过分量.OS FlagNodeNext和.OSFlagNodePrev连接成链。
⒉、任务可以等待事件标志组中某些位置位1,也可以等待事件标志组中某些位清0,而置1(或清0)又可以分为所有事件都发生的“与”型和任何一个事件发生的“或”型。
这样便有了4种不同的类型存放在.OSFlagNodeWaitType(OS_FLAG_NODE)中。
3、事件标志组和信号量我觉得是有不同的。
信号量建立以后,假设初始值为N,前N个任务调用OSSemPend()函数都会得到信号量。
之后如果第N+1个任务调用OSSemPend()函数申请信号量,该任务将会被置为等待事件发生的状态(睡眠态)。
只到前N个任务中有任务运行完了所要运行的程序,调用OSSenmP ost()函数,释放了所占用了信号量,第N+1个任务。
(这里假设该任务是所有等待信号量任务中优先级最高的任务)才会获得信号量,被从睡眠态转入就绪态。
嵌入式实时操作系统实验报告任务间通信机制的建立系别计算机与电子系专业班级电子0901班学生姓名高傲指导教师黄向宇提交日期 2012 年 4 月 1 日一、实验目的二掌握在基于嵌入式实时操作系统μC/OS-II的应用中,任务使用信号量的一般原理。
掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理及解决优先级反转的策略——优先级继承的原理。
二、实验内容1.建立并熟悉Borland C 编译及调试环境。
2.使用课本配套光盘中第五章的例程运行(例5-4,例5-5,例5-6),观察运行结果,掌握信号量的基本原理及使用方法,理解出现优先级反转现象的根本原因并提出解决方案。
3.试编写一个应用程序,采用计数器型信号量(初值为2),有3个用户任务需要此信号量,它们轮流使用此信号量,在同一时刻只有两个任务能使用信号量,当其中一个任务获得信号量时向屏幕打印“TASK N get the signal”。
观察程序运行结果并记录。
4. 试编写一个应用程序实现例5-7的内容,即用优先级继承的方法解决优先级反转的问题,观察程序运行结果并记录。
5.在例5-8基础上修改程序增加一个任务HerTask,它和YouTask一样从邮箱Str_Box里取消息并打印出来,打印信息中增加任务标识,即由哪个任务打印的;MyTask发送消息改为当Times为5的倍数时才发送,HerTask接收消息采用无等待方式,如果邮箱为空,则输出“The mailbox is empty”, 观察程序运行结果并记录。
三、实验原理1. 信号量µC/OS-II中的信号量由两部分组成:一个是信号量的计数值,它是一个16位的无符号整数(0 到65,535之间);另一个是由等待该信号量的任务组成的等待任务表。
用户要在OS_CFG.H中将OS_SEM_EN开关量常数置成1,这样µC/OS-II 才能支持信号量。
在使用一个信号量之前,首先要建立该信号量,也即调用OSSemCreate()函数(见下一节),对信号量的初始计数值赋值。
UCOS-II-信号量的理解
1.信号量的理解
(1)uc/os-ii的信号量是由两个部分组成:一部分是16位的无符号整型信号量的计数值(0~65535);另一部分是等待该信号量的任务组成的等待任务表。
(另外参考事件控制块ECB)
(2)信号量可以是2值的变量(称为二值信号量),也可以是计数式的。
根据信号量的值,内核跟踪那些等待信号量的任务。
(3)建立信号量的工作必须在任务级代码中或者多任务启动之前完成。
(4)任务要得到信号量的问题。
想得到信号量的任务,必须执行等待操作(pend)。
如果信号量有效(非0),则信号量减1,任务得以继续运行。
如果信号量无效,则等待信号量的任务就被列入等待信号量的任务表中。
多少内核允许定义等待超时,当等待时间超过了设定值,该信号量还是无效,则等待该信号量的任务进入就绪态,准备运行,并返回出错代码(等待超时错误)。
(5)任务对信号量的释放问题。
任务执行发信号(post)操作来释放信号量。
如果没有任务等待信号量,那么信号量的值仅是简单的加1(则信号量大于0,有效);如果有任务等待该信号量,那么就会有另一个任务进入就绪态,信号量的值就不加1。
之后,这个释放的信号量给那个等待中的任务,要看内核如何调度的。
收到信号量的任务可能是如下两者之一:
◆等待任务中,优先级最高的;(uc/os-ii仅支持这种方式)。
◆最早开始等待信号量的任务(如果是按先进先出FIFO原则)。
2.信号量的有效与无效问题
信号量有效:信号量的计算器非0(.OSEventCnt!=0)。
信号量有效表示任务对资源可用。
信号量无效:信号量的计算器为0。
信号量无效表示任务对目前资源不可用,需要等待其他另一个任务(或者中断服务子程序)发出该信号量(OSSemPost)。
3.信号量的值(.OSEventCnt)大小表示什么?
二值信号量,表示任务可以独占共享资源。
计数式信号量,用于某资源可同时为N个任务所用。
4.信号量是如何实现任务之间的通信的?
参见第1点的(4)(5)概述。
5.信号量有关的三个重要函数分析
◆OSSemCreate()创建一个信号量(注:由任务或启动代码操作)
创建工作必须在任务级代码中或者多任务启动之前完成。
功能只要是先获取一个事件控制块ECB,写入一些参数。
其中调用了OS_EeventWaitListInt()函数,对事件控制块的等待任务列表进行初始化。
完成初始化工作后,返回一个该信号量的句柄(Handle)。
◆OSSemPend()等待一个信号量(注:只能由任务操作)
本函数应用于任务试图获得共享资源的使用权、任务需要与其他任务或中断同步及任务需要等待特定事件发生的场合。
如果任务Task_A调用OSSemPend(),且信号量的值有效(非0),那么OSSemPend()递减信号量计数器(.OSEventCnt),并返回该值。
换句话说,Task_A获取到共享资源的使用权了,之后就执行该资源。
如果如果任务Task_A调用OSSemPend(),信号量无效(为0),那么OSSemPend()调用OS_EventTaskWait()函数,把Task_A放入等待列表中。
(等待到什么时候呢?要看OSSemPost()(或者等待超时情况),由它释放信号量并检查任务执行权,见下资料)
◆OSSemPost()发出(释放)一个信号量(注:由任务或中断操作)
本函数其中调用OS_EventTaskRdy()函数,把优先级最高的任务Task_A(在这假如是Task_A,另外假设当前调用OSSemPost()的任务是Task_B)从等待任务列表中去除,并使它进入就绪态。
然后调用OSSched()进行任务调度。
如果Task_A是当前就绪态中优先级最高的任务,则内核执行Task_A;否则,OSSched()直接返回,Task_B继续执行.
----------------------------------------------------------------
互斥型信号量
1.互斥型信号量(mutex)
互斥型信号量具备uc/os-ii信号量的所有机制,但还具有其他一些特性。
任务可利用互斥型信号量来实现对共享资源的独占处理。
Mutex是二值信号量,1表示资源是可以使用的。
2.关于优先级反转
下面概述优先级反转原理:
假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。
任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。
当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。
运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。
此时任务C得以继续运行。
同理,任务B的事件到来后,会剥夺任务C的CPU使用权。
任务B把事情搞定以后,把CPU使用权归还给任务B(呵呵,优先级低就是给人欺负啊,所以做人还真的要争口气!)。
任务B又得以继续运行,任务B认真处理完毕资源S1后,终于可以释放S1的信号量。
而处于等待该信号量的任务A马上得到信号量并开始处理共享资源S1。
综述上面情况,任务C和任务A的优先级发生了反转。
而互斥型信号量就是具有解决优先级反转问题的特性。
3.uc/os-ii的互斥型信号量由三个部分组成:
◆一个标志,指示mutex是否可以使用(0或1)
◆一个优先级,准备一旦高优先级的任务需要这个mutex,赋予给占有mutex 的任务。
◆一个等待该mutex的任务列表。