μC/OS-II在ARM平台上移植的深入探讨

发布者:boczsy2018最新更新时间:2010-07-26 来源: 微型机与应用关键字:嵌入式操作系统  μC/OS-II  ARM  S3C2410 手机看文章 扫描二维码
随时随地手机看文章

    μC/OS-II在ARM平台的移植是一个重要的学习过程,有助于提高对RTOS的认识与理解,从而提高嵌入式工作者的理论与技术水平。μC/OS-II是一个小的实时内核,源代码公开,有详尽的解释。正是因为其内核小,才便于研究、理解和掌握。另外,参照TCP/IP协议、标准和一些公开的图书,在μC/OS-II上增加TCP/IP协议栈,蓝牙通信软件、红外通信协议也十分方便,商业价值得到了认可。

    随着科技的发展,嵌入式应用的复杂性越来越高,同时ARM体系处理器的价格越来越低,ARM平台 + 实时操作系统的架构体系的使用会越来越广泛。有鉴于此,本文对μC/OS-II在ARM平台下的移植进行了深入探讨。

1 操作系统μC/OS-II及S3C2410开发平台简介

1.1 μC/OS-II简介

    μC/OS最早出自于1992年美国嵌入式系统专家Jean J.Labrosse在《嵌入式系统编程》杂志5月和6月上刊登的文章连载,并把μC/OS的源代码发表在该杂志的BBS上。μC/OS-II是目前最新的版本。

 μC/OS-II是专门为计算机的嵌入式应用而设计的,绝大部分代码用C语言编写。CPU的相关部分采用汇编语言编写,总量在200行左右的汇编语言被压缩到最低限度,目的是便于移植到任何一种其他的CPU上去。μC/OS-II具有执行效率高、占用空间小、实时性优良、可扩展等特点,最小内核可编译至2 KB。μC/OS-II可移植到几乎所有知名的CPU上。

1.2 μC/OS-II的组成

    严格地说μC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度、任务管理、时间管理、内存管理和任务间的通信和同步等基本功能。没有提出输入输出管理、文件系统、网络通信等额外的服务。但由于μC/OS-II良好的可扩展性和源代码开放,这些非必须的功能完全可以由用户根据自己的需要分别实现。

    μC/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信、CPU的移植等5个部分[1]。

    (1)核心部分(OSCore.c):操作系统的处理核心,包括操作系统的初始化、操作系统运行、中断进出的前导、时钟节拍、任务调度、事件处理等多部分。

    (2)任务处理部分(OSTask.c):与任务操作密切相关的部分。包括任务的建立、删除、挂起、恢复等等。

    (3)时钟部分(OSTime.c):μC/OS-II中最小的时钟单位是timetick(时钟节拍)。任务延时等操作在此完成。

    (4)任务同步和通信部分:为事件处理部分,包括信号量、邮箱、邮箱队列、事件标志等部分,主要用于任务间的相互联系和对临界资源的访问。

    (5)与CPU的接口部分:这里是指μC/OS-II针对所使用的CPU需要改写的部分。由于μC/OS-II是一个通用性的操作系统,其开放的源代码是以X86内核为例而编写的,在应用到其他处理器平台上时,这部分代码必须做相应的改变。

1.3 ARM硬件开发平台简介

    调试时所用的硬件开发平台是一款基于三星S3C2410A芯片的开发平台。S3C2410开发板是一款通用的ARM9开发板,其基本配置采用三星公司的S3C2410 ARM920T芯片,主频203 MHz。集成有SDRAM控制器、NAND Flash控制器、SD读卡器、USB Host和USB Device控制器、LCD控制器、I2C总线控制器、SPI总线接口等。开发板上Flash空间为32 MB,SDRAM容量为128 MB。

2 S3C2410引导程序

    开发板原有引导程序由VIVI公司提供,其运行过程分成两个阶段。第一阶段的代码用汇编语言编程,主要完成以下任务: (1)初始化CPU速度、存储器、存储器配置寄存器,以及串口等硬件资源的配置;(2)建立内存空间的映射图,将系统的软硬件环境带到合适的状态,为最终调用操作系统内核做准备; (3)装载操作系统映像到内存中;(4)设置相关寄存器和资源,跳转到main()函数,进入第二阶段。

    第二阶段的代码用C语言编写,从main()函数开始,主要工作有:开发板外部接口初始化(I/O接口、UART接口、LCD接口等)、内存映射和内存管理单元初始化等,最后启动linux内核。有大量文章对此开发板引导程序作了详细的分析[3],本文在这里不做重复,本文的重点是将引导程序与μC/OS-II操作系统二者融合,既利用了开发板源代码提供的关于UART口、LCD和触摸屏接口程序;时钟、内存管理等丰富的驱动程序和接口程序,又成功地完成了对μC/OS-II实时操作系统的移植和整合。

3 移植要点

  μC/OS-II的内核分成2个部分,与处理器无关的代码和与处理器有关的代码。移植过程中需要根据S3C2410处理器和ADSV1.2开发平台(这里特地强调编译平台的因素,主要考虑到各个编译平台对数据格式的理解略有差别)的特点来重新编写3个文件,用C语言编写的OS_CPU.H、OS_CPU_C.C和用汇编语言编写的OS_CPU_A.ASM,此外,要将S3C2410开发板引导程序和μC/OS-II内核程序融合在一起,还必须将各自main()函数融为一体。

3.1 OS_CPU.H的移植

    μC/OS-II内核中OS_CPU.H代码是根据X86内核而写的,其中的数据格式定义与ARM9内核以及ADSv1.2开发平台不完全相符。OS_CPU.H的移植分为以下4个部分:

    (1)数据类型定义:在调试时发现,虽然定义8 bit或16 bit数据类型时,在编译过程中不会报错,但这些变量并不会按要求被正确初始化或赋值,运行过程常常出错。所以,在改写OS_CPU.H代码时,将所有变量都定义成32 bit或64 bit;

    (2)堆栈生长方向定义:ARM的堆栈是从上往下生长的,OS_STK_GROWTH定义为1;

    (3)开关中断的宏定义:用开关中断的汇编函数实现,放在OS_CPU_A.ASM文件中。

    (4)宏定义OS_TASK_SW():这个宏定义是在ARM中断处理之外时,μC/OS-II从低优先级切换到高优先级任务时所调用的代码,它总是在任务级代码中被调用。在有些资料中[1],将OS_TASK_SW()和OSIntCtxSw()等同起来,这在ARM内核中是不行的,因为后者是ARM内核在中断模式下的任务切换函数,而不同模式下处理器的寄存器组是不同的,所要保护的寄存器内容也不相同,经过调试,发现以下代码可达到目的。

OS_TASK_SW    
    stmfd    sp!, {lr}                         ; PC入栈,lr其实是任务的返回地址,
    stmfd    sp!, {r0-r12, lr}
    mrs        r4,  cpsr
    stmfd    sp!, {r4}                     ;最后保存CPSR        ldr        r4, =OSTCBCur
    ldr        r5, [r4]
    str        sp, [r5]                      ;将SP保存在当前任务的控制块中        ldr    r5, =OSTCBHighRdy
    ldr        r5, [r5]
    str        r5, [r4]                       ;OSTCBCur = OSTCBHighRdy        ldr    r6, =OSPrioHighRdy
    ldr        r6, [r6]
    ldr        r4, =OSPrioCur
    str        r6, [r4]                       ;OSPrioCur = OSPrioHighRdy
    ldr        sp, [r5]                    ;得到新任务的堆栈指针
    ldr        r4, [sp], #4        
    msr        cpsr_cxsf, r4                            ;先恢复CPSR
    ldmfd    sp!, {r0-r12, lr, pc}

3.2  OS_CPU_C.C.H的移植

    在OS_CPU_C.C中,最主要的函数是OSTaskStkInit(),它在任务建立时,用来初始化任务堆栈结构,其余钩子函数可以不用动,这个函数的代码比较简单[2]。需要说明的是,由于本文所述系统,用户任务运行在SVC模式下,没有保存SPSR寄存器。

3.3 OS_CPU_A.ASM的移植

    OS_CPU_A.ASM文件的汇编程序是μC/OS-II移植工程的重点和难点。它通常包括OSStartHighRdy()、OSIntCtxSw()、OSTickISR()和开关中断代码等。其中,OSStartHighRdy()的主要工作是将优先级最高任务对应的所有寄存器按顺序从任务堆栈中恢复出来,其代码简单[2]。对于开关中断函数,在调试时所用代码如下:

EnterCritical   
    mrs    r1, cpsr
    str    r1, [r0]
    orr    r1, r1, #NOINT
    msr    cpsr_cxsf, r1        
    mov pc, lr    
