UCOS-II在MC9S12XS128上的移植

——BY DABAO

操作系统是一种与硬件为基础的系统软件,硬件系统不一样,那在其上面运行的操作系统也会不一样。一般来说,操作系统是与芯片相关联的。要在某型号的芯片上运行操作系统,那得在操作系统内核的基础上编写一些与芯片相关的驱动程序,并对内核的配置文件做相应的改动,然后在编译器上编译,链接,然后下载到芯片上。这个过程就是所谓的操作系统的移植了。

UCOS-II是个开源的也就是原代码公开的内核,可以免费用于非商业的各种运用中。其原代码可以在http://micrium.com/page/products/rtos/os-ii上找到。上面有好多在某些芯片上移植成功的实例,如果芯片型号对应,则可以下载下来直接用。这样就可以省去好多移植的工作,而直接在上面编写用户任务就可以了。

UCOS-II的文件有:

一、与处理器无关的代码:

OS_CORE.C(与内核运作有关的文件)

OS_FLAG.C(事件标志组管理)

OS_MBOX.C(消息邮箱)

OS_MEM.C(内存管理)

OS_MUTEX.C(互斥型信号量)

OS_Q.C(消息列队)

OS_SEM.C(信号量)

OS_TASK.C(任务管理)

OS_TIME.C(时钟管理)

UCOS_II.C()

UCOS_II.H()

二、UCOS-II的配置文件(需要用户根据具体的运用来配置)

OS_CFG.H(配置使用哪些系统函数,按需裁剪操作系统)

INCLUDES.H(系统总头文件,把所有用的到头文件都加进来)

三、UCOS-II的移植文件(与处理器相对应的功能实现)

OS_CPU.H(定义数据类据、临界代码实现方法、堆栈方向、任务切换宏)

OS_CPU_C.C(与硬件相关的代码)

OS_CPU_A.S (若移植使用的C编译器允许在C代码中插入汇编语句,则汇编部分的代码可以放到OS_CPU_C.C中,此时0S_CPU_A.S就可以不要了)

要移植UCOS-II的芯片必须满足以下要求:

1、 处理器的C语言编译器能产生可重入型代码;

2、 处理器支持中断,并且能产生定时中断(通常为10~100Hz);

3、 用C语言就可以开或关中断;

4、 处理器能支持一定数量的数据存储硬件堆栈;

5、 处理器有将堆栈指针以及其他CPU寄存器的内容读出并存储到堆栈或内存中去的指令。

下面结合UCOS-II在MC9S12XS128上的移植来讨论一下UCOS-II的移植方法及过程。

UCOS-II的移植分成几个步骤:

一、文件OS_CPU.H的编写,要求对处理器的内部结构有所了解:

#ifndef OS_CPU_H

#define OS_CPU_H

【定义数据类型。因为不同的编译器对数据的定义不尽相同,而UCOS-II系统中采用统一的数据类型名,以便于移植。故这里要把操作系统中的数据类型和所用的编译器的数据类型对应起来。】

typedef 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位整数】

typedef signed   long INT32S;     【有符号32位整数】

typedef float          FP32;      【单精度浮点数】

typedef double         FP64;     【双精度浮点数】

//

typedef unsigned char OS_STK;     【堆栈的数据类型,这由处理器决定,堆栈变量都由OS_STK定义】

typedef unsigned short OS_CPU_SR;    【CPU状态寄存器PSW的数据类型,因为在临界代码方法3中,会把PSW中的值存入到OS_CPU_SR定义的变量cpu_sr中】

【三个函数声明】

void OSStartHighRdy(void);

void OSIntCtxSw (void);

void OSCtxSw (void);

#define OS_CRITICAL_METHOD    3  【这里可以是1、2或者3,选择3表示用方法3进入临界代码区】

【这里定义临界代码方法3的具体程序实现,这跟处理器结构相关】

#if     OS_CRITICAL_METHOD == 3

#define OS_ENTER_CRITICAL()  (cpu_sr =OS_CPU_SR_Save())

#define OS_EXIT_CRITICAL()  (OS_CPU_SR_Restore(cpu_sr))

#endif

/

#define OS_TASK_SW()    _asm("swi")  【这里定义一个宏,是在UCOS-II做任务切换时必须用到的。在UCOS-II中,处于就绪态的任务的堆栈结构看起来就像刚发生过中断一样,所有的寄存器都保存大堆栈中。要运行就绪的任务时,系统要做的就是从任务堆栈中恢复处理器所有的寄存器,并执行中断返回指令。任务调度时,可以通过执行OS_TASK_SW()模仿中断的产生。绝大多数处理器会提供软中断或指令陷阱来完成这项功能。在XS128中就是通过软中断SWI来完成的。】

