关键词不能为空

当前您在: 主页 > 英语 >

UCOS-II概念及内核

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 23:46
tags:

-

2021年2月1日发(作者:悲伤)


实时系统概念



1.



有两种类型的实时系统:


软实时系统和硬实时系统。

< p>
在软实时系统中系统


的宗旨是使各个任务运行得越快越好,并不要求限定某 一任务必须在多长


时间内完成。在硬实时系统中,各任务不仅要执行无误而且要做到准时 。



2.



前后台系统


:


应用程序是一个无限的 循环,


循环中调用相应的函数完成相


应的操作,这部分可以看成 后台行为


(background)


。中断服务程序处理异


步事件,这部分可以看成前台行为(


foreground


)。


后台也可以叫做任务



前台也叫中断级




3.



可重入型函数


:


可重入型函数可以被 一个以上的任务调用,


而不必担心数


据的破坏

< br>。可重入型函数任何时候都可以被中断,一段时间以后又可以运


行,而相应数据不 会丢失。可重入型函数或者只使用局部变量,即变量保


存在


CP U


寄存器中或堆栈中。如果使用全局变量,则要对全局变量予以保


护。以下技术之一即可使不可重入函数具有可重入性:



?



把变量定义为局部变量



?



调用函数之前关中断,调动后再开中断



?



用信号量禁止该函数在使用过程中被再次调用



4.



优先级反转


:


应用程序执行过程中, 任务的优先级是可变的,则称之为动


态优先级。


实时内核应当避 免出现优先级反转问题


。为防止发生优先级反



,


内核能自动变换任务的优先级


,

这叫


做优先级继



(Priori ty


inheritance)



5.



互斥条件


:


实现任务间通讯最简便到办法是使用


共享数据结构



特别是当所


有到任务都在一个单一地 址空间下,能使用全程变量、指针、缓冲区、链


表、循环缓冲区等,使用共享数据结构通 讯就更为容易。虽然共享数据区


法简化了任务间的信息交换,但是必须保证每个任务在处 理共享数据时的


排它性,以避免竞争和数据的破坏。与共享资源打交道时,使之满足互斥


条件最一般的方法有:



?



关中断


(


μ


C/OS-


Ⅱ在 处理内部变量和数据结构时就是使用的这种手



)


?



使用测试并置位指令



?



禁止做任务切换



?



利用信号量



6.



信号量


:


信号量用于:



?



控制共享资源 的使用权


(


满足互斥条件


)


?



标志某事件的发生



?



使两个任务的行为同步



对信号量只能实施三种操作:



?



初始化


(INITIALIZE)


,也可称作建立


( CREATE)




?



等信号


(WAIT)


也可称作挂起


(PEND)




?



给信号


(SIGNAL)


或发信号


(POST)




这是我自己写的验证信号量的部分代码


:


void task_one(void* pdata);



void task_two(void* pdata);




OS_EVENT *tasktwo;



#include




GUI_Init();



VCInit();


//


初始化一些变量




OSInit();



timeSetEvent(OS_TICKS_PER_SEC,


0,


OSTickISR,


0,


TIME_PERIODIC); //


产生节拍



tasktwo = OSSemCreate(0);




OSTaskCreate(task_two, 0, &TaskStk[7][TASK_STK_SIZE-1], 1);



OSTaskCreate(task_one, 0, &TaskStk[8][TASK_STK_SIZE-1], 2);




OSStart();





7.



使用实时内核的优缺点


:


实时内核也 称为实时操作系统或


RTOS



它的使 用


使得实时应用程序的设计和扩展变得容易,不需要大的改动就可以增加新


的功能。通过将应用程序分割成若干独立的任务,


RTOS

< br>使得应用程序的设


计过程大为减化。使用可剥夺性内核时,所有时间要求苛刻的事 件都得到


了尽可能快捷、有效的处理。通过有效的服务,如信号量、邮箱、队列、


延时、超时等,


RTOS


使得资源得到更好的 利用。如果应用项目对额外的需


求可以承受,应该考虑使用实时内核。这些额外的需求是 :内核的价格,


额外的


ROM/RAM