ExitCritical
    ldr    r1, [r0]
    msr    cpsr_cxsf, r1    
    mov pc, lr    

    需要指出的是,在每次成对调用这两个函数时,需要提前声明变量r,代码如下所示:

    INT32U          r;
    EnterCritical(&r);
    ExitCritical(&r);

    需要慎重对待的是OSIntCtxSw()、OSTickISR()函数。在调试时发现,用一般参考资料所介绍的代码都无法实现多任务的正常运行,其主要原因是,对ARM9内核而言,其每种特定的中断返回,都有特定的返回指令,在中断处理过程中,强制使用模式切换指令,使处理器的中断处理机制发生混乱,程序无法正常执行。例如在ISR模式中使用指令:

 MSR CPSR_c, #(NO_INT | SVC32_MODE)

其目的是返回ISR发生之前的模式,然后保存一些寄存器。但调试时发现,在上述指令执行之后,处理器重新响应ISR中断,并没有顺序执行,而是立即回到ISR模式下


 还有,对于S3C2410的ARM920T内核而言,其ISR模式的返回指令是:

    ldmfd    sp!, {r0-r12, lr}
    subs        pc, lr, #04

其他任何形式的指令都无法使处理器正确返回。有些资料用下述指令:

    Ldmfd  sp!, {r0-r12, lr,pc}; 执行之前堆栈中相应存储单元的内容为(lr-4)。

 看起来与前面的两行代码意义相同,但后面的代码仅仅让处理器实现PC指针的跳转,而无法实现处理器的模式转换,即从ISR模式回到中断发生之前的模式。

 但在中断发生时,无法在中断处理过程中保存所有的处理器寄存器。例如,在ISR模式下,无法保存SVC模式的LR寄存器等。为了解决这个问题,本文采取了如图1所示的框图结构来编写中断处理代码和OSIntCtxSw()函数。

    因为S3C2410在进入ISR模式后,自动屏蔽ISR中断,所以粗存在中断嵌套,可以表明2个全部变量ISR_LR和ISR_SPSR用于保存ISR中断发生之时处理器的lr和spsr寄存器。其代码的特别之处在于,在ISR中断处理过程中通过修改lr寄存器,而使处理器在退出ISR模式时能根据任务的需要返回至ISR中断发生之处或者代码指定地点。在代码指定地点,可以保存上次中断发生时被中断任务的处理器的所有寄存器数据。这里需要注意一点,当处理器退出ISR模式时跳转到Saveregister处开始执行命令,需要提前将Saveregister处的地址加上4,然后赋值给lr寄存器。因为在ISR退出时,需要将lr减去4再赋值给程序计数器pc。

4 S3C2410启动代码和μC/OS-II的融合

 本文1.1节已经介绍过,S3C2410的启动代码开始部分是汇编语言的初始化过程,然后跳转到main()函数。融合的工作就从改造S3C2410的main()函数和μC/OS-II的main()函数(在test.c中)开始。在S3C2410的main()函数中,保留原启动代码中关于端口、内存、外部设备初始化代码,删去跳转到Linux操作系统的代码;在μC/OS-II的test.c文件的main()函数中,删去一切与X86内核有关的初始化代码和输入输出函数代码(因为这部分代码在S3C2410的启动代码中已经实现),并将与 μC/OS-II内核有关的3个函数OSInit()、OSTaskCreate(…)、OSStart()复制到S3C2410的main()函数中,同时删去μC/OS-II的test.c文件。融合后的main()函数主要代码如下:

 ChangeClockDivider(1, 1);                           //1:2:4
      ChangeMPllValue(161,3,1);             //FCLK=203.0 MHz
      SetClockDivider(1, 1);
      SetSysFclk(FCLK_203M);
      Port_Init();
      Isr_Init();
      Uart_Init(0, 115200);
      Uart_Select(0);    
      MMU_Init();                                         //MMU 初始化
     EnableModuleClock(CLOCK_ALL);    
      rMISCCR &= ~(0x3007);
    OSInit(); 
    OSTaskCreate(TaskStart,……, 0); 
      OSStart();               

    至此,处理器已执行完S3C2410的启动代码,并开始执行μC/OS-II内核代码。当然,要实现多任务,处理器的中断必须是打开的。这个工作在OSStart ()函数中完成,在执行OSStartHighRdy之前,要按照系统的需求完成处理器的中断初始化工作,同时打开中断。至此,融合工作基本完成,剩下的工作就是按照系统的需求在μC/OS-II的TaskStart(…)函数中自由添加实际工作所需的任务了。

    在本文所述系统中,在μC/OS-II所带3个系统任务的基础上添加了3个任务Task1、Task2和Task3,方法是在OSStatInit( )之前添加OSTaskCreate(Task1,…)等代码,然后按下述格式和自己的需求编写Task1、Task2和Task3函数。代码为:

    void    Task1(void *data)
  {
          while(1)    { ;任务代码    }
  }

    因篇幅所限,无法详述在融合过程中遇到的所有问题,尤其是在ADSv1.2环境下编译、调试过程出现的语法问题和各种细节问题。

    随着科技的发展和实际任务复杂性的逐步增加,传统的单片机前后台编程模式渐渐不能满足实际应用的要求。在嵌入式应用开发中使用嵌入式操作系统已经成为一种趋势,本文在S3C2410开发板上将原有的引导程序和μC/OS-II操作系统结合在一起,开发出能自引导的μC/OS-II操作系统,该系统除了3个系统任务外,还自带3个实际任务,在ADSV1.2环境下编译、调试,并在板卡上成功运行,对μC/OS-II在ARM平台上的移植有一定借鉴意义。

