2473|1

78

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

今天老师留的作业.我不会做,有哪位高人给我指点一下 [复制链接]

实验3  优先级继承
1 实验目的
    掌握嵌入式实时操作系统?C/OS-II解决优先级反转的策略——优先级继承的原理。
2 原理及程序结构
2.1        实验设计
2.1.1 优先级继承原理
优先级继承的主要思想是:当高优先级任务因申请某共享资源失败被阻塞时,把当前拥有该资源的、且优先级较低的任务的优先级提升,提升的高度等于这个高优先级任务的优先级。在?C/OS-II中,在创建管理共享资源的互斥信号量时,可以指定一个PIP(优先级继承优先级),之后可以把拥有共享资源的任务优先级提升到这个高度。具体过程如下:
1.        当任务A申请共享资源S时,首先判断是否有别的任务正在占用资源S,若无,则任务A获得资源S并继续执行;
2.        如果任务A申请共享资源S时任务B正在使用该资源,则任务A被挂起,等待任务B释放该资源;同时判断任务B的优先级是否低于任务A的,若高于任务A,则维持任务B的优先级不变;
3.        如果任务B的优先级低于任务A的,则提升任务B的优先级到PIP,当任务B释放资源后,再恢复其原来的优先级。
2.1.2 设计要点
在本实验中设计了处于不同优先级的应用任务,如下图所示:

              任务TASK0:         任务TASK1:       任务TASK2 :   
                                     图3-1
注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各个任务启动和执行的相对先后关系。
这3个应用任务因为要竞争同一互斥资源mutex而相互制约。其中,任务TASK0的原始优先级最低,任务TASK1的原始优先级中等,任务TASK2的原始优先级最高。在使用mutex时采用优先级继承策略,并指定各任务在使用mutex时的PIP(优先级继承优先级)为8。
2.1.3 系统的运行流程
TaskStart任务首先运行,由它创建其他3个应用任务:
TaskStart任务挂起后,操作系统调度它所创建的3个应用任务,整个系统的运行流程如下:
(1)TASK2拥有最高优先级10,最先开始运行,它在t1时刻,执行OSMutexPend(mutex, 0, &err),成功获得互斥信号量mutex;
(2)t2时刻,TASK2执行延时函数OSTimeDlyHMSM(0, 0, 0, 200)被挂起200ms,操作系统调度优先级次之的TASK1运行;
(3)t3时刻,TASK1执行OSMutexPend(mutex, 0, &err)申请互斥信号量失败后被阻塞,操作系统调度优先级最低的TASK0运行。TASK0执行OSMutexPend(mutex, 0, &err)申请互斥信号量失败后也被阻塞。在TASK1和TASK0被阻塞的时候,由于当前拥有mutex的TASK2优先级最高,因此保持其优先级不变。当所有的应用任务都阻塞时,系统有一个空闲任务在运行,这个空闲任务是在初始化操作系统的时候创建的,它的优先级最低;
(4)t4时刻,TASK2延时到并运行,它执行OSMutexPost(mutex)释放互斥信号量并由TASK1获得此信号量。t5时刻TASK2将自己延时一段时间(150ms),任务回到运行状态;
(5)TASK1执行延时函数OSTimeDlyHMSM(0, 0, 0, 200)后被挂起200ms,空闲任务运行;在t6时刻TASK2因延时时间到恢复执行,它执行OSMutexPend(mutex, 0, &err)申请互斥信号量失败后被阻塞,空闲任务运行。此时操作系统发现当前拥有信号量的任务TASK1的优先级低于TASK2的,因此将TASK1的优先级提升到PIP,但TASK1此时仍处于延时状态未运行;
(7)t7时刻,TASK1延时到,它在高优先级(PIP)下继续运行,调用OSMutexPost(mutex)释放互斥信号量并由TASK2获得此信号量,TASK1的优先级恢复到原来的高度,而TASK2因优先级较高而抢占TASK1运行(在t8时刻);
(8)TASK2又将自己延时一段时间(200ms),任务TASK1恢复执行后也将自己延时一段时间(300ms),空闲任务运行;t9时刻TASK2延时时间先到,它执行OSMutexPost(mutex)释放互斥信号量,此时TASK0获得此信号量;
(9)t10时刻,TASK2延时(150ms),任务TASK0被调度运行;TASK0在打印输出信息后,将自己延时(200ms),空闲任务运行;
(10)t11时刻,TASK1延时到恢复运行。TASK1执行OSMutexPend(mutex, 0, &err)申请互斥信号量失败后被阻塞;此时操作系统发现当前拥有信号量的TASK0优先级低于TASK1的,因此提升TASK0的优先级到PIP,空闲任务运行;
(11)t12时刻,TASK2延时到恢复运行,它执行OSMutexPend(mutex, 0, &err)申请互斥信号量失败后被阻塞;此时拥有信号量的TASK0的优先级已经被提升到了PIP,且高于TASK2的优先级,操作系统就没有针对TASK0再做优先级提升的工作。之后空闲任务运行;
(12)t13时刻,TASK0延时到,在高优先级(PIP)下继续运行,它执行OSMutexPost(mutex)释放互斥信号量,其优先级恢复到原来的高度,并由TASK2获得此信号量,TASK2抢占TASK0运行;
系统如此周而复始地运行下去……
2.2 操作系统配置
修改uC_OS-II/OS_CFG.h:
#define OS_MAX_EVENTS      10           /*最多可以有10个事件*/
#define OS_MAX_FLAGS        5            /*最多可以有5个事件标志*/
#define OS_MAX_MEM_PART    5            /*最多可以划分5个内存块*/
#define OS_MAX_QS            2            /*最多可以使用2个队列*/
#define OS_MAX_TASKS         6           /*最多可以创建6个任务*/
#define OS_LOWEST_PRIO       14           /*任务优先级不可以大于14*/
#define OS_TASK_IDLE_STK_SIZE    1024     /*空闲任务堆栈大小*/
#define OS_TASK_STAT_EN          1        /*是否允许使用统计任务*/
#define OS_TASK_STAT_STK_SIZE     1024    /*统计任务堆栈大小*/

