您的位置 首页 传感器

μC/OS-II实时操作系统内存办理的改善

摘要:分析了μC/OS-II实时操作系统在内存管理上存在的不足,提出了改进方法,通过一个具体实例描述了该方法的实现。关键词:实时操作系统 内存

摘要:剖析了μC/OS-II实时操作体系在内存办理上存在的缺乏,提出了改善办法,经过一个详细实例描绘了该办法的完成。

关键词:实时操作体系 内存办理 微处理器 链接器

μC/OS-II是一种开放源码的实时操作体系,具有抢先式、多使命的特色,已被运用到很多的微处理器上。尽管该内核功用较多,但仍是有不甚完善的当地。笔者在剖析运用中发现,内核在使命办理(包含使命调度、使命间的通讯与同步)和中止办理上是比较完善的,具有能够承受的稳定性和可靠性;但在内存办理上显得过于简略,内存分区的树立办法有不合理之处。

1 内存办理缺乏之处的剖析

在剖析许多μC/OS-II的运用实例中发现,使命栈空间和内存分区的创立采用了界说大局数组的办法,即界说一维或二维的大局数组,在创立使命或内存分区时,将数组名作为内存地址指针传递给生成函数。这样完成起来当然简略,可是不行灵敏有用。

编译器会将大局数组作为未初始化的大局变量,放到运用程序映像的数据段。数组巨细是固定的,生成映像后不行能在运用中动态地改动。关于使命栈空间来说,数组界说大了会形成内存糟蹋;界说小于了使命栈溢出,会形成体系溃散。关于内存分区,在不知道体系初始化后给用户留下了多少自在内存空间的状况下,很难界说内存分区所用数组的巨细。总归运用大局数组来分配内存空间是很不合理的。

别的,现在的μC/OS-II只支撑固定巨细的内存分区,简略形成内存糟蹋。μC/OS-II将来应该被改善以支撑可变巨细的内存分区。为了完成这一功用,体系初始化后能清楚地把握自在内存空间的状况是很重要的。

2 解决问题的办法

为了能清楚把握自在内存空间的状况,防止运用大局数组分配内存空间,关键是要知道整个运用程序在编译、链接后代码段和数据段的巨细,在方针板内存中是怎么定位的,以及方针板内存巨细。关于最终一条,体系编程人员当然是清楚的,第一条编译器会给出,而怎么定位是由编程人员依据详细运用环境在体系初始化确认的。因而,体系初始化时,假如能正确组织代码段和数据段的方位,就能清楚地知道用户能够自在运用的内存空间开端地址。用方针板内存最高端地址减去开端地址,便是这一自在空间的巨细。

3 举例描绘该办法的完成

下面以在CirrusLogic公司的EP7211微处理器上运用μC/OS-II为例,描绘该办法的完成进程。假定依据μC/OS-II的运用程序比较简略,以简化问题的论述。

3.1 芯片初始化进程和链接器的功用

EP7211采用了RISC体系结构的微处理器核ARMTDMI,该芯片支撑内存办理单元MMU。体系电复位后,从零地址开端履行由汇编语言编写的初始化代码。零地址寄存着中止向量表,第一个是复位中止,经过该中止向量指向的地址能够跳转到体系初始化部分,

履行微处理器寄存器初始化。假如运用虚拟内存,则发动MMU,然后是为C代码履行而进行的C环境初始化。之后创立中止处理程序运用的栈空间,最终跳转到C程序的进口履行体系C程序。

关于运用程序,ARM软件开发包含供给的ARM链接器会发生只读段(read-only section RO)、读写段(read-write section RW)和零初始化段(zero-initialized section ZI)。每种段能够有多个,对较简略程序一般各有一个。

只读段便是代码段,读写段是现已初始化的大局变量,而零初始化段中寄存未初始化的大局变量。链接器一起供给这三种段的开端地址和完毕地址,并用已界说的符号表明。描绘如下:Image$$RO$$Base表明只读段的开端地址,Image$$RO$$Limit表明只读段完毕后的首地址;Image$$Limit表明读写段完毕后的首地址;Image$$ZI$$Base表明零初始化段的开端地址,Image$$ZI$$Limit表明零初始化段完毕后的首地址。

一般嵌入式运用,程序链接定位后生成bin文件,即肯定地址空间的代码,因而上述符号的值表明物理地址。关于简略程序,可在编译链接时指定RO和RW的根底址,协助链接器核算上述符号的值。关于较杂乱的程序能够由scatter描绘文件来界说RO和RW的基地址。

3.2 详细实例及阐明

所谓C环境初始化,便是运用上述符号初始化RW段和ZI段,以使后边运用大局变量的C程序正常运转。下面是初始化部分的实例:

ENTRY ;运用程序进口,应该坐落内存的零地址。

;中止向量表

B Reset_Handler

B Undefined_Handler

B SWI_Handler

B Prefetch_Handler

B Abort_Handler

NOP ;保存向量

B IRQ_Handler

B FIQ_Handler

;当用户运用除复位中止以外的几个中止时,应将跳转地址换成中止处理程序的进口地址。

Undefined_Handler

B Undefined_Handler

SWI_Handler

B SWI_Handler

Prefetch_Handler

B Prefech_Handler

Abort_Handler

B Abort_Handler

IRQ_Handler

B IRQ_Handler

FIQ_Handler

B FIQ_Handler

;程序初始化部分

Reset_Handler

;初始化微处理器寄存器,以使其正常作业。

……

;发动MMU,进入虚拟内存办理。

……

;初始化C环境。

IMPORT |Image$$RO$$Limit|

IMPORT |Image$$RW$$Base|

IMPORT |Image$$ZI$$Base|

IMPORT |Image$$ZI$$Limit|

LDR r0,=|Image$$RO$$Limit|

LDR r1,=|Image$$RW$$Base|

LDR r3,=|Image$$ZI$$Base|

CMP r0,r1

BEQ %F1

0 CMP r1,r3

LDRCC r2,[r0],#4

STRCC r2,[r1],#4

BCC $B0

1 LDR r1,=|Image$$ZI$$Limit|

MOV r2,#0

2 CMP r3,r1

STRCC r2,[r3],#4

BCC %B2

在RAM中初始化RW段和ZI段后,ZI段完毕后的首地址到体系RAM最高端之间的内存便是用户能够自在运用的空间,也便是说Image$$ZI$$Limit是这一内容空间的开端地址。

假如体系运用了 FIQ和IRQ中止,在ZI段之后能够创立这两种中止的栈空间,然后是操作体系运用的SVC形式下的栈空间,假定每一个栈巨细为1024个字节。假如体系运用了定时器,还可在此之后创立定时器中止的栈空间,假定其巨细也为1024个字节。此刻自在内存空间的开端地址变为:

Image$$ZI$$Limit+1024×4

在初始化代码的最终将其作为一个参数传递到C程序进口,代码如下:

LDR r0,=|Image$$ZI$$Limit|

;创立IRQ栈空间。

……

;添加地址指针。

ADD r0,r0,#1024

;创立FIQ栈空间。

……

;添加地址指针。

ADD r0,r0,#1024

;创立SVC栈空间。

……

;添加地址指针。

ADD r0,r0,#1024

;创立定时器中止栈空间。

……

;添加地址指针。

ADD r0,r0,#1024

;导入C代码进口点。

IMPORT C_ENTRY

;跳转到C代码,此刻r0作为进口参数。

B C_ENTRY

3.3 对实例的总结

在C程序中,上述开端地址能够作为内存分区创立函数OSMemCreate()的内存地址参数,内存分区的最大值便是方针板RAM的最高端地址减去开端地址的值。图1显现了RO段在RAM中的内存散布状况,这种状况下,程序映像一般被保存方针板内存中。体系从闪存发动后,将RO段拷贝到RAM中持续履行。图2显现了RO段在闪存中,RW和ZI段在RAM中的状况。这种状况下,体系发动和代码的履行都发生在闪存中。

用户知道开端地址的值和自在内存的巨细后,就能够清楚、灵敏地树立和运用内存分区了。能够依据详细需求树立一些巨细不同的内存分区,使命栈、事情操控块和音讯行列都能够在这些内存分区中分配。体系能够十分明晰地把握内存运用状况。

本文针对一种芯片描绘了怎么完成对μC/OS-II内存办理的改善。关于其它类型的微处理器,例如CISC指令集的芯片,尽管详细完成进程有所不同,但思路是相同的。

μC/OS-II的内存办理还有需求改善的当地,例如,现在的内存办理只支撑固定巨细的分区,而实践运用中有动态分配非固定分区的需求。这就要求μC/OS-II有完成该功用的软件结构和内存分配、收回算法。现在能清楚地把握体系初始化后内存散布状况,为往后完成这些软件结构和算法打下了根底。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/chuanganqi/299627.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部