/

#define OS_STK_GROWTH    1     【用于根据处理器堆栈的方向来配置操作系统,当处理器的堆栈是从下(低地址)往上(高地址)递增时,OS_STK_GROWTH定为0;当处理器的堆栈是从上往下递减时,OS_STK_GROWTH定为1。】

【声明两个与用方法3实现临界代码有关的函数】

#if     OS_CRITICAL_METHOD == 3

OS_CPU_SR OS_CPU_SR_Save(void);【返回PSW寄存器的值,保存在cpu_sr中,并关中断】

void   OS_CPU_SR_Restore(OS_CPU_SR  os_cpu_sr);  【把cpu_sr的值恢复到PSW寄存器中去】

#endif

#endif

二、文件OS_CPU_C.C的编写,要求对处理器的堆栈结构有所了解:

在这个文件中,得编写10个函数,分别是:

OSTaskStkInit()

OSTaskCreateHook()

OSTaskDelHook()

OSTaskSwHook()

OSTaskIdleHook()

OSTaskStatHook()

OSTimeTickHook()

OSInitHookBegin()

OSInitHookEnd()

OSTCBInitHook()

除了OSTaskStkInit()外,其他9个函数必须声明,但不一定要包含任何代码。

只有OS_CFG.H文件中的OS_CPU_HOOKS_EN置为1时,才会生成下面OS_XXXHook()的这些代码,这个由程序中的条件编译可以看出。这些函数相当于是用户对操作系统功能扩展的接口函数,它的设置是为了方便用户根据需要扩展UCOS-II的功能。这些函数在其相应的函数中初调用,来实现用户的扩展功能;如果不需要扩展功能,则只需声明一个空函数。强调一点是,不管是否需要扩展UCOS-II的功能,都必须得声明这些函数。

OS_CPU_C.C文件中的程序如下:

#include "includes.h"

【下面这个函数是堆栈初始化函数,需要在了解处理器堆栈结构的基础上编写。其中的参数分别表示:task是指向任务的函数指针,即任务的起始地址,其中pd为task指向的任务的参数;p_arg为任务开始执行时传递给任务的参数的指针;ptos为堆栈栈顶值,也就是传入堆栈的初始值; opt为OS_TCB的选择项,用于设定OSTaskCreateExt()的选项,指定是否允许堆栈检验,是否将堆栈清0,任务是否要进行浮点操作等,在OSTaskCreate()中没有opt参数,故当OSTaskCreate()调用OSTaskStkInit()时,将opt设置为0X0000。】

OS_STK *OSTaskStkInit (void (*task)(void*pd), void *p_arg, OS_STK *ptos, INT16U opt)

{

【因为要压入堆栈中的数据有十六位的,也有八位的,所以就定义了两个指针,一个十六位,一个八位。】

INT16U *wstk;

INT8U  *bstk;

opt     = opt;     【这条语句没有实际意义,因为这个参数没有用到,为了避免编译时发出警告,就令opt =opt,表示这个参数已经用过了,就不会有这个警告了。】

wstk    = (INT16U *)ptos;   【载入堆栈的初始值】

*--wstk=  (INT16U)p_arg;   【任务中传递的参数】

*--wstk=  (INT16U)(((INT32U)task) >>8);  【把任务的地址压入堆栈,相当于PC值入栈】

*--wstk =  (INT16U)(((INT32U)task) >> 8);  【????】

*--wstk =  (INT16U)0x2222;           【Y寄存器】

*--wstk =  (INT16U)0x1111;           【X寄存器】

*--wstk =  (INT16U)0xBBAA;          【D寄存器】

*--wstk =  (INT16U)0x0080;           【CCR寄存器】

bstk    = (INT8U *)wstk;    【十六位指针强制类型转化为八位后赋给八位指针bstk】

*--bstk =*(INT8U *)0x10;      【GPAGE寄存器】

*--bstk = *(INT8U*)0x17;      【EPAGE寄存器】

*--bstk =*(INT8U *)0x16;      【RPAGE寄存器】

*--bstk =  (INT8U )task;     【任务的PPAGE寄存器值】

return ((OS_STK*)bstk);    【返回当前堆栈的值】

}

【OS_VERSION的值表示当前所用的UCOS-II的版本号,在文件UCOS_II.H中有定义。203表示的版本号是2.03;252表示的版本号是2.52 。这里用到条件编译,表示2.03以上的版本中才会用到OSInitHookBegin (void)和OSInitHookEnd (void)】

#if (OS_CPU_HOOKS_EN > 0) &&(OS_VERSION > 203)

void OSInitHookBegin (void)

{

}

#endif

#if (OS_CPU_HOOKS_EN > 0) &&(OS_VERSION > 203)

void OSInitHookEnd (void)

{

}

#endif

#if (OS_CPU_HOOKS_EN > 0)

void OSTaskCreateHook (OS_TCB *ptcb)

{

(void)ptcb;

}

#endif

#if (OS_CPU_HOOKS_EN > 0)

void OSTaskDelHook (OS_TCB *ptcb)

{

(void)ptcb;

}

#endif

#if (OS_CPU_HOOKS_EN > 0) &&(OS_VERSION >= 251)

void OSTaskIdleHook (void)

{

}

#endif

#if (OS_CPU_HOOKS_EN > 0)

void OSTaskStatHook (void)

{

}

#endif

#if (OS_CPU_HOOKS_EN > 0)

void OSTaskSwHook (void)

{

}

#endif

#if (OS_CPU_HOOKS_EN > 0) &&(OS_VERSION > 203)

void OSTCBInitHook (OS_TCB *ptcb)

{

(void)ptcb;

}

#endif

#if (OS_CPU_HOOKS_EN > 0)

void OSTimeTickHook (void)

{

}

#endif

三、编写OS_CPU_A.ASM文件(对于CW编译器,这部分代码可以放在OS_CPU_C.C文件中,以C语言插入汇编语言的方式出现)

在这部分中要编写的函数有:

1、 OSStartHighRdy()  【OSStart()函数调用OSStartHighRdy()来使就绪态任务中优先级最高的任务开始运行】

2、 OSCtxSw()   【任务级的任务切换,通过执行软中断指令来实现】

3、 OSIntCtxSw()   【中断级的任务切换】

4、 OSTickISR()   【时钟节拍中断服务函数】

四、产生时钟节拍中断

UCOS-II的运行要求处理器提供一个时钟中断节拍,用于任务的延时或挂起等功能,因此得编写代码产生时钟节拍中断。在XS128中可以利用实时中断模块RTI来实现时钟中断节拍功能。其实就两句:

RTICTL=0XCF;  【分频】

CRGINT|=0X80;  【开实时中断】

开实时中断的动作必须在UCOS-II初始化之后,多任务开始之前,所以这两句语句一般放在第一个建立的任务函数中。

最后要修改CW建立工程时自动生成的XXX.prm链连文件,把时钟节拍中断向量放到中断向量表中,即在XXX.prm文件后面添加语句VECTOR 7 OSTickISR。

到这里,移植工作就算是完毕了。在添加任务之前可以先编译一下,以及调试一下程序,排除在移植过程中产生的错误。

当然要运用这个操作系统的工作还没完成:

1、 把所有的头文件都包进系统总头文件INCLUDES.H中。

2、 根据实际运用需要在OS_CFG.C文件中配置及裁剪系统。

3、 编写main.c文件及任务函数。

UCOS-II在51单片机上的移植方面的信息可与杨屹先生沟通,其网址为www.armecos.com ,电子邮箱为asdjf@163.com。UCOS-II在ARM核上移植方面的信息可与周立功先生联系,其电子邮箱为zlg3@zlgmcu.com。

参考文献

[1]嵌入式实时操作系统UC/OS-II(第二版)   [美] Jean J.Labrosse  著   邵贝贝等译  北京航空航天大学出版社

[2]嵌入式实时操作系统UC/OS-II原理及应用   任哲  编著   北京航空航天大学出版社

[3]单片机与嵌入式系统开发方法   薛涛 宫辉 龚光华 邵贝贝等编著    清华大学出版社

UCOS-II在MC9S12XS128上的移植相关推荐

  1. 用C语言写ucos中断服务程序,在ARM处理器上移植uCOS II的中断处理

    uCOS II是一个源码公开.可移植.可固化.可剪裁和抢占式的实时多任务操作系统,其大部分源码是用ANSI C编写,与处理器硬件相关的部分使用汇编语言编写.总量约200行的汇编语言部分被压缩到最低限度 ...

  2. UCOS II移植到STM32F103开发板

    早期嵌入式开发没有嵌入式操作系统的概念 ,直接操作裸机,在裸机上写程序,比如用51单片机基本就没有操作系统的概念.通常把程序分为两部分:前台系统和后台系统. 简单的小系统通常是前后台系统,这样的程序包 ...

  3. 51单片机中使用ucos ii的优缺点(好文)

    摘要:近年来,在单片机系统中嵌入操作系统已经成为人们越来越关心的一个话题.本文通过对一种源码公开的嵌入式实时操作系统ucos ii的分析,以51系列单片机为例,阐述了在单片机中使用该嵌入式操作系统的优 ...

  4. lwip协议栈在linux运行,LwIP协议栈在uCOS II下的实现

    1.概述: LwIP协议栈在设计时就考虑到了将来的移植问题,因此把所有与硬件.OS.编译器相关的部份独立出来,放在ucosii&LwIPsource etlwiparch目录下.因此LwIP在 ...

  5. 移植c语言算法到arm上,μCOS-II移植到ARM处理器上的几个要点

    原标题:μCOS-II移植到ARM处理器上的几个要点 本文主要介绍μCOS-II移植到ARM处理器上的几个要点,如下所示: uCOS II在ARM处理器上移植过程中的中断处理 uCOS II是一个源码 ...

  6. 基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现

    基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现 在基于STM32的示波器的实现的基础上,在STM32上移植UCOS II嵌入式实时操作系统. 在UCOS II操作系统中将各个功能分发 ...

  7. RTOS 在 stm32f407 探索者上的移植(一)

    RTOS是什么 先看他们的定义.非实时操作系统指 操作系统无法保证 最高优先级任务开始执行 的最后时限. 软实时操作系统指 操作系统只能保证在xx时间内开始执行最高优先级的用户代码,但无法保证用户软件 ...

  8. uCOS-II在51单片机上的移植

    uCOS-II在51单片机上的移植 约定:文中所写的硬件堆栈或系统堆栈是指51单片机SP指针所指向的堆栈空间,而用户堆栈或任务堆栈是指用来保存任务状态为每个任务分配的堆栈空间. 前一段时间一直在学习U ...

  9. ucos II任务管理之一:挂起任务

    Ucos II 任务管理之一 创建好了任务之后,就已经初步跨进了ucos II 的编程了.随着进一步的编程,发现学会创建了任务还是不够的. 在我的项目里,需要实现485通信功能,我创建了任务1用于串口 ...

最新文章

  1. BCH收银APP已在Android系统上下载超10000次
  2. alibaba cloud is expensive
  3. python基础1 第一天
  4. leetcode 152 乘积最大子序列
  5. php 高德地图计算距离,距离、长度、面积
  6. 下拉刷新和UITableView的section headerView冲突的原因分析与解决方案
  7. 大学计算机课挂科补考,【挂科的同学请注意!】关于本学期补考、缓考的通知(转)...
  8. NOI / 1.3编程基础之算术表达式与顺序执行——12:计算球的体积
  9. (2021总结篇)面向对象软件设计模式--(八)结构型模式---树形结构的处理--组合模式
  10. APP开发项目团队成员要求及职责
  11. Sigfox的物联网生意经:弱水三千只取一瓢饮
  12. java 如何读取解析 mac 下的 pages 文稿,实现数据库正向工程
  13. 便宜的虚拟主机可以使用吗?
  14. opencv python 实现图片添加带透明的 logo
  15. 分类算法-决策树、随机森林
  16. 微信第三方平台 错误码
  17. AI不仅要智能,更需要人文:联邦学习重构大数据风控范式
  18. 渗透测试流程 - 渗透测试的9个步骤
  19. CSS语义-icont+text
  20. 钢琴转录论文Onsets and Frames:dual-objective piano transcription

热门文章

  1. Java后端2017书单推荐
  2. Python 小型课设作业,仅200行代码,使用youtube-dl下载视频,使用OpenCV和ffmpeg处理视频成字符视频
  3. TNS-12547 TNS-12560 TNS-00517
  4. c#实现猜数游戏(do-while和for循环实现方法)
  5. 智慧城管视频监控AI智能分析系统 线上巡城 [Python+yolov7]
  6. 裸辞25k鹅厂工作,待在家里全职接单,一个月我挣了多少?
  7. 《比特彗星-教程》-《教程3.使种子市场的他人共享快速增长》
  8. 《比特彗星-教程》-《教程1.安装比特彗星》
  9. C#基础知识之依赖注入
  10. java基础总结大全