关键字:嵌入式操作系统  μC/OS-II  ARM  S3C2410 引用地址:μC/OS-II在ARM平台上移植的深入探讨

上一篇:实时操作系统从RTOS移植到实时Linux
下一篇:μC/OS-II的多任务信息流与CAN总线驱动

推荐阅读最新更新时间:2024-05-02 21:06

瑞萨电子推出采用超小封装的全新RA MCU产品群
实现超低功耗和创新的外围功能 基于Arm® Cortex®-M23核心的全新RA2E2产品群,针对空间受限、功耗敏感的物联网终端、可穿戴设备、医疗、工业自动化及其他消费电子和家电等应用进行优化 2021年10月13日,日本东京讯 - 全球半导体解决方案供应商瑞萨电子集团今日宣布,其32位RA微控制器(MCU)产品家族推出全新产品群RA2E2。该系列产品基于Arm® Cortex®-M23内核,具备低功耗特性和适用于IoT终端应用的外设,封装包括采用1.87mm x 1.84mm的超小型16管脚WLCSP(Wafer Level Chip Scale Package,晶圆级芯片封装),构建独特的性能组合。全新48MHz RA
[单片机]
瑞萨电子推出采用超小封装的全新RA MCU产品群
μCOS-II在LPC213X上的多种移植方案
μC/OS-II是可移植、适用于对安全性要求苛刻的剥夺型实时多任务嵌入式系统,简单易学,在工程应用和嵌入式系统教学中很受欢迎。LPC213X是Philips公司推出的基于ARM7TDMI-S核的32位RISC微处理器,也适合于ARM学习开发平台和工程应用。 1 与μC/OS-II移植工作相关的主要特性 ARM体系结构分为7种运行模式,ARM和Thumb两种工作状态。LPC213X的编程模型就是标准的ARM7体系结构;同时LPC213X也具备ARM的标准异常模式IRQ和FIQ。稍具特色的是其VIC向量中断控制器。分别对IRQ、FIQ、非向量中断和软件中断进行了分类,具有对32个中断输入的可编程分配机制。这对于μC/OS-II的移植
[嵌入式]
基于ARM920T内核的S3C2410处理器的移动电子邮件终端
  该系统为基于无线局域网WLAN(Wireless Loeal Area Network)的无线电子邮件终端,用户可以方便地通过手写笔,在触摸屏上输入邮件内容,通过USB无线网卡收发电子邮件。当使用键盘输入时,插上USB键盘也能完成输入信息功能,在Email发送和接收方面,采用标准的STMP协议和POP3协议,考虑到一般的嵌入式设备Flash存储容量有限,该系统提供了U盘存储功能,用户能够将邮件转存在大容量的U盘。与传统的邮件客户端相比,采用无线网卡,无需连接网线即可实现Email的收发,适用于偏远山区及环境恶劣的地方;采用嵌入式终端,可移动性强,方便用户实时进行邮件操作。    1 系统硬件设计   基于开发的方便性和简便
