嵌入式实时操作系统uCOS-II(高清).pdf (邵贝贝)

所需积分/C币:49 2013-12-28 17:51:08 4.34MB PDF
287
收藏 收藏
举报

很清晰的ucosII操作系统,对于想了解操作系统的人,非常有利,对于c语言的学习也是起到非常重要作用
数 程序清单L1.1可移植型数据类型。 以INI6U数据类型为例,它代衣16位无符号整数数据类型。C/(O-1l和用户的应用代 码可以定义这种类型的数据,范围从0到65,535。如果将C0/S-I移植到32位处理器中 那就意味着INT1'L不再不是一个无符号整型薮据,而是一个无符号短整型数据。然而将无论 C/0S-II用到哪里,都会当作INMT16U处理。表1.1是以 Borland o/C+编译器为例,为80x86 提供的定义语句。为了和C/0S兼容,还定义了BYTE,WORD,ONG以及相应的无符号变量。这 使得用户可以不作任何修改就能将CUS的代码移植到C/s-⊥中。之所以这样做是因为笔 者觉得这种新的数据类型定义有更多的灵活性,也更加易读易懂。对一些人来说,WORD意味 着32位数,而此处却意味着16位数。这些新的数据类型应该能够消除此类含混不请 1.03全局变量 以下是如何定义仝局变量。众所周知,仝局变量应该是得到内存分配且可以被其他模块 通过C语言中 extern关键字调用的变量。因此,必须在.C和.H文件中定义。这种重复的 定义很容易导致错误。以下讨论的方法只需用在头文件中定义一次。虽然有点不易懂,但用户 一旦掌握,使用起来却很灵活。表1.2中的定义出现在定义所有全局变量的.H头文件中。 程序清单L定义全局宏。 # i fdef xx× GLOBALS 井 define XT #else tdefine xxx EXT extern #endif 文件中每个全局变量都加上了 XXX EXT的前缀。ⅹxx代表模块的名字。该模块的.C文件中 有以下定义 #define XXX GLOBAlS include includes. h" 当编译器处理.C文件时,它强制ⅹ XX EXT(在相应.H文件中可以找到)为空,(因为ⅹ XX GLOBALS 己经定义)。所以编译器给每个仝局变量分配内存空间,而当编译器处理其他.C文件时, XXX GLOBAL没有定义,xXX被定义为 extern,这样用户就可以调用外部全局变量。为了 说明这个概念,可以参见uC/0SI.H,其中包括以下定义 #iDef OS GLOBALS tdefine OS EXT #else 抖 define Os ExT extern #endif OS EXI工NT32U osIdlectri OS EXT INT3 2U oSIdlectrrun OS EXT INT3ZU oSIdlectrmax 可时 I有中以下定义 tdefine OS GlobAlS include includes, h 当编译器处理uCUS11.C时,它使得头文件变成如下所示,因为 OS EXT被设置为空。 ⊥N32U oSIdlectr 工NT32U osIdlectrRun INT32U oSIdlectrMax 这样编译器就将这些全局变量分配在内存中。当编译器处其他.C文件时,头文件变成了 如下的样子,因为0 S GLOBAL没有定义,所以0SEXT被定义为 extern extern INT32U oSIdlectr extern INT3 2U oSIalectrRun i extern INT 3 2U ○ SIdlectrmax 在这和情况下,不产生内存分配,而任何.C文件都可以使用这些变量。这样的就只需在.H 文件中定义一次就可以了。 1.040现 ER CRITICAL0和 OS EXIT CRITICAL( 用户会看到,调用 OS ENTER CRITICAL O和0 S EXIT CRITICAL两个宏,贯穿本书的所 有源代码。0 S ENTER CRITICAL关中断;而 OS EXIT CRITICAL开中断。关中断和开中断 是为了保护临界段代码。这些代码很显然与处理器有关。关于宏的定义可以在 OS CPU.H中找 到。9.03.02节详细讨论定义这些宏的两种方法。 程序清单L进入正确部分的宏。 tdefine OS CRITICAL METHOD 2 #if OS CRITICAL METHOD ==1 #define OS ENTER CRITICAL( asm CLI #define oS EXIT CRITICAL( asm STI #已dif #iE ○ S CRITICAL METHOD=2 #define OS ENTER CRITICAL ( asmiPUSHF; CLI J #define oS EXIT CRITICAL() asm POPF 井 endif 用户的应用代码可以使用这两个宏来开中断和关中断。很明显,关中断会影响中断延迟, 所以要特别小心。用户还可以用信号量来保护林阶段代码. 1.05基于FC的服务 PC.C文件和PC.H文件(在\ SOFTWARE\ BLOCKS\PC\ SOURCE目录下)是笔者在范例中使 用到的一些基于PC的服务稈序。与C/0S-1I以前的版本(即C/0S)不同,笔者希望集 中这些函数以避免在各个例子中都重复定义,也更容易适应不同的编译器。PC.C包括字符显 示,时间度量和其他各和服务。所有的函数都以PC为前缀。 1.05.01字符显示 为了性能更好,显示函数直接向显示内存区中写数据。在VGA显示器中,显示内存从绝对 地址0x000B8000开始(或用段、偏移量表小则为B800:0000)。在单色显小器中,用户可以 把# define constant disP base从0xB800改为0xB000。 PC.C中的显示函数用ⅹ和y坐标来直接向显示内存中写ASCI字符PC的显示可以达到 25行80列一共2,000个字符。每个字符需要两个字节来显示,第一个字节是用户想要显示 的字符,第二个字节用来桷定前景色和背景色。前景色用低四位来表示,背景色用第4位到 6位来表小。最高位表小这个字符是否闪烁,(1)表小闪烁,(0)表小不闪烁。用PC.H中 # defies constants定义前景和背景色,PC.C包括以下四个函数 PC DispClrScr( Clcar the screen PC DispClrLine( Clear a single row (or line) C DispChar o Display a single aScii character anywhere on the screen PC Dispstr( Display an aScii string anywhere on the screen 1.05.02花费时间的测量 时间测量函数主要用于测试一个函数的运行花了多少时间。测量时问是用PC的82C54 定时器2。被测的程序代码是放在函数 PC ElapsedStart O和 PC Elapsedstop(之间来测量 的。在用这两个函数之前,应该调用 PC Elapsedlnit o来初始化,它主要是计算运行这两个 数本身所附加的的时间。这样, PC ElapsedStop(函数中返回的数值就是准确的测量结果 了。注意,这两个函数都不具备可重入性,所以,必须小心,不要有多个任务同时调用这两 个函数。表1.4说明了如何测量 PC Display Char(的执行时间。注意,时间是以uS为单位 的 程序湾单L测量代码执行时间。 intu time PC ElapsedInit(); PC Elapsedstart( PC DispChar(40, 24,'A', DISP F'GND WHITE) time PC Elapsedstop()i 1.05.03其他函数 C/0S-∏Ⅰ的应用稈序和其他DOS应用程序是一样的,换句话说,用户可以像在DOS下编 译其他单线程的程序·样编译和链接用广程序。所生成的.LXE程序可以在DS下装载和运行 当然应用程序应该从main()函数开始。因为C/OS-II是多任务,而且为每个任务开辟 个堆栈,所以单线程的DS环境应该保存,在退出C/0S-TI程序时返回到D0S。调用 PC DOSSaveReturno可以保存当前DOS环境,而调用 PC DOSRe turn0可以返回到DOS。PC.C 中使用 ANSI C的 set Jmp(, long jmp○函数来分别倮存和恢复DoS环境。 Borland c/C艹编译 库提供这些函数,多数其它的编译程序也应有这类函数 应该注意到无论是应用程序的错误还是只调用exit(0)而没有调用 PC DOSReturn(函数 都会使DOS坏境被破坏,从而导致DOS或 WINDOWS95下的D0S窗口崩溃。 调用 PC GctDateTime(函数可得到PC中的日期和时间,并且以 SACII字符串形式返回。 格式是M-DD-YYH:MM:SS,用户需要19个字符来存放这些数据。该函数使用了 Borland c/C++ 的 gettime o和 getdate O函数,其它DOS环境下的C编译应该也有类似函数。 pC_ Get Key()函数检査是否有按键被按下。如果有按键被按下,函数返冋其值。这个函 数使用了 Borland c /c++的 khit○和 getch(函数,其它D0S环境下的C编译应该也有类似 数。 函数 PC SetTickRateo允许用户为C/0SII定义频率,以改变钟节拍的速率。在 下,每秒产生18.20648次时钟节拍,或每隔54.925ms一次。这是因为82C54定时器芯片没 有初始化,而使用默认值65,535的结果。如果初始化为58,659,那么时钟节拍的速率就会 精确地为20.0z。笔者决定将时钟节拍设得更快一些,用的是200Hz(实际是上是 199.9966H)。注意 OS CPU A.ASM中的 oSTickIsro函数将会每11个时钟节拍调用一次DOS 中的时钟节拍处理,这是为了保证在D0s下时钟的准确性。如果用户希望将时钟节拍的速度 设置为20HZ,就必须这样做。在返回DOS以前,要调用 PC SetTickRate(,并设置18为目 标频率, PC Settickrate(就会知道用户要设置为18.2Hz,并且会正确设置82C54, PC.C中最后两个函数是得到和设置中断向量,笔者是用 Borland c/C++中的库函数来完 成的,但是 PC VectGet(和 PC VectSet(很容易改写,以适用于其它编译器。 1.06应用COS-I的范例 木章中的例子都用 Borland c/C++编译器编译通过,是在 Windows95的D0S窗口下编译 的。可执行代码可以在每个范例的OBJ了目录下找到。实际上这些代码是在 Bor land de ( Integrated Development Environment)下编译的,绵译时的选项如表1.1所示 表 中编译选项。 DS 笔者的 Borland c/c+编译器安装在C:\CPP目录下,如果用户的编译器是在不同的目录 下,可以在 Options/ Directories的提示卜改变IDE的路径 C/0S-IⅠ是一个可裁剪的操作系统,这意味着用户可以去掉不需要的服务。代码的削减 可以通过设置0SCFG.中的* defines0S??!E为0米实现。用户不需要的服务代码就不 生成。本章的范例就用这种功能,所以每个例子都定义了不同的0s??EN。 1.07例1 第一个范例可以在\ SOFTWARE UCOS II\EX1x86L日录下找到,它有13个任务(包括 C/OS-II的空闲任务)。C/0S-II增加了两个内部任务:空闲任务和一个计算CPU利用率 的任务。例1建立了11个其它任务。 TaskStart0任务是在函数main(中建立的;它的功能 是建立其它任务并且在屏幕上显示如下统计信息 ●每秒钟任务切换次数 ●CPU利用百分率; 寄存器切换次数 目前日期和时间 ●C/0SII的版本号; Taskstart○还检查是否按下ESC键,以决定是否返回到DOS。 其余10个任务基」相同的代码—Task;每个任务在屏幕上随札的位置显示一个0到 9的数字。 1.07.01main 例1基本上和最初中的第一个例子做一样的事,但是笔者整理了其中的代码,并 且在屏幕上加了彩色显示。同时笔者使用原来的数据类型( UBYTE, UWORD等)来说明 C/OS-II向下兼容。 main(程序从清整个屏幕开始,为的是保证屏幕上不留有以前的DOS下的显示 L1.5(1)]。注意,笔者定义了白色的字符和黑色的背景色。既然要请屏幕,所以可以只定义 背景色而不定义前景色,但是这样在退同D0S之后,用户就什么也看不见了。这也是为什么 总要定义个可见的前景色 C/0S-II要用户在使用仟何服务之前先调用 OSInit()[L1.5(2)]。它会建立两个任务: 空闲任务和统计任务,前者在没有其它任务处于就绪态时运行;后者计算CPU的利用率 程序清单 L main() void main (void) PC Di spClrscr(DISP FGND WHITE DISP BGND BLACK) OSInit( (2) PC DOSSaveReturn( (3) PC Vectset(ucos OSCtxSw) (4) RandomSem- OSSemcreate(1) (5) OSTaskCreate(Taskstart (5) (void *)&Taskstartstk [TASK STK SIZE-1l 0); osstart( (7) 当前D0S环境是通过调用 PC DOSSavereturn(|L1.5(3)来保存的。这使得用户可以返回 到没有运行C0S-II以前的DS环境。跟随清单L1.6中的程序可以看到 Pc DOSSavereturn() 做了很多事情。 PC DOSSavereturn()首先设置 PC ExitFlag为 FALSE[L1.6(1)],说明用户 不是要返回D0S,然后初始化 OSTickdOSCtr为1L1.6(2)],因为这个变量将在 OSTickIsro中 递减,而0将使得这个变量在0 STickier(中减1后变为255。然后, PC DOSSave return将 DOS的时钟节拍处理( tick handler)存入一个自由向量表入口中L1.6(3)-(4),以便为 C/0s-I的时钟节拍处理所调用。接着 PC DOSSaveReturnO调用Jjm()[L1.6(5)],它将处 理器状态(即所有寄存器的值)存入被称为 PC Jump Bu的结构之中。保存处理器的全部寄存 器使得稈序返回刭 PC DOSSavereturn(并月在调用 set ]mp()之后立即执行。因为 PC Exite1ag 被初始化为 FALSE[L.6(1)]。 PC DOSSavereturn跳过状态语句[L1.6(6)(9)]回到 main()函数。如果用户想要返回到DOS,可以调用 PC DOSReturn()(程序清单L1.7),它 设置 PC ExitFlag为TREE,并且执行 long jmp()语句L1.7(2)],这时处理器将跳回 PC DOSSaveReturn([在调用 setjmp()之后』[L1.6(5)],此时 PC EXit1ag为TRUE,故if 语句以后的代码将得以执行。 PC DOSSavereturn(将时钟节拍改为18.2HzL1.6(6)1,恢复 PC时钟节拍中断服务[L1.6(7)],清屏幕[L1.6(8)],通过exit(0)返回D0S[L.6(9)]。 程序清单L保存环培。 void PC DOSSaveReturn (void) PC ExitFlag = FALSE (1) OSTickDosctr PC TickISR= PC VectGet (VECT TICK) (3) OS ENTER CRITICAL ()i Pc Vectset ( vect Dos Chain Pc TickISR) (4) OS EXIT CRITICAL( Set jmp(PC JumpBuf) if (PC ExitFlag = TRUE) OS ENT三 R CRITICAL(); PC SetTickRate(18) (6) PC VectSet(vECt TICK pc TickIsr (7) OS EXIT CRITICAL O PC Dispclrscr(DISP FGND WHITE DISP BGND BLACK)i (8) exit(0) (9) 程序清单L投置返园。 void PC DOSReturn (void) PC ExitFlad= TRUE (1) longjmp(PC JumpBuf, 1) 现在回到main()这个跞数,在程序清单L1.5中,Ⅲain()调用 PC VectSet(来设 置COS-I中的CPI寄存器切换。任务级的CPU寄存器切换由80x86INT指令来分配向量地 址。笔者使用向量0x80(即128),因为它未被DUS和BOS使用。 这里用了一个信号量来保护 Borland c/c++库中的产生随机数的函数L1.5(5)|,之所以 使用信号量保护一下,是因为笔者不知道这个函数是否具备可重入性,笔者假设其不具备, 初始化将信号量设置为1,意思是在某一时刻只有一个任务可以调用随机数产生函数。 在开始多仟务之前,笔者建立了一个叫做 TaskStart O的仟务[1.5(6)],在启动多仟务 OSStart O之前用户至少要先建立个任务,这点非常重要[L1.5(7)]。不这样做用户的应用 程序将会崩溃。实际上,如果用户要计算CPU的利用率时,也需要先.建立一个任务。COS-II 的统计任务要求在整个一秒钟内没有任何其它任务运行。如果用户在启动多任务之前要建立 其它任务,必须保证用户的任务代码监控全局变量0 SStatrdy和延时程序[即调用 OSTimeDIy()]的执行,直到这个变量变成TRLE。这表明C/0S-1的CPU利用率统计两数已终 采集到了数据。

...展开详情
试读 127P 嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)
立即下载
限时抽奖 低至0.43元/次
身份认证后 购VIP低至7折
一个资源只可评论一次,评论内容不能少于5个字
您会向同学/朋友/同事推荐我们的CSDN下载吗?
谢谢参与!您的真实评价是我们改进的动力~
上传资源赚钱or赚积分
最新推荐
嵌入式实时操作系统uCOS-II(高清).pdf (邵贝贝) 49积分/C币 立即下载
1/127
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第1页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第2页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第3页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第4页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第5页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第6页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第7页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第8页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第9页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第10页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第11页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第12页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第13页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第14页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第15页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第16页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第17页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第18页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第19页
嵌入式实时操作系统uCOS-II(高清).pdf  (邵贝贝)第20页

试读结束, 可继续阅读

49积分/C币 立即下载