ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:21.35KB ,
资源ID:3515986      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3515986.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ucosii中文书邵贝贝第10章.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ucosii中文书邵贝贝第10章.docx

1、ucosii中文书邵贝贝第10章第10章从 C/OS 升级到 C/OS-II本章描述如何从C/OS 升级到 C/OS-II。如果已经将C/OS移植到了某类微处理器上,移植C/OS-II所要做的工作应当非常有限。在多数情况下,用户能够在1个小时之内完成这项工作。如果用户熟悉C/OS的移植,可隔过本章前一部分直接参阅10.05节。10.1 目录和文件用户首先会注意到的是目录的结构,主目录不再叫 SOFTWAREuCOS。而是叫 SOFTWAREuCOS-II。所有的C/OS-II文件都应放在用户硬盘的SOFTWAREuCOS-II 目录下。面向不同的微处理器或微处理器的源代码一定是在以下两个或三个

2、文件中: OS_CPU.H, OS_CPU_C.C,或许还有OS_CPU_A.ASM.。汇编语言文件是可有可无的,因为有些C编译程序允许使用在线汇编代码,用户可以将这些汇编代码直接写在 OS_CPU_C.C.中。与微处理器有关的特殊代码,即与移植有关的代码,在 C/OS 中是放在用微处理器名字命名的文件中的,例如,Intel 80x86的实模式(Real Mode),在大模式下编译(Large Modle)时,文件名为Ix86L.H, Ix86L_C.C, 和Ix86L_A.ASM.。表 L10.1在C/OS-II中重新命名的文件.SOFTWAREuCOSIx86LSOFTWAREuCOS-I

3、IIx86LIx86L.HOS_CPU.HIx86L_A.ASMOS_CPU_A.ASMIx86L_C.COS_CPU_C.C升级可以从这里开始:首先将C/OS目录下的旧文件复制到C/OS-II 的相应目录下,并改用新的文件名,这比重新建立一些新文件要容易许多。表10.2给出来几个与移植有关的新旧文件名命名法的例子。表 L10.2对不同微处理器从C/OS到C/OS-II,要重新命名的文件.SOFTWAREuCOSI80251SOFTWAREuCOS-III80251I80251.HOS_CPU.HI80251.COS_CPU_C.CSOFTWAREuCOSM680x0SOFTWAREuCOS-

4、IIM680x0M680x0.HOS_CPU.HM680x0.COS_CPU_C.CSOFTWAREuCOSM68HC11SOFTWAREuCOS-IIM68HC11M68HC11.HOS_CPU.HM68HC11.COS_CPU_C.CSOFTWAREuCOSZ80SOFTWAREuCOS-IIZ80Z80.HOS_CPU.HZ80_A.ASMOS_CPU_A.ASMZ80_C.COS_CPU_C.C10.2 INCLUDES.H用户应用程序中的INCLUDES.H 文件要修改。以80x86 实模式,在大模式下编译为例,用户要做如下修改: 变目录名 C/OS 为 C/OS-II 变文件名 I

5、X86L.H 为 OS_CPU.H 变文件名UCOS.H 为 uCOS_II.H新旧文件如程序清单 L10.1和 L10.2所示10.3 OS_CPU.HOS_CPU.H 文件中有与微处理器类型及相应硬件有关的常数定义、宏定义和类型定义。10.3.1 与编译有关的数据类型s为了实现 C/OS-II,用户应定义6个新的数据类型:INT8U、INT8S、INT16U、NT16S、INT32U、和INT32S。这些数据类型有分别表示有符号和无符号8位、16位、32位整数。在C/OS中相应的数据类型分别定义为:UBYTE、BYTE、UWORD、WORD、ULONG和LONG。用户所要做的仅仅是复制C/

6、OS中数类型并修改原来的UBYTE为INT8U,将BYTE为INT8S,将UWORD修改为INT16U等等,如程序清单 L10.3所示。程序清单 L10.1 C/OS 中的 INCLUDES.H./* INCLUDES.H*/#include #include #include #include #include #include #include SOFTWAREUCOSIX86LIX86L.H#include OS_CFG.H#include SOFTWAREUCOSSOURCEUCOS.H程序清单 L10.2 C/OS-II 中的 INCLUDES.H./* INCLUDES.H*/#i

