分享

嵌入式操作系统的简化及其在电力保护系统中的应用

 WUCANADA 2013-02-15
嵌入式操作系统的简化及其在电力保护系统中的应用
作 者:上海同济同捷科技有限公司  赵 杰

1  引言
近 年来,随着微计算机软、硬件技术的不断进步,嵌入式系统的开发研究已成为工程界应用研究的热点。国内外越来越多的厂家青睐以uclinux为代表的功能强 大且完全免费的linux操作系统为开发平台,快速开发出成本低廉、性能忧异的各类产品。和过去使用简单的实时操作系统甚至没有使用任何操作系统的嵌入式 程序设计相比,采用基于linux的成熟、高效、健壮、可靠、模块化和易于配置的操作系统来开发用户的应用程序,无疑能进一步提高开发效率,并使之具有很 好的可移植性。
在电力保护系统中,如母线保护、线路保护、发电机保护和变压器保护等,一般高端用户采用的多是基于mcf5282等32位高性能微 处理器,并采用汇编或c语言开发系统,但所开发的系统可移植性差,由于缺乏底层功能调用接口,系统开发量大,若采用嵌入式系统开发平台uclinux就可 以较好地解决上述问题。但uclinux内核有750k左右,不可能固化在mcf5282的512k flash内,若能将其裁剪到约300k左右,再加上200k左右的控制算法代码,就有可能将uclinux嵌入到mcf5282的512k flash内,这样就可以充分利用uclinux系统的强大功能和可移植性好的优势,方便快速地开发出新系统。本文探讨如何将uclinux简化以满足上 述需要。

2  嵌入式系统简介
mcf5282是 motorola公司生产的32位微处理器,该处理器采用coldfire v2可变长risc处理器核心技术。mcf5282的处理能力在80mhz时钟下工作时其性能与76dhrystone2.1mips相当,其硬件乘法累 加mac单元可用于数字信号处理运算,处理速度快和运算能力强[6]。mcf5282内部的sim单元有丰富的外围器件接口: ethernet模块、i2c模块、qspi接口、dma模块、qadc模块等等,从而简化了控制器外围电路设计,降低了产品的设计成本,减少了体积和功 耗。因此,嵌入式网络控制器选用mcf5282作为系统的微处理器,对工业现场和网络测控的应用独具优势。
uclinux是linux的嵌入式系 统版本,其显著的特征是无需要硬件mmu的支持,特别适合于那些没有mmu处理器的应用,例如motorola公司的coldfire系列、dragon ball系列处理器等。uclinux可移植性强,它可移植到68k、coldfire、power pc、arm等多种处微控制器中[4],其内核可以定制、修改,重编译后可适合于各种特定的嵌入式应用场合。但是在稳定性、强大的网络功能和出色的文件系 统支持等方面却继承了linux操作系统的主要优点[3],因此uclinux在嵌入式应用领域中受到了广泛的关注。

3  uclinux在mcf5282系统中的系统应用
某电站继电保护系统改造后的系统框图如图1所示。
该 系统用于100kv高压母线保护,通过a/d端口采集高压线上的电压变化,经过mfc5282的滤波、模型匹配检测和判定,最后输出相应的控制信号。 lcd显示模块提供人机操作界面,用于电压、电流参数的实时观测和系统参数设置,并用于各种信息管理。外扩flash用于保存不同用户通过人机操作界面产 生的操作记录以及系统产生的报警和提示信息等。各种采集信息、操作记录和系统参数,都可通过ethernet或can总线与主机系统进行交互。 uclinux提供了对a/d采集、滤波、用户操作、记录保存、ethernet和can传输等操作的多进程管理,调度、通信的支持和对多种文件系统操作 的支持。

图1     继电保护系统框图

4  uclinux的移植
移植前首先要搭建交叉 编译平台,安装交叉编译工具链,包括gcc,binutils,uclibc, 安装步骤可参见[1]。准备就绪后即可进行移植操作,在移植过程中最大的困难是如何压缩uclinx系统的空间。对此本文从两个方面着手:内核配置级裁剪 和内核源代码级裁剪。
4.1  内核配置级的裁剪
该方法是普遍采用的最直接 和最有效的方式。具体做法是将必要的功能编译到内核配置菜单中,去除不用的功能。系统对内核性能要求如下:文件系统,仅支持记录型文件系统 (refs);can总线驱动模块,ethernet驱动模块,串口驱动,并口驱动,lcd驱动,a/d驱动,usb驱动。在菜单中选择的网络设备支持 tcp/ip协义和can设备支持,usb支持,块设备,字符设备支持。对uclinux内核不支持的设备,用户可以编制所需的设备驱动程序,然后添加进 到内核。配置完内核后,在对内核源代码文件的依赖性和完整性进行检验,最后作编译[1]。
4.2  内核源代码的裁剪
uclinux 内核包括:进程管理模块、内存管理模块、文件系统、设备驱动模块和网络模块。在内核中文件系统和设备驱动程序占了约1/3以上的比重,删除不必要的文件系 统和设备驱动程序后,其内核大小将有较大幅度的缩减。考虑整个根文件系统约占用700k字节,因此为了缩减系统必须删除根文件系统,但内核与应用程序必须 一体化,系统的框架如图2所示。为了保持vfs向上层提供统一接口,系统中删除根文件系统后,仍应保留vfs。对文件规模小的嵌入式系统,vfs应减小规 模和裁剪功能。规模的减小主要是靠删除不需要的物理文件系统、设备驱动程序及其系统调用源码。功能简化主要是简化部分数据结构和系统调用。refs文件系 统是根据电力保护系统特点而开发的一种新的文件系统。根文件系统缺失所带来的影响在后文将作详细分析。

