uCOS-II

2020-05-23 14:25

实验一、任务创建与删除

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提供了两个函数来创建任务:OSTaskCreate()或OSTaskCreateExt()。可以使用其中任意一个即可,其函数原型如下:

INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)

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调用,而不是删除任务代码。删除任务主要是把任务控制块从OSTCBList链表中移到OSTCBFreeList。uC/OS-II提供了两个函数来删除任务:OSTaskDel()或OSTaskDelReq()。 INT8U OSTaskDel (INT8U prio) //删除任务

INT8U RequestorTask (INT8U prio) //请求删除其他任务 prio:需要删除任务的优先级

3、实验分析

本次实验创建两个任务,任务一每隔两秒秒打印一次“AppTask1”,任务二每隔1s打印一次“AppTask2”,打印6次后打印“删除任务2”并删除任务。其源代码如下: int main (void) {

SysTick_Configuration(); //系统定时器初始化 USART_Configuration(); //串口初始化 LED_Configuration();

OSInit(); //usos ii初始化 AppTaskCreate();//创建任务 OSStart(); //开始任务调度

}

static void AppTaskCreate(void) {

INT8U err;

OSTaskCreateExt(AppTask1,(void*)0,(OS_STK )&AppTask1Stk[APP_TASK1_STK_SIZE-1],APP_TASK1_PRIO,APP_TASK1_PRIO,(OS_STK )&AppTask1Stk[0],APP_TASK1_STK_SIZE,(void )0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务1

OSTaskNameSet(APP_TASK1_PRIO, \&err);

OSTaskCreateExt(AppTask2,(void*)0,(OS_STK )&AppTask2Stk[APP_TASK2_STK_SIZE-1],APP_TASK2_PRIO,APP_TASK2_PRIO,(OS_STK )&AppTask2Stk[0],APP_TASK2_STK_SIZE,(void*)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务2

OSTaskNameSet(APP_TASK2_PRIO, \&err); }

//任务1

static void AppTask1 (void *p_arg) {

while(1) {

printf(\ LED1(0);

OSTimeDlyHMSM(0,0,1,0); LED1(1);

OSTimeDlyHMSM(0,0,1,0); }

}

//任务2

static void AppTask2 (void *p_arg) {

INT8U i;

for(i=0;i<6;i++) {

printf(\\\r\\n\

OSTimeDlyHMSM(0,0,0,1); }

printf(\删除任务2\\r\\n\

OSTaskDel(APP_TASK2_PRIO); //删除任务2 }

如下图是串口打印的数据:

实验二、任务调度

本节我们主要介绍的是uC/OS-II任务调度。 1、uC/OS-II任务调度原理

在uC/OS-II创建的任务中,每个任务都是一个无限循环的函数,实现任务的切换需要操作系统完成。用户任务创建后,调用OSStart()开始进行任务调度。任务调度始终会运行就绪列表中优先级最高的任务。

如下图是任务状态的转换表图,正在运行的任务通过调用OS..Pend和延时函数进入等待状态,同时将其从就绪列表中删除,并加入到等待列表中,此时在就绪列表中查找优先级最高的任务设置为当前任务并运行。正在运行的任务通过调用OS..Post或OS..Resume函数使得正在等待挂起的任务进入就绪态,若有任务处于延时等待中,在心跳时钟是延时值减一,当减为零时延时等待任务充等待状态切换到就绪态,同时将其从等待列表中删除,并加入到就绪列表中。如果此任务优先级高于正在运行的任务优先级,则进行任务切换。

下面是系统定时器中断源代码

void SysTick_Handler(void) {

OS_CPU_SR cpu_sr;

OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断 OSIntNesting++;

OS_EXIT_CRITICAL(); //恢复全局中断标志

OSTimeTick(); //延时计数值减一,判断计数时间到后进行任务切换 OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务 //就绪了,则执行一次任务切换 }

2、实验分析

本次实验创建两个任务,任务一循环从串口打印“AppTask1”后延时2s,LED1闪烁一次,任务二循环从串口打印“AppTask2”后延时1s,LED2闪烁一次。其源代码如下: int main (void) {

SysTick_Configuration(); //系统定时器初始化 USART_Configuration(); //串口初始化 LED_Configuration(); OSInit(); //usos ii初始化 AppTaskCreate();//创建任务 OSStart(); //开始任务调度 }

static void AppTaskCreate(void) {

INT8U err;

OSTaskCreateExt(AppTask1,(void*)0,(OS_STK )&AppTask1Stk[APP_TASK1_STK_SIZE-1],APP_TASK1_PRIO,APP_TASK1_PRIO,(OS_STK )&AppTask1Stk[0],APP_TASK1_STK_SIZE,(void )0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务1 OSTaskNameSet(APP_TASK1_PRIO, \&err);

OSTaskCreateExt(AppTask2,(void*)0,(OS_STK )&AppTask2Stk[APP_TASK2_STK_SIZE-1],APP_TASK2_PRIO,APP_TASK2_PRIO,(OS_STK )&AppTask2Stk[0],APP_TASK2_STK_SIZE,(void*)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务2 OSTaskNameSet(APP_TASK2_PRIO, \&err); }

//任务1

static void AppTask1 (void *p_arg) {

while(1) {

printf(\ LED1(0);

OSTimeDlyHMSM(0,0,1,0); LED1(1);

OSTimeDlyHMSM(0,0,1,0); } }

//任务2

static void AppTask2 (void *p_arg) {

while(1) {

printf(\\\r\\n\ LED2(0);

OSTimeDlyHMSM(0,0,0,500); LED2(1);

OSTimeDlyHMSM(0,0,0,500); } }

如下图是串口打印的数据,通过修改OSTimeDlyHMSM()的延时值,其中该延时函数的四个参数分别代表时分秒毫秒,可以看到打印速度的变化及两个字符串打印出来的比例。


uCOS-II.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:当代中国政府与政治

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: