uC_Faraday 基于ARM的嵌入式操作系统的说明 杭州电子科技大学计算机学院 俞岳军讲师 EMAIL: yuejun_yu@sohu.com QQ: 358969078 智慧的火光
一.uC_Faraday源代码的大致介绍:
uC_Faraday是一款专门针对ARM指令集嵌入式系统的多任务操作系统,目前已经实现了任务管理、任务间通讯这二部分功能。将来还要实现文件系统(先是实现FAT32)、TCP/IP协议、GUI、USB驱动等功能。
为什么要专门针对“ARM”指令集呢?而不象一般的OS,比如LINUX、uC/OS II这类操作系统,允许在不同的指令集间移植?本人认为如果要实现易移植性,必然会导致操作系统的性能下降,同时也考虑到ARM指令集是一个大有前途的指令集,那就选中它了,哈哈,考虑到周立功公司的ARM资料比较丰富,所以原始的uC_Faraday版本就是跑在 EASYARM2200扳子上的。
这个uC_Faraday目前包含下面的几个目录:Init_dir、Common_dir、include、SysCall_dir、 TIMER0_dir、App_dir
Init_dir目录:这个目录包含了系统的启动代码和设备初始化代码,Startup.s是最先执行的, 它先是设置中断向量表,然后就是调用TargetResetInit.s中的TargetResetInit函数对CPU内部的片内外设进行初始化,然后调用GeneralInit.s中的GeneralInit函数对各个板上外设进行相应的初始化。 这里有个TIMER0_Init.s,内部有个TIMER0_Init函数,那是对TIMER0进行初始化的,这个定时器提供系统的时钟。
Common_dir:这个目录包含了内核的一些核心函数,Common_Varc.c是用来定义内核用到的全局变量的,Common_Vars.s也是定义内核的全局变量的,只不过 Common_Varc.c里定义的,一般是在C文件里用的,Common_Vars.s里定义的,则往往是在汇编里用到的。 DisEn_IRQ.s里面定义的是允许、禁止中断的子程序代码 EnterExit_CRITICAL.s里面定义的是进出临界区的代码 所有的中断服务程序都有一个汇编的外壳,这个外壳是由IRQ_Enter IRQ_Exit二部分组成的,IRQ_Enter是在include目录里面,IRQ_Exit就在这 个目录下的,它们做的主要就是中断现场的保护和恢复工作。 System_Call和System0_Call和系统调用密切相关,System_Call是系统调用的 汇编外壳,这个情况和IRQ_Enter和IRQ_Exit的情况类似。。。 而System0_Call则负责对系统调用进行散转,先是根据系统调用的高16位(部 门号),然后再根据低16位,进行散转。。。
OS0_Sched.c 、OS_Sched.s 、Pre_Sched.s实现任务的调度作业。 OS_Sched.s、OS0_Sched.c实现基本的任务间调度,我们假设这个时候任务的 现场已经保护好了,OS_Sched函数把任务的堆栈指针作为参数传递给 OS0_Sched,OS0_Sched把这个堆栈指针保存在当前任务的TCB里,然后在 OSPRIOTbl数组寻找就绪任务中的最合适者(优先级最高的),然后把新任务 的堆栈指针返回给OS_Sched函数,由OS_Sched函数把新的堆栈指针赋值给 SP寄存器,接下去任务恢复现场,自然新的任务开始运行了。。。
Pre_Sched函数是给那些在内核无法继续运行的任务调用的,这个函数先是保 护现场,然后就调用OS_Sched函数实现任务调度,然后再恢复现场。。。
Incude : 这个目录下的文件是头文件,要么给C文件使用、要么给汇编文件使用的, 注意IRQ_Enter.inc这个文件,呵呵,里面包含的是汇编程序啊!
TIMER0_dir:这个目录下的是定时器0的中断服务程序,IRQ_TIMER0.s是汇编外壳, IRQ0_TIMER0.C是C语言写的真正的中断服务程序。
APP_dir: 这是应用程序的目录,the_syscalls.h是内核提供的API函数的头文件, The_syscalls.s是把内核提供的系统调用进行封装,产生用户方便使用的API 函数,注意!!!当参数数目多于4个的时候,处理起来可有点特殊的! Main.c里面是包含着main函数,这是应用程序的开始!!!
SysCall_dir: 这里面存放的是系统调用的实现。目前只实现了一系列任务管理、任务间通讯 的系统调用,存放在SYSTEM_dir目录下。 在SYSTEM_dir目录下又有许多文件和子目录: SysCall_SYSTEM.s文件里的SysCall_SYSTEM函数,由System0_Call来调用, 它根据系统调用号中的低16位来进行散转,进入相应的系统调用入口 OSEvent_TaskWait.c文件里面有OSEvent_TaskWait和OSEvent_TaskRdy二函 数,OSEvent_TaskWait做挂起运行任务的前期工作,把任务从就绪队列摘下, 如果需要延时的话,加入延时队列。OSEvent_TaskRdy做恢复任务进入就绪状 态的前期工作,如果任务有定时请求的话,把它从延时队列上摘下,加入任务 就绪队列。 OSMutex_InsertEvent.c文件里的OSMutex_InsertEvent函数,把互斥信号控制 块插入 获得这个互斥信号的任务控制块的 “拥有队列”中去。 OSTask_ChgPrio.c里面的OSTask_ChgPrio函数,用于改变某任务的优先级。 Do_Timer.c文件里的Do_Timer函数,这是由定时中断调用的,处理延时事务 的函数。目前暂时只处理为了获取某些资源而挂起的任务比如 (SUSPEND、SEM、MUTEX、MBOX、Q、QBYTE、QWORD、QDWORD、 FLAG) 还有子目录和它们相应的功能: Task_dir:实现任务管理 Mem_dir:实现内存管理 Sem_dir:实现信号量管理 Mutex_dir:实现互斥信号量管理 Mbox_dir:实现邮箱管理 Q_dir: 实现消息队列管理 Flag_dir:实现事件标志组管理 QByte_dir:实现字节队列管理 QWord_dir:实现字队列管理 QDWord_dir:实现双字队列管理
二.uC_Faraday和uC/OS II的渊源和区别 在开始编写uC_Faraday前,本人已经研究过Linux和uC/OS II的源代码,所以有许多思想和方法,是直接从这二者那里学过来的。尤其是uC/OS II ,但是uC_Faraday和 uC/OS II还是有许多区别的: 1. 在uC/OS II的模式下,内核和应用程序是混在一起的,没有明显的边界。 uC_Faraday是采用的传统操作系统的方式,内核以系统调用的方式为应用层提供服务,这些系统调用实际上是被包装成API函数的格式。应用程序运用API函数,通过SWI软中断,最后进入内核的。。。 这样的方式,系统比较容易发展
2. 在uC/OS II下,任务的优先级是必须不同的,正是基于这个前提,Jean J. Labrosse 才可以应用他得意的OSMapTbl[],OSUnMapTbl[]表技术,但是这样一来,各个任务必须要分个高低上下了,而实际上,许多任务间的优先关系是不明显的,几乎是平等的。 在uC_Faraday下,对任务的优先级采用分层的概念,系统定了总的等级数,任务可以处于某一等级,这个等级里可以有多个任务,另外,应用层可以要求任务改变优先级。总的说来,是采用一种分等级、分层次的优先级方式。 注意,在uC_Faraday下,任务还是采用抢占方式的。。。
3. uC/OS II里面某些实现不完善。比如互斥信号量问题,如果一个任务申请到了一个 互斥信号量,那它的优先级就可能发生改变,变成互斥信号量的当前优先级了;但 现在如果这个任务又要申请另外一个互斥信号量呢?那优先级如何改变?当释放 了一个互斥信号量,任务优先级又如何恢复?这些问题uC/OS II上面似乎没有对应 的办法。对事件标志组管理上,也有类似的问题。 在uC_Faraday里面,已经对这些问题进行了改良完善。
三.实验环境 APP_dir下的例子给出了定时控制蜂鸣器鸣叫的例子,main0.c里的是用the_TaskTimeDly延时函数直接实现的;而main.c里的是通过创建一个子任务(kissme函数), 运用任务间通讯技术来实现的:the_TaskSuspend函数、the_TaskTimeDly函数、the_TaskResume函数。 如果要用main0.c的方法,你就把main.c改成main0.c,把main0.c改成main.c 如果要用main.c的方法,你现在直接就好用了。
对EASYARM2200实验板的跳线的设置: JP1 全部断开 JP2 全部断开 JP3 全部断开 JP4 全部断开 JP5 全部连接 JP6 处于BANK0—RAM,BANK1—FLASH JP7 处于OUTSIDE JP8 全部连接 JP9 全部连接
四.对uC_Faraday的感想 本人是杭州电子科技大学计算机学院的教师,对编写操作系统非常有兴趣,原来就写过一个叫ARCHIMEDES(阿基米德)的PC机上的保护模式下的单任务操作系统,那个系统是能够在真实的PC机上跑的,并且能够执行可执行文件的。 这里是ARCHIMEDES的源代码说明: http://bbs.redhome.cc/viewthread ... &extra=page%3D1 这里是ARCHIMEDES的演示视频: http://bbs.redhome.cc/viewthread ... &extra=page%3D2 http://bbs.redhome.cc/upload/archimedes.wmv
去年,本人的兴趣转移到给嵌入式系统编写操作系统上了,这个uC_Faraday就是专门针对ARM指令集的嵌入式操作系统,已经实现了任务管理和任务间通讯这二部分的功能。 但对操作系统来说非常重要的文件系统和TCP/IP协议却还没有实现。
其实本人编写那类模块的技术是成熟的,在ARCHIMEDES上,就已经实现硬盘上的类似EXT2的文件系统和软驱上的FAT12文件系统,效果是很理想的。目前,本人对FAT32的机理也相当的熟悉,,,,对TCP/IP的机理也比较熟悉,,, 关键是本人对编写这类模块的兴趣也是相当高的。。。
最大的苦恼来自IDE硬盘接口的中文资料比较缺乏,RTL8019AS的也是一样缺乏,本人的英语水平也不够好,这些资料估计老外的网络上是应该有的。但我没有办法去利用。 在ARCHIMEDES里,对硬盘的操作只用到了二种操作:读物理扇区和写物理扇区,其他的操作命令都没有用到,并且如果读写扇区失败,就没有其他的办法,只有死循环了。
对uC_Faraday,我不希望采用同样的处理方法,应该能把IDE接口的所有操作命令都用起来,对读写扇区的失败,也应该有补救的措施的。。。 对RTL8019AS网卡芯片,也要有更高的认识,我看啊,现在的许多中文书上的介绍太不够精密了,许多参数的意义没有讲明白的。
现在把这个uC_Faraday放在网络,希望能够起抛砖引玉的作用,,,希望能见到嵌入式操作系统的蓬勃发展。。。
附件里的是加上注释的 uC_Faraday 源代码!
相关链接:https://bbs.21ic.com/upfiles/img/20077/200772923911940.rar |