




已阅读5页,还剩32页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目前因项目开发要用到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,建立起任务与事件标志组之间的联系,说明该任务是等待该事件标志组中某些事件标志位的任务。当有多个任务都需要等待某个事件标志组中某些事件标志位时,这些任务分别建立自己的事件标志节点。并且将这些事件标志节点通过分量.OSFlagNodeNext和.OSFlagNodePrev连接成链。、任务可以等待事件标志组中某些位置位1,也可以等待事件标志组中某些位清0,而置1(或清0)又可以分为所有事件都发生的“与”型和任何一个事件发生的“或”型。这样便有了4种不同的类型存放在.OSFlagNodeWaitType(OS_FLAG_NODE)中。3、事件标志组和信号量我觉得是有不同的。信号量建立以后,假设初始值为N,前N个任务调用OSSemPend()函数都会得到信号量。之后如果第个任务调用OSSemPend()函数申请信号量,该任务将会被置为等待事件发生的状态(睡眠态)。只到前N个任务中有任务运行完了所要运行的程序,调用OSSenmPost()函数,释放了所占用了信号量,第N+1个任务。(这里假设该任务是所有等待信号量任务中优先级最高的任务)才会获得信号量,被从睡眠态转入就绪态。而事件标志组是事件标志组建立之后,某个任务需要事件标志组中某些事件标志位(置位或者清0)才能继续运行,于是任务调用OSFlagPend()函数,而此时若这些标志位满足要求,任务返回,继续执行。否则,任务将被挂起。而当有另外一个任务调用OSFlagPost()函数将前一个任务所需要的标志位(置位或清0)使之满足要求,前一个被挂起的任务将被置为就绪态。因此几个任务可以同时得到所需要的事件标志进入就绪态。注意:只要任务所需要的标志位满足要求,任务便进入就绪态。与信号量不同,信号量中的任务需要是在等待该信号量中优先级最高的任务才能得到信号量进入就绪态。事件标志组可以一个任务与多个任务同步,而信号量只能是一个任务与另一个任务同步以下所有文档摘自一位网友博客上的,写的很好,转一下:ucosii学习(2)事件标志组2010-08-23 20:54 FLAG-事件标志组管理,在UCOSII里我个人觉相对比较复杂,首先我们要有个大致的概念,就是FLAG事件组能用来干什么。以下只摘自一位网友博客上的,写的很好,转一下: (一)描述:对于flag-事件组的使用,可以用一个简单的例子做说明:比如,我现在用迅雷下载一部10集的连续剧,我打算10集全部下载完成之后,才开始正式看,现在310集因为种子原因,先早下完了,现在第1集下到了82%,第2集下到了97%,因为我的计划是10集全部下完才开始看,而第1集和第2集由于网络,种子等等各种原因,迟迟不能下载完成,进而导致我的计划被悬停,不能进行,已下载的8集,也因为前2集没能下完,而白白等待-这就等同于flag事件组, 110集,每一集都是一个事件,因为我内定,10个事件全部完成之后,才进入下一事件-观看所以及早完成自己事件的第310集,将主动把自己通过flag事件组函数OSFlagPost()登记到事件组上,他们不关心,其他友邻事件完成否,只专注自己的事件是否完成,自己的事件一旦完成就登记到事件组上,最后310集,都把自己登记上去了,只剩下第1集和第2集,一旦某天的某个时刻,第2集下完了,那么第2集也把自己登记到事件组上,这样整个事件距离完成还剩下一个事件,就是第1集是否下载完成,只要第1集下载完成,那么我内定的观看计划开始启动,过了3分钟,由于网速提高,竟以300k的速度开始下载第1集,1分钟之后,第1集也下载完成了,第1集立即调用OSFlagPost事件组函数,将自己登记到事件组上,ok,OSFlagPost()检测到所有事件已经完成,OSFlagPost()将是我自动进入下一事件-观看还有一点就是关于flag事件组和Sem,Mbox,Queue的区别之处,flag事件组不使用事件控制矩阵来管理被阻塞在事件上的task进程,flag事件组使用pgrp的双向链表来挂接起所有task,在OSFlagPost()中将遍历这个链表,查找符合当前flag事件的task,将该task从双向链表中摘下然后放入就绪控制矩阵中,之所以这样,是因为flag事件组不像Sem,Mbox,Queue那样具有二值性,即Sem,Mbox,Queue,要么有,要么没有,flag事件组,还要进一步判断,有的话,是什么程度的有。 通过以上介绍,对于FLAG事件组有了大致的了解,但要具体了解其实现过程,最好还是去看看其原代码,原代码就不在这贴出来了。UCOSII使用等待事件标志组的任务列表是一个双向链表,使用了3个数据结构:OS-FLAG-GRP,任务控制块TCB,OS-FLAG-NODE。 特别是对OS-FLAG-NODE我觉得要注意一下,当一个任务开始等待某些事件标志时,就建立一个OS-FLAG-NODE数据结构。当这些等待事件标志发生后,这个数据被删除。具体分析看邵贝贝老师的书,写的比较详细。对于原代码自己在有些细节上还是有些没有弄清楚,但基本用用还是可以的,下面就来举几个自己实现过的例子吧。 (二)举例。以下举的例子,是自己从网上找来的,再经过一定的修改,在STM32上跑的。1).简单的OSFLAGPEND()与OSFLAGPOST()函数的应用显示用,LCD1602和两个LED灯(条件有限啊)TASK1():建一个OSFlagPend() 若等待事件标志没有发生 该函数挂起该任务若事件标志发生,则LCD显示一个值,LED灯每隔一秒闪一次。TASK2():OSFlagPost()向任务一发送一个信号量TASK3():OSFlagPost()向任务一发送一个信号量,具体看代码static void Task1(void *pdata) INT8U error; INT8U i=0; pdata = pdata; while(1) /若等待事件标志没有发生 该函数挂起该任务 OSFlagPend(Sem_F, /请求信号量集 (OS_FLAGS)3, /请求第0位和第1位信号/且都置为1时为有效 否则任务挂在这里OS_FLAG_WAIT_SET_ALL, 0, /无限等待 直到收到为止&error);/OSFLAGPEND收到有效信号后 在LCD显示字符串/闪两个LED 可以跟据自己代码而? write_com(0x80+10); while(table1i != 0) write_dat(table1i); i+; GPIO_ResetBits(GPIOD, GPIO_Pin_15); GPIO_ResetBits(GPIOD, GPIO_Pin_13); /任务挂起1秒 否则优先级低的任务就没机会执行了 OSTimeDlyHMSM(0,0,1,0); GPIO_SetBits(GPIOD, GPIO_Pin_15); GPIO_SetBits(GPIOD, GPIO_Pin_13); OSTimeDlyHMSM(0,0,1,0); /让两个LED每秒闪一次 static void Task2(void *pdata) INT8U error; pdata = pdata; while(1) OSFlagPost(Sem_F, /发送信号量集(OS_FLAGS)2, /给第1位发信号OS_FLAG_SET, /信号量置1&error); OSTimeDlyHMSM(0, 0, 1, 0); /等待1秒 static void Task3(void *pdata) INT8U error; pdata = pdata; while(1) /在执行此函数时 发生任务切换 去执行TASK1 在OSFLAGPOST中发生任务切换 OSFlagPost(/发送信号量集 Sem_F, (OS_FLAGS)1, /给第0位发信号 OS_FLAG_SET, /信号量置1 &error ); OSTimeDlyHMSM(0, 0, 1, 0); /等待1秒 void main(void) #if (OS_TASK_NAME_SIZE 14) & (OS_TASK_STAT_EN 0) INT8U err; #endif /目标板初始化, Target_Init(); lcd_init(); OSInit(); /设置空闲任务名称 #if OS_TASK_NAME_SIZE 14 OSTaskNameSet(OS_TASK_IDLE_PRIO, uC/OS-II Idle, &err); #endif /设置统计任务名称 #if (OS_TASK_NAME_SIZE 14) & (OS_TASK_STAT_EN 0) OSTaskNameSet(OS_TASK_STAT_PRIO, uC/OS-II Stat, &err); #endif Sem_F = OSFlagCreate(0,&error); /用任务建立任务 OSTaskCreateExt(APP_TaskStart, /void (*task)(void *pd) 任务首地址(void*)0, /void *pdata 数据指针/OS_STK *ptos 指向任务堆栈栈顶的指针&APP_TaskStartStkAPP_TASK_START_STK_SIZE - 1,/INT8U prio 任务优先级(INT8U)APP_TASK_START_PRIO,/INT16U id 任务的ID号(INT16U)APP_TASK_START_ID,/OS_STK *pbos 指向任务堆栈栈底的指针&APP_TaskStartStk0, /INT32U stk_size 堆栈容量(INT32U)APP_TASK_START_STK_SIZE,(void*)0, /void *pnext 数据指针/INT16U opt 设定OSTaskCreateExt的选项OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); OSStart();上述例子中,TASK1()OSFLGAPEND()需要第0,1位都置位时才有效,任务刚进来时不满足即被挂起。等待着OSFLGAPOST()把相应位置1。TASK2,TASK3分别把第0,1位置位。即等到执行完TASK3时,TASK1()有效。2.)若TASK1()如下static void Task1(void *pdata) INT8U error; INT8U i=0; pdata = pdata; while(1) /若等待事件标志没有发生 该函数并不挂起该任务 OSFlagAccept(/请求信号量集 Sem_F, (OS_FLAGS)3, /请求第0位和第1位信号 /第0位和第1位信号都为1为有效 OS_FLAG_WAIT_SET_ALL, &error ); /OSFLAGPEND收到有效信号后 在LCD显示字符串/ 闪两个LED 可以跟据己代码而定 write_com(0x80+10); while(table1i != 0) write_dat(table1i); i+; GPIO_ResetBits(GPIOD, GPIO_Pin_15); GPIO_ResetBits(GPIOD, GPIO_Pin_13); /任务挂起1秒 否则优先级低的任务就没机会执行了 OSTimeDlyHMSM(0,0,1,0); GPIO_SetBits(GPIOD, GPIO_Pin_15); GPIO_SetBits(GPIOD, GPIO_Pin_13); OSTimeDlyHMSM(0,0,1,0); /让两个LED每秒闪一次 即为无等待获取,当信号量不满足,任务也不挂起,即TASK2(),TASK3()不给OSFLAGCCEPT()发送信号,TASK1()仍然执行,在本例中,LCD,LED显示正常。3.)我们还可以用OSFLGAQUERY()来查询事件标志组的状态。跟据状态来执行自己所期望的代码,用起来很方便且很好。static void Task1(void *pdata) INT8U error; INT8U i=0,j=0,k=0,Flags; pdata = pdata; while(1) Flags=OSFlagQuery( /查询事件标志组的状态 Sem_F, &error ); switch(Flags) case 1: write_com(0x80+10); while(table1i != 0) write_dat(table1i); i+; break; case 2: write_com(0x80+0x40); while(table2j != 0) write_dat(table2j); j+; break; case 3: write_com(0x80+0x40+8); while(table3k != 0) write_dat(table3k); k+; break; OSTimeDlyHMSM(0, 0, 1, 0); /等待2秒 (三)总结,对于FLAG事件组大致就这些吧。自己也正在学习中,可能有很多地方还不对。最后再讲一点体会吧。关键是理解两个函数,OSFLAGPEND(),OSFLAGPOST()。具体它们是在干什么的:OSFLAGPEND(): 任务等待事件标志组中的事件标志,可以是多个事件标志的不同组合方式。可以等待任意指定事件标志位置位或清0,也可以是全部指定事件标志位置位或清0。如果任务等待的事件标志位条件尚不满足,则任务会被挂起,直到指定的事件标志组合发生或指定的等待时间超时。OSFLAGPOST(): 给出设定的事件标志位。指定的事件标志位可以设定为置位或清除。若OSFlagPost()设置的事件标志位正好满足某个等待使劲标志组的任务,则OSFlagPost()将该任务设为就绪。注意: 必须先创建事件标志组,然后使用; 这个函数的运行时间决定于等待事件标志组的任务的数目; 关闭中断的时间也取决于等待事件标志组的任务的数目。 (四)参考资料:来自各位网友博客嵌入式实时操作系统第2版ucosii学习(3)信号量2010-08-25 21:51 对于UCOSII中信号量的理解相对还是比简单的,但怎么能够灵活的运用还是要多实践的。信号量为操作系统用于处理临界区问题和实现进程间同步提供了一种有效的机制。想要具体深入了解最好去看看原代码。 (一)、描述。以下文字摘自一位网友的。作者: yzhu 于 2006-2-9 20:49:00 发布: 以下为个人理解,仅供参考简单地说: 当信号量=0时,表示信号量代表的资源不可用,操作系统就调用OSSemPend()函数的任务加入该信号量的等待任务列表中; 当信号量0时,表示信号量代表的资源可用,OSSemPend()函数返回,任务可以使用资源。 一般地,信号量的最大值(nmax)表示资源的最大同时共享数。nmax=1,表示资源最多只能由一个任务使用,如读写某内存单元时,为保证该单元不被其它任务篡改,就使用nmax=1的(二值)信号量;nmax1,表示资源可由多个任务使用,如FIFO,一个任务写某单元时,另一个任务可以写其它单元,则可使用nmax1的(多值)信号量,信号量的大小用来表示FIFO的可用单元数。 减1操作:当该信号量=0时表示FIFO已满,任务只能等待;当该信号量0时表示FIFO有空,可以使用,同时要减1表示调用OSSemPend()函数的任务已经使用了一个资源(FIFO单元),可使用资源少了一个。 加1操作:当某任务调用OSSemPost()从FIFO中取出一个值时,该FIFO单元就空出一个可写单元,也就是资源多了一个,为表示这个变化,信号量要加1,一旦信号量由0-1,则把资源给等待任务列表中优先级最高的任务(通过OSSemPend()函数的返回)。 总之,信号量的值代表共享资源的剩余量,用掉一个减1,空出一个加1。举个例子:顾客(任务)到银行办事,银行(OS)现有N名业务员(共享资源)。1. 办事前先要取号(OSSemPend(),号条一般有“前面有xx位顾客”,表示正在等待服务(资源)的顾客(任务)数。2. 另外假设银行有一指示牌(信号量)指示当前空闲的业务员的数量为n(信号量的值)。3. 当n0时,表示有空闲的业务员,那么顾客可以立即去业务员那办理业务(OSSemPend()立即返回),这样空闲的业务员就少一个,指示牌指示的数量(信号量的值)就要减1,但n只能减到N。4. 当n=0时,表示没有空闲的业务员,那么顾客只能等待(OSSemPend()不返回,切换到其它任务)。5. 当某位业务员为顾客办完手续后,他就空闲下来,这样空闲的业务员就多一个,指示牌指示的数量(信号量的值)就要加1,但n只能加到N。 这时银行就会去查找有没有正在等待的顾客,如果有,就找出其中优先级最高的顾客,让他来办理业务(OSSemPend()返回)。6. 顾客在取号时若设置了等待时间,那么在等待时间过后,银行就会通知顾客时间到(OSSemPend()返回),顾客接着去办其它事。7. 也有的顾客希望:在取号时,如果有空闲的业务员他就办事,没有的话就走(去办其它事),那么就要用特殊的取号方式(OSSemAccept()。8. N=1时,表示只有一个业务员,指示牌只能指示0或1两个值,这就是二值信号量。不知道这个例子能不能说清楚信号量的概念,请大伙完善。(二)、代码举例。通过上述文字的描述,我想我们对信号量有了一定的了解,下面的一些代码是自己在自己开发板上跑的,运行结果只是为了分析各任务运行情况,一定有很多不妥之处。1.)用信号量实现同步。建立TASK1(),TASK2()。实现两个任务同步,以LED灯来显示。static void Task1_LED1(void *pdata) /优先级10 INT8U error; pdata = pdata; while(1) OSSemPend(sem,0,&error); /任务作1刚进来由SEM=0即任务被挂起转而执行任务2 GPIO_SetBits(GPIOD, GPIO_Pin_11); GPIO_ResetBits(GPIOD, GPIO_Pin_10);/由于任务2释放信号量后执行到此外 任务1又要申请信号量/即又被挂起 等待信号量再次释放 OSSemPend(sem,0,&error); GPIO_SetBits(GPIOD, GPIO_Pin_10); GPIO_ResetBits(GPIOD, GPIO_Pin_11); static void Task2_LED2(void *pdata) /优先级11 pdata = pdata; while(1) GPIO_SetBits(GPIOD, GPIO_Pin_9); GPIO_ResetBits(GPIOD, GPIO_Pin_8);/任务执行到此处释放信号量SEM 因为TASK1在等待该信号量 马上切换到任务1 OSSemPost(sem);OSTimeDlyHMSM(0,0,1,0); /挂起1秒 GPIO_SetBits(GPIOD, GPIO_Pin_8); GPIO_ResetBits(GPIOD, GPIO_Pin_9); OSSemPost(sem); /再次释放信号量去执行任务1 OSTimeDlyHMSM(0,0,1,0); void main(void) #if (OS_TASK_NAME_SIZE 14) & (OS_TASK_STAT_EN 0) INT8U err; #endif /目标板初始化, Target_Init(); lcd_init(); EXTI_Configuration(); NVIC_Configuration(); OSInit(); sem = OSSemCreate(0);/创建一个信号量表示一个事件的发生 故取值为0 /设置空闲任务名称 #if OS_TASK_NAME_SIZE 14 OSTaskNameSet(OS_TASK_IDLE_PRIO, uC/OS-II Idle, &err); #endif /设置统计任务名称 #if (OS_TASK_NAME_SIZE 14) & (OS_TASK_STAT_EN 0) OSTaskNameSet(OS_TASK_STAT_PRIO, uC/OS-II Stat, &err); #endif /用任务建立任务 OSTaskCreateExt(APP_TaskStart, /void (*task)(void *pd) 任务首地址 (void *)0, /void *pdata 数据指针 /OS_STK *ptos 指向任务堆栈栈顶的指针 &APP_TaskStartStkAPP_TASK_START_STK_SIZE-1, (INT8U)APP_TASK_START_PRIO, /INT8U prio任务优先级 (INT16U)APP_TASK_START_ID, /INT16U id任务的ID号 /OS_STK *pbos指向任务堆栈栈底的指针 &APP_TaskStartStk0, (INT32U)APP_TASK_START_STK_SIZE, /INT32U stk_size堆栈容量 (void *)0, /void *pnext数据指针 /INT16U opt设定OSTaskCreateExt的选项 OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); #if OS_TASK_NAME_SIZE 14 OSTaskNameSet(APP_TASK_START_PRIO, Task-Start, &err); #endif OSStart();大致代码如上所示,这样我们就实现了TASK1(),TASK2()的同步。同时我刚在网上看到,有网友讨论全局变量也有在任务之间传递值(有点类似于信号量)。但我也觉得,全局变量虽然有这作用,但是它与真正的信号量最大的区别就在于它不能实现同步,所以这就是UCOSII的优点了。2.)信号理作为共享信号sem1 = OSSemCreate(0);/创建一个信号量表示一个共享资源 故取值为1static void Task3_LED3(void *pdata) /优先级10 INT8U error; pdata = pdata; while(1) /开始进入TASK3时SEM1=1 即立即执行 是OSSPEND执行最快的 OSSemPend(sem1,0,&error); GPIO_SetBits(GPIOD, GPIO_Pin_15); /OSTimeDly(OS_TICKS_PER_SEC / 2); OSTimeDlyHMSM(0,0,1,0); /任务被挂起一秒表 跳到其他任务如TASK4 OSSemPost(sem1); /*static void Task4_LED4(void *pdata) /优先级11 INT8U error; pdata = pdata; while(1) /进来后由于SEM1=0 任务被挂起 等到TASK3释放共享信号后才得以继续执行 OSSemPend(sem1,0,&error); GPIO_ResetBits(GPIOD, GPIO_Pin_15); /OSTimeDly(OS_TICKS_PER_SEC / 2); OSTimeDlyHMSM(0,0,1,0); OSSemPost(sem1); 这样,我们就把信号量用作共享信号了。3.)其中当我们用信号量实现共享资源进行访问时,我个人觉得可能会出现优先级反转。具体什么是优先级反转,等下次再学习一下。不过还是先把代码贴上。#define Task1_LED1_Prio 11#define Task2_LED2_Prio 12#define Task3_LED3_Prio 13OS_EVENT *Sem;Sem = OSSemCreate(1);static void Task1_LED1(void *pdata) INT8U error; pdata = pdata; while(1) INT8U i=0,j=0; OSTimeDlyHMSM(0,0,0,200); /一进来 马上任务挂起 转去执行任务2 GPIO_SetBits(GPIOD, GPIO_Pin_15); GPIO_ResetBits(GPIOD, GPIO_Pin_14); while(table4i != 0) /显示一个W 表示任务等待在此处 write_dat(table4i); i+; OSSemPend(Sem,0,&error); while(table1j != 0) /显不一个1 表示任务1执行了一次 write_dat(table1j); j+; GPIO_SetBits(GPIOD, GPIO_Pin_14); GPIO_ResetBits(GPIOD, GPIO_Pin_15); OSSemPost(Sem); OSTimeDlyHMSM(0,0,0,200); /*static void Task2_LED2(void *pdata) pdata = pdata; while(1) INT8U i=0; GPIO_SetBits(GPIOD, GPIO_Pin_13); GPIO_ResetBits(GPIOD, GPIO_Pin_12); while(table2i != 0) /显示2 代表示任务2执行过了 write_dat(table2i); i+; GPIO_SetBits(GPIOD, GPIO_Pin_12); GPIO_ResetBits(GPIOD, GPIO_Pin_13); OSTimeDlyHMSM(0,0,0,300); /任务2执行到此处也挂起 /*static void Task3_LED3(void *pdata) INT8U error; INT32U times; pdata = pdata; while(1) INT8U i=0; /任务3所先申请该信号量 即此时信号量可用 代码继续执行 OSSemPend(Sem,0,&error); GPIO_SetBits(GPIOD, GPIO_Pin_11); GPIO_ResetBits(GPIOD, GPIO_Pin_10); while(table3i != 0)/显示3 表示任务3执行过了 write_dat(table3i); i+; for(times=0;times=3(我认为=2就可能发生反转)个进程同时访问一个共享的情况下,/所以至少有3个进程才有可能发生优先级翻转,即ABC时,B才可能将A翻转./COS/II v2.85内核采用变相置顶的方式来解决优先级翻转问题,/优先级继承方式是指一个较高优先级的任务申请某信号量,但此信号量已被一个较低优先级的任务占有,这时,抬升较低优先级任务的优先级到较高优先级任务的优先级,这是一个自动过程./置顶方式是指一旦有进程访问互斥资源,立即把该进程的优先级提升到置顶值./变相置顶的方式是指我们根据工程应用任务需要,自己内定一个最高优先级,结合优先级继承方式,根据情况来判断当前task进程优先级是否需要抬升到置顶值./这个最高优先级可能不是0,比如可能是5(5空闲,不能用于创建其他任务),原因是04,之间的任务不会访问互斥空间,/仅仅优先级=6的进程才会访问互斥空间,这时5就是所谓的A,假如优先级为10的进程要访问互斥空间,/这时因为没有任何进程访问互斥空间,所以10作为pevent-OSEventCnt的低8位值,被保存,之后持有/互斥空间的操作权利,此时优先级为12的进程也要访问互斥空间,因为12处于C的角色,所以不会发生优先级翻转,/12将直接被悬停在Mutexevent事件控制矩阵上,之后8打算访问互斥资源空间,/那么,因为8处于B的角色,这时10需要提升自己到这个所谓的顶-优先级5,/这样,以后所有访问互斥资源的进程都因为优先级小于5而直接悬停在Mutexevent事件控制矩阵上,/不会出现因为6、7、8悬停在Mutexevent事件控制矩阵上,而此时9因为获得cpu执行权,/而抢占了10的执行,进而发生优先级翻转现象.gliethttp/但是如果真的04中的某个进程不守规矩,贸然访问了共享资源,会发生什么呢,让我们来看看:/如2要访问资源,那么2一定是直接悬停在事件控制矩阵上,直到已经提升优先级或未提升优先级的占用互斥资源空间/的进程退出,重新计算悬停在事件控制矩阵上的优先级最高的任务的时候,2将会被加入到就绪控制矩阵中,等待cpu/调度,进而占用互斥资源,这好像也没有问题,那么继续进行假设,如果4优先级在操作互斥资源,此时2打算操作,/那么2需要等待,被添加到了mutex事件控制矩阵中,这时就那么巧,3又获得了cpu的使用权,那么优先级4将被3抢占/所以出现了优先级翻转现象-3把2给翻转了,所以对于优先级高于内定置顶值pip的进程访问互斥资源时,/并不能受到mutex互斥保护机制的保护,所以对于这些进程,他们可能会发生优先级翻转,也可能不会./因此,这使我们更坚定一点,不要存在侥幸心里,踏踏实实的把pip设置成真正的置顶值.gliethttp(二)、举例:static void Task1_LED1(void *pdata) INT8U error; pdata = pdata; while(1) INT8U i=0,j=0; OSTimeDlyHMSM(0,0,0,200); /一进来 马上任
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 商业区景观设计及施工协议
- 个人营运工作总结
- 2025医疗行业劳动合同变更及医疗服务协议
- 2025年文艺演出肖像使用权合同
- 2025年光伏建筑一体化项目在建筑节能技术创新中的应用报告
- 2025年工业互联网平台网络隔离技术市场分析与竞争格局报告
- 修饰词语法讲解
- 施工企业成本管理
- 财富管理行业2025年客户需求洞察与财富管理行业竞争力分析报告
- 茶香咖啡韵:2025年融合业态市场投资价值报告
- 2025年第一届安康杯安全生产知识竞赛试题题库及答案(完整版)
- 电力工程冬季施工安全技术措施
- 贵州省贵阳市2026届高三上学期摸底考试数学试卷含答案
- 公司年度员工安全教育培训计划
- 供电所安全教育培训课件
- 2025年杭州市上城区望江街道办事处 编外人员招聘8人考试参考试题及答案解析
- 百果园水果知识培训资料课件
- 2025年灌注桩考试题及答案
- 公司安全生产责任书范本
- 养老护理员培训班课件
- 隔爆水棚替换自动隔爆装置方案及安全技术措施
评论
0/150
提交评论