[单片机]
基于<font color='red'>ARM</font>920T内核的<font color='red'>S3C</font>2410处理器的移动电子邮件终端
平台安全架构(PSA):下一步实现安全物联网的行业通用框架
  安全,毋庸置疑是 物联网 行业面临的最为关键的问题。然而,如今众多供应商林林总总各自发布的一系列安全申明令人感到困惑,如何有效实施安全措施变得无从入手。2017年10月, Arm 宣布了平台安全架构(PSA)——PSA是一个行业通用框架,允许 物联网 生态系统中的每位成员以更高的、可扩展的安全性以及更强大的信心向前迈进。下面就随网络通信小编一起来了解一下相关内容吧。   PSA旨在为 物联网 安全提供一套全面的安全指导方针,使从芯片制造商到设备开发商等价值链中的每位成员都能成功实现安全运行。在我们发布PSA之际,我们概述了PSA将向业界交付的目标,我们也一直在为实现这一愿景而不断努力。    威胁模型:建立“正确的”安全级别
[网络通信]
英考虑对英伟达400亿美元收购Arm提出附加条件
据知情人士透露,英国政府正在考虑对英伟达公司(Nvidia Corp.)将在英国保留的职位数量提出附加条件,这也是英伟达拟议收购英国科技企业Arm的一部分条款内容。 知情人士表示,政府官员们不太可能去阻止这笔规模为400亿美元的交易。但是英国政府提出的附加条件预计将保留约3000名英国员工,并要求Arm公司继续将总部放在剑桥。 目前Arm的东家是总部位于东京的软银集团(SoftBank Group Corp.)。软银在2016年以320亿美元收购了这家半导体巨头,当时软银也做出了类似的具有法律约束力的承诺。此外,软银还承诺在五年内会将Arm在英国的员工数量增加至少一倍。 英国政府有能力通过国家安全等因素干预收购交易。知情人士补充称
[手机便携]
基于ARM&Linux图形用户界面开发平台的设计
  1 引言   嵌入式产品如 PDA、机顶盒、WAP 手机等迅速地普及,给广大的非专业用户带来了极大方便。同时,这些产品都需要有高性能、稳定可靠的GUI(图形用户界面)来提供支持。   因此,在嵌入式产品的开发过程中,关键的一步就是嵌入式图形用户界面开发平台的设计。本文介绍了一种基于ARM、Linux 及MiniGUI 的图形用户界面系统开发平台的设计过程。   2 硬件平台设计及开发环境的搭建   2.1 硬件平台设计   硬件平台ARM221 为自行研发的基于AT91RM9200 处理器芯片的ARM 板,其核心板结构图如图1 所示。AT91RM9200 处理器是一款基于ARM920T 内核的高性价比、低功耗、32
[单片机]
基于<font color='red'>ARM</font>&Linux图形用户界面开发平台的设计
Intel CEO:ARM有天然优势,Ulrabook将重振PC市场
    在近日举行的瑞士信贷举办的科技大会上,英特尔总裁兼CEO保罗·欧德宁(Paul Otellini)亲自出席并发言,在回应关于外界关于英特尔质疑的同时,表达了其对超极本(Ulrabook)将重振PC市场的信心。                    英特尔CEO保罗·欧德宁 PC市场需求依然旺盛 超极本将为全民普及价 欧德宁首先谈到了PC市场依然存在旺盛的需求,他说:“在中国、巴西和印度,PC依然非常流行,这些地区将是未来PC的主力消费市场。也许目前市面上的PC确实有些过时,但产业内部会及时对产品进行调整,英特尔正在带领产业再次重新定义PC。”                   英特尔CEO保罗·欧
[工业控制]
利用NXP S32DS和IAR for Arm加快基于NXP S32K3 MCU的汽车软件开发
利用NXP S32DS和IAR Embedded Workbench for Arm加快基于NXP S32K3 MCU的汽车软件开发 一个如何充分结合原厂MCU开发环境与业内领先软件工具优势来加速关键任务应用开发的案例 随着市场需求和汽车行业不断推进电动化、网联化、智能化和共享化等 “新四化” ,工程师将会面对越来越多的软件开发项目,去用高性能的、获得车规级和功能安全认证的MCU开发相关应用。将MCU供应商匹配提供的MCU开发环境,与业内领先的开发工具相结合,将会给开发人员带来开发效率和成果性能的大幅提升。本文以在汽车行业被广泛使用的 S32K系列32位Arm Cortex汽车MCU为例 ,来介绍通过整合利用其S32DS开
[嵌入式]
利用NXP S32DS和IAR  for <font color='red'>Arm</font>加快基于NXP S32K3 MCU的汽车软件开发
小广播
最新嵌入式文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved