




已阅读5页,还剩34页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C_OS-II实验指导书 C/OS-II实验内容简介1 任务管理实验此实验的目的是让读者理解嵌入式操作系统中任务管理的基本原理,了解任务的各个基本状态及其变迁过程;掌握C/OS-II中任务管理的基本方法(创建、启动、挂起和解挂任务);熟练使用C/OS-II任务管理的基本系统调用。2 优先级反转实验通过此实验读者可以了解在基于抢占式嵌入式实时操作系统并有共享资源的应用中,出现优先级反转现象的原理。优先级反转发生在有多个任务共享资源的情况下,高优先级任务被低优先级任务阻塞,并等待低优先级任务执行的现象。3 优先级继承实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II解决优先级反转的策略优先级继承的原理,以此解决低优先级任务在占用了共享资源的情况下,被高优先级任务抢占了CPU使用权而导致的优先级反转的问题。4 哲学家就餐实验通过经典的哲学家就餐应用,读者可以了解如何利用嵌入式实时操作系统C/OS-II的信号量机制来对共享资源进行互斥访问。5 内存管理实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中的内存管理的原理,包括对内存的分配和回收。6 时钟中断实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中,时钟中断的使用情况。7 消息队列实验通过此实验读者可以了解嵌入式实时操作系统C/OS-II中的消息队列机制。读者可以了解一个应用中的任务是如何进行通信的,如何能使它们相互协调工作。实验1 任务的基本管理1 实验目的 理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; 掌握C/OS-II中任务管理的基本方法(创建、启动、挂起、解挂任务); 熟练使用C/OS-II任务管理的基本系统调用。2 实验原理及程序结构2.1 实验设计为了展现任务的各种基本状态及其变迁过程,本实验设计了Task0、Task1两个任务:任务Task0不断地挂起自己,再被任务Task1解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。起始任务Task0Task1Task0Task0Task1Task1t0 t1 t2 t3 t4 t5 t6 t7 t8 图1-1图1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。2.1.1 运行流程整个应用的运行流程如图1所示,其描述如下:(1)系统经历一系列的初始化过程后进入boot_card()函数,在其中调用ucBsp_init()进行板级初始化后,调用main()函数;(2)main()函数调用OSInit()函数对C/OS-II内核进行初始化,调用OSTaskCreate创建起始任务TaskStart;(3)main()函数调用函数OSStart()启动C/OS-II内核的运行,开始多任务的调度,执行当前优先级最高的就绪任务TaskStart;(4)TaskStart完成如下工作:a、安装时钟中断并初始化时钟,创建2个应用任务;b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任务Task0。之后整个系统的运行流程如下:l t1时刻,Task0开始执行,它运行到t2时刻挂起自己;l t2时刻,系统调度处于就绪状态的优先级最高任务Task1执行,它在t3时刻唤醒Task0,后者由于优先级较高而抢占CPU;l Task0执行到t4时刻又挂起自己,内核调度Task1执行;l Task1运行至t5时刻再度唤醒Task0;l 2.1.2 C/OS-中的任务描述一个任务通常是一个无限的循环 ,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成void。在C/OS-中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就会被抢占,高优先级任务会立刻得到CPU的控制权(在系统允许调度和任务切换的前提下)。C/OS-可以管理多达64个任务,但目前版本的C/OS-有两个任务已经被系统占用了(即空闲任务和统计任务)。必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从0到OS_LOWEST_PR10-2。优先级号越低,任务的优先级越高。C/OS-总是运行进入就绪态的优先级最高的任务。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 3 /*最多可以创建3个任务*/#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_FLAG_WAIT_CLR_EN 1 /*是否允许等待清除事件标志*/#define OS_FLAG_ACCEPT_EN 1 /*是否允许使用OSFlagAccept()*/#define OS_FLAG_DEL_EN 1 /*是否允许使用OSFlagDel()*/#define OS_FLAG_QUERY_EN 1 /*是否允许使用OSFlagQuery()*/#define OS_MBOX_EN 0 /*是否允许使用邮箱功能*/#define OS_MBOX_ACCEPT_EN 1 /*是否允许使用 OSMboxAccept() */#define OS_MBOX_DEL_EN 1 /*是否允许使用 OSMboxDel()*/#define OS_MBOX_POST_EN 1 /*是否允许使用OSMboxPost()*/#define OS_MBOX_POST_OPT_EN 1 /*是否允许使用OSMboxPostOpt() */#define OS_MBOX_QUERY_EN 1 /*是否允许使用OSMboxQuery()*/#define OS_MEM_EN 0 /*是否允许使用内存管理的功能*/#define OS_MEM_QUERY_EN 1 /*是否允许使用OSMemQuery()*/#define OS_MUTEX_EN 0 /*是否允许使用互斥信号量的功能*/#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_Q_ACCEPT_EN 1 /*是否允许使用OSQAccept()*/#define OS_Q_DEL_EN 1 /*是否允许使用OSQDel()*/#define OS_Q_FLUSH_EN 1 /*是否允许使用 OSQFlush()*/#define OS_Q_POST_EN 1 /*是否允许使用 OSQPost()*/#define OS_Q_POST_FRONT_EN 1 /*是否允许使用OSQPostFront()*/#define OS_Q_POST_OPT_EN 1 /*是否允许使用OSQPostOpt()*/#define OS_Q_QUERY_EN 1 /*是否允许使用OSQQuery()*/#define OS_SEM_EN 0 /*是否允许使用信号量功能*/#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 0 /*是否允许使用 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 0 /*是否允许使用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 /*设置每秒之内的时钟节拍数目*/2.3 源程序说明系统启动后,经历一系列的初始化过程,进入main()函数,这是我们编写实现应用程序的起点。首先需要在main()函数里创建起始任务TaskStart:OSTaskCreate(TaskStart, (void *)0, &TaskStartStkTASK_STK_SIZE - 1, 4); TaskStart任务TaskStart任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务:ucos_x86_idt_set_handler(0x20,(void *)OSTickISR,0x8e00); /* Install uC/OS-IIs clock tick ISR */ucos_timer_init(); /*Timer 初始化*/ TaskStartCreateTasks(); /* Create all the application tasks */ OSTaskSuspend(OS_PRIO_SELF);具体负责应用任务创建的TaskStartCreateTasks函数代码如下,它创建了两个应用任务Task0和Task1:static void TaskStartCreateTasks (void) INT8U i;for (i = 0; i N_TASKS; i+) /* Create N_TASKS identical tasks */ TaskDatai = i; /* Each task will display its own letter */ OSTaskCreate(Task0, (void *)&TaskDatai, &TaskStkiTASK_STK_SIZE - 1, 5); OSTaskCreate(Task1, (void *)&TaskDatai, &TaskStk1TASK_STK_SIZE - 1, 6); TaskStart任务完成上述操作后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0运行。应用任务应用任务Task0运行后将自己挂起,之后操作系统就会调度处于就绪状态的优先级最高的任务,具体代码如下:void Task0 (void *pdata)INT8U i;INT8U err;i=*(int *)pdata; for (;) /*此处为输出信息,显示任务运行的状态 */err=OSTaskSuspend(5); /* suspend itself */ 应用任务Task1运行后将Task0唤醒,使其进入到就绪队列中:void Task1 (void *pdata) INT8U i; INT8U err; i=*(int *)pdata;for (;) OSTimeDly(150); /*此处为输出信息,显示任务运行的状态 */OSTimeDly(150); err=OSTaskResume(5); /* resume task0 */ 3 运行及观察应用输出信息按照本实验手册第一部分所描述的方法建立应用项目并完成构建,当我们在LambdaTOOL调试器的控制下运行构建好的程序后,将看到在C/OS-内核的调度管理下,两个应用任务不断切换执行的情形:T1时刻的截图T2时刻的截图T3时刻的截图T4时刻的截图4 本实验中所用到的C/OS-II相关函数4.1 OSTaskCreate()建立一个新任务。任务的建立可以在多任务环境启动之前,也可以在正在运行的任务中建立。中断处理程序中不能建立任务。一个任务可以为无限循环的结构。函数原型:INT8U OSTaskCreate(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio);参数说明:task是指向任务代码首地址的指针。Pdata指向一个数据结构,该结构用来在建立任务时向任务传递参数。返回值:OSTaskCreate()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_PRIO_EXIST:具有该优先级的任务已经存在。l OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO。l OS_NO_MORE_TCB:系统中没有OS_TCB可以分配给任务了。4.2 OSTaskSuspend()无条件挂起一个任务。调用此函数的任务也可以传递参数OS_PRIO_SELF,挂起调用任务本身。当前任务挂起后,只有其他任务才能唤醒被挂起的任务。任务挂起后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。唤醒挂起任务需要调用函数OSTaskResume()。任务的挂起是可以叠加到其他操作上的。例如,任务被挂起时正在进行延时操作,那么任务的唤醒就需要两个条件:延时的结束以及其他任务的唤醒操作。又如,任务被挂起时正在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。函数原型:INT8U OSTaskSuspend ( INT8U prio);参数说明:prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本身。此时,下一个优先级最高的就绪任务将运行。返回值:OSTaskSuspend()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_TASK_ SUSPEND_IDLE:试图挂起C/OS-II中的空闲任务(Idle task)。此为非法操作。l OS_PRIO_INVALID:参数指定的优先级大于OS_LOWEST_PRIO或没有设定OS_PRIO_SELF的值。l OS_TASK_ SUSPEND _PRIO:要挂起的任务不存在。4.3 OSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。OSTaskResume()也是唯一能“解挂”挂起任务的函数。函数原型:NT8U OSTaskResume ( INT8U prio);参数说明:prio指定要唤醒任务的优先级。返回值:OSTaskResume ()的返回值为下述之一:l OS_NO_ERR:函数调用成功。l OS_TASK_RESUME_PRIO:要唤醒的任务不存在。l OS_TASK_NOT_SUSPENDED:要唤醒的任务不在挂起状态。l OS_PRIO_INVALID:参数指定的优先级大于或等于OS_LOWEST_PRIO。实验2 优先级反转1 实验目的掌握在基于优先级的可抢占嵌入式实时操作系统的应用中,出现优先级反转现象的原理。2 原理及程序结构2.1 实验设计2.1.1 优先级反转原理在本实验中,要体现嵌入式实时内核的优先级抢占调度的策略,并显现由于共享资源的互斥访问而出现的优先级反转现象。优先级反转发生在有多个任务需要使用共享资源的情况下,可能会出现高优先级任务被低优先级任务阻塞,并等待低优先级任务执行的现象。高优先级任务需要等待低优先级任务释放资源,而低优先级任务又正在等待中等优先级任务,这种现象就被称为优先级反转。两个任务都试图访问共享资源是出现优先级反转最通常的情况。为了保证一致性,这种访问应该是顺序进行的。如果高优先级任务首先访问共享资源,则会保持共享资源访问的合适的任务优先级顺序;但如果是低优先级任务首先获得共享资源的访问,然后高优先级任务请求对共享资源的访问,则高优先级任务被阻塞,直到低优先级任务完成对共享资源的访问。2.1.2 设计要点1)设计了3个应用任务TA0TA2,其优先级逐渐降低,任务TA0的优先级最高。2)除任务TA1外,其它应用任务都要使用同一种资源,该资源必须被互斥使用。为此,创建一个二值信号量mutex来模拟该资源。虽然C/OS-在创建信号量时可以选择采用防止优先级反转的策略,但在本实验中我们不使用这种策略。3)应用任务的执行情况如图2-1所示:t1t2t4t5t6t7t8t9t10t117优先级65t123100120 任务2: 任务1: 任务0: 图2-1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各个任务启动和执行的相对先后关系。2.1.3 系统的运行流程1) 系统初始化,之后进入main函数;2) 在main函数中,首先创建一个二值的信号量mutex;3) 在main函数中创建TaskStart任务,由TaskStart任务创建所有的应用任务(TA0、TA1、TA2)。优先级较高的任务TA0、TA1先延时若干个时钟节拍,以便低优先级任务TA2运行。4) t1时刻,任务TA2运行并首先申请到信号量mutex;5) t2时刻,任务TA1延时到期,任务TA1的优先级高于任务TA2的优先级,因此任务TA1立刻抢占TA2执行,任务TA2由执行态转为就绪态;6) t3时刻,任务TA0延时到期,任务TA0的优先级高于任务TA1的优先级,所以任务TA0立刻抢占执行,任务TA1由执行态转为就绪态,任务TA0申请二值信号量mutex被阻赛;7) t4时刻,任务TA1由就绪态转回为执行态;此时TA0在等待TA2保持的mutex , 而TA2又因为优先级低于TA1被阻塞。如果TA1一直执行而TA2没有机会被调度的话,那么TA2将一直等到TA1执行完后才能执行,而TA0更要等到TA2释放它所占有的信号量资源后才能执行,这样就出现了优先级高的TA0任务等待优先级低的TA1任务的现象;8) t5时刻,任务TA1挂起自己,而TA0又因为申请二值信号量mutex而处于阻塞状态,所以任务TA2由就绪态转为执行态,任务TA2释放信号量mutex;9) t6时刻,TA0获得信号量并立刻抢占执行,任务TA2由执行态转为就绪态;10) t7时刻,任务TA0将自己延时一段时间,而TA1仍然处于挂起状态,TA2是当前最高优先级的就绪任务,它又转为执行状态,任务TA2因申请二值信号量mutex而阻塞;11) t8时刻,任务TA1延时到期转为执行态,任务TA1又因等待一个事件而阻塞;12) t9时刻,任务TA0延时到,释放二值信号量mutex,mutex被TA2得到后,内核自动切换任务;13) t10时刻,在就绪队列中,TA0优先级最高,TA0执行,又因为任务TA0等待一事件而阻塞;14) t11时刻,任务TA1延时到期,立刻抢占执行,又由于任务TA1等待一事件而阻塞;15) t12时刻,任务TA2执行,保持信号量mutex;以后系统再次出现优先级反转现象;16) 系统如此周而复始地运行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 9 /*最多可以创建9个任务*/#define OS_LOWEST_PRIO 24 /*任务优先级不可以大于24*/#define OS_TASK_IDLE_STK_SIZE 1024 /*空闲任务堆栈大小*/#define OS_TASK_STAT_EN 1 /*是否允许使用统计任务*/#define OS_TASK_STAT_STK_SIZE 1024 /*统计任务堆栈大小*/#define OS_FLAG_EN 1 /*是否允许使用事件标志功能*/#define OS_FLAG_WAIT_CLR_EN 1 /*是否允许等待清除事件标志*/#define OS_FLAG_ACCEPT_EN 1 /*是否允许使用OSFlagAccept()*/#define OS_FLAG_DEL_EN 1 /*是否允许使用OSFlagDel()*/#define OS_FLAG_QUERY_EN 1 /*是否允许使用OSFlagQuery()*/#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 /*设置每秒之内的时钟节拍数目*/2.3 源程序说明首先,在main()函数中创建一个二值信号量:mutex=OSSemCreate(1);然后,在main()函数中创建TaskStart任务。TaskStart任务在TaskStart任务中创建并启动所有的应用任务TA0, TA1,TA2。static void TaskStartCreateTasks (void) INT8U i;for (i = 0; i N_TASKS; i+) /* Create N_TASKS identical tasks */TaskDatai = i; /* Each task will pass its own id */OSTaskCreate(Task0, (void *)&TaskData0, &TaskStk0TASK_STK_SIZE - 1, 5);OSTaskCreate(Task1, (void *)&TaskData1, &TaskStk1TASK_STK_SIZE - 1, 6);OSTaskCreate(Task2, (void *)&TaskData2, &TaskStk2TASK_STK_SIZE - 1, 7); 任务TA0的优先级最高,它需要使用信号量mutex:void Task0 (void *pdata) INT8U err; INT8U id; INT16U value;id=*(int *)pdata; for (;) printk(Task %d is waitting a event.n,id); OSTimeDly(200); /* Delay 200 clock tick */ printk(The event of Task %d come.n,id); printk(Task %d is try to get mutex.n,id); OSSemPend(mutex,0,&err); /* Acquire mutex */switch(err)case OS_NO_ERR: printk(Task %d has got the mutex.n,id); printk(n); break;default:printk(Task %d is suspended.n,id);printk(n);OSTimeDly(200); /* Delay 200 clock tick */printk(Task %d release mutex.n,id); OSSemPost(mutex); /* Release mutex */ 任务TA1具有中等优先级,它不使用信号量:void Task1 (void *pdata) INT8U err; INT8U id; int i;id=*(int *)pdata; for (;) printk(Task %d is waitting a event.n,id); OSTimeDly(100); /* Delay 100 clock tick */ printk(The event of Task %d come.n,id); OSTimeDly(100); 任务TA2的优先级最低,和高优先级任务TA0共用信号量mutex:void Task2 (void *pdata) INT8U err; INT8U id; INT16U value;id=*(int *)pdata;int i; for (;) printk(Task %d is trying to get mutex.n,id); OSSemPend(mutex,0,&err); /* Acquire mutex */switch(err) case OS_NO_ERR: printk(n);printk(-n);printk(Task %d has got the mutex.n,id);OSTimeDly(200); /* Delay 100 clock tick */break;default :printk(Task %d is failed to get mutex.n,id);printk(n);OSTimeDly(200); /* Delay 100 clock tick */break; printk(Task %d release mutex.n,id); printk(n);OSSemPost(mutex); /* Release mutex */3 运行及观察应用输出信息4 本实验中所用到的C/OS-II相关函数4.1 OSSemCreate()该函数建立并初始化一个信号量,信号量的作用如下:l 允许一个任务和其他任务或者中断同步l 取得设备的使用权l 标志事件的发生函数原型:OSSemCreate( INT16U value);参数说明:value 参数是所建立的信号量的初始值,可以取0到65535之间的任何值。返回值:OSSemCreate()函数返回指向分配给所建立的信号量的控制块的指针。如果没有可用的控制块,OSSemCreate()函数返回空指针。4.2 OSSemPend()该函数用于任务试图取得设备的使用权、任务需要和其他任务或中断同步、任务需要等待特定事件的发生的场合。如果任务调用OSSemPend()函数时,信号量的值大于零,OSSemPend()函数递减该值并返回该值。如果调用时信号量值等于零,OSSemPend()函数将任务加入该信号量的等待队列。OSSemPend()函数挂起当前任务直到其他的任务或中断设置信号量或超出等待的预期时间。如果在预期的时钟节拍内信号量被设置,C/OS-默认让最高优先级的任务取得信号量并回到就绪状态。一个被OSTaskSuspend()函数挂起的任务也可以接受信号量,但这个任务将一直保持挂起状态直到通过调用OSTaskResume()函数恢复该任务的运行。函数原型:Void OSSemPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err );参数说明:pevent 是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考OSSemCreate()函数)。Timeout 允许一个任务在经过了指定数目的时钟节拍后还没有得到需要的信号量时恢复就绪状态。如果该值为零表示任务将持续地等待信号量,最大的等待时间为65535个时钟节拍。这个时间长度并不是非常严格的,可能存在一个时钟节拍的误差。Err 是指向包含错误码的变量的指针。返回值:OSSemPend()函数返回的错误码可能为下述几种:l OS_NO_ERR :信号量不为零。l OS_TIMEOUT :信号量没有在指定数目的时钟周期内被设置。l OS_ERR_PEND_ISR :从中断调用该函数。虽然规定了不允许从中断调用该函数,但C/OS-仍然包含了检测这种情况的功能。l OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针。4.3 OSemPost()该函数用于设置指定的信号量。如果指定的信号量是零或大于零,OSSemPost()函数递增该信号量的值并返回。如果有任何任务在等待该信号量,则最高优先级的任务将得到信号量并进入就绪状态。任务调度函数将进行任务调度,决定当前运行的任务是否仍然为最高优先级的就绪任务。函数原型:INT8U OSSemPost(OS_EVENT *pevent);参数说明:pevent 是指向信号量的指针。该指针的值在建立该信号量时可以得到。(参考OSSemCreate()函数)。返回值:OSSemPost()函数的返回值为下述之一:l OS_NO_ERR :信号量被成功地设置l OS_SEM_OVF :信号量的值溢出l OS_ERR_EVENT_TYPE :pevent 不是指向信号量的指针4.4 OSTimeDly()该函数用于将一个任务延时若干个时钟节拍。如果延时时间大于0,系统将立即进行任务调度。延时时间的长度可从0到65535个时钟节拍。延时时间0表示不进行延时,函数将立即返回调用者。延时的具体时间依赖于系统每秒钟有多少个时钟节拍(由文件SO_CFG.H中的OS_TICKS_PER_SEC宏来设定)。函数原型:void OSTimeDly ( INT16U ticks);参数说明:ticks为要延时的时钟节拍数。返回值:无实验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 设计要点在本实验中设计了处于不同优先级的应用任务,如下图所示:210t1t2t3t4t5t6t7t8t9t10t1112优先级11108t12t13t142101212021220212 任务TASK0: 任务TASK1: 任务TASK2 : 图3-1注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各个任务启动和执行的相对先后关系。这3个应用任务因为要竞争同一互斥资源mutex而相互制约。其中,任务TASK0的原始优先级最低,任
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生物化学分子基础概念题库及解析
- 珠宝首饰行业设计大赛试题
- 药品进口代理协议
- 2025年经济师备考方法分享试题及答案
- 人员管理与绩效考核试题及答案
- 项目扩展及合作策略试题及答案
- 信阳市学法用法考试试题及答案
- 防钓鱼测试题及答案
- 急诊精神科的合作模式计划
- 购房贷款协议书
- 加油站职业危害防治计划和实施方案
- 路面弯沉温度修正系数
- 闭合导线平差计算表-电子表格自动计算
- 山东省济南市槐荫区2024届中考联考化学试题含解析
- (完整版)xx中学“双积双评”积分入团实施方案
- 拖拉机和联合收割机安全技术检验合格证明
- 文化产业政策与法规
- 钢结构培训课件
- 第四讲婴幼儿情绪情感及社会功能的发育
- 采矿学王庄煤矿
- 平野苍流:打渔张引黄灌区开灌60周年纪念专辑
评论
0/150
提交评论