计算机应用 | 古代文学 | 市场营销 | 生命科学 | 交通物流 | 财务管理 | 历史学 | 毕业 | 哲学 | 政治 | 财税 | 经济 | 金融 | 审计 | 法学 | 护理学 | 国际经济与贸易
计算机软件 | 新闻传播 | 电子商务 | 土木工程 | 临床医学 | 旅游管理 | 建筑学 | 文学 | 化学 | 数学 | 物理 | 地理 | 理工 | 生命 | 文化 | 企业管理 | 电子信息工程
计算机网络 | 语言文学 | 信息安全 | 工程力学 | 工商管理 | 经济管理 | 计算机 | 机电 | 材料 | 医学 | 药学 | 会计 | 硕士 | 法律 | MBA
现当代文学 | 英美文学 | 通讯工程 | 网络工程 | 行政管理 | 公共管理 | 自动化 | 艺术 | 音乐 | 舞蹈 | 美术 | 本科 | 教育 | 英语 |

MicroC/OS-II在80C196上的移植实现

2016-10-07 01:11
导读:计算机应用论文论文,MicroC/OS-II在80C196上的移植实现应该怎么写,有什么格式要求,科教论文网提供的这篇文章是一个很好的范例:摘  要:在嵌入式系统中使用实时操作系统,可以提高系统的稳定性、可靠
摘  要:在嵌入式系统中使用实时操作系统,可以提高系统的稳定性、可靠性和实时性。MicroC/OS-II是一个完整的,可移植、可固化、可剪裁的抢占式多任务实时内核,并且开放源代码,得到了广泛应用。本文结合具体应用,介绍了MicroC/OS-II在80C196上移植实现过程和注意事项。
关键词:实时操作系统  MicroC/OS-II  80C196  移植
    在嵌入式系统开发中,很长时间以来,一直采用传统的嵌入式系统软件设计模式:无限循环+中断服务。该模式下,主程序为一个无限循环,单任务顺序执行各个处理任务。在循环之外,设计一个或多个中断服务函数,用于处理异步事件。在相对简单的应用中,这种模式,完全可以胜任。而对于实时性要求较高、处理任务较多的应用,就会暴露出实时性差的缺点,甚至不能够达到应用的要求,系统可靠性低,稳定性差。引入实时操作系统,可以较好解决这个问题。 MicroC/OS-II是一个完整的,可移植、可固化、可剪裁的抢占式多任务实时内核,并且开放源代码,在嵌入式系统中得到了广泛应用。为了实现老系统功能升级,达到了不改变硬件设计,增加系统功能、提高系统性能的目的,从而采用该实时操作系统。本文介绍了将其移植应用于80C196的具体实现和注意事项。 所谓移植,就是使一个实时内核能够在其他微处理器或微控制器上运行。移植要做的是,修改或编写与处理器硬件相关的代码。由于80C196系统的资源有限,除了代码移植,还要根据具体应用,对MicroC/OS-II进行裁剪,以达到系统的设计要求。 1. MicroC/OS-II简介 MicroC/OS-II的系统结构见图1。 MicroC/OS-II最主要的特点之一是源代码开放,有利于用户根据具体应用对操作系统进行充分的裁减。这也使得其可移植性非常的强。 MicroC/OS-II是为嵌入式应用专门设计的,完全可与应用软件融合在一起,进行编译、连接,进而作为产品的一部分发布。 MicroC/OS-II是完全可剥夺型的实时内核,总是运行就绪任务中最高优先级的任务,即准备就绪的高优先级任务可以剥夺正在运行的低优先级任务的CPU使用权。 2. 移植的基本思路 2.1 编译器 采用TASKING公司的C196编译器,可以方便的嵌入汇编语言,因此该移植所有的函数都在OS_CPU_C.C中实现,没有OS_CPU_A.ASM文件。能够采用C语言编码的,尽量采用C语言编码;不能采用C代码的,采用嵌入汇编的方式。以此降低代码的分散度,提高代码的可读性。 2.2 代码移植 代码移植,需要修改或编写与处理器硬件相关的代码。包括与处理器相关的数据类型定义,函数定义,存储器操作等。其中的主要任务有: 1)    重新编辑INCLUDES.H文件,增加与应用相关的头文件;改写OS_CPU.H文件; 2)    改写OS_CFG.H文件;编写OS_CPU_C.C; 3)    优化代码效率。 2.3 存储资源 由于80C196系统的物理资源十分有限,需要对系统内核进行充分的裁剪。 片内可用内存为220个字节,在系统中外部扩展3584(3.5K)个字节。为了提高系统速度,操作系统尽量使用片内存储区。系统应用中经常使用的变量,也需要分配在片内存储区。 为了节约存储资源采取以下措施: 1)    裁剪不使用的功能模块和其使用相应变量。 2)    根据应用的需要裁剪所需资源的规模。例如,在应用中实际使用任务为6个,所以将OSRdyTbl由一个数组,更改为一个8位变量,并去掉OSRdyGrp,因为其永远是0。 3)    修改OS_InitTaskIdle内容,将OS_TaskIdle任务换为应用的最低优先级的任务。 4)    裁剪OS_TCB的内容。例如,永远不会使用的变量OSTCBY和OSTCBBitY。 5)    裁剪中断嵌套的相关内容。 2.4 时间资源 MicroC/OS-II推荐的时钟节拍为10~200ms,而本系统的实际时钟节拍为250μs,这样系统额外开销必然大幅度增加,系统时间资源十分紧张。 为了节约时间资源采取以下措施: 1)    弃用OSTimeDly函数,直接操作任务定时器,调用OS_Sched函数。 2)    弃用OSIntExit和OSIntCtxSw函数,将其源代码直接加入软件定时器中断服务函数。 3)    降低其他中断服务函数的代码长度,且不进行任务切换,降低系统时钟的误差。 4)    根据编译得到的汇编代码,对部分C语言代码进行优化。 3. 移植实现 3.1 任务分配 一个任务,也称为一个线程,是一个简单的程序,该程序可以认为CPU完全属于自己。每个任务有独立的堆栈空间和优先级。 根据每个任务的内容可以在相应位置,使任务就绪。而任务就绪和任务切换可以分开。例如,在接收中断中,使可以CAN通信任务就绪,但可以不进行任务切换,而在系统时钟函数中进行任务切换。系统总是让处于就绪态的、优先级最高的任务先运行。 3.2 时钟节拍 时钟节拍是特定的周期性中断,根据应用系统的需要,时钟节拍的周期为250μs,采用软件定时器实现。在该服务函数中实现任务切换,为了节省时间和存储资源,不进行函数调用。     软件定时器中断服务函数实现代码如下: void OSTickISR(void) { … …// 重置软件定时器      OS250usCount++;    // 计数器加1      if((OS250usCount&0x03)==0)  {          … …          OS1msCount++; // 1ms定时器          OS50msDly++;  // 50ms定时器          OSRdyTbl |= 0x20;  // 1ms定时到,就绪TaskChk任务 … …    }      // OSIntExit() 中断退出任务切换      OSPrioHighRdy = OSUnMapTbl[OSRdyTbl]; // 取得最高优先级就绪任务的优先级 (科教作文网http://zw.ΝsΕAc.Com编辑整理)
     if (OSPrioHighRdy != OSPrioCur)// 判断当前任务优先级是否与最高优先级就绪任务的优先级相同      {          // OSIntCtxSw();          OSTCBCur->OSTCBStkPtr = psp;         // 存储被中断任务的堆栈指针          OSTCBCur = OSTCBPrioTbl[OSPrioHighRdy];   // 取得最高优先级就绪任务的TCB          OSPrioCur = OSPrioHighRdy;  // 设当前任务优先级为最高优先级就绪任务的优先级          psp = OSTCBCur->OSTCBStkPtr;     // 取得堆栈指针          asm{     // 现场恢复               pop  dx;  pop  cx;  pop  bx;  pop  ax;  popa;               ret; // 切换到最高优先级就绪任务,必须要有的          }      } } 3.3 中断 由于中断的存在,任何代码在任何时候,都有可能被中断。而有些代码是不可分割的,如果被中断将会产生不可预料的后果。因此定义临界段,以处理不可分割的代码。一旦该部分代码开始执行,不允许任何中断插入。为了确保临界段代码的执行不被中断,在进入临阶段之前,必须关中断,临界段代码执行结束,开中断。
    为80C196定义OS_ENTER_CRITICAL和OS_EXIT_CRITICAL如下: // 中断禁止函数 #define  OS_ENTER_CRITICAL()  asm DI // 中断使能函数 #define  OS_EXIT_CRITICAL()   asm EI 3.4 其他代码实现 3.4.1 任务堆栈初始化函数 任务堆栈初始化函数代码如下: OS_STK  *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) {      … …      stk = (OS_STK*)ptos; *--stk = (OS_STK)task; // 任务开始地址 *--stk = (OS_STK)0x0000|gimask;  // PSW IMASK *--stk = (OS_STK)0x0000|gimask1;// IMASK1 WSR *--stk = (OS_STK)4;    // DX *--stk = (OS_STK)3;    // CX *--stk = (OS_STK)2;    // BX *--stk = (OS_STK)1;    // AX   return ((OS_STK *)stk); } 3.4.2 开始运行最高优先级就绪任务 系统开始运行时,调用该函数,以开始运行,其实现代码如下: void OSStartHighRdy(void) {      OSRunning = TRUE;  // 置系统正在运行标志      … …      OSTCBCur = OSTCBHighRdy;    // 置当前TCB为最高优先级就绪任务的TCB      psp = OSTCBHighRdy->OSTCBStkPtr; // 取得堆栈指针      asm{     // 恢复现场          pop  dx;  pop  cx;  pop  bx;  pop  ax;  popa;    // 转到新任务      } } 3.4.3 现场切换函数 OS_Sched函数调用该函数实现真正的任务切换。 void OSCtxSw(void) {      asm{     // 保存被中断任务的现场          pusha;   push ax;  push bx;  push cx;  push dx;      } OSTCBCur->OSTCBStkPtr = psp;     // 存储被中断任务的堆栈指针      OSTCBCur = OSTCBPrioTbl[OSPrioHighRdy];   // 取得最高优先级就绪任务的TCB      OSPrioCur = OSPrioHighRdy;  // 设当前任务优先级为最高优先级就绪任务的优先级      psp = OSTCBCur->OSTCBStkPtr;              // 取得堆栈指针      asm{     // 现场恢复          pop  dx;  pop  cx;  pop  bx;  pop  ax;  popa;      } } 4. 注意事项 在实现过程中的得到如下经验教训: 1)       尽量减少任务的数量,以减少系统额外开销。相对少的任务数,可以减少,系统花在任务切换上的时间。 2)       合理分配各个任务的优先级。 3)       注意开中断、关中断的时机。 4)       注意入栈和出栈要匹配。如果堆栈指针出现错位,将会出现灾难性后果。特别注意中断服务函数的处理,其调用时的入栈内容和退出中断的出栈内容要对应,而中断退出有两种可能:正常退出和任务切换。 5)       合理选择定时器时间周期。
6)       同类型工作,也同样需要有优先级区分。例如:同样是通信任务,接收数据需要较高的优先级,而通信故障处理需要较低的优先级。一般情况下,通信处理都有一定的故障容忍时间,只要在容忍时间内得到处理就可以了。如果发生不可恢复性错误,故障处理将会占用大量的时间,如果在较高优先级,将会影响整个系统的性能。 5. 结论 通过在80C196上移植实现MicroC/OS-II,达到了不改变硬件设计,增加应用功能,提高了应用系统性能的目的。在嵌入式系统中使用嵌入式实时操作系统,不但可以提高系统的实时性、可靠性和稳定性,还可以提高应用软件的可移植性和可维护性,降低开发人员的工作量。因此,只要硬件环境允许,应尽量采用实时操作系统。 参考文献: 1.Jean J.Labrosse 著,邵贝贝等译,《嵌入式实时操作系统 μC/OS-II(第二版)》,北京航空航天大学出版社,2003年5月 第1版 2.孙涵芳主编,《Intel 16位单片机》,北京航空航天大学出版社,1995年11月 第1版
    上一篇:计算机网络安全及防范技术 下一篇:没有了