当前位置:首页 > 嵌入式 > 嵌入式硬件
[导读]O 引言目前,市场以及院校科研用嵌入式系统产品,如Vxworks,Linux和Windows CE等都已经相当成熟,提供了有力的开发和调试工具,但有些开发成本昂贵,周期较长,而μC/O

O 引言

目前,市场以及院校科研用嵌入式系统产品,如Vxworks,Linux和Windows CE等都已经相当成熟,提供了有力的开发和调试工具,但有些开发成本昂贵,周期较长,而μC/OS-Ⅱ是一种多任务实时源代码的公开操作系统,内核精简,移植性较强,非常适合用于一些小型控制和实验系统的开发。

1 操作系统及CPU介绍

μC/OS-Ⅱ是基于优先级的占先式实时多任务操作系统,包含有任务管理、时间管理、任务间同步通信(信号量,邮箱,消息队列)和内存管理等功能。绝大部分代码用C语言写成,极少部分与处理器密切相关的代码用汇编语言编写,便于移植。作为一个源代码公开的实时操作系统,最多可以管理64个任务,并支持信号量、邮箱、消息队列等多种进程间的通信机制,同时用户可以根据需求对内核中的功能模块进行裁剪。

LPC2378是一款基于ARM7TDMI-S内核的嵌入式精简指令集微控制器,包含了1个支持仿真的ARM7TDMI-SCPU,适用于为了各种目的而需要进行串行通信的应用。该体系机构支持用户、软中断、中断、管理、中止、未定义、系统等7种处理器模式,ARM7TDMI-S处理器内部有31个通用32位寄存器,6个状态寄存器。LPC2378包含了1个10/100 EthernetMAC,USB 2.0全速接口,4个UART接口,2路CAN通道,1个SPI接口,2个同步串行端口(SSP),3个I2C接口,1个I2S接口和 MiniBus(MiniBus仅用于LPC2378,它是8位数据/16位地址并行的总线)。下面以μC/OS-Ⅱ在工业级芯片LPC2378上的移植为例,通过分析操作系统内核来介绍μC/OS-Ⅱ操作系统移植的一般方法和过程及相关问题的解决。

2 μC/OS-Ⅱ内核结构及工作原理

2.1 内核基本结构

图1是接近μC/OS-Ⅱ的简单内核体系结构图,内核保留给上层应用的接口有3个,分别是软保护、ITC和DSR。由于μC/OS-Ⅱ操作系统内核是可剥夺型实时多任务内核,因此最高优先级的任务一旦就绪,总能得到CPU的使用权。如果是中断服务子程序使一个高优先级的任务进入就绪态,则中断完成时,中断了的任务被挂起,优先级高的任务开始运行。

 

2.2 μC/OS-Ⅱ内核基本工作原理

多任务系统中,操作系统内核负责管理各个任务,或者说为每个任务分配CPU,并且负责各任务之间的通信和协同,任务切换是内核提供的基本服务。μC/OS-Ⅱ多任务操作系统的基本工作原理如下:

(1)在使用μC/OS-Ⅱ的所有服务之前,必须调用初始化函数OSInit(),初始化所有的变量和数据结构,同时创建空闲任务 OSTaskIdle(),并赋予最低的优先级别和永远的就绪态,同时完成任务控制块(TCB)的初始化、TCB优先级表的初始化、TCB链表的初始化和事件控制块(ECB)链表的初始化。

(2)调用OSTaskCreate()或OSTaskCreateExt()创建至少一个新任务,并给任务赋予一定的优先级,而且它们有各自的一套CPU寄存器和自己的栈空间。

(3)调用OSSTART()函数,通过从任务就绪表中找出用户建立的优先级别最高的任务控制块,然后开始多任务调度。

3 μC/OS-Ⅱ在LPC2378上的移植过程及相关问题分析

现以LPC2378微控制器上的移植为例,分析μC/OS-Ⅱ操作系统移植的一般方法,所采用的开发环境为ARM公司的集成开发环境ADS1.2。

3.1 移植代码

(1)μC/OS-Ⅱ与CPU类型无关的代码有μC/OS-Ⅱ.H,μC/OS- Ⅱ.C,OS_CORE.C,OS_TASK.C,OS_TIME.C,OS_SEM.C,OS_MBOX.- C,OS_MUTEX.C,OS_FLAG.C,也就是说这些文件可以不用修改就直接添加。

(2)μC/OS-Ⅱ与CPU类型有关的代码有OSCPU.H,OS_CPU_A.ASM,OS_CPU_C.C,也就是说用户需要根据所选CPU的类型将这些函数进行修改后才能添加入内核。

3.2 OS_CPU.H文件的定义与修改

OS_CPU.H文件定义了与编译器及CPU相关的数据类型、堆栈的宽度和增长方式以及开关中断的宏定义。由于微处理器和微控制器所支持的堆栈增长方式不同,这里需要根据所选芯片LPC2378支持的类型对宏OS_STK_GRWOTH进行定义,由于ARM7 TD-MI-S内核堆栈支持从上往下的生长方式,所以应做如下定义:

#define OS_STK_GROWTH 1 //堆栈是从上往下长的OS_CPU.H文件中另外3个宏 OS_CRITICAL_METHOD,OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL()用于定义开关中断的方式及开关中断的实现。通过调用开关中断2个宏来保护临界代码如下:

 

3.3 OS_CPU_C.C文件中主要函数的定义及编写