#define OS_FLAG_EN                 0       /*是否允许使用事件标志功能*/

#define OS_MBOX_EN                0        /*是否允许使用邮箱功能*/

#define OS_MEM_EN                 1         /*是否允许使用内存管理的功能*/
#define OS_MEM_QUERY_EN         1         /*是否允许使用OSMemQuery()*/

#define OS_MUTEX_EN               1         /*是否允许使用互斥信号量的功能*/
#define OS_MUTEX_ACCEPT_EN      1         /*是否允许使用OSMutexAccept()*/
#define OS_MUTEX_DEL_EN          1         /*是否允许使用OSMutexDel()*/
#define OS_MUTEX_QUERY_EN       1         /*是否允许使用OSMutexQuery()*/

#define OS_Q_EN                     0         /*是否允许使用队列功能*/

#define OS_SEM_EN                   1         /*是否允许使用信号量功能*/
#define OS_SEM_ACCEPT_EN          1         /*是否允许使用OSSemAccept()*/
#define OS_SEM_DEL_EN              1         /*是否允许使用 OSSemDel() */
#define OS_SEM_QUERY_EN           1         /*是否允许使用 OSSemQuery()*/

#define OS_TASK_CHANGE_PRIO_EN    1        /*是否允许使用 OSTaskChangePrio()*/
#define OS_TASK_CREATE_EN          1        /*是否允许使用OSTaskCreate()*/
#define OS_TASK_CREATE_EXT_EN     1        /*是否允许使用OSTaskCreateExt()*/
#define OS_TASK_DEL_EN              1        /*是否允许使用OSTaskDel()*/
#define OS_TASK_SUSPEND_EN    1    /*是否允许使用OSTaskSuspend() and OSTaskResume()*/
#define OS_TASK_QUERY_EN           1         /*是否允许使用OSTaskQuery()*/

#define OS_TIME_DLY_HMSM_EN       1         /*是否允许使用OSTimeDlyHMSM()*/
#define OS_TIME_DLY_RESUME_EN     1         /*是否允许使用OSTimeDlyResume()*/
#define OS_TIME_GET_SET_EN         1     /*是否允许使用OSTimeGet() 和 OSTimeSet()*/
#define OS_SCHED_LOCK_EN       1     /*是否允许使用OSSchedLock()和OSSchedUnlock()*/
#define OS_TICKS_PER_SEC         200          /*设置每秒之内的时钟节拍数目*/

