[计算机]ucos-ii源代码开放的确良嵌入式os
教程
人力资源管理pdf成真迷上我教程下载西门子数控教程protel99se入门教程fi6130z安装使用教程
第一章,范例
在这一章里提供三范例这明如何使用 将个来。者之所笔µC/OS-II以在本这一这始就这一章是这了这这者快这始使用 写尽。在这µC/OS-II始这述这些例子之前~者想先这明一些在这本这里的这定。笔
这些例子曾这用这这器;,这这这~用这这这这生Borland C/C++ V3.1
这理器;大模式下这这,的代这。这些代这这这上是在Intel/AMD80186
;,上行和这这这~运Intel Pentium II PC 300MHzIntel Pentium II
可以看成是特这快的。者这这笔做这目这系这是由于以PC80186PC
下原因,首先也是最这重要的~以几个做这目这系这比起以其PC
他嵌入式这境~如这板~器等~更容易这行代这的这这~不用估仿真
不地这断写~不地向断仿真器中下这程序等等。EPROMEPROM
用这只需要这这地这这、这接和这行。其次~使用这生的Borland C/C++
的目这代这;这模式~在大模式下这这,所有与80186
、、公司的兼容。IntelAMDCyrix80x86 CPU
安 装1.00 µC/OS-II
本这附这一这这这包括了所有我这这这的源代这。是假定这者在
~~或者这理器上行运或80x86PentiumPentium-IIDOS
。至少需要硬这空这安来装。Windows955MbuC/OS-II
这按照以下步这安,装
这入到;或在下打这窗并口,且指定1.DOSWindows 95DOS
,这默这这这器。C
将插磁这入到,这这器。2.A
这入 ,【】3.AINSTALL drive
注意『』是这者想要将,安的目这磁这的这符。装driveµC/OSII
是一个的批这理文件~位于磁这的根目这INSTALL.BAT DOS
下。自这在这者指定的目这这这器中建立它会目这且并将\SOFTWARE
文件从,这这器这制到并运且行。uCOS-II.EXEA\SOFTWARE
,将在目这下添加所有的目这和文件。完成µC/OSII\SOFTWARE
之后将这除并将且目这改INSTALL.BATuCOS-II.EXE这~第一例子就存放在这里。个\SOFTWARE\uCOS-II\EX1_x86L
在安之前这一定这这一下装文件。当已READ.MEINSTALL.BAT
这完成这~用这的目这目这下这这有一下子目这,, \SOFTWARE
这是根目这~是所有这件相这的文件都放在这目这下。个, \SOFTWARE\BLOCKS子程序模这目这。者例子中笔将用到的与相这的函数µC/OS-IIPC模这这这以后放在这目这下。个
, \SOFTWARE\HPLISTC
这目这中存放的是范例个与相这的文件;这看附这HPLIST
~和,。存放DHPLISTCTOHPLIST.C
在目这下。下的可这行文件\SOFTWARE\HPLISTC\SOURCEDOS;,存放在中。HPLIST.EXE\SOFTWARE\TO\EXE
, \SOFTWARE\TO
这目这中存放的是和范例个相这的文件;这看附这TO
~和,。源文件存放DHPLISTCTOTO.C
在中~下的可这行文件\SOFTWARE\TO\SOURCEDOS
;,存放在中。注意需要一个TO.EXE\SOFTWARE\TO\EXETO
文件~必这放在根目这下。用这可以它TO.TBL
在目这下到找文件。如果要行运\SOFTWARE\TO\EXETO.TBL
~必这将这制到根目这下。TO.EXETO.TBL
, \SOFTWARE\uCOS-II
与相这的文件都放在这目这下。个µC/OS-II
, \SOFTWARE\uCOS-II\EX1_x86L
这目这里包括例个的源代这参这 例~可以在1(1.07, 1)DOS;或下的窗运口,下行。Windows 95DOS
, \SOFTWARE\uCOS-II\EX2_x86L
这目这里包括例个的源代这参这 例~可以在2(1.08, 2)DOS;或下的窗运口,下行。Windows 95DOS
, \SOFTWARE\uCOS-II\EX3_x86L
这目这里包括例个的源代这参这 例~可以在3(1.09, 3)DOS
;或下的窗运口,下行。Windows 95DOS
, \SOFTWARE\uCOS-II\Ix86L
这目这下包括依这于这理器这型的代这。此这是这在个这理器80x86上行运而必这的一些代这~这模式~在大模式下这这。uC/OS-II
, \SOFTWARE\uCOS-II\SOURCE
这目这里包括这理器这型无这的源代这。这些代这完全可移植到个与
其架的这理器上。它构
1.01 INCLUDES.H
用这注意到本这中所有的 将文件都包括了以下定这,*.C
#include "includes.h"
可以使用这不必在工程这目中每个文件中都考这需INCLUDE.H*.C要什这这的这文件。这句这这~是主这文件。这这做唯一的缺INCLUDE.H
点是中这多这文件在一些文件的这这中是不需要INCLUDES.H*.C
的。这意味着逐这这这些文件要花这这外的这这。这这有些不便~但代这个
的可移植性却增加了。本这中所有的例子使用一共同的这文件个
~个副本分这存放在INCLUDES.H3\SOFTWARE\uCOS-
~~以II\EX1_x86L\SOFTWARE\uCOS-II\EX2_x86L及中。然可以重新这这当\SOFTWARE\uCOS-II\EX3_x86L
以添加用这自己的这文件。INCLUDES.H
不依这于这这的据这型数1.02
因这不同的微这理器有不同的字这~的移植文件包括µC/OS-II很确参多这型定这以保可移植性;这\SOFTWARE\uCOS-
~是这这它的这模式~在大模式下这这,。II\Ix86L\OS_CPU.H80x86
不使用这言中的等据这型的定这~因这数µCOS-IICshort,int,long它与笔这这理器这型有这~这含着不可移植性。这者代之以移植性强的整据这型~这这~直这又可移植~如表数数既所示。这了方便起L1.1
这~这定这了浮点据这型~这然数数中有使用浮点。没数µC/OS-II
程序这 清L1.1可移植型据这型。数
Typedef unsigned char BOOLEAN;Typedef unsigned char INT8U;Typedef signed char INT8S;Typedef unsigned int INT16U;Typedef signed int INT16S;Typedef unsigned long INT32U;Typedef signed long INT32S;Typedef float FP32;Typedef double FP64;#define BYTE INT8S#define UBYTE INT8U#define WORD INT16S#define UWORD INT16U#define LONG INT32S
#define ULONG INT32U以数它据这型这例~代表位无符整据这型号数数。INT16U16
和用这的这用代这可以定这这这这型的据~范这数从到µC/OS-II0
。如果将移植到位这理器中~那就意味着65,535µCO/S-II32
不再不是一无符整型据~而是一无符短整型个号数个号INT16U
数将据。然而无这用到里~都作哪会当这理。 表µC/OS-IIINT16U
是以这这器这例~这提供的定这这句。这了和1.1Borland C/C++80x86
兼容~这定这了以及相这的无符这量号。µC/OSBYTE,WORD,LONG这使得用这可以不作任何修改就能将的代这移植到µC/OSµC/OS-中。之所以这这做是因这者这得这这新的据这型定这有更多的笔数灵II
活性~也更加易这易。这一些人这~懂来意味着位~数WORD32而此这却意味着位。这些新的据这型这这能这消除此这含混不这数数16
全局这量1.03
以下是如何定这全局这量。所周知~全局这量这这是得到存众内
分配且可以被其他模这通这这言中这这字这用的这量。因此~Cextern
必这在 和 文件中定这。这这重这的定这容易这致这这。以下这这的很.C .H
方法只需用在这文件中定这一次。这然有点不易懂但用这一旦掌握~,使用起却活。表来很灵中的定这出这在定这所有全局这量的这1.2.H文件中。
L 1.2程序这 清定这全局宏。
#ifdef xxx_GLOBALS
#define xxx_EXT
#else
#define xxx_EXT extern#endif
文件中每全局这量都加上了个的前这。代表模这的.H xxx_EXTxxx名字。这模这的文件中有以下定这,.C
#define xxx_GLOBALS
#include "includes.h"当这这器这理文件这~强制它;在相这文件中可以找.Cxxx_EXT.H到,这空~;因这已这定这,。所以这这器这每全局个xxx_GLOBALS
这量分配存空这~而这这器这理其他内当文件这~.Cxxx_GLOBAL
没有定这~被定这这~这这用这就可以这用外部全局这xxx_EXTextern
量。这了这明这念~可以这个概参其中包括以下定这,uC/OS_II.H,#ifdef OS_GLOBALS
#define OS_EXT
#else
#define OS_EXT extern#endif
OS_EXT INT32U OSIdleCtr;
OS_EXT INT32U OSIdleCtrRun;OS_EXT INT32U OSIdleCtrMax;同这~有中以下定这,uCOS_II.H
#define OS_GLOBALS
#include “includes.h”
当这这器这理这~使得这文件这成如下所示~因这它uCOS_II.C
被这置这空。OS_EXT
INT32U OSIdleCtr;
INT32U OSIdleCtrRun;
INT32U OSIdleCtrMax;
这这这这器就这些全局这量分配在存中。这这器这理其他会将内当文件.C这~这文件这成了如下的这子~因这没有定这~所以OS_GLOBAL
被定这这。OS_EXTextern
extern INT32U OSIdleCtr;extern INT32U OSIdleCtrRun;extern INT32U OSIdleCtrMax;在这这情下~不这生存分配~而任何 况内文件都可以使用这些这.C
量。这这的就只需在 文件中定这一次就可以了。.H
和 1.04OS_ENTER_CRITICAL()
OS_EXIT_CRITICAL()
用这看到~这用会和OS_ENTER_CRITICAL()
两个宏~这穿本这的所有源代这。OS_EXIT_CRITICAL()
这中~而断这中断。OS_ENTER_CRITICAL() OS_EXIT_CRITICAL()这中和这中是这了保这这界段代这。这些代这这然这理器有这。这于断断很与
宏的定这可以在中到。找这这这这这定这这些宏的两OS_CPU.H9.03.02
这方法。
程序这 清L 1.3这入正部分的宏。确
#define OS_CRITICAL_METHOD 2#if OS_CRITICAL_METHOD == 1#define OS_ENTER_CRITICAL() asm CLI#define OS_EXIT_CRITICAL() asm STI#endif
#if OS_CRITICAL_METHOD == 2#define OS_ENTER_CRITICAL() asm {PUSHF; CLI}
#define OS_EXIT_CRITICAL() asm POPF#endif
用这的这用代这可以使用这宏这中和这中。明这~这中两个来断断很断
会响断号来影中延这~所以要特这小心。用这这可以用信量保这林这
段代这。
基于的服这1.05PC
文件和 文件PC.C PC.H
;在目这下,是者在范例笔\SOFTWARE\BLOCKS\PC\SOURCE
中使用到的一些基于的服这程序。 与以前的版本PCµC/OS-II
; 即,不同~者希望集中这些函以避免在各例子笔数个µC/OS
中都重这定这~也更容易适这不同的这这器。包括字符这示~这这PC.C
度量和其他各这服这。所有的函都以数这前这。PC_
字符这示1.05.01
这了性能更好~这示函直接向这示存中据。在数内区写数这VGA
示器中~这示存这这地址内从这始;或用段、偏移量表0x000B8000
示这这,。在这色这示器中~用这可以把B800:0000#define constant
从改这。DISP_BASE0xB8000xB000
中的这示函用数和坐这直接向这示存中来内写字PC.CxyASCII
符。的这示可以到达行列一共个个字符。每字符PC25802,000
需要字这这示。第一字这是用这想要这示的字符~第两个来个个二字
这用定前来确来景色和背景色。前景色用低四位表示~背景色用
第位到位表示。最来个高位表示这字符是否这这~;,表示这461
这~;,表示不这这。用中 定这前景和背0PC.H#defien constants景色~包括以下四个数函,PC.C
PC_DispClrScr()Clear the screenPC_DispClrLine()Clear a single row (or line)PC_DispChar()Display a single ASCII character anywhere
on the screen
PC_DispStr()Display an ASCII string anywhere on the
screen
花这这这的这量1.05.02
这这这量函主要用于这这一函的行花了多少这这。这量这这是数个数运
用的定这器。被这的程序代这是放在函数PC82C542
和之这这量的。在用这来两个PC_ElapsedStart()PC_ElapsedStop()函之前~这这这用数来它运初始化~主要是这算PC_ElapsedInit()行这函本两个数身所附加的的这这。这这~函中数PC_ElapsedStop()返回的这就是数确两个数准的这量这果了。注意~这函都不具这可重入性~所以~必这小心~不要有多任这同这这用这函。表个两个数
这明了如何这量的这行这这。注意~这这是以1.4PC_DisplayChar()uS这这位的。
程序这 清L 1.4这量代这这行这这。
INT16U time;
PC_ElapsedInit();
.
.
PC_ElapsedStart();
PC_DispChar(40, 24, ‘A’, DISP_FGND_WHITE);
time = PC_ElapsedStop();
其他函数1.05.03
的这用程序和其他这用程序是一这的~这句这这~用这µC/OS-IIDOS
可以像在下这这其他这这程的程序一这这这和这接用这程序。所生DOS
成的程序可以在下这和行~然这用程序这这装运当从.EXEDOS
;,函这始。因这数是多任这~而且这每任这这一个辟mainµC/OS-II
个堆这~所以这这程的这境这这保存~在退出程序这返DOSµC/OS-II 回到。这用可以保存前当这境~DOSPC_DOSSaveReturn()DOS而这用可以返回到。 中使用PC_DOSReturn()DOSPC.CANSI C的函分这保存和数来恢这这境。setjmp(),longjmp()DOSBorland
这这这提供这些函~多其的这这程序也这有这这函。数数它数C/C++
这这注意到无这是这用程序的这这这是只这用而有这用没exit(0)
函都使数会这境被破坏从~而这致或PC_DOSReturn()DOSDOS
下的窗口崩这。WINDOWS95DOS
这用函可得到数中的日期和这这~且以并PC_GetDateTime()PC
字符串形式返回。格式是~用这需SACIIMM-DD-YY HH:MM:SS要个来数数字符存放这些据。这函使用了的19Borland C/C++
和函~其数它这境下的这这这这也有这似gettime()getdate()DOSC
函。数
函这这是数否有按这被按下。如果有按这被按下~函PC_GetKey()
数个数返回其这。这函使用了的和Borland C/C++kbhit()getch()函~其数它这境下的这这这这也有这似函。数DOSC
函数允这用这这 定这这率~以改这这这拍PC_SetTickRate()µC /OS-II
的速率。在下~每秒这生次这这这拍~或每隔DOS18.20648
一次。这是因这定这器芯片没有初始化~而使用54.925ms82C54
默这这的这果。如果初始化这~那这这这这拍的速率就会65,53558,659
精确地这。者定这这这笔决将拍这得更快一些~用的是20.000Hz
这这是上是 。注意中的200Hz(199.9966Hz)OS_CPU_A.ASM
函每数将会个这这这拍这用一次中的这这这拍这理~OSTickISR()11DOS
这是这了保这在下这这的准确将性。如果用这希望这这这拍的速度这DOS
置这~就必这这这做。在返回以前~要这用20HZDOS
~这置并这目这这率~就会PC_SetTickRate()18PC_SetTickRate()知道用这要这置这~且正这置并会确。18.2Hz82C54
中最后函是得到和这置中向量~者是用两个数断笔PC.C
中的这函完成的~但是数来和Borland C/C++PC_VectGet()
很写它容易改~以适用于其这这器。PC_VectSet()
这用 的范例1.06 µC/OS-II
本章中的例子都用这这器这这通这~是在Borland C/C++
的窗个口下这这的。可这行代这可以在每范例的Windows95 DOS
子目这下到。这这上这些代这是在找OBJBorland IDE (Integrated
下这这的~这这这的这这如表所示,Development Environment)1.1表 T1.1IDE中这这这这。
Code generation
Model: Large
Options: Treat enums as intsAssume SS Equals : Default for memory modelDS
Advanced code
generation
Floating point: Emulation
Instruction set: 80186
Options: Generate underbars
Debug info in OBJs
Fast floating pointOptimizations
OptimizationsGlobal register allocation
Invariant code motion
Induction variables
Loop optimization
Suppress redundant loads
Copy propagation
Dead code elimination
Jump optimization
In-line intrinsic functionsRegister variablesAutomatic
Common Optimize globallysubexpressions
Optimize forSpeed
笔者的这这器安在装目这下~如果用这的这这Borland C/C++C:\CPP
器是在不同的目这下~可以在的提示下改这Options/Directories
的路径。IDE
是一可个裁剪的操作系这~这意味着用这可以去掉不需要µC/OS-II
的服这。代这的削减可以通这这置中的OS_CFG.H#defines OS_???
这来这这。用这不需要的服这代这就不生成。本章的范例就用这这_EN 0
功能~所以每例子都定这了不同的个。OS_???_EN
例1.071
第一范例可以在个目这下到找~\SOFTWARE\uCOS_II\EX1_x86L它有个任这包括 的空这任这。增加了两个内13(µC/OS-II )µC/OS-II 部任这,空这任这和一这个算利用率的任这。例建立了个CPU111其任这。它任这是在函数中建立的~的它功能是TaskStart()main()
建立其任这且在它并屏幕上这示如下这这信息,
, 每秒这任这切这次~数
, 利用百分率~CPU
, 寄存器切这次~数
, 目前日期和这这~
, 的版本~号µC/OS-II
这这这是否按下这~以定是决否返回到。TaskStart()ESCDOS其余个——任这基于相同的代这每任这在个屏随幕上机的10Task();
位置这示一个到的字。数09
1.07.01 main()
例基本上和最初中的第一例子做一这的个笔事~但是1µC/OS
者整理了其中的代这~且在并屏笔幕上加了彩色这示。同这者使用原的据这型;来数等,这明来向下兼UBYTE, UWORDµC/OS-II容。
程序整从清个屏屏幕这始~这的是保这幕上不留有以前的main()
下的这示。注意~者定这了笔白色的字符和黑色的背DOS[L1.5(1)]
景色。然要这既屏幕~所以可以只定这背景色而不定这前景色~但是这这在退回之后~用这就什这也看不这了。这也是这什这这要定这DOS
一可这的前个景色。
要用这在使用任何服这之前先这用。它会µC/OS-IIOSInit() [L1.5(2)]
建立任这,空这任这和这这任这~前者在有其任这这于就这这这两个没它
运行~后者这算的利用率。CPU
L 1.5main().程序这 清
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE +
DISP_BGND_BLACK); (1)
OSInit(); (2)
PC_DOSSaveReturn(); (3)
PC_VectSet(uCOS, OSCtxSw); (4)
RandomSem = OSSemCreate(1); (5)
OSTaskCreate(TaskStart, (6)
(void *)0,
(void *)&TaskStartStk[TASK_STK_SIZE-1],
0);
OSStart(); (7)}
当前这境是通这这用来保存的。DOSPC_DOSSaveReturn()[L1.5(3)]
这使得用这可以返回到有行没运以前的这境。跟随µC/OS-IIDOS
清这中的程序可以看到做了多很事L1.6PC_DOSSaveReturn()
情。首先这置这PC_DOSSaveReturn()PC_ExitFlag
~这明用这不是要返回~然后初始化FALSE[L1.6(1)]DOS
这~因这这这量在个将中这减~OSTickDOSCtr1[L1.6(2)]OSTickISR()
而将个使得这这量在中减后这这。然后~0OSTickISR()1255
将的这这这拍这理;,存入PC_DOSSaveReturn()DOS tick handler
一自由向量表入口中个~以便这的这这这拍这[L1.6(3)-(4)]µC/OS-II
理所这用。接着这用;,~它PC_DOSSaveReturn()jmp[L1.6(5)]将状即称这理器这;所有寄存器的这,存入被这的这PC_JumpBuf
构之中。保存这理器的全部寄存器使得程序返回到
并且在这用;,之后立这行。因这即PC_DOSSaveReturn()setjmp
被初始化这。PC_ExitFlagFALSE[L1.6(1)]PC_DOSSaveReturn()跳这状这这句 回到;,函。如果用这想要数返if[L1.6(6)–(9)] main
回到~可以这用 程序这 清~这置它DOSPC_DOSReturn()(L 1.7)
这~且这行并;,这句~这这这PC_ExitFlagTRUElongjmp[L1.7(2)]理器将跳回 在这用 之后PC_DOSSaveReturn()[setjmp()]
~此这这~故这句以后的代这得以将[L1.6(5)]PC_ExitFlagTRUEif
这行。 将这这这拍改这 ~恢这PC_DOSSaveReturn()18.2Hz[L1.6(6)]
这这这拍中服这断~清屏幕~通这返回PC [L1.6(7)][L1.6(8)]exit(0)
。DOS [L1.6(9)]
程序这 清L 1.6保存DOS这境。.
void PC_DOSSaveReturn (void)
{
PC_ExitFlag = FALSE; (1)
OSTickDOSCtr = 8; (2)
PC_TickISR = PC_VectGet(VECT_TICK); (3)
OS_ENTER_CRITICAL();
PC_VectSet(VECT_DOS_CHAIN, PC_TickISR);
(4)
OS_EXIT_CRITICAL();
Setjmp(PC_JumpBuf); (5)
if (PC_ExitFlag == TRUE) {
OS_ENTER_CRITICAL();
PC_SetTickRate(18); (6)
PC_VectSet(VECT_TICK, PC_TickISR);
(7)
OS_EXIT_CRITICAL();
PC_DispClrScr(DISP_FGND_WHITE +
DISP_BGND_BLACK); (8)
exit(0); (9)
}
}
程序这 清L 1.7这置返回DOS 。
void PC_DOSReturn (void)
{
PC_ExitFlag = TRUE; (1)
longjmp(PC_JumpBuf, 1); (2)}
这在回到;,这函~在程序这 个数清中~;,这mainL 1.5main
用来这置中的 寄存器切这。任这这的PC_VectSet()µCOS-IICPU
寄存器切这由指令来笔分配向量地址。者使用向CPU80x86 INT
量;即,~因这它未被和使用。0x80128DOSBIOS
这里用了一信量保这个号来这中的这生随数机的函Borland C/C++
数~之所以使用信量保这一下~是因这者不知号笔个道这[L1.5(5)]
函是数笔将号否具这可重入性~者假这其不具这~初始化信量这置这~意思是在某一这刻只有一任这可以这用个随数数机这生函。1
在这始多任这之前~者建立了一笔个叫做的任这TaskStart()
~在这多任这启之前用这至少要先建立一任这个[L1.5(6)]OSStart(),这一点非常重要。不这这做用这的这用程序将会崩这。这这上~[L1.5(7)]
如果用这要这算的利用率这~也需要先建立一任这。个CPUµCOS-II的这这任这要求在整一个内没它运秒这有任何其任这行。如果用这在启它这多任这之前要建立其任这~必这保这用这的任这代这这控全局这量
和延这程序 即这用 的这行~直到这这个OSStatRdy[OSTimeDly()]量这成。这表明的利用率这这函已这数采集到了TRUEµC/OS-IICPU
数据。
1.07.02 TaskStart()
例中的主要工作由来完成。函的示意数1TaskStart()TaskStart()代这如程序这 清所示。首先在屏个幕这端这示一这这~L 1.8TaskStart()
这明这是例。然后这中~以改这中向量~这其指向断断1 [L1.8(1)]
的这这这拍这理~而后~改这这这这拍率~从的 µC/OS-IIDOS18.2Hz 这这 。在这理器改这中向量这以及系这有完全断没初200Hz [L1.8(3)]
始化前~然不希望有中打入当断,注意;,这函个数这程main(序这 清在系这初始化的这候并没将断有中向量这置成L 1.5)µC/OS-的这这这拍这理程序~做嵌入式这用这~用这必这在第一任这中打这个II
这这这拍中。断
程序这 清L 1.8建立其任这的任这。它
void TaskStart (void *data)
{
Prevent compiler warning by assigning ‘data’ to itself;
Display banner identifying this as EXAMPLE #1; (1)
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); (2)
PC_SetTickRate(200); (3)
OS_EXIT_CRITICAL();
Initialize the statistic task by calling ‘OSStatInit()’; (4)
Create 10 identical tasks; (5)
for (;;) {
Display the number of tasks created;
Display the % of CPU used;
Display the number of task switches in 1 second;
Display uC/OS-II’s version number
If (key was pressed) {
if (key pressed was the ESCAPE key) {
PC_DOSReturn();
}
}
Delay for 1 Second;
}
}
在建立其他任这之前~必这这用来确定用这的OSStatInit()[L1.8(4)]
有多快~如程序这清所示。在一这始~就自将PCL1.9OSStatInit()
身延这了这这这两个它与断拍~这这就可以这这这拍中同步。因[L1.9(1)]
此~必这在这这这拍启这之后这用~否这~用这的这用程序OSStatInit()
就会当崩这。这用这~一个位的这器数µC/OS-IIOSStatInit()32
被这清~这生一延这~这延这使并另个个OSIdleCtr0 [L1.9(2)]
挂起。此这~没它有这的任这可以这行~只能这OSStatInit()uCOS-II
行空这任这;的部任这,。空这任这是一无这的内个它循这~µC/OS-II
不的这增断。秒以后~重新这始OSIdleCtr[L1.9(3)]1uCOS-II
~且并将保存在中。OSStatInit()OSIdleCtrOSIdleMax[L1.9(4)
所以是所能到的最大这。而用这再增加达当OSIdleMaxOSIdleCtr
其他这用代这这~空这任这就不会占用那这多的这这。CPUOSIdleCtr
不可能到那这多的这~;如果这这程序每达数秒这位一次
,利用率的这算由中的函OSIdleCtrCPUµC/OS-II OSStatTask()
数来个当完成~这任这每秒这行一次。而置这OSStatRdy
表示将这这的利用率。TRUE[L1.9(5)],µC/OS-IICPU
程序这 清L 1.9这这CPU速度。
void OSStatInit (void)
{
OSTimeDly(2); (1)
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; (2)
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC); (3)
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; (4)
OSStatRdy = TRUE; (5)
OS_EXIT_CRITICAL();
}
;,1.07.03TaskN
将返回到。这在~用这可以建立个同这OSStatInit()TaskStart()10的任这;所有任这共享同一段代这,。所有任这都由中TaskStart()建立~由于的这先这这;最高,~新任这建立后不这行TaskStart()0
任这这度。所有任这都建立完成后~当将这入无限循这之TaskStart()中~在屏并幕上这示这这信息~这这是否有这按下~如果有没ESC
按这这入~这延这一秒这始下一次循这~如果在这期这用这按下了ESC这~将这用返回系这。TaskStart()PC_DOSReturn()DOS
程序这清这出了任这的代这。任这一这始~这用这L1.10OSSemPend()取信量号程序这清;也就是禁止其他任RandomSem [L1.10(1)]这行这段代这运—这者注,~然后这用的这函数Borland C/C++
;,这得一来个随数机程序这清~此这这random[L1.10(2)]
;,函是不可重入的~所以数个将号任这这流这得信量~random10
并数当这用这函。这算出和坐这后程序这清~任这这放信xy[L1.10(3)]号随号量。后任这在这算的坐这这这示其任这;~任这建立这的这这,0-9
程序这清。最后~任这延这一这这这个拍程序这清[L1.10(4)][
~等待这入下一次循这。系这中每任这每个秒这行次~L1.10(5)]200
个将任这每秒这切这次。102000
L 1.10程序这 清在屏随数幕上这示机位置这示字的任这。
void Task (void *data)
{
UBYTE x;
UBYTE y;
UBYTE err;
for (;;) {
OSSemPend(RandomSem, 0, &err); (1)
x = random(80); (2)
y = random(16);
OSSemPost(RandomSem);
(3)
PC_DispChar(x, y + 5, *(char *)data,
DISP_FGND_LIGHT_GRAY);(4)
OSTimeDly(1); (5)
}
}
例1.082
例使用了这这展功能的任这建立函数;,和2OSTaskCreateExt
的堆这这这操作;要使用堆这这这操作必这用uCOS-II
;,建立任这—这者注,。用这不知当道这这这任这OSTaskCreateExt
分配多少堆这空这这~堆这这这功能是有用的。在这例子里~先分很个
配足这的堆这空这这任这~然后用堆这这这操作看看任这到底需要多少
堆这空这。这然~任这要行运并况足这这这这~要考这各这情才能得到正确数决据。最后定的堆这大小这要考这系这今后的这展~一般多分配
,~,或者更多。如果系这这这定性要求高~这这这多一倍以上。1025
的堆这这这功能要求任这建立这堆这清零。uCOS-II
可以这行此这操作;这置这这OSTaskCreateExt()
和打这此OS_TASK_OPT_STK_CHKOS_TASK_OPT_STK_CLR这操作,。如果任这行这程中要这行建立、这除任这的运操作~这这这置好上述的这这~保任这建立后确清堆这是空的。同这要意这到
这行堆这清很零操作是一这这这的工作~而且取OSTaskCreateExt()
决于堆这的大小。这行堆这这这操作的这候~从这底向这这搜索uCOS-II非元素参看这~同这用一这这器这这个数元素的。个数0(F 1.1)0
例的磁这文件这~包含它个2\SOFTWARE\uCOS-II\EX2_x86L9任这。加上本身的任这,空这任这;两个,和这这任uCOS-IIidle task这。例与一这;,由;,函建立~其数功能是建1TaskStartmain
立其他任这在并屏数幕上这示如下的这这据,
, 每秒这任这切这的次~数
, 利用率的百分比~CPU
, 当前日期和这这~
, 的版本~号uCOS_II
这F 1.1µC/OS-II stack checking.
1.08.01 main()
例的函和例数的看起来参清差不多;看程序这2main()1
,~但是有这不同。第一~两函这用数L1.11main()
程序这清来初始化定这器这这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(); (1)
OSTaskCreateExt(TaskStart, (2)
(void *)0,
&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()需要五个参数;一共个,,任这的~一指向任这个堆这这底的9ID
指这~堆这的大小;以堆这这元这这位~中这字,~一指向个80X86
用这定这的这展数构个据这的指这~和一用于指定这任这操作的TCB
这量。这这量的一这这就是用这定个来堆这这这是否允这。例中uCOS-II2并没有用到这展数构据这指这。TCB
1.08.02TaskStart()
程序这清列出了的这这。前五这操作和例中相同。L1.12TaskStart()1
;,建立了这两个箱~分这提供这任这和任这程序这清TaskStart45[
。除此之外~这建立了一这这这示这这和个日期的任这。L1.12(1)]
L 1.12TaskStart().程序这 清的这这。
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()
任这将个这这其他七任这堆这的大小~同这这这函1OSTackStkChk()数的这行这这程序这清~并与来堆这大小一起这示出。[L1.13(1)–(2)]
注意所有堆这的大小都是以字这这这位的。任这每秒这行次程序110[
清这;这隔,。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(); (2)
if (err == OS_NO_ERR) {
sprintf(s, "%3ld %3ld %3ld %5d",
data.OSFree + data.OSUsed,
data.OSFree,
data.OSUsed,
time);
PC_DispStr(19, 12+i, s,
DISP_FGND_YELLOW);
}
}
OSTimeDlyHMSM(0, 0, 0, 100); (3)
}
}
程序这清所示的任这在屏个幕上这示一这这这旋这的指这;用L1.142
横—这~斜这等字符表示这者注,~每旋这一格。200ms
程序这 清L 1.14任这2
void Task2 (void *data)
{
data = data;
for (;;) {
PC_DispChar(70, 15, '|', DISP_FGND_WHITE + DISP_BGND_RED);
OSTimeDly(10);
PC_DispChar(70, 15, '/', DISP_FGND_WHITE + DISP_BGND_RED);
OSTimeDly(10);
PC_DispChar(70, 15, '-', DISP_FGND_WHITE + DISP_BGND_RED);
OSTimeDly(10);
PC_DispChar(70, 15, '\\', DISP_FGND_WHITE + DISP_BGND_RED);
OSTimeDly(10);
}
}
任这程序这 清也这示了任这与相同的一个旋这指这~但是3(L1.15)2
旋这的方向不同。任这在堆这中分配了一大的这~个很数将填堆这3
充掉~使得只需花这少的这这定很来确堆这的利OSTaskStkChk()
用率~尤其是当堆这已这快这的这候。
程序这 清L 1.15任这3
void Task3 (void *data){
char dummy[500];
INT16U i;
data = data;
for (I = 0; i < 499; i++) {
dummy[i] = '?';
}
for (;;) {
PC_DispChar(70, 16, '|', DISP_FGND_WHITE +
DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '\\', DISP_FGND_WHITE +
DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '-', DISP_FGND_WHITE +
DISP_BGND_BLUE);
OSTimeDly(20);
PC_DispChar(70, 16, '/', DISP_FGND_WHITE +
DISP_BGND_BLUE);
OSTimeDly(20);
}
}
任这程序这清向任这这送消息并确等待这程序这清4(L1.16)5[
。这送的消息是一指向字符的指这。每任这个当从任这L1.16(1)]45收到这确程序这清就这这的将这加再这送程序这清[L1.16(2)],ASCII1[
~这果是不的这断送“。L1.16(3)]ABCDEFG....”程序这 清L 1.16任这4
void Task4 (void *data){
char txmsg;
INT8U err;
data = data;
txmsg = 'A';
for (;;) {
while (txmsg <= 'Z') {
OSMboxPost(TxMbox, (void *)&txmsg);
(1)
OSMboxPend(AckMbox, 0, &err); (2)
txmsg++; (3)
}
txmsg = 'A';
}
}
当任这程序这清接收消息后程序这清;这送的5 [L1.17][L1.17(1)]
字符,~就消将屏息这示到幕上程序这清~然后延这[L1.17(2)]1秒程序这清~再向任这这送确这信息。[L1.17(3)]4
程序这 清L 1.17任这5
void Task5 (void *data)
{
char *rxmsg;
INT8U err;
data = data;
for (;;) {
rxmsg = (char *)OSMboxPend(TxMbox, 0, &err);
(1)
PC_DispChar(70, 18, *rxmsg, DISP_FGND_YELLOW+DISP_BGND_RED);(2)
OSTimeDlyHMSM(0, 0, 1, 0); (3)
OSMboxPost(AckMbox, (void *)1); (4)
}
}
函数程序这清这示前当日期和这这~每秒更新一次。TaskClk()[L1.18]
程序这 清L 1.18这这这示任这
void TaskClk (void *data)
{
Struct time now;
Struct date today;
char s[40];
data = data;
for (;;) {
PC_GetDateTime(s);
PC_DispStr(0, 24, s, DISP_FGND_BLUE +
DISP_BGND_CYAN);
OSTimeDly(OS_TICKS_PER_SEC);
}
}
例1.093
例中使用了这多提供的附加功能。任这使用了3uCOS-II3
中的这展数构据这~用这定这的任这切这这外OSTaskCreateExt()TCB
接口函;数,~用这定这的这这任这;OSTaskSwHook()statistic
,的这外接口函;数,以及消息这列。例task OSTaskStatHook()的磁这文件是~包括它个任这。3\SOFTWARE\uCOS-II\EX3_x86L9除了空这任这;,和这这任这;,~这有个idle taskstatistic task 7任这。例与~例一这~由;,函建立~其数功12TaskStart()main
能是建立其他任这~这示这这信并息。
1.09.01 main()
函数程序这清和例中的相不多~不同的是在用这main()[L1.19]2
定这的这展数构个称据这中可以保存每任这的名程序这清TCB[
;这展这的明在构声中定这~也可看程序参L1.19(1)]INCLUDES.H清这,。者定这了笔个来字这存放任这名;包括空格,程L1.2030[
序这清。本例中有用到没堆这这这操作~中禁止L1.20(1)]TaskStart()
这操作程序这清。[L1.19(2)]
程序这 清L 1.19例3的main()函数
void main (void)
{
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
PC_ElapsedInit();
Strcpy(TaskUserData[TASK_START_ID].TaskName, "StartTask"); (1)
OSTaskCreateExt(TaskStart,
(void *)0,
&TaskStartStk[TASK_STK_SIZE-1],
TASK_START_PRIO,
TASK_START_ID,
&TaskStartStk[0],
TASK_STK_SIZE,
&TaskUserData[TASK_START_ID],
0); (2)
OSStart();
}
程序这 清L 1.20TCB这展数构据这。
typedef struct {
char TaskName[30]; (1)
INT16U TaskCtr;
INT16U TaskExecTime;
INT32U TaskTotExecTime;
} TASK_USER_DATA;
任这1.09.02
的这这如程序这清所示~例与有这不同,TaskStart()L1.2123
, 这任这~~建立了一消个息这列程序这清123[
~L1.21(1)]
, 每任这都有一名字~保存在任这的个个这展数TCB
据这中构程序这清~[L1.21(2)]
, 禁止堆这这这。
程序这 清L 1.21TaskStart()的这这。
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 a message queue; (1)
Create a task that will display the date and time on the
screen;
Create 5 application tasks with a name stored in the TCB
ext.; (2)
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[L1.22(1)]
消息这送完成程序这清。这段这这可以这接收消息的任这这示[L1.22(2)]
收到的消息。这送的消息有三这。
程序这 清L 1.22任这1。
void Task1 (void *data)
{
char one = '1';
char two = '2';
char three = '3';
data = data;
for (;;) {
OSQPost(MsgQueue, (void *)&one); (1)
OSTimeDlyHMSM(0, 0, 1, 0); (2)
OSQPost(MsgQueue, (void *)&two);
OSTimeDlyHMSM(0, 0, 0, 500);
OSQPost(MsgQueue, (void *)&three);
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
任这这于等待消息的起这~且不这定最大等挂状待这这程序这清2[
。所以任这将当一直等待直到收到消息。收到消息后~L1.23(1)]2
任这这示消息并且延这程序这清~延这的这这可以2500mS[L1.23(2)]使任这这这消息这列。3
程序这 清L 1.23任这2。
void Task2 (void *data){
INT8U *msg;
INT8U err;
data = data;
for (;;) {
msg = (INT8U *)OSQPend(MsgQueue, 0, &err);
(1)
PC_DispChar(70, 14, *msg, DISP_FGND_YELLOW+DISP_BGND_BLUE); (2)
OSTimeDlyHMSM(0, 0, 0, 500); (3)
}
}
任这同这这于等待消息的起这~但是这定了等挂状它待这束这这3
程序这清。如果有消息来到~任这将号这示消息250mS[L1.24(1)]3程序这清~如果超这了等待这这~任这就这示“;意这[L1.24(3)]3T”
,程序这清。timeout[L1.24(2)]
L 1.243程序这 清任这
void Task3 (void *data){
INT8U *msg;
INT8U err;
data = data;
for (;;) {
msg = (INT8U *)OSQPend(MsgQueue,
OS_TICKS_PER_SEC/4, &err); (1)
If (err == OS_TIMEOUT) {
PC_DispChar(70,15,'T',DISP_FGND_YELLOW+D
ISP_BGND_RED); (2)
} else {
PC_DispChar(70,15,*msg,DISP_FGND_YELLO
W+DISP_BGND_BLUE);(3)
}
}
}
任这的操作只是这从箱这送程序这清和接收程序这清4[L1.25(1)][
~这使得用这可以这量任这在自己上这行的这这。任这每L1.25(2)]PC4
这行一次程序这清。10mS[L1.25(3)]
程序这 清L 1.25任这4。
void Task4 (void *data){
OS_EVENT *mbox;
INT8U err;
data = data;
mbox = OSMboxCreate((void *)0);
for (;;) {
OSMboxPost(mbox, (void *)1); (1)
OSMboxPend(mbox, 0, &err); (2)
OSTimeDlyHMSM(0, 0, 0, 10); (3)
}
}
任这除了延这一这这这个拍以外什这也不做程序这清。注意5[L1.26(1)]所有的任这都这这这用的函~等数待延这这束或者事件的这uCOS-II
生而这出。如果始这占用~这使将低这先这的任这无法得到CPUCPU
。CPU
程序这 清L 1.26任这5。
void Task5 (void *data)
{
data = data;
for (;;) {
OSTimeDly(1); (1)
}
}
同这~ 函数程序这清这示前当日期和这这。TaskClk()[L1.18]
注意1.09.03
有些程序的这这只有这您仔这这一这才能理解。中有EX3L.CEX3L.C
函的代这~这函用这量每任这的这行这这~数数来个OSTaskSwHook()
可以用这这每一任这的这度这来个个运率~也可以这这每任这行这这的这和。这些信息将个存这在每任这的这展数构据这中。每次任这切这TCB
的这候都被这用。将OSTaskSwHook()
每次任这切这这生的这候~先这用OSTaskSwHook()
函数程序这清来运这取任这的行这这PC_ElapsedStop()[L1.27(1)] 程序这清~要和[L1.27(1)]PC_ElapsedStop()PC_ElapsedStart()
一起使用~上述函用到了两个数的定这器;,。其PC2timer 2中功能这这定这器这始这~而启数PC_ElapsedStart()
功能这这取定这器的这~然后清数零~这下一次这PC_ElapsedStop()
做准这。定这器从数将取得的这拷这到这量程序这清。time[L1.27(1)]然后这用重新这定这器做启OSTaskSwHook()PC_ElapsedStart()下一次这数程序这清。需要注意的是~系这这后~第一启[L1.27(2)]
次这用是在初始化代这中~所以第一次任这切这PC_ElapsedStart()
这用所得到的这这有这这意这~但这这有什这数没没PC_ElapsedStop()
影。响如果任这分配了这展数构据这程序这清~其中TCB[L1.27(4)]的这器数这行累加程序这清。可以这这任这TaskCtr[L1.27(5)]TaskCtr被切这的这繁程度~也可以这这某个运任这是否在行。
程序这清用这这函来数从切入到切出的TaskExecTime [L1.27(6)]
运行这这~程序这清这这任这这的行这这。运TaskTotExecTime[L1.27(7)]这这每任这的上述这量~可以这个两个内个算出一段这这各任这占用
的百分比。函这示这些这这信数会息。CPUOSTaskStatHook()
L 1.27OSTaskSwHook()程序这 清用这定这的
void OSTaskSwHook (void)
{
INT16U time;
TASK_USER_DATA *puser;
time = PC_ElapsedStop(); (1)
PC_ElapsedStart(); (2)
puser = OSTCBCur->OSTCBExtPtr; (3)
if (puser != (void *)0) { (4)
puser->TaskCtr++; (5)
puser->TaskExecTime = time; (6)
puser->TaskTotExecTime += time; (7)
}
}
本例中的这这任这;,这用这外接口函将数statistic task
;这置文件中的OSTaskStatHook()OS_CFG.H
这允这这外接口函,。数这这任这每秒运行一OS_TASK_STAT_EN1
次~本例中用这来并算这示各任这占用的OSTaskStatHook()CPU
情。况
函中首先这数运算所有任这的行这这程序这清OSTaskStatHook()[
~用字这示这来将数字符程序这清L1.28(1)]DispTaskStat()ASCII[
。然后是这算每任这行这这的个运百分比程序这清L1.28(2)][
~这示在合适的位置上 程序这清。L1.28(3)][L1.28(4)]
L 1.28OSTaskStatHook().程序这 清用这定这的
void OSTaskStatHook (void)
{
char s[80];
INT8U i;
INT32U total;
INT8U pct;
total = 0L;
for (I = 0; i < 7; i++) {
total += TaskUserData[i].TaskTotExecTime;
(1)
DispTaskStat(i); (2)
}
if (total > 0) {
for (i = 0; i < 7; i++) {
pct = 100 * TaskUserData[i].TaskTotExecTime /
total; (3)
sprintf(s, "%3d %%", pct);
PC_DispStr(62, i + 11, s, DISP_FGND_YELLOW); (4)
}
}
if (total > 1000000000L) {
for (i = 0; i < 7; i++) {
TaskUserData[i].TaskTotExecTime = 0L;
}
}
}