您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > ucos原理详细介绍
12009-4-242009.3.29华中科技大学工程实训中心宗晓东uCOS操作系统介绍22009-4-24前言:今天给大家简要的介绍uCOS操作系统内核的原理。并介绍如何在ARM9上运用uCOS操作系统。32009-4-24uC/OS-II实时多任务操作系统•µC/OS-II是对微处理器、微控制器或DSP进行资源管理的软件•支持到64个优先级•支持到64个任务•为应用程序提供多种服务–信号量和互斥量–消息邮箱和队列–事件标志–时延,定时器和超时–任务管理–内存分区管理uC/OS-II操作系统内核uC/FS文件系统uC/TCPIP网络协议栈uC/USBuC/CANuC/GUI图形库µC/OS-II系统模块组成42009-4-24uC/OS-II实时多任务操作系统•ANSIC书写–业界最洁净源代码–以源代码方式提供•高度的可移植–已移植到45种不同处理器构架–可以在Window下模拟(例如Win32移植)–多种第三方工具支持•可裁减和ROM化–2.5K到24K字节代码-ROM–1K到4.5K字节数据-RAM•高实时性–上下文切换时间约300clocks•大量用户基础–全世界上千种产品使用52009-4-24uC/OS-II实时多任务操作系统CPUSpecific(Port)CPUIndependentBoardSupportPackageYOURProduct62009-4-24ISR低优先级任务(LPT)高优先级任务(HPT)中断服务程序ISRmakeHighPriorityTaskReadyInterruptOccursVectortoISRISRCompletes(SwitchtoHPTask)HPTaskCompletes(SwitchbacktoLPTask)uC/OS-II实时多任务操作系统任务切换示意图72009-4-24uC/OS-II实时多任务操作系统上面分析了uCOS操作系统的特点和一些基本的概念下面就详细讲解这个操作系统的原理。怎样能深入了解操作系统的原理?当然是自己写个操作系统。下面详细讲解怎样设计一个类似uCOS的操作系统。希望大家能从系统的设计中,了解操作系统设计的一些常识,从而了解uCOS操作系统的原理和使用方法。82009-4-24uC/OS-II实时多任务操作系统bluemoon一般嵌入式程序结构Main(){变量初始化函数;系统初始化函数;while(1){显示部分(液晶屏等);按键处理部分;数据处理;}}定时器中断函数;外部中断函数;等各种中断;92009-4-24uC/OS-II实时多任务操作系统bluemoon任务D任务调度内核BECDA任务A任务C任务E任务B这里的每个任务可以理解成一个函数而任务调度内核一般是在中断中完成有操作系统的程序结构102009-4-24uC/OS-II实时多任务操作系统非操作系统中断过程:Function(){….….遇到了中断中断返回….….….}中断处理过程:环境保护(通用寄存器,中断时程序地址等压入堆栈)中断函数。。。环境恢复(从堆栈恢复寄存器程序指针等)大家可以想一下,如果在中断函数里改变了堆栈里的函数返回地址,会发生什么事?112009-4-24大家可以想一下,如果在中断函数里改变了堆栈里的函数返回地址,会发生什么事?大家可以进一步想如果改变了其他通用寄存器会发生什么事?如果更改了堆栈指针呢?其实,堆栈对于嵌入式程序设计是至关重要的,其作用不仅仅在中断处理中。事实上在所有用C写的程序都和堆栈关系密切。Function(){….sub_function()….}编译器编译后的sub_function():{堆栈保存环境变量(其中包括RPC寄存器);RPC寄存其用来保存子函数返回地址;自己写的代码。。。。恢复环境变量,执行返回指令。}uC/OS-II实时多任务操作系统122009-4-24uC/OS-II实时多任务操作系统bluemoonFunction1(){….….}Function2(){….….}Function3(){….….}通用寄存器函数返回地址Function1堆栈通用寄存器函数返回地址Function2堆栈通用寄存器函数返回地址Function3堆栈2000H3000H4000HSP指针SP指针SP指针定时器中断改变SP指针的数值就可以返回不同的函数进入不同的任务!任务一任务二任务三132009-4-24uC/OS-II实时多任务操作系统下面看UCOS的任务切换的代码:stmfdsp!,{lr}//将LR的值压入堆栈中去stmfdsp!,{r0-r12,lr}//将当前任务的寄存器的值mrsr4,cpsr//压入堆栈中去stmfdsp!,{r4}//保存cpsrmrsr4,spsr//保存spsrstmfdsp!,{r4}ldrr4,=OSPrioCur//当前任务号ldrr5,=OSPrioHighRdyldrbr6,[r5]//将当前任务号设置为最高strbr6,[r4]//优先级的任务号ldrr4,=OSTCBCurldrr5,[r4]//取当前任务结构体中的指针strsp,[r5]//保存当前的堆栈指针到当前任务结构体中142009-4-24blOSTaskSwHook;//用户自定义的函数,目前为空ldrr6,=OSTCBHighRdy//找到准备好的优先级别最高的任务ldrr6,[r6]//把这个任务所对应的堆栈ldrsp,[r6]//加载到Sp寄存器中strr6,[r4];设置当前任务为最高优先级别任务ldmfdsp!,{r4};从堆栈中取出SPSRldmfdsp!,{r4};从堆栈中CPSRmsrSPSR_cxsf,r4ldmfdsp!,{r0-r12,lr,pc}^;取出新任务各个寄存器的数值跳转到新的任务中去。{}^表示更新PC的同时用SPSR更新CPSR.uC/OS-II实时多任务操作系统152009-4-24uC/OS-II实时多任务操作系统刚才是一个任务切换过程。其关键是切换了堆栈的位置并且保存和恢复了一些寄存器的内容。从上面的分析中我们可以知道设计一个操作系统关键是保证每个任务都有自己的运行环境,都有自己的堆栈。当自己运行时好像自己独自占用了CPU。在简单的操作系统中,一个任务可以理解成一个死循环函数。那么设计操作系统的关键就在于:怎样把一个函数和一个堆栈联系起来;怎样进行任务之间的调转和切换;怎样进行任务之间的通信和同步;162009-4-24uC/OS-II实时多任务操作系统下面就分析一个任务创建函数,看一下堆栈如何和程序相联系:OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT8Uprio);可以看出创建一个任务需要几个参数:task:指向函数的指针,对应一个任务函数;pdata:传递给任务的参数;ptos:堆栈的首地址;prio:任务的优先级别;下面分析这个函数的详细代码,看任务函数如何和一个堆栈相联系的。172009-4-24uC/OS-II实时多任务操作系统下面是除去一写预编译指令后的代码:{OS_ENTER_CRITICAL();//禁止中断if(OSTCBPrioTbl[prio]==(OS_TCB*)0)//确认此优先级//无其他任务{OSTCBPrioTbl[prio]=(OS_TCB*)1;//占用此优先级OS_EXIT_CRITICAL();//开启中断psp=(OS_STK*)OSTaskStkInit(task,pdata,ptos,0);err=OS_TCBInit(prio,psp,(OS_STK*)0,0,0,(void*)0,0);if(err==OS_NO_ERR){OS_ENTER_CRITICAL();OSTaskCtr++;//任务数加一182009-4-24OS_EXIT_CRITICAL();if(OSRunning==TRUE){OS_Sched();//执行任务切换}}else{OS_ENTER_CRITICAL();OSTCBPrioTbl[prio]=(OS_TCB*)0;OS_EXIT_CRITICAL();}return(err);}OS_EXIT_CRITICAL();return(OS_PRIO_EXIST);uC/OS-II实时多任务操作系统192009-4-24uC/OS-II实时多任务操作系统下面分析OSTaskStkInit的代码:OS_STK*stk;opt=opt;stk=ptos;*(stk)=(OS_STK)task;*(--stk)=(INT32U)0;/*lr*/*(--stk)=(INT32U)0;/*r12*/*(--stk)=(INT32U)0;/*r11*/*(--stk)=(INT32U)0;/*r10*/*(--stk)=(INT32U)0;/*r9*/*(--stk)=(INT32U)0;/*r3*/*(--stk)=(INT32U)0;/*r1*/…*(--stk)=(INT32U)pdata;/*r0:argument202009-4-24uC/OS-II实时多任务操作系统#ifdefTHUMB_TASKS*(--stk)=(INT32U)(SVCMODE|TBIT);/*PSR*/#else*(--stk)=(INT32U)(SVCMODE|0x0);/*PSR*/#endif*(--stk)=(INT32U)(SVCMODE|0x0);/*SPSR*/return(stk);可以看出经过堆栈初始化后,堆栈里就保存了函数的地址,这样在执行任务切换时就会跳转到对应的任务中去。函数返回的数值为堆栈里的指针的当前位置。这个数值下面会用来初始化任务结构体。下面介绍任务结构体。212009-4-24uC/OS-II实时多任务操作系统有了上面的概念后,下面分析一个最简单的任务结构体:typedefstructtask_tcb{ulong32point;//本任务所对应堆栈指针structtask_tcb*next;//建立链表时用来指向下一个结构体structtask_tcb*pre;//建立链表时用来指向上一个结构体structevent_tcb*eventPtr;//指向所等待的事件的指针uchar16delaytime;//任务等待的时间uchar16state;//任务的当前状态uchar16prio;//任务的优先级别uchar16prio_x;//任务优先级别相关的变量,用于计算方便uchar16prio_y;//任务优先级别相关变量,用于计算方便uchar16bit_x;//prio=prio_y3+prio_xuchar16bit_y;//将prio_x和prio_y变成相关的比特的形式void*message;}BM_TASK;222009-4-24uC/OS-II实时多任务操作系统任务创造函数分析中用到的OS_TCBInit函数其原理就是填充一个类似于上面所描述的结构体。这个结构体为OSTCBPrioTbl[prio]这样就和优先级,任务,堆栈联系起来了。关于结构体中的关于任务优先级的几个成员。下面将进行详细的分析。232009-4-24uC/OS-II实时多任务操作系统上面是一个任务结构体,其中关于优先级的部分解释如下:7654321015141312111098232221201918171631302928272625243938373635343332474645444342414055545352515049486362616059585756gl_ready_group_table[7]gl_ready_group_table[1]gl_ready_group_table[2]gl_ready_group_table[3]gl_ready_group_table[4]gl_ready_group_table[5]gl_ready_group_table[6]gl_ready_group_t
本文标题:ucos原理详细介绍
链接地址:https://www.777doc.com/doc-6425591 .html