嵌入式实时操作系统uCOS-II(中文版)(5)

2021-09-24 14:51

的库函数random()来获得一个随机数[程序清单L1.10(2)],此处设random()函数是不可重入的,所以10个任务将轮流获得信号量,并调用该函数。当计算出x和y坐标后[程序清单L1.10(3)],任务释放信号量。随后任务在计算的坐标处显示其任务号(0-9,任务建立时的标识)[程序清单L1.10(4)]。最后,任务延时一个时钟节拍[程序清单L1.10(5)],等待进入下一次循环。系统中每个任务每秒执行200次,10个任务每秒钟将切换2000次。

程序清单 L 1.10 在屏幕上显示随机位置显示数字的任务。

void Task (void *data) {

UBYTE x; UBYTE y; UBYTE err;

for (;;) {

OSSemPend(RandomSem, 0, &err); x = random(80); y = random(16); OSSemPost(RandomSem);

(3)

(4)

(1)

(2)

PC_DispChar(x, y + 5, *(char *)data, DISP_FGND_LIGHT_GRAY); OSTimeDly(1); } }

(5)

1.08 例2

例2使用了带扩展功能的任务建立函数OSTaskCreateExt()和uCOS-II的堆栈检查操作(要使用堆栈检查操作必须用OSTaskCreateExt()建立任务—译者注)。当用户不知道应该给任务分配多少堆栈空间时,堆栈检查功能是很有用的。在这个例子里,先分配足够的堆栈空间给任务,然后用堆栈检查操作看看任务到底需要多少堆栈空间。显然,任务要运行足够长时间,并要考虑各种情况才能得到正确数据。最后决定的堆栈大小还要考虑系统今后的扩展,一般多分配10%,25%或者更多。如果系统对稳定性要求高,则应该多一倍以上。

uCOS-II的堆栈检查功能要求任务建立时堆栈清零。OSTaskCreateExt()可以执行此项操作(设置选项OS_TASK_OPT_STK_CHK和OS_TASK_OPT_STK_CLR打开此项操作)。如果任务运行过程中要进行建立、删除任务的操作,应该设置好上述的选项,确保任务建立后堆栈是清空的。同时要意识到OSTaskCreateExt()进行堆栈清零操作是一项很费时的工作,而且取决于堆栈的大小。执行堆栈检查操作的时候,uCOS-II从栈底向栈顶搜索非0元素(参看图F 1.1),

同时用一个计数器记录0元素的个数。

例2的磁盘文件为\SOFTWARE\uCOS-II\EX2_x86L,它包含9个任务。加上uCOS-II本身的两个任务:空闲任务(idle task)和统计任务。与例1一样TaskStart()由main()函数建立,其功能是建立其他任务并在屏幕上显示如下的统计数据:

z 每秒种任务切换的次数; z CPU利用率的百分比; z 当前日期和时间; z uCOS_II的版本号;

图F 1.1

µC/OS-II stack checking.

1.08.01 main()

例2的main()函数和例1的看起来差不多(参看程序清单L1.11),但是有两处不同。第一,main()函数调用PC_ElapsedInit()[程序清单L1.11(1)]来初始化定时器记录OSTaskStkChk()的执行时间。第二,所有的任务都使用OSTaskCreateExt()函数来建立任务[程

),这使得每一个任务都可进行堆栈检查。 序清单L1.11(2)](替代老版本的OSTaskCreate()

程序清单 L 1.11 例2中的Main()函数.

void main (void) {

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSInit();

PC_DOSSaveReturn();

PC_VectSet(uCOS, OSCtxSw);

PC_ElapsedInit();

OSTaskCreateExt(TaskStart, (void *)0,

(1)

(2)

&TaskStartStk[TASK_STK_SIZE-1], TASK_START_PRIO, TASK_START_ID, &TaskStartStk[0], TASK_STK_SIZE, (void *)0,

OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); OSStart(); }

除了OSTaskCreate()函数的四个参数外,OSTaskCreateExt()还需要五个参数(一共9个):任务的ID,一个指向任务堆栈栈底的指针,堆栈的大小(以堆栈单元为单位,80X86中为字),一个指向用户定义的TCB扩展数据结构的指针,和一个用于指定对任务操作的变量。该变量的一个选项就是用来设定uCOS-II堆栈检查是否允许。例2中并没有用到TCB扩展数据结构指针。

1.08.02TaskStart()

程序清单L1.12列出了TaskStart()的伪码。前五项操作和例1中相同。TaskStart()建立了两个邮箱,分别提供给任务4和任务5[程序清单L1.12(1)]。除此之外,还建立了一个专门显示时间和日期的任务。

程序清单 L 1.12 TaskStart()的伪码。.

void TaskStart (void *data) {

Prevent compiler warning by assigning ‘data’ to itself; Display a banner and non-changing text; Install uC/OS-II’s tick handler; Change the tick rate to 200 Hz; Initialize the statistics task;

Create 2 mailboxes which are used by Task #4 and #5;

(1)

Create a task that will display the date and time on the screen; (2) Create 5 application tasks; for (;;) {

Display #tasks running;

Display CPU usage in %;

Display #context switches per seconds; Clear the context switch counter; Display uC/OS-II’s version; If (Key was pressed) {

if (Key pressed was the ESCAPE key) { Return to DOS; } }

Delay for 1 second; } }

1.08.03 TaskN()

任务1将检查其他七个任务堆栈的大小,同时记录OSTackStkChk()函数的执行时间[程序清单L1.13(1)–(2)],并与堆栈大小一起显示出来。注意所有堆栈的大小都是以字节为单位的。任务1每秒执行10次[程序清单L1.13(3)](间隔100ms)。

程序清单 L 1.13 例2, 任务1

void Task1 (void *pdata) {

INT8U err; OS_STK_DATA data; INT16U time; INT8U i; char s[80];

pdata = pdata; for (;;) {

for (i = 0; i < 7; i++) { PC_ElapsedStart();

(1)

err = OSTaskStkChk(TASK_START_PRIO+i, &data) time = PC_ElapsedStop(); if (err == OS_NO_ERR) {

嵌入式实时操作系统uCOS-II(中文版)(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2014年人教版七年级(下)第一次月考语文试卷及答案

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

马上注册会员

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