OS_CPU_C.C中要求用户编写10个简单的函数:

 

结合要移植的CPU内核的硬件和寄存器特性,简要对任务堆栈初始化函数进行分析和创建:

 


其他9个函数必须声明,但并不一定包含任务代码。

3.4 μC/OS-Ⅱ的移植

μC/OS-Ⅱ的移植,还要求编写4个简单的汇编语言函数;即OSStartHighRdy(),OSintCtxSw(),OSTIckISR(),OSCtxSw()。

3.4.1 函数OSStart()调用OSStartHighRdy()

函数OSStart()用于调用OSStartHighRdy(),以使使就绪态任务中优先级最高的任务开始运行:

 


3.4.2 时钟节拍中断服务程序

μC/OS-Ⅱ要求用户提供一个周期性的时钟源,以实现时间延迟和超时确认功能,时钟节拍每秒发生10~100次。必须在开始多任务后,启动时钟节拍中断,但由于Osatart()函数不会返回,用户无法实现这一操作,所以可以在OSStart()运行之后,μC/OS启动的第1个任务中初始化节拍中断。基于LPC2378移植下OSTicklSR()的简易代码编写如下:[!--empirenews.page--]

 


当时钟节拍中断发生时,CPU会自动把CPU寄存器推入堆栈,但并不包括存储页面寄存器PPAGE,如果单片机系统的寻址范围超过64 KB,则需要通过给PPAGE赋值来区分不同的16 KB地址,需要把PPAGE也推入堆栈。当某任务的任务控制块中时间延时项OSTCBDly减到了零,OSTi-mtick()就进入了就绪态。 OSIntExit()会调用中断级的任务切换函数OSIntCtxSw执行任务切换,而不再执行后面的指令。如果没有更高优先级的任务进入就绪态,则 CPU会返回中断前状态。

3.4.3 任务级任务切换

实际上任务级的切换就是通过执行软中断指令,或者根据处理器的不同,执行TRAP指令来实现。中断服务子程序、TRAP或者异常处理的向量地址必须指向OSCtXSW(),利用系统在跳转到中断服务程序时会自动把断点指针压入堆栈的功能,把断点指针存入堆栈,而利用中断返回指令IRET,能把断点指针推入CPU的PC寄存器功能,恢复待运行任务的断点,这样就可以实现断点的保存和恢复。

 


3.4.4 中断级任务切换

OSIntExit()通过调用OSIntSw(),在ISR中执行任务切换函数。因为OSIntCtxSw()是在ISR中被调用的,所以假定所有的处理器寄存器都被正确地保存到了被中断任务的堆栈中。OSIntSw()函数的绝大多数代码与OSCtxSw()函数是一样的,区别只是:因为 ISR已经保存了CPU的寄存器,而不再需要在OSIntSw()函数中保存CPU的寄存器。在进行操作系统移植时,该段程序的代码如下:

 

 


3.5 移植中的问题

ARM处理器的软件调试通过JTAG口直接在系统的外部SRAM运行,因此在程序调试之前,ARM处理器的开发环境软件首先调用初始化文件 (*.ini),用户可以根据自己系统的外部存储器和设备的地址来修改文件。如果该文件有误,开发环境软件将无法通过JTAG与处理器通信。系统调试过程中,经常会出现程序跑飞的现象,经过测试与分析,主要有4个方面原因:

(1)中断处理程序的中断矢量地址没有正确赋值,从而导致发生中断后CPU无法运行到中断处理程序位置;

(2)在OsctxSw和OSIntctxSw中的任务切换语句后加人几条NOP空语句,确保任务切换的相应指令执行结束,如果在这些位置没有加相应的空操作指令,也会导致程序跑飞;

(3)由于堆栈的空间分配不够,以及没有给CPU的各个工作模式分配空间,导致任务切换时,堆栈溢出;

(4)μC/OS-Ⅱ要求用户提供一个时钟资源来实现时钟节拍,时钟节拍应该每秒钟发生10~100次,用户必须在开始多任务调度后(即调用 OSStart后)允许时钟节拍中断。通常的错误是在调用OSlnit()和OSStart()之间允许时钟节拍中断,同时用户不要单纯地追求实时性,而将系统的时钟节拍频率增加太高。以上几个方面的问题解决后,系统的工作非常稳定。

4 系统测试

移植完成后的系统包括4个部分:自启动程序、μC/OS-Ⅱ系统文件、移植代码、应用程序。开发环境是ARM公司提供的ADSl.2(ARM Dev-eloper Suite)。该系统创建了以下3个任务来验证μC/OS-Ⅱ的移植成功:

 

 

在为自己的微处理器做完μC/OS-Ⅱ的移植后,首先建立3个任务,之后不加任何其他应用代码来测试移植好的μC/OS-Ⅱ,也就是说应该先测试内核自身的运行状况。这样做有2个原因:不希望将事情复杂化;如果有些地方没有工作可以明白是移植本身的问题,而不是应用代码产生的问题。经过测试和修改,无相关错误产生,说明移植成功。

5 结语

μC/OS-Ⅱ具有很强的移植性,具有多任务实时可剥夺型内核,而且代码量较小,源代码开放,可被广泛移植到8位、16位等许多微处理器上。国外诸如APC,ROTEK等企业都在产品中成功地使用了μC/OS-Ⅱ内核,不仅开发成本低,而且系统精简,因此将μC/OS-Ⅱ移植到LPC-2378 这种工业级的芯片上,具有相当的商业价值。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