图2     系统框架


(1) 根文件缺失对系统调用的影响
系统调用约有177个,包括进程调用函数、文件调用函数以及其它相关的调用,其中文件系统调用占71个。由于没有根系统,系统调用中没必要从根文件系统上装载、执行可执行文件,所以必须做相应的更改。例如,系统调用execve( ),执行流程如图3所示:

图3     execve()执行流程


do_execve( )是execve( )的核心,它调用open_exec( )寻找可执行文件,函数open exec()返一个file结构指针,表示读入可执行文件的上下文,并将其保存在数据结构bprm中。然后调用prepare_binprm( ),以完成对bprm的后续工作,包括从可执行文件头读取相关信息,以及考贝运行环境参数等到bprm中。内核中有一个叫formats的队列,队列中的 每个成员只认识并且处理一种特定格式的可执行文件。search_ binary_handler( )在formats的队列中寻找跟bprm中的信息相符的成员,并由该成员完成可执行文件的装载和初始化运行。由于不存在从文件系统加载可执行文件问题, 所以bprm数据结构及涉及prepare_binprm( ), search_binary_hanlder( )等相关操作都可以删除。
其 次,由于没有可供挂载的文件节点,有关挂接的系统调用也必须做相应调整。比如:mount()用于文件系统挂接的系统调用,完全可以删去;内核函数 mount_ root( )在初始化时用于安装根文件系统,同样可以删去; vfsmount( )是内核数据结构,用于描述挂载节点的信息,包括挂载点的根目录,被挂载系统的级块指针等信息。内核中凡涉及操作该数据结构的函数也须更改,比 如,alloc_vfsmnt()和free_vfsmnt()用于分配和释放vfsmount结构,可以删去,但有些内核函数部分地涉及vfsmnt结 构操作,不能全部删除,只须对其相应部分做出修改。
(2) 根文件缺失对内核启动初始化的影响
由于init( )进程不能从根文件系统加载,凡是涉及根文件系统初始化函数的都必须删除,以支持内核与应用程序的一体化。初始化进程init代码如下:
static int init(void * unused)
{ . . .
if (open("/dev/console", o_rdwr, 0) < 0)
. . .
if (execute_command)
execve(execute_command,argv_init,envp_init);
execve("/sbin/init",argv_init,envp_init);
. . .
panic("no init found. try passing init= option to kernel.");
}
init( )完成系统的初始化:初始化外部设备;释放init( )之前代码占用的内存;初始化控制台;从根文件系统加载整个系统的第一个进程init。由于根文件已经删除,因此可删除控制台和调用的init进程。
(3) 根文件缺失对refs和外部设备的影响
refs 可直接当成根文件系统安装,但它并没有bash, gretty等应用程序,也不具备挂载其它系统的能力,不是真正的根文件系统。内核中有几个跟文件系统和外设相关的重要内核的全局变 量:file_system_type,blkdevs[max_blkdev],chrdevs[max_chrdev],super_block。
file_system_type 是一个用于描述系统中所有支持文件系统的数据结构。vfs用于维护该数据结构列表,全局指针变量为file_systems[2]。为了系统识别,新文件 系统必须通过register_filesystem( )注册,即是在链表file_systems结尾插入一个file_system_type数据结构。blkdevs[max_blkdev]和 chrdevs[max_chrdev]分别为块设备和字符设备的注册数组,包含主设备号和次设备号,以及有关设备操作的跳转指针。块设备和字符设备分别 通过register_blkdev()和register_chrdev()向系统注册设备。super_block是超级块数据结构,用于存放整个文 件系统的信息和超级块操作的函数。在通用内核中根文件系统安装的顺序是:从file_systems处取得根文件系统的read_super(), read_super()指向具体的驱动程序读操作,通过读操作取得超级块,然后在内存中创建inode,file, dentry等数据结构,用于文件的读写操作。在这里,可以用与根文件系统相同的装载方法初始化refs系统,但是比前者简单得多,因为后者不涉及安装挂 载点及与此相关的操作。对于外设,内核一般是通过根文件系统搜索到设备文件后,再访问外设。其中涉及到搜索路径和挂接点到外设的问题,由于在本系统中外设 是独立的,不依赖于根系统,实现起来更简单,可以直接依据内核数据结构blkdevs[max_blkdev]和chrdevs[max_chrdev] 提供的操作函数表指针调用驱动程序操作外设。

