第二部分 μC/OS-II实验
实验1 任务的基本管理
1 实验目的
? 理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程; ? 掌握μC/OS-II中任务管理的基本方法(创建、启动、挂起、解挂任务); ? 熟练使用μC/OS-II任务管理的基本系统调用。
2 实验原理及程序结构
2.1 实验设计
为了展现任务的各种基本状态及其变迁过程,本实验设计了Task0、Task1两个任务:任务Task0不断地挂起自己,再被任务Task1解挂,两个任务不断地切换执行。通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。
起始 任务 Task0 Task0 Task0 Task1 Task1 Task1 t0 t1 t2 t3 t4 t5 t6 t7 t8
图1
注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。
2.1.1 运行流程
整个应用的运行流程如图1所示,其描述如下:
9
(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。 之后整个系统的运行流程如下:
? t1时刻,Task0开始执行,它运行到t2时刻挂起自己;
? t2时刻,系统调度处于就绪状态的优先级最高任务Task1执行,它在t3时刻唤醒Task0,
后者由于优先级较高而抢占CPU;
? Task0执行到t4时刻又挂起自己,内核调度Task1执行; ? Task1运行至t5时刻再度唤醒Task0; ? ……
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个内存块*/
10
#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 #define OS_FLAG_WAIT_CLR_EN #define OS_FLAG_ACCEPT_EN #define OS_FLAG_DEL_EN #define OS_FLAG_QUERY_EN
#define OS_MBOX_EN #define OS_MBOX_ACCEPT_EN #define OS_MBOX_DEL_EN #define OS_MBOX_POST_EN #define OS_MBOX_POST_OPT_EN #define OS_MBOX_QUERY_EN
#define OS_MEM_EN #define OS_MEM_QUERY_EN
#define OS_MUTEX_EN #define OS_MUTEX_ACCEPT_EN #define OS_MUTEX_DEL_EN #define OS_MUTEX_QUERY_EN
#define OS_Q_EN #define OS_Q_ACCEPT_EN #define OS_Q_DEL_EN #define OS_Q_FLUSH_EN #define OS_Q_POST_EN #define OS_Q_POST_FRONT_EN #define OS_Q_POST_OPT_EN 0 /*是否允许使用事件标志功能*/ 1 /*是否允许等待清除事件标志*/ 1 /*是否允许使用OSFlagAccept()*/ 1 /*是否允许使用OSFlagDel()*/ 1 /*是否允许使用OSFlagQuery()*/ 0 /*是否允许使用邮箱功能*/
1 /*是否允许使用 OSMboxAccept() */ 1 /*是否允许使用 OSMboxDel()*/ 1 /*是否允许使用OSMboxPost()*/ 1 /*是否允许使用OSMboxPostOpt() */ 1 /*是否允许使用OSMboxQuery()*/ 0 /*是否允许使用内存管理的功能*/ 1 /*是否允许使用OSMemQuery()*/ 0 /*是否允许使用互斥信号量的功能*/ 1 /*是否允许使用OSMutexAccept()*/ 1 /*是否允许使用OSMutexDel()*/ 1 /*是否允许使用OSMutexQuery()*/ 0 /*是否允许使用队列功能*/ 1 /*是否允许使用OSQAccept()*/ 1 /*是否允许使用OSQDel()*/ 1 /*是否允许使用 OSQFlush()*/ 1 /*是否允许使用 OSQPost()*/ 1 /*是否允许使用OSQPostFront()*/ 1 /*是否允许使用OSQPostOpt()*/
11
#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, &TaskStartStk[TASK_STK_SIZE - 1], 4);
TaskStart任务
TaskStart任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务:
ucos_x86_idt_set_handler(0x20,(void *)OSTickISR,0x8e00);
/* Install uC/OS-II's clock tick ISR */
ucos_timer_init(); /*Timer 初始化*/
TaskStartCreateTasks(); /* Create all the application tasks */ OSTaskSuspend(OS_PRIO_SELF);
具体负责应用任务创建的TaskStartCreateTasks函数代码如下,它创建了两个应用任务Task0和Task1:
12
相关推荐: