移植COSII中英文翻译资料

上传人:s9****2 文档编号:510056171 上传时间:2022-10-12 格式:DOC 页数:15 大小:82KB
返回 下载 相关 举报
移植COSII中英文翻译资料_第1页
第1页 / 共15页
移植COSII中英文翻译资料_第2页
第2页 / 共15页
移植COSII中英文翻译资料_第3页
第3页 / 共15页
移植COSII中英文翻译资料_第4页
第4页 / 共15页
移植COSII中英文翻译资料_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《移植COSII中英文翻译资料》由会员分享,可在线阅读,更多相关《移植COSII中英文翻译资料(15页珍藏版)》请在金锄头文库上搜索。

1、移植C/OS-II这篇文章介绍如何将C/OS-II移植到不同的处理器上。所谓移植,就是使一个实时内核能在其他的微处理器上运行。为了方便移植,大部分C/OS-II的代码是用C语言编写的:但是,仍需要用C语言和汇编语言编写一些与处理器硬件相关的代码,这是因为C/OS-II在读/写处理器寄存器时,只能通过汇编语言来实现。由于C/OS-II在设计前就已经考虑了可移植性,所以它的移植相对来说是比较容易的。要使C/OS-II正常运行,处理器必须满足以下要求:(1) 处理器的C编译器能产生可重入型代码:(2) 处理器支持中断,并且能产生定时中断(通常为10-100Hz);(3) 用C语言就可以开关中断;(4

2、) 处理器能支持一定数量的数据存储器的硬件堆栈;(5) 处理器有将堆栈指针以及其他CPU寄存器的内容读出、并存储到堆栈或内存中去的指令;如果已经了解处理器和C编译器的技术细节,那么移植的工作是非常容易的,测试一个像C/OS-II这样的实时内核其实并不复杂,甚至可以在没有任何应用程序下测试,换句话说,就是让内核自己测试自己。有两种原因要这样做:第一,避免使本来就复杂的事情变的更加复杂化;第二,如果出现问题可以知道问题出在内核代码中,而不是应用程序中。刚开始时,可以运行一些简单的任务和时钟节拍中断程序。一旦多任务调度成功运行了,再添加应用程序的任务就更加容易了。1.1 开发工具如前所述移植C/OS

3、-II需要标准的C交叉编译器,并且是针对所使用的CPU的;因为它是一个可剥夺的内核,只能通过C编译器来产生可重入型代码。同时C编译器还要支持汇编语言程序。绝大部分为嵌入式系统设计的C编译器都包括汇编器、链接器、定位器。链接器用来将不同的模块(编译过或汇编过的文件)链接成目标文件;定位器则允许将代码和数据放置在目标处理器的指定内存空间中。所用的C编译器还提供另一种机制,能在C编译器中开中断和关中断。一些编译器允许在C语言源代码中直接插入汇编语句,这就使得插入相应的处理器中的指令开中断和关中断变得容易了。1.2 文件(1)INCLUDES.H文件INCLUDES.H是一个头文件,它出现在每个.C文

4、件的第一行,如下:# include “ includes.h ”INCLUDES.H文件使得工程项目中的每个.C文件无需分别考虑它实际上需要哪些头文件。使用INCLUDES.H文件的唯一缺点就是它可能包含一些与当前要编译的.C文件实际上不相干的头文件。这意味着每个文件的编译时间都会增加;但由于他增加了代码的可移植性,所以还是决定使用这种方法。也可以通过重新编译INCLUDES.H文件来增加头文件,但是头文件必须添加在文件列表的最后。(2) OS_CPU.H文件OS_CPU.H包含了用#define语句定义的、与处理器相关的常数、宏以及类型。OS_CPU.H文件的大体结构如程序清单T1所列:#

5、ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endiftypedef unsigned char BOOLEAN;typedef unsigned char INT8U;/* 无符号8位整数*/typedef signed char INT8S;/* 有符号8位整数*/typedef unsigned int INT16U;/* 无符号16位整数*/typedef signed int INT16S;/* 有符号16位整数*/typedef unsigned long INT32U;/* 无符号32位

6、整数 */typedef signed long INT32S;/* 有符号32位整数*/typedef float FP32;/* 单精度浮点数 */typedef double FP64;/* 双精度浮点数 */typedef unsigned int OS_STK;/* 堆栈入口宽度为16位*/#define OS_ENTER_CRITICAL() ?/* 关中断*/#define OS_EXIT_CRITICAL() ? /* 开中断s */ #define OS_STK_GROWTH 1 /* 定义堆栈方向:1=向下递减,0=向上递增 */#define OS_TASK_SW() ?

7、 程序清单 T1 OS_CPU.H,与编译器相关的数据类型因为不同的微处理器有不同的字长,所以C/OS-II的移植包括了一系列的数据类型的定义,而确保其可移植性。尤其是,C/OS-II代码从不使用C语言中的 short, int 及long等数据类型,因为它们是与编译器相关的,是不可移植的。相反,定义的数据结构等既是可移植的,又很直观。举例来说,INT16U数据类型总是代表16位的无符号整型数。这样C/OS-II就可以断定,声明为该数据类型变量的范围都是065535。将C/OS-II移植到32位的处理器上,就意味着INT16U实际被声明为无符号短整型数,而不是无符号整数,但是,C/OS-II处

8、理的仍然是INT16U。你必须将任务堆栈的数据类型告诉C/OS-II。这是通过为OS_STK声明恰当的C数据类型来实现的。如果处理器的堆栈是32位的,那么就应该将OS_STK声明:为:unsigned int,所有的任务堆栈都必须声明使用OS_STK作为它的数据类型。用户需要做的只是查阅编译器文档,找出对应于C/OS-II的标准的C的相应数据类型。 OS_CPU.H,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()像其它的实时内核一样,C/OS-II需要先关中断再处理临界段代码,并且在处理完毕后再重新开中段。这就能够保证临界段代码免受多任务或中断服务子程序的破坏。通

9、常每个处理器都会提供一定的汇编指令来开关中断,C编译器必须有一定的机制直接从C语言中执行这些操作。有些编译器允许在C源代码中直接加入汇编语句,这就使得插入处理器指令来开关中断变的容易,有些其它的编译器提供语言扩展功能,可以直接从C语言中开关中断。为了隐藏编译器厂商提供的不同实现方法,以增加可移植性,C/OS-II定义了2个宏,用来关开中断:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),如T1:它们都是成对出现的,分别加在临界段代码的前面和后面;C/OS-II Service Function OS_ENTER_CRITICAL();/*临界段代码*/OS_EXI

10、T_CRITICAL();T1方法一:实现OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()这两个宏的这种方法是最简单的方法,在中调用处理器指令关中断,以及在中调用相应处理器指令开中断;但是这个过程还存在小小的问题:如果在禁止中断的情况下调用C/OS-II函数,那么从C/OS-II函数返回时,中断可能会变成允许的了。而实际上如果调用C/OS-II之前中断是关掉的希望从C/OS-II函数返回时,希望中断还是关掉的。在这种情况下,仅靠这种方法是不适宜的。方法二:执行OS_ENTER_CRITICAL()时,先将中断状态保存到堆栈中,然后关中断;而当执行OS_EXIT_CR

11、ITICAL()时,再从堆栈中恢复原来的中断开关状态。如果用这种方法,那么不管用户是在中断禁止,还是中断允许的情况下调用C/OS-II的功能函数,调用后都不会改变中断状态。应用程序可以调用OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL(),以保护临界段代码;但是,在使用这种方法时需特别小心,因为如果在调用像OSTimeDly()之类的功能函数之前就关掉了中断,应用程序就会崩溃。发生这种情况的原因是,任务被挂起,知道延迟时间到,而中断是关掉的。OSTimeDly()实际上是依靠时钟节拍实现中断的,而因为中断是关掉的,程序不可能获得时钟节拍中断。明显的,所有的PEND调用

12、都会涉及到这个问题,需十分小心。一个通用的办法是,应该在中断允许的情况下调用C/OS-II的系统功能函数。 OS_CPU.H, OS_STK_GROWTH绝大多数微处理器和微控制器的堆栈都是从上往下递减的,但是也有某些处理器使用的是相反的方式,C/OS-II被设计成对这两种情况都可以处理,只要再用配置常数OS_STK_GROWTH指定堆栈的方向就可以了:置OS_STK_GROWTH为0,表示堆栈从下(低地址)往上(高地址)递增:置OS_STK_GROWTH为1,表示堆栈从上(高地址)往下(低地址)递减。 OS_CPU.H, OS_TASK_SW()OS_TASK_SW()是一个宏,是在C/OS

13、-II从低优先级任务切换到高优先级任务时须用到的。OS_TASK_SW()总是在任务级代码中被调用。另一个函数OSIntExit()用在中断服务子程序ISR中。任务切换只是简单地将处理器的寄存器保存到将被挂起的任务的堆栈中,并且从堆栈中恢复要运行的更高优先级的任务。在C/OS-II中,处于就绪态任务的堆栈结构看起来就像刚刚发生过中断一样,所有的寄存器都保存在堆栈中。换句话说,C/OS-II要运行处于就绪态的任务必须要做的事是,从任务堆栈中恢复所有的寄存器,并且执行中断返回指令。为了任务调度,可以通过执行OS_TASK_SW()模仿中断的产生。绝大多数处理器会提供软中断或指令陷阱来完成这项功能。

14、中断服务子程序或指令陷阱处理函数(也叫做异常处理函数)的中断向量地址必须指向汇编语言函数OSCtxSw()。例如,在Intel或者AMD80X86处理器上可以使用INT指令,但是中断向量必须指向OSCtxSw()。有些处理器如Z80,并不提供软中断机制。在这种情况下需要想办法将堆栈结构设置成与软中断发生后的堆栈结构一样。在OS_TASK_SW()函数中调用OSCtxSw(),而不是将某个中断向量指向OSCtxSw()。实际上C/OS-II已经被移植到了Z80处理器上,C/OS-II也同样是可以的。(3) OS_CPU_A.ASMC/OS-II的移植实例要求用户编写4个简单的汇编程序:OSSta

15、rtHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()如果编译器支持插入行汇编代码,就可以将所有与处理器相关的代码放到OS_CPU.C文件中,而不必再有单独的汇编语言文件。 OS_CPU_A.ASM, OSStartHighRdy()OSStart()函数调用OSStartHighRdy()来使就绪态任务中优先级最高的任务开始运行,在调用它之前,要已经建立了至少一个应用任务。OSStartHighRdy()假设OSTCBHighRdy指向最高优先级任务的任务控制块。就像先前提到的,在C/OS-II中处于就绪态任务的堆栈结构看起来就像刚发生过中断一样,所有的寄存器都保存在堆栈中。要想运行最高优先级任务,需将所有处理器按顺序从任务堆栈中恢复出来,并且执行中断返回指令。为简单起见,堆栈指针总是存储字任务控制块的开头。换句话说,也就是需要恢复的任务堆栈指针总是存储在任务控制块的偏移地址

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号