3 运行及观察应用输出信息
本实验运行后,从虚拟机的窗口中可以看到如下信息:


4 本实验中所用到的?C/OS-II相关函数
4.1 OSMutexCreate()
   本实验通过调用OSMutexCreate(8,&err),设置了一个互斥信号量,其中8为PIP(优先级继承优先级)的值。
4.2 OSMutexPend()
   该函数用于获得互斥信号量,其具体执行过程如下(关键代码解释):
If ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE){}
判断互斥信号量是否被占用

pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8;    /*Yes, Acquire the resource  */
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio;         /* Save priority of owning task */
pevent->OSEventPtr  = (void *)OSTCBCur;           /*   Point to owning task's OS_TCB */
   如果互斥信号量没有被占有,则获得互斥信号量,任务继续运行。

pip   = (INT8U)(pevent->OSEventCnt >> 8);  /* No, Get PIP from mutex            */
mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);  /*     Get priority of mutex owner   */
    ptcb  = (OS_TCB *)(pevent->OSEventPtr);         /*     Point to TCB of mutex owner   */
if (ptcb->OSTCBPrio != pip && mprio > OSTCBCur->OSTCBPrio) {  /*     Need to promote prio of owner?*/
互斥信号量被占用,但是占有互斥信号量的任务的优先级高于请求互斥信号量的任务的优先级,则不改变占有互斥信号量的任务的优先级。

ptcb->OSTCBPrio         = pip;    /* Change owner task prio to PIP   */
ptcb->OSTCBY            = ptcb->OSTCBPrio >> 3;
ptcb->OSTCBBitY         = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX            = ptcb->OSTCBPrio & 0x07;
ptcb->OSTCBBitX         = OSMapTbl[ptcb->OSTCBX];
if (rdy == TRUE) {                                 /* If task was ready at owner's priority ...*/
        OSRdyGrp  |= ptcb->OSTCBBitY;     /* ... make it ready at new priority.       */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        }
        OSTCBPrioTbl[pip]  = (OS_TCB *)ptcb;
    }
占有互斥信号量的任务的优先级低于请求互斥信号量的任务的优先级,改变占有互斥信号量的任务的优先级到PIP。
4.3 OSMutexPost()
该函数用于释放互斥信号量,具体代码说明如下:
if (OSTCBCur->OSTCBPrio == pip) {       /* Did we have to raise current task's priority? */
判断任务的优先级是否在申请获得互斥信号量的过程中被改变。

if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) {
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBPrio         = prio;
        OSTCBCur->OSTCBY            = prio >> 3;
        OSTCBCur->OSTCBBitY         = OSMapTbl[OSTCBCur->OSTCBY];
        OSTCBCur->OSTCBX            = prio & 0x07;
        OSTCBCur->OSTCBBitX         = OSMapTbl[OSTCBCur->OSTCBX];
        OSRdyGrp                   |= OSTCBCur->OSTCBBitY;
        OSRdyTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;
        OSTCBPrioTbl[prio]          = (OS_TCB *)OSTCBCur;
}
OSTCBPrioTbl[pip] = (OS_TCB *)1;             /* Reserve table entry */
如果任务的优先级在申请获得互斥信量的过程中被改变,则还原其初始优先级。
5 应用调试过程
在LambdaTOOL的调试界面中,在“优先级继承.c”文件中Task任务代码调用函数OSMutexPend()和OSMutexPost()处设置断点。


当程序运行至断点处时,选择“单步跳入”运行模式,可以进入到OS_MUTEX.c文件中,查看OSMutexPend()和OSMutexPost()函数的运行过程,深入了解?C/OS-II操作系统的内核代码。

最新回复

我也想知道,正在找這方面的資料~~~~~  详情 回复 发表于 2008-4-30 19:49
点赞 关注

回复
举报

65

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我也想知道,正在找這方面的資料~~~~~
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表