开销,


2



4


百分点的


CPU


额外负荷。


















内核结构



1.



任务


:


一个任务通常是一个无限的循 环。看起来像其它


C


的函数一样,有


函 数返回类型,有形式参数变量,


但是任务是绝不会返回的


。故返 回参数


必须定义成


void



当任务完成以后任务代码并非真的删除了,


μ


C /OS-


Ⅱ只


是简单地不再理会这个任务了。

< br>


列出一任务:



void YourTask (void *pdata)


{


for (;;) {


(2)


/*


用户代码


*/



调用


uC/OS- II


的某种系统服务


:


OSMboxPend();


OSQPend();


(1)


OSSemPend();


OSTaskDel(OS_PRIO_SELF);


OSTaskSuspend(OS_PRIO_SELF);


OSTimeDly();


OSTimeDlyHMSM();


/*


用户代码


*/


}


}


形式参数变量


(1)


是由用户代码在第一次执行的时候带入的 。该变量的类型是一


个指向


void


的 指针。这是为了允许用户应用程序传递任何类型的数据给任务。


μ


C/OS-


Ⅱ可以管理多达


64


个任 务,但目前版本的


μ


C/OS-


Ⅱ有两 个任务已经被


系统占用了。作者保留了优先级为


0



1



2

< br>、


3



OS_LOWEST_P RIO-3



OS_LOWEST_PRI0-2



OS_LOWEST_PRI0-1


以及


OS_LOWEST_PRI0



8

< p>
个任务以被将


来使用。为了使


μ

< br>C/OS-


Ⅱ能管理用户任务,用户必须在建立一个任务的时候,


将任务的起始地址与其它参数一起传给下面两个函数中的一个:


OSTastC reat



OSTaskCreatExt()




2.



任务控制块:一旦任务建立了,任务控制块


OS_TCBs


将被赋值。任务控制


块是一个


数据结构


,当任务的


CPU


使用权被剥夺时,

< p>
μ


C/OS-


Ⅱ用它来保存


该任务的状态。当任务重新得到


CPU


使用权时,任务控制块 能确保任务从


当时被中断的那一点丝毫不差地继续执行。


OS_ TCBs


全部驻留在


RAM


中。



?C/OS- II


任务控制块清单:



typedef struct os_tcb {


OS_STK *OSTCBStkPtr; //


指向当前任务 栈顶的指针。


每个任务的栈的


容量可以是


//


任意的




#if OS_TASK_CREATE_EXT_EN


void *OSTCBExtPtr; //


指向用户定义的任务控制块扩展



OS_STK *OSTCBStkBottom; //


是指向任务栈底的指针



INT32U OSTCBStkSize; //


存有栈中可容纳的指针元数目



INT16U OSTCBOpt; //


把“选择 项”传给


OSTaskCreateExt()



INT16U OSTCBId; //


存储任务的识别码,留给将来扩展用



#endif


//


用于任务控制块< /p>


OS_TCBs


的双重链接,该


链表在时 钟节



struct


os_tcb


*OSTCBNext;


//

拍函数


OSTimeTick()


中使用,用于刷新各个< /p>


任务的任



struct os_tcb *OSTCBPrev;


//


务延迟变量


.




#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN


OS_EVENT *OSTCBEventPtr; //


指向事件控制块的指针



#endif



#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN


void *OSTCBMsg; //


是指向传给任务的消息的指针



#endif



INT16U OSTCBDly;


INT8U OSTCBStat;


INT8U OSTCBPrio;



INT8U OSTCBX;


INT8U OSTCBY;


INT8U OSTCBBitX;


INT8U OSTCBBitY;



#if OS_TASK_DEL_EN


BOOLEAN OSTCBDelReq;


#endif


} OS_TCB;


目前,


一个用于空闲任务,


另一个用于任务统计


(如果


OS_TASK_STAT_EN


是设为


1


的)。在


μ


C/O S-


Ⅱ初始化的时候,所有任务控制块


OS_TCBs


被链接成单向空


任务链表。


当任务一旦建立,< /p>


空任务控制块指针


OSTCBFreeList

< br>指向的任务控制