5  内核与应用程序的一体化
内核通过创建进程的 方式实现内核与应用程序的一体化。创建进程可以采用内核函数do_fork( )和do_execve( ),也可以仍然用系统调用fork()和execve(),因为不带mmu的微控制器,内核与应用程序是一样的,没有特权之分。经过修改过的 execve()可直接采用跳转到可执行文件入口点,运行应用程序。应用程序跳转表为
struct app_table{
int (*app_main)();//主程序
int (*lcd_window)();//人机操作界面管理程序
int (*ad)();//a/d采样程序
...}
然后在init()末尾添加代码如下:
if(fork()==0) execve(app_table->app_main);
else panic("no app_main found.");
...

6  新型文件系统(refs)的开发
电力保护系 统中要保存的文件大都是一条条操作记录或系统警告提示信息,有固定的数据格式和长度,就好像数据库里的记录一样。记录格式,如:××年××月××日××时 ××分××秒××××动作,前面是动作发生的时间,后面是发生的动作,比如删除,更改,警告等等,分别用唯一的标识来代表。不同用户有不同的操作权限,可 形成不同的操作记录,系统发生警告、错误信息也会产生记录。借鉴ext2和jffs2等可开发一种新文件系统,本文中称为refs记录型文件系统,其存储 的物理结构如图4所示:

图4     refs结构图


数据块的大小是记录大小的n倍,是数据分配的最小单位,可以事先给不同用户分配不同的的空间,也可以限制用户使用的存储空间,然后动态地分 配实际物理块。一个节点代表一个文件,文件是不同用户操作记录的一个集合,可由多个数据块构成。由于空间有限,可将整个空间构成一个循环链表,插入和删除 的动作分别在表头和表尾进行。随着时间增长和记录条数的增加,整个存储空间会饱和,后面存进的记录会覆盖前面的记录,由于在这之前系统会隔一断时间将记录 通过网络传送到主机,而且外扩16m flash,一条记录以24byte计算,可以保存约50万条的记录,因此数据在被覆盖前早已失去应用价值,所以只需对链表进行插入,删除,查找等简单操 作,就可以轻松实现对该文件系统的管理。待整个文件系统的数据结构和操作函数完成后,把该文件系统加进uclinux中去。该步骤主要是构造超级块、节 点、文件在内存中的结构,然后写出相应的超级块、节点、文件操作函数集 super_operations,inode_operations,file_operations(细节略,可参考文献[2])。再编写 read_super函数和注册函数init_refs_fs,最后在linux的初始例程filesystem_setup()函数中添加:
#ifdef config_refs_fs
init_refs_fs();
#endif

7  驱动程序的开发
由于内核中没有相关的驱动程 序支持,所以在系统中要开发a/d转换的驱动程序和lcd显示模块的驱动程序,程序的具体开发过程可参考文献[5]。然后定义 file_operations结构,再用register_chrdev()和register_ blkdev()函数在操作系统中将设备注册,即向uclinux管理的设备链表中加入一个节点,使用request_irq()函数注册中断向量,实际 上就是向内核注册一个设备文件(主设备号/次设备号)及其一系列标准操作接口。

8  实验仿真
本实验包括uclinux简化和向 mcf5282移植两个方面。uclinux简化属于高层次的软件设计和开发,一般不用考虑底层硬件的实现细节,先在一个提供源码级调试的软件仿真器上进 行开发,由于市场上暂时还没有mcf5282的软件仿真器,采用mcf5206的coldfire emulator0.3.1软件仿真器替代作近似仿真,在保证基本功能不变的情况下精简uclinux,其大小可控制在250k左右。裁剪完毕后,利用 mcf5282evb开发板,加进板级开发包和硬件驱动的程序,进行硬件的移植调试,经过不断的反复调试修改,再与其它控制程序进行整合,使整个系统可嵌 入到512k的flash内。实验表明,改进后的系统运行效果良好。

9  结束语
将简化的uclinux写入512k flash内,增加了系统的可移植性,易于扩展,提高了后续应用程序开发的效率。但由于对原系统的某些功能作了裁剪、删除,在一定程度上影响了 uclinux系统原有的可扩展性和移植性,从本质上看,文中提出的只是一个折衷方案,但相对于原系统从硬件底层到应用层的全过程开发,效率是大大地提高 了。因此用户应根据实际情况修改uclinux内核,才能整合出适合自己需要的应用系统。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多