您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 信息化管理 > 嵌入式实时操作系统uCOS-II[邵贝贝]
第一章:范例在这一章里将提供三个范例来说明如何使用µC/OS-II。笔者之所以在本书一开始就写这一章是为了让读者尽快开始使用µC/OS-II。在开始讲述这些例子之前,笔者想先说明一些在这本书里的约定。这些例子曾经用BorlandC/C++编译器(V3.1)编译过,用选择项产生Intel/AMD80186处理器(大模式下编译)的代码。这些代码实际上是在IntelPentiumIIPC(300MHz)上运行和测试过,IntelPentiumIIPC可以看成是特别快的80186。笔者选择PC做为目标系统是由于以下几个原因:首先也是最为重要的,以PC做为目标系统比起以其他嵌入式环境,如评估板,仿真器等,更容易进行代码的测试,不用不断地烧写EPROM,不断地向EPROM仿真器中下载程序等等。用户只需要简单地编译、链接和执行。其次,使用BorlandC/C++产生的80186的目标代码(实模式,在大模式下编译)与所有Intel、AMD、Cyrix公司的80x86CPU兼容。1.00安装µC/OS-II本书附带一张软盘包括了所有我们讨论的源代码。是假定读者在80x86,Pentium,或者Pentium-II处理器上运行DOS或Windows95。至少需要5Mb硬盘空间来安装uC/OS-II。请按照以下步骤安装:1.进入到DOS(或在Windows95下打开DOS窗口)并且指定C:为默认驱动器。2.将磁盘插入到A:驱动器。3.键入A:INSTALL【drive】注意『drive』是读者想要将µC/OS-II安装的目标磁盘的盘符。INSTALL.BAT是一个DOS的批处理文件,位于磁盘的根目录下。它会自动在读者指定的目标驱动器中建立\SOFTWARE目录并且将uCOS-II.EXE文件从A:驱动器复制到\SOFTWARE并且运行。µC/OS-II将在\SOFTWARE目录下添加所有的目录和文件。完成之后INSTALL.BAT将删除uCOS-II.EXE并且将目录改为\SOFTWARE\uCOS-II\EX1_x86L,第一个例子就存放在这里。在安装之前请一定阅读一下READ.ME文件。当INSTALL.BAT已经完成时,用户的目标目录下应该有一下子目录:l\SOFTWARE这是根目录,是所有软件相关的文件都放在这个目录下。l\SOFTWARE\BLOCKS子程序模块目录。笔者将例子中µC/OS-II用到的与PC相关的函数模块编译以后放在这个目录下。l\SOFTWARE\HPLISTC这个目录中存放的是与范例HPLIST相关的文件(请看附录D,HPLISTC和TO)。HPLIST.C存放在\SOFTWARE\HPLISTC\SOURCE目录下。DOS下的可执行文件(HPLIST.EXE)存放在\SOFTWARE\TO\EXE中。l\SOFTWARE\TO这个目录中存放的是和范例TO相关的文件(请看附录D,HPLISTC和TO)。源文件TO.C存放在\SOFTWARE\TO\SOURCE中,DOS下的可执行文件(TO.EXE)存放在\SOFTWARE\TO\EXE中。注意TO需要一个TO.TBL文件,它必须放在根目录下。用户可以在\SOFTWARE\TO\EXE目录下找到TO.TBL文件。如果要运行TO.EXE,必须将TO.TBL复制到根目录下。l\SOFTWARE\uCOS-II与µC/OS-II相关的文件都放在这个目录下。l\SOFTWARE\uCOS-II\EX1_x86L这个目录里包括例1的源代码(参见1.07,例1),可以在DOS(或Windows95下的DOS窗口)下运行。l\SOFTWARE\uCOS-II\EX2_x86L这个目录里包括例2的源代码(参见1.08,例2),可以在DOS(或Windows95下的DOS窗口)下运行。l\SOFTWARE\uCOS-II\EX3_x86L这个目录里包括例3的源代码(参见1.09,例3),可以在DOS(或Windows95下的DOS窗口)下运行。l\SOFTWARE\uCOS-II\Ix86L这个目录下包括依赖于处理器类型的代码。此时是为在80x86处理器上运行uC/OS-II而必须的一些代码,实模式,在大模式下编译。l\SOFTWARE\uCOS-II\SOURCE这个目录里包括与处理器类型无关的源代码。这些代码完全可移植到其它架构的处理器上。1.01INCLUDES.H用户将注意到本书中所有的*.C文件都包括了以下定义:#includeincludes.hINCLUDE.H可以使用户不必在工程项目中每个*.C文件中都考虑需要什么样的头文件。换句话说,INCLUDE.H是主头文件。这样做唯一的缺点是INCLUDES.H中许多头文件在一些*.C文件的编译中是不需要的。这意味着逐个编译这些文件要花费额外的时间。这虽有些不便,但代码的可移植性却增加了。本书中所有的例子使用一个共同的头文件INCLUDES.H,3个副本分别存放在\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.H,它是针对80x86的实模式,在大模式下编译)。µCOS-II不使用C语言中的short,int,long等数据类型的定义,因为它们与处理器类型有关,隐含着不可移植性。笔者代之以移植性强的整数数据类型,这样,既直观又可移植,如表L1.1所示。为了方便起见,还定义了浮点数数据类型,虽然µC/OS-II中没有使用浮点数。程序清单L1.1可移植型数据类型。TypedefunsignedcharBOOLEAN;TypedefunsignedcharINT8U;TypedefsignedcharINT8S;TypedefunsignedintINT16U;TypedefsignedintINT16S;TypedefunsignedlongINT32U;TypedefsignedlongINT32S;TypedeffloatFP32;TypedefdoubleFP64;#defineBYTEINT8S#defineUBYTEINT8U#defineWORDINT16S#defineUWORDINT16U#defineLONGINT32S#defineULONGINT32U以INT16U数据类型为例,它代表16位无符号整数数据类型。µC/OS-II和用户的应用代码可以定义这种类型的数据,范围从0到65,535。如果将µCO/S-II移植到32位处理器中,那就意味着INT16U不再不是一个无符号整型数据,而是一个无符号短整型数据。然而将无论µC/OS-II用到哪里,都会当作INT16U处理。表1.1是以BorlandC/C++编译器为例,为80x86提供的定义语句。为了和µC/OS兼容,还定义了BYTE,WORD,LONG以及相应的无符号变量。这使得用户可以不作任何修改就能将µC/OS的代码移植到µC/OS-II中。之所以这样做是因为笔者觉得这种新的数据类型定义有更多的灵活性,也更加易读易懂。对一些人来说,WORD意味着32位数,而此处却意味着16位数。这些新的数据类型应该能够消除此类含混不请1.03全局变量以下是如何定义全局变量。众所周知,全局变量应该是得到内存分配且可以被其他模块通过C语言中extern关键字调用的变量。因此,必须在.C和.H文件中定义。这种重复的定义很容易导致错误。以下讨论的方法只需用在头文件中定义一次。虽然有点不易懂,但用户一旦掌握,使用起来却很灵活。表1.2中的定义出现在定义所有全局变量的.H头文件中。程序清单L1.2定义全局宏。#ifdefxxx_GLOBALS#definexxx_EXT#else#definexxx_EXTextern#endif.H文件中每个全局变量都加上了xxx_EXT的前缀。xxx代表模块的名字。该模块的.C文件中有以下定义:#definexxx_GLOBALS#includeincludes.h当编译器处理.C文件时,它强制xxx_EXT(在相应.H文件中可以找到)为空,(因为xxx_GLOBALS已经定义)。所以编译器给每个全局变量分配内存空间,而当编译器处理其他.C文件时,xxx_GLOBAL没有定义,xxx_EXT被定义为extern,这样用户就可以调用外部全局变量。为了说明这个概念,可以参见uC/OS_II.H,其中包括以下定义:#ifdefOS_GLOBALS#defineOS_EXT#else#defineOS_EXTextern#endifOS_EXTINT32UOSIdleCtr;OS_EXTINT32UOSIdleCtrRun;OS_EXTINT32UOSIdleCtrMax;同时,uCOS_II.H有中以下定义:#defineOS_GLOBALS#include“includes.h”当编译器处理uCOS_II.C时,它使得头文件变成如下所示,因为OS_EXT被设置为空。INT32UOSIdleCtr;INT32UOSIdleCtrRun;INT32UOSIdleCtrMax;这样编译器就会将这些全局变量分配在内存中。当编译器处理其他.C文件时,头文件变成了如下的样子,因为OS_GLOBAL没有定义,所以OS_EXT被定义为extern。externINT32UOSIdleCtr;externINT32UOSIdleCtrRun;externINT32UOSIdleCtrMax;在这种情况下,不产生内存分配,而任何.C文件都可以使用这些变量。这样的就只需在.H文件中定义一次就可以了。1.04OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()用户会看到,调用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()两个宏,贯穿本书的所有源代码。OS_ENTER_CRITICAL()关中断;而OS_EXIT_CRITICAL()开中断。关中断和开中断是为了保护临界段代码。这些代码很显然与处理器有关。关于宏的定义可以在OS_CPU.H中找到。9.03.02节详细讨论定义这些宏的两种方法。程序清单L1.3进入正确部分的宏。#defineOS_CRITICAL_METHOD2#ifOS_CRITICAL_METHOD==1#defineOS_ENTER_CRITICAL()asmCLI#defineOS_EXIT_CRITICAL()asmSTI#endif#ifOS_CRITICAL_METHOD==2#defineOS_ENTER_CRITICAL()asm{PUSHF;CLI}#defineOS_EXIT_CRITICAL()asmPOPF#endif用户的应用代码可以使用这两个宏来开中断和关中断。很明显,关中断会影响中断延迟,所以要特别小心。用户还可以用信号量来保护林阶段代码。1.05基于PC的服务PC.C文件和PC.H文件(在\SOFTWARE\BLOCKS\PC\SOURCE目录下)是笔者在范例中使用到的一些基于PC的服务程序。与µC/OS-II以前的版本(即µC/OS)不同,笔者希望集中这些函数以避免在各个例子中都重复定义,也更容易适应不同的编译器。PC.C包括字符显示,时间度量和其他各种服务。所有的函数都以PC_为前缀。1.05.01字符显示为了性能更好,显示函数直接向显示内存区中写数据。在VGA显示器中,显示内存从绝对地址0x000B8000开始(或用段、偏移量表示则为B800:0000)。在单色显示器中,用户可以把#defineconstantDISP_BASE从0xB800改为0xB000。PC.C中的显示函数用x和y坐标来直接向显
本文标题:嵌入式实时操作系统uCOS-II[邵贝贝]
链接地址:https://www.777doc.com/doc-6279283 .html