7、nclude #include #include #include #include #include #include SOFTWAREuCOS-IIIX86LOS_CPU.H#include OS_CFG.H#include SOFTWAREuCOS-IISOURCEuCOS_II.H程序清单 L10.3C/OS到C/OS-II 数据类型的修改./* uC/OS data types: */typedef unsigned char UBYTE; /* Unsigned 8 bit quantity */typedef signed char BYTE; /* Signed 8 bit q

8、uantity */typedef unsigned int UWORD; /* Unsigned 16 bit quantity */typedef signed int WORD; /* Signed 16 bit quantity */typedef unsigned long ULONG; /* Unsigned 32 bit quantity */typedef signed long LONG; /* Signed 32 bit quantity */* uC/OS-II data types */typedef unsigned char INT8U; /* Unsigned 8

9、 bit quantity */typedef signed char INT8S; /* Signed 8 bit quantity */typedef unsigned int INT16U; /* Unsigned 16 bit quantity */typedef signed int INT16S; /* Signed 16 bit quantity */typedef unsigned long INT32U; /* Unsigned 32 bit quantity */typedef signed long INT32S; /* Signed 32 bit quantity */

10、在C/OS中,任务栈定义为类型OS_STK_TYPE,而在C/OS-II中任务栈要定义类型OS_STK.,为了免于修改所有应用程序的文件,可以在OS_CPU.H中建立两个数据类型,以Intel 80x86 为例,如程序清单 L10.4所示。程序清单 L10.4 C/OS 和 C/OS-II任务栈的数据类型#define OS_STK_TYPE UWORD /* 在 uC/OS 中 */#define OS_STK INT16U /* 在 uC/OS-II 中 */10.3.2 OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()C/OS-II和C/OS一样,分别定义两个