块便赋给了该任务,


然后


OSTCBFreeList


的值调整为指向下链表中下一个空的任

< p>
务控制块。一旦任务被删除,任务控制块就还给空任务链表。



3.



就绪表(


Ready


List


):每个任务被赋予不同的优先级等级,从


0


级到最


低优先级


OS_LOWEST_PR1O


。每个任务的就绪态标志都放入就绪表中的,就


绪表中有两个变量


OSRedyGrp



OSRdyTbl[]




OSRdyGrp


中,


任务按优先


级分组,


8


个任务为一组。


OSRdyGrp


中的每一位表 示


8


组任务中每一组中


是否有进入就绪 态的任务。任务进入就绪态时,就绪表


OSRdyTbl[]


中 的相


应元素的相应位也置位。



以下程 序清单中的代码用于将任务放入就绪表。


Prio


是任务的优先 级



OSRdyGrp |= OSMapTbl[prio >> 3];


OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];



如果一个任务被删除了,则用程序清单中的代码做求反处理



if ((OSRdyTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0)



OSRdyGrp &= ~OSMapTbl[prio >> 3];



找出进入就绪态的优先级最高的任务



y = OSUnMapTbl[OSRdyGrp];



x = OSUnMapTbl[OSRdyTbl[y]];



prio = (y << 3) + x;




4.



任务调度(


Task


Schedul ing


):


μ


C/OS-


Ⅱ总是运行进入就绪态任务中优


先级最高的那一个。确定哪个任务优先级最高 ,下面该哪个任务运行了的


工作是由调度器(


Schedule r


)完成的。


任务级的调度是由函数


O SSched()


完成的。


中断级的调度是由另一个函数


OSIntExt()


完成的



OSSched()


的所


有代码都属临界段代码。< /p>



5.


< br>系统初始化


OSIint():OSInit()


建立空 闲任务


idle task


,这个任务总是

处于就绪态的。


OSInit()


还得建立统计任务


OSTaskStat()


并且让其进入就


绪 态。


以上两个任务的任务控制块



OS _TCBs



是用双向链表链接在一起的。

μ


C/OS-


Ⅱ还初始化了


4


个空数据结构缓冲区。



6.



任务启动


OSStart()


:多任务的启动是用户通过调用

OSStart()


实现的。


然而,


启动


μ


C/OS-


Ⅱ之前,


用户至少要建立一个应用任务。


当调用


OSSt art()


时,


OSStart()


从 任务就绪表中找出那个用户建立的优先级最高任务的任务


控制块,然后,


OSStart()


调用高优先级就绪任务启动函数






















任务管理



1.



建立任务


:


建立任务:


OSTaskCreate()



OSTaskCreateExt()


OSTaskCreate()



?C/OS


是向下兼容的,


OSTaskCreateExt ()



OSTaskCreate()


的扩展版本,提供了一些附加的功能。任务可以在多任务


调度开始前建立,也可以在其它 任务的执行过程中被建立。在开始多任务


调度


(


即调用


OSStart())


前,

用户必须建立至少一个任务。


任务不能由中断


服务程序


(ISR)


来建立。


OSTaskCreate()


需要四个参数:


task< /p>


是任务代码的指针,


pdata


是当任务 开


始执行时传递给任务的参数的指针,


ptos


是分配给任务的堆栈的栈顶指针,


prio


是分配给任 务的优先级。



OSTaskCreate()


清单



INT8U


OSTaskCreate


(void


(*task)(void


*pd),


void


*pdata,


OS_STK


*ptos,


INT8U prio)


{


void *psp;


INT8U err;


if (prio > OS_LOWEST_PRIO) { //


检测分配给任务的优先级是否


有效



return (OS_PRIO_INVALID);


}


OS_ENTER_CRITICAL(); //


关中断



if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { //


确保在规定的优先级上还没


有建立任务



OSTCBPrioTbl[prio] = (OS_TCB *)1; //


放置一个非空指针保留该优


先级


-


-


-


-


-


-


-


-



本文更新与2021-02-01 23:46,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/595899.html

UCOS-II概念及内核的相关文章