随着8051微控制器性能的不断提高,使用多任务操作系统对单片机进行资源管理已成为当代开发的需要。由于受静态链接的限制,8051系统的多任务开发需要处理代码重入(reentrance)的问题。
为了实现重入,通常可以利用Keil C51的关键字reentrant,将函数声明为重人类型。通过在重入堆栈分配局部变量,使函数具有可重入性;但该重入方案的实时性较差。
为提高多任务系统的实时性,本文介绍一种新方案——基于页的多任务模型。
1 重入函数的原理与不足
当使用Kcil C51的关键字reentrant来指定函数届性时,即得重入函数(reentrant function)。
1.1 重入函数的原理
重入函数的原理是Keil C编译器建立一个软件操作的重入堆栈。重入函数能自动为不同的调用者在重入堆栈中分配独立局部变量,使函数具备重入性。
变量分配过程如图l所示,函数人口首先申请存储空间。函数返回前,必须将所申请的存储空间归还。变量分配和回收的位置都是重入堆栈的栈顶。
1.2 重入函数的不足
重入堆栈的最大缺点为效率低,Keil C51用户手册中已有明确记载。
由图l可作以下分析:首先,每次使用局部变量都需要计算变量地址,大大降低了变量存取速度,也消耗了处理器时间;其次,因为重入堆栈是纯软件实现的,因此反复进行的堆栈操作使重入函数的实时性进一步恶化。
2 基于页的多任务模型原理与实现
2.1 原理
解决函数重入的关键在于局部变量的分配,可以从8051存储器类型的分析和选择入手。
8051控制器能直接寻址的存储器类型很丰富。在这些类型中,我们注意到了页变量(pdata)及其与众不同的特性。
(1)页变量pdata
根据Intel公司的用户手册,805l的页存储器就是指单字节地址方式操作的外部存储器。使用单字节地址方式时,允许使用P2对外部数据来分页,该方式的操作指令为“MOVX@Ri”。指令中R0或R1提供页内地址(低8位地址),P2寄存器隐藏地提供页地址(高8位地址)。
单字节地址方式将8051的64 KB外部存储器分成256个页面,如图2所示。其硬件特征如下:①系统的256个页面的存储结构完全一致;②工作页面可以被指定为这256页中的任意一页;③页地址由P2隐式提供给地址总线,且页地址可以由程序修改。
工具方面,Keil C51专用关键字pdata表示单字节方式寻址的外部数据类型,pdata变量即页变量。编译后的页变量具有以下特性:①页变量操作严格对应单字节地址方式;②页变量全部转换成了静态页内地址。
(2)页函数
根据页变量性质,只要函数的所有局部变量都被指定为页变量类型,那么,函数所生成的代码就可以工作于系统任一页面上。
当操作系统为一个函数分配多个页面时,该函数与每一个页面上的局部变量均构成一个进程。
与重入函数不同,这类函数本身不能自动分配变量,因此没有重入性。只有在操作系统的协助下,为其分配工作页后,页函数才是可重入的。页函数中变量使用静态地址,因此其存取速度得到大幅提升,改善了系统的实时性。
为区别Keil C51定义的重入函数(reentrant func-tion),我们称这种只使用页变量的函数为“基于页的重入函数(page-based reentrant function)”,简称为“页函数”。
2.2 实现
根据原理分析中的可行性,笔者设计了名为Celia的基于页的占先式8051多任务调度内核。沿用μC/OS-II的结构框图与处理流程,在TCB(Task Control Block,任务控制块)中增加一个字节的页面字段,并改写了部分程序。有μC/OS-II为参照,使该调度内核的设计可以很快完成。经过在以W78P438为核心的平台上实测,该系统调度正常,程序运行正确。这证明该重入方案可行。
3 基于页的多任务模型性能分析
基于页的多任务模型的程序结构与μC/OS-II基本一致,其区别主要是页函数与重入函数的区别,因此,这里主要分析页变量存取与重入堆栈变量存取的性能对比。
3.1 优点
(1)更高的变量存取带宽
8051为8位总线接口,单字节存取是其基本操作。研究单字节变量的存取带宽可以从根本上说明页变量的优点。
805l系统操作外部存储器使用的是MOVX指令。执行该指令需要2个机器周期。在标准8051中,1个机器周期为12/fOSC,则总线带宽如式(1)所示。其中fOSC为晶振频率。
如图l,重入函数操作单字节变量i=0xaa,共需要15个机器周期。其中仅计算变量地址就需要12个机器周期。因此,重入堆栈的实际存取带宽如式(2)所示。
相对地,页函数中变量地址是确定的。因为不需要计算地址的额外操作,其变量操作速度比重入堆栈有大幅提高。如图3所示,页函数中操作单字节变量只需要4个机器周期。页变最的实际存取带宽如式(3):
各种带宽的对比如下:
进一步分析可知,操作多字节变量时,重入函数也只需要计算一次变量地址。故进行单字节变量存取时,重入堆栈的存取带宽就是最低值。
综上所述,相对重入堆栈,存取单字节变量过程中,页函数的带宽加速比达到最大值Rmax=3.75,如式(4)所示。这表示相对于过去的重入函数,页函数具有更高的执行效率和实时性。
另外,如果页函数不需要计算和操作重入堆栈指针,则不需要图1中函数入口和出口处的指针操作(C?ADDXBP),可再次节省22个(首尾各11)指令周期。
(2)较好的安全性
配置页面的工作是由操作系统完成的。在使用基于页的多任务开发中,任务本身不能更换页面;因此,私有变量的操作只在当前页进行,不会影响到其他页或其他任务。这样的程序封装体现了较好的安全性。
3.2 存在问题与解决方法
(1)容量的限制
8051的硬件决定了页面大小为256字节,不可变更。这使得“页面容量限制”成为基于页的多任务开发中最需要考虑的问题。
存储器的一页为256字节,与最小模式下8051的内部数据空间(IDATA空间)大小相同。因此,笔者认为页变量的256字节能满足最小模式任务的需要。
对于需求超过256字节的任务,可在页面外的外部存储器中申请后备空间。只要指向后备空间的指针在页面内,则该后备空间仍是私有的,满足重入条件,其结构示意图如图4所示。虽然后备存取区使用指针操作,但不需要计算变量地址,因此后备存储区存取速度优于重入堆栈。
(2)工具的限制
目前,Keil C51开发工具不提供多任务以及多页面支持。这主要体现在两点:
①需要新的函数库。现有的大量函数库不支持页函数方式重入。准确地说,大部分函数库不支持任何方式的重入——即使使用重入堆栈,函数库问题也依然存在。目前的解决方法只有程序员根据需要编写新的页函数库。
②一个项目中只允许存在一个pdata页面,不能按任务将变量安排在不同的逻辑页面上。其后果是,多任务开发中,编译链接工具只在同一个页面中分配所有任务的页变量,导致存储器迅速溢出。
问题②的解决方案是:为使每个任务具有自己的工作页,为每个任务单独建立工程,并使用COMPACT方式进行编译。各个任务工程之间和操作系统之间使用绝对地址表传递系统调用和任务入口地址。绝对地址表是对一些系统调用的约定地址。
这些不便之处是暂时的、可克服的。
结语
8051主要应用领域为实时控制,因此努力提高系统实时性是开发者不断追求的目标。笔者从提高实时性的角度出发,提出了一种基于页的多任务模型。相对于目前重入堆栈多任务模型,它具有较好的实时性,也是处理重入问题的一种新思路。
本模型已经过Keil C5l仿真工具的一般性测试,并在W78P438芯片上实测成功,相信其结果适用于全部8051及兼容系列。考虑到8051依然广泛应用在多任务开发中,本文中的新模型值得推广。
评论
查看更多