11、宏来开中断和关中断:OS_ENTER_CRITICAL()和 OS_EXIT_CRITICAL()。在C/OS向C/OS-II升级的时候,用户不必动这两个宏。.10.3.3 OS_STK_GROWTH大多数微处理器和微处理器的栈都是由存储器高地址向低地址操作的,然而有些微处理器的工作方式正好相反。C/OS-II设计成通过定义一个常数OS_STK_GROWTH来处理不同微处理器栈操作的取向:对栈操作由低地址向高地址增长,设OS_STK_GROWTH 为 0对栈操作由高地址向低地址递减,设OS_STK_GROWTH 为 1有些新的常数定义(#define constants )在C/OS中是没有的

12、,故要加到OS_CPU.H中去。10.3.4 OS_TASK_SW()OS_TASK_SW()是一个宏,从C/OS升级到C/OS-II时,这个宏不需要改动。当C/OS-II从低优先级的任务向高优先级的任务切换时要用到这个宏,OS_TASK_SW()的调用总是出现在任务级代码中。 10.3.5 OS_FAR因为Intel 80x86的结构特点,在C/OS中使用过OS_FAR 。这个定义语句(#define )在C/OS-II 中去掉了,因为这条定义使移植变得不方便。结果是对于Intel 80x86,如果用户定义在大模式下编译时,所有存储器属性都将为远程(FAR).在C/OS-II中,任务返回值类

13、型定义如程序清单L10.5所示。用户可以重新编辑所有OS_FAR的文件,或者在C/OS-II中将OS_FAR定义为空,去掉OS_FAR,以实现向C/OS-II的升级。程序清单 L10.5 在 C/OS 中任务函数的定义void OS_FAR task (void *pdata) pdata = pdata; while (1) . . 10.4 OS_CPU_A.ASM移植C/OS 和C/OS-II 需要用户用汇编语言写4个相当简单的函数。OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()10.4.1 OSStartHighRdy()在C/OS-I

14、I中,OSStartHighRdy ()要调用OSSTaskSwHook()。OSTaskSwHook()这个函数在C/OS中没有。用户将最高优先级任务的栈指针装入CPU之前要先调用OSTaskSwHook()。还有, OSStartHighRdy要在调用OSTaskSwHook()之后立即将OSRunning设为1。程序清单L10.6 给出OSStartHighRdy()的示意代码。.C/OS只有其中最后三步。程序清单 L10.6 OSStartHighRdy()的示意代码OSStartHighRdy: Call OSTaskSwHook(); 调用OSTaskSwHook(); Set O

15、SRunning to 1; 置 OSRunning 为 1;Load the processor stack pointer with OSTCBHighRdy-OSTCBStkPtr;将 OSTCBHighRdy-OSTCBStkPtr 装入处理器的栈指针; POP all the processor registers from the stack; 从栈中弹出所有寄存器的值; Execute a Return from Interrupt instruction; 执行中断返回指令;10.4.2 OSCtxSw()在C/OS-II中,任务切换要增作两件事,首先,将当前任务栈指针保存到当

16、前任务控制块TCB后要立即调用OSTaskSwHook()。其次,在装载新任务的栈指针之前必须将OSPrioCur设为OSPrioHighRdy 。OSCtxSw()的示意代码如程序清单L10.7所示。C/OS-II加上了步骤 L10.7(1)和(2)。程序清单 L10.7 OSCtxSw()的示意代码OSCtxSw:PUSH processor registers onto the current tasks stack;所有处理器寄存器的值推入当前任务栈; Save the stack pointer at OSTCBCur-OSTCBStkPtr; Call OSTaskSwHook()

17、; 1) OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; (2)Load the processor stack pointer with OSTCBHighRdy-OSTCBStkPtr;将 OSTCBHighRdy-OSTCBStkPtr 装入处理器的栈指针; POP all the processor registers from the stack; 从栈中弹出所有寄存器的值; Execute a Return from Interrupt instruction; 10.4.3 OSIntCtxSw()如同上述函数一样,在C/O

18、S-II.中,OSCtxSw()也增加了两件事。首先,将当前任务的栈指针保存到当前任务的控制块TCB后要立即调用OSTaskSwHook()。其次,在装载新任务的栈指针之前必须将OSPrioCur 设为OSPrioHighRdy。程序清单L10.8给出OSIntCtxSw()的示意代码。C/OS-II.中增加了L10.8(1)和 (2)。程序清单 L10.8 OSIntCtxSw()的示意代码OSIntCtxSw(): Adjust the stack pointer to remove call to OSIntExit(), locals in OSIntExit()and the cal

19、l to OSIntCtxSw();调整由于调用上述子程序引起的栈指针值的变化;Save the stack pointer at OSTCBCur-OSTCBStkPtr;保存栈指针到OSTCBCur-OSTCBStkPtr; Call OSTaskSwHook(); 调用OSTaskSwHook();(1) OSTCBCur = OSTCBHighRdy; OSPrioCur = OSPrioHighRdy; (2)Load the processor stack pointer with OSTCBHighRdy-OSTCBStkPtr; 将 OSTCBHighRdy-OSTCBStkP

20、tr 装入处理器的栈指针; POP all the processor registers from the stack; 从栈中弹出所有寄存器的值; Execute a Return from Interrupt instruction; 执行中断返回指令;10.4.4 OSTickISR()在C/OS-II和C/OS 中,这个函数的代码是一样,无须改变。10.5 OS_CPU_C.C移植 C/OS-II 需要用C语言写6个非常简单的函数:OSTaskStkInit()OSTaskCreateHook()OSTaskDelHook()OSTaskSwHook()OSTaskStatHook(

21、)OSTimeTickHook()其中只有一个函数OSTaskStkInit()是必不可少的。其它5个只需定义,而不包括任何代码。10.5.1 OSTaskStkInit()在C/OS中,OSTaskCreate()被认为是与使用的微处理器类型有关的函数。实际上这个函数中只有一部分内容是依赖于微处理器类型的。在C/OS-II中,与使用的微处理器类型有关的那一部分已经从函数OSTaskCreate() 中抽出来了,放在一个叫作OSTaskStkInit()的函数中。OSTaskStkInit()只负责设定任务的栈,使之看起来好像中断刚刚发生过,所有的CPU寄存器都被推入堆栈。作为提供给用户的例子

22、,程序清单L10.9给出Intel 80x86实模式,在大模式下编译的 C/OS的OSTaskCreate()函数的代码。程序清单L10.10是同类微微处理器的C/OS-II的OSTaskStkInit()函数的代码。比较这两段代码,可以看出:从 L10.9(1) OS_EXIT_CRIITICAL()到L10.9(2)调用OSTaskStkInit()都抽出来并移到了OSTaskStkInit()中。程序清单L10.9 C/OS 中的 OSTaskCreate()UBYTE OSTaskCreate(void (*task)(void *pd), void *pdata, void *pst

23、k, UBYTE p) UWORD OS_FAR *stk; UBYTE err; OS_ENTER_CRITICAL(); if (OSTCBPrioTblp = (OS_TCB *)0) OSTCBPrioTblp = (OS_TCB *)1; OS_EXIT_CRITICAL(); (1) stk = (UWORD OS_FAR *)pstk; *-stk = (UWORD)FP_OFF(pdata); *-stk = (UWORD)FP_SEG(task); *-stk = (UWORD)FP_OFF(task); *-stk = (UWORD)0x0202; *-stk = (UWO

24、RD)FP_SEG(task); *-stk = (UWORD)FP_OFF(task); *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = (UWORD)0x0000; *-stk = _DS; err = OSTCBInit(p, (void far *)stk

25、); (2) if (err = OS_NO_ERR) if (OSRunning) OSSched(); else OSTCBPrioTblp = (OS_TCB *)0; return (err); else OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); 程序清单 L10.10 C/OS-II中的OSTaskStkInit()void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt) INT16U *stk; opt = opt; stk = (

26、INT16U *)ptos; *stk- = (INT16U)FP_SEG(pdata); *stk- = (INT16U)FP_OFF(pdata); *stk- = (INT16U)FP_SEG(task); *stk- = (INT16U)FP_OFF(task); *stk- = (INT16U)0x0202; *stk- = (INT16U)FP_SEG(task); *stk- = (INT16U)FP_OFF(task); *stk- = (INT16U)0xAAAA; *stk- = (INT16U)0xCCCC; *stk- = (INT16U)0xDDDD; *stk- =

27、 (INT16U)0xBBBB; *stk- = (INT16U)0x0000; *stk- = (INT16U)0x1111; *stk- = (INT16U)0x2222; *stk- = (INT16U)0x3333; *stk- = (INT16U)0x4444; *stk = _DS; return (void *)stk);10.5.2 OSTaskCreateHook()OSTaskCreateHook()在C/OS中没有,如程序清单L10.11所示,在由.C/OS 向C/OS-II升级时,定义一个空函数就可以了。注意其中的赋值语句,如果不把Ptcb赋给Ptcb,有些编译器会产生

28、一个警告错误,说定义的Ptcb变量没有用到。程序清单10.11 C/OS-II 中的OSTaskCreateHook()#if OS_CPU_HOOKS_ENOSTaskCreateHook(OS_TCB *ptcb) ptcb = ptcb;#endif用户还应该使用条件编译管理指令来处理这个函数。只有在OS_CFG.H 文件中将OS_CPU_HOOKS _EN设为1时,OSTaskCreateHook()的代码才会生成。这样做的好处是允许用户移植时可在不同文件中定义钩子函数。 10.5.3 OSTaskDelHook()OSTaskDelHook() 这个函数在C/OS中没有,如程序清单1

29、0.12所示,从C/OS 到C/OS-II,只要简单地定义一个空函数就可以了。注意,如果不用赋值语句将ptcb赋值为ptcb,有些编译程序可能会产生一些警告信息,指出定义的ptcb变量没有用到。程序清单 L10.12 C/OS-II中的OSTaskDelHook().#if OS_CPU_HOOKS_ENOSTaskDelHook(OS_TCB *ptcb) ptcb = ptcb;#endif也还是要用条件编译管理指令来处理这个函数。只有把OS_CFG.H. 文件中的OS_CPU_HOOKS_EN 设为1,OSTaskDelHook()的代码才能生成。这样做的好处是允许用户移植时在不同的文件中定义钩子函数。10.5.4 OSTaskSwHook()OSTaskSwHook() 在C/OS 中也不存在。从C/OS向C/OS-II升级时,只要简单地定义一个空函数就可以了,如程序清单L10.13所示。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1