⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 00000002.htm

📁 水木社区 embeded 版精华区 下载
💻 HTM
字号:
<?xml version="1.0" encoding="gb2312"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"/><title>uCOS的应用与扩展                       jacobw </title></head><body><center><h1>BBS 水木清华站∶精华区</h1></center><a name="top"></a>发信人:&nbsp;flyman&nbsp;(又改昵称喽),&nbsp;信区:&nbsp;Embedded&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />标&nbsp;&nbsp;题:&nbsp;uCOS的应用与扩展&nbsp;<br />发信站:&nbsp;BBS&nbsp;水木清华站&nbsp;(Thu&nbsp;Jul&nbsp;12&nbsp;23:52:19&nbsp;2001)&nbsp;<br />&nbsp;<br />清华大学工程物理系Motorola中心&nbsp;许庆丰&nbsp;<br />&nbsp;<br />摘要:本文介绍了μC/OS在ColdFire为核心系统上的具体应用,并在此基础上做了扩展,&nbsp;<br />在μC/OS的核心上实现了RAM盘和文件系统。为了方便应用和调试,还实现了用户Shell程&nbsp;<br />序,可以接受并执行用户命令,扩展并丰富了μC/OS的功能。&nbsp;<br />关键字:μC/OS&nbsp;,uCLinux,嵌入式系统,ColdFire。&nbsp;<br />&nbsp;<br />概述:&nbsp;<br />近年来,随着微控制器性能的不断提高,嵌入式应用越来越广泛。目前市场上的大型商用&nbsp;<br />嵌入式实时系统,如VERTEX,VXWORK,PSOS等等,已经十分成熟,并为用户提供了强有力&nbsp;<br />的开发和调试工具。但商用嵌入式实时系统价格昂贵而且都针对特定的硬件平台。对于国&nbsp;<br />内中小型系统的开发,购买商用实时系统并不划算。此时,采用免费软件和开放代码不失&nbsp;<br />为一种选择。目前源码开放(C代码)的嵌入式系统有μC/OS和uCLinux,μC/OS简单易学&nbsp;<br />,提供了嵌入式系统的基本功能,其核心代码短小精悍,如果针对硬件进行优化,还可以&nbsp;<br />获得更高的执行效率。但是μC/OS相对商用嵌入式系统来说还是过于简单,而且存在开发&nbsp;<br />调试困难的问题。uCLinux是自由软件运动的产物,包含丰富的功能,包括文件系统、各种&nbsp;<br />外设的驱动程序、通讯模块,TCP/IP,PPP,HTTP,甚至WEB服务器的代码。在INTERNET上&nbsp;<br />流传的uCLinux已经被移植到当前几乎所有的硬件平台上,功能与PC机上运行的Linux不相&nbsp;<br />上下,其代码也十分复杂。完全移植没有必要也十分困难,但uCLinux的代码经过世界范围&nbsp;<br />内的优化,稳定可靠而且高效,所有模块的代码都可以从INTERNET上获得。可以进行模块&nbsp;<br />移植。在本例应用中,笔者在ColdFire硬件平台上运行了μC/OS的核心,并实现了uCLinu&nbsp;<br />x&nbsp;的文件系统。使得在嵌入式应用中可以进行文件操作。同时针对μC/OS调试困难的问题&nbsp;<br />&nbsp;<br />,还移植了uCLinux的用户Shell,使得用户可以用命令行方式进行程序的调试和开发。&nbsp;<br />硬件平台:&nbsp;<br />本系统的硬件平台采用GPFC(General&nbsp;Purpose&nbsp;Fieldbus&nbsp;Controller)数据采集系统,该&nbsp;<br />系统是由德国汉堡国家同步辐射实验室(DESY)&nbsp;Dr.&nbsp;Clausen&nbsp;Matthias领导的研究小组开发&nbsp;<br />。采用Motorola公司的ColdFire&nbsp;MCF5206处理器为核心。ColdFire&nbsp;MCF5206处理器属于Mo&nbsp;<br />torola&nbsp;32位MCU家族,在源码上与68K兼容。全静态设计,在33MHZ的工作频率下可达最大&nbsp;<br />17MIPS的处理能力。除了具有68K系列的通用功能外模块,片内还带有DRAM控制模块,可以&nbsp;<br />直接外接DRAM芯片。由于ColdFire将片选逻辑电路,总线控制器,DRAM控制模块等全部集&nbsp;<br />成在了MCU内部,使得外围电路变的十分简单。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在笔者所用的GPFC系统中,ColdFire工作中在32MHZ,外围电路包括两片DRAM芯片,共计&nbsp;<br />4M的RAM,一片128K的FLASH,用于存放引导程序。其余为I/O电路。系统通过RS-232串口与&nbsp;<br />PC机相连。&nbsp;<br />&nbsp;<br />软件设计:&nbsp;<br />本系统的软件采用μC/OS为嵌入式平台。在应用中切实感到了开放源代码的无可替代的优&nbsp;<br />点:首先是可以根据自己的需要对源代码进行取舍,去掉不需要的变量和不使用的函数。&nbsp;<br />甚至可以根据需要改写相关函数。在μC/OS的源代码中,函数执行中有许多条件判断,作&nbsp;<br />用是防止参数的错误传递。例如和信号量有关的函数在执行前都会检查一下传递给函数的&nbsp;<br />指针是不是一个有效的信号量指针。作为通用系统,这些条件判断是完全必要的,避免出&nbsp;<br />现错误时系统崩溃。但作为具体的应用,只要在程序设计时保证参数传递的正确性,完全&nbsp;<br />可以不用条件判断,提高函数的执行速度,尤其是一些频繁调用的函数,或当MCU速度不高&nbsp;<br />的时候,重写部分函数往往可以显著提高系统性能。另外,由于用户对系统有源码级的了&nbsp;<br />解,可以添加自己编写的模块,与原系统兼容,使系统具有可扩展性。&nbsp;<br />正是由于μC/OS的可扩展性,笔者将uCLinux的RAM盘、文件系统和用户&nbsp;Shell移植到了μ&nbsp;<br />C/OS上,在用户程序中可以进行文件操作,文件系统可以为任务保存数据,并提供了统一&nbsp;<br />的接口函数。用户编制的单个任务也可以保存在RAM盘上,可以在终端上用命令方式运行、&nbsp;<br />监控、删除任务。&nbsp;<br />&nbsp;<br />文件系统:&nbsp;<br />uCLinux的文件系统与Linux的基本相同,文件以树型目录组织。由于篇幅所限,关于文件&nbsp;<br />系统的细节,读者可参考Linux和Unix的相关资料。本例中将RAM中高端的1M分配给文件系&nbsp;<br />统,建立了容量为1M的RAM盘。uCLinux的文件系统由逻辑块组成,如果是磁盘文件系统,&nbsp;<br />对应为磁盘块;RAM盘则对应为内存块,每个块为512字节。一个标准的逻辑盘划分成几个&nbsp;<br />部分:引导块、超级块、索引节点区和数据区。&nbsp;<br />&nbsp;&nbsp;<br />图1&nbsp;文件系统的布局&nbsp;<br />引导块在文件系统的开头,通常为一个逻辑块,存放引导程序,用于启动和引导操作系统&nbsp;<br />。在我们的RAM文件系统中由于不需要RAM盘引导,所以不分配引导块。超级块记录文件系&nbsp;<br />统当前状态,盘有多大,能存放多少文件,何处可以找到空闲空间和用于文件系统管理的&nbsp;<br />信息。索引节点区紧接在超级块后面,存放文件系统的索引节点表。在文件系统中每一个&nbsp;<br />文件(包含目录)占据一个索引节点表项。索引节点是一个记录文件信息的数据结构:&nbsp;<br />struct&nbsp;dinode{&nbsp;<br />short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_mode;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件模式:是文件还是目录,是可读、可写还是可执行*/&nbsp;<br />short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_nlink;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*和文件相关的链接数*/&nbsp;<br />short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_uid;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件所有者的标示*/&nbsp;<br />short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_gid;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件所有者的组标示*/&nbsp;<br />long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_size;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件大小*/&nbsp;<br />char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_addr[&nbsp;];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件数据所在的逻辑块编号*/&nbsp;<br />time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_atime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件最后一次访问的时间*/&nbsp;<br />time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_mtime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件最后一次修改的时间*/&nbsp;<br />time_t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;di_ctime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*文件建立的时间*/&nbsp;<br />}&nbsp;<br />其中的数组di_addr[&nbsp;]记录文件数据所在的逻辑块号。本例中RAM盘为1M,每个逻辑块512&nbsp;<br />字节,共2048个逻辑块,所以每个逻辑块的编号要用两个字节表示。为了记录足够长的文&nbsp;<br />件,di_addr[&nbsp;]中的逻辑块可分为直接块和间接块,关于直接块和间接块的概念,请读者&nbsp;<br />参考Linux的相关文档。分析索引节点可知,通过索引节点就可以完全确定一个文件。索引&nbsp;<br />节点表中的第一项就是根目录。索引节点区的大小决定了文件系统中最多能有多少个文件&nbsp;<br />(包括目录)。在本例中,笔者设定为128项。在索引节点区后就是数据区,数据区以逻辑&nbsp;<br />块为单位按次序编号。如果要访问某个文件,只要找到该文件对应的索引节点表项,从di&nbsp;<br />_addr[]项中就可以查出文件数据所在的逻辑块。文件的访问需要通过fread()或fwrite(&nbsp;<br />)函数,其细节不再复述。&nbsp;<br />添加了文件系统后,任务的运行将和文件相关,所以TCB(任务控制块)要做相应的修改。&nbsp;<br />需要添加任务所在目录项和任务打开文件项。当一个任务调用OSTaskCreate创立新的任务&nbsp;<br />的时候,子任务应该继承先前任务的目录项和任务打开文件项。&nbsp;<br />&nbsp;<br />用户Shell:&nbsp;<br />用户Shell实际上是一个在μC/OS下独立运行的任务,处于最低的优先级。Shell启动后,&nbsp;<br />进入睡眠状态,等待用户输入。用户从终端上输入命令后将唤醒Shell,Shell首先检测输&nbsp;<br />入命令是不是内部命令,如果不是,则在TCB中查询当前所在文件目录,然后在目录中查询&nbsp;<br />是否有与输入匹配的文件,如果有且文件属性为可执行时,则调用OSTaskCreate创立一个&nbsp;<br />新的任务。由于Shell优先级为最低,新创建的任务将马上运行。新任务执行完后可以用O&nbsp;<br />STaskDel删除自己。如果在当前目录中找不到匹配项,则返回错误信息。&nbsp;<br />在本例中,Shell中包含的内部命令为cd(改变当前目录),pwd(显示当前工作目录),&nbsp;<br />mkdir,rmdir(创立删除目录),ps(显示当前系统中的任务),kill(删除任务)。&nbsp;<br />由于μC/OS&nbsp;中的OSTaskCreate不能动态分配堆栈空间,OSTaskDel也不能释放任务的堆栈&nbsp;<br />空间。为了实现Shell的加载和删除任务的功能,笔者对上述两个函数进行了改写,添加了&nbsp;<br />内存管理函数malloc()和mfree()。为了简单起见,以8K为单位申请和释放内存块。系&nbsp;<br />统的内存资源由一个双向链表进行管理。在OSTaskCreate中调用malloc(),参数为希望&nbsp;<br />分配的内存块数,malloc()将检索内存管理的双向链表,返回空闲块地址。而OSTaskDe&nbsp;<br />l中将调用mfree()释放内存,重新加入双向链表。为了避免内存空洞,在Shell中启动的&nbsp;<br />任务采用相同大小的堆栈。&nbsp;<br />通过用户Shell,单独的任务可以保存在RAM盘上,通过命令方式运行、监控,查看任务状&nbsp;<br />态、删除任务,作为一种有力的开发和调试手段。&nbsp;<br />&nbsp;<br />结束语:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;μC/OS的出现和应用也只是近年来的事,其迅猛的发展证明了开放源码软件的巨大生命力&nbsp;<br />。相信经过广大用户的不断丰富和完善,μC/OS的功能将日趋成熟,应用也会更加广阔。&nbsp;<br />&nbsp;<br />&nbsp;<br />--&nbsp;<br />&nbsp;<br />※&nbsp;来源:·BBS&nbsp;水木清华站&nbsp;smth.org·[FROM:&nbsp;166.111.171.26]&nbsp;<br /><a href="00000001.htm">上一篇</a><a href="javascript:history.go(-1)">返回上一页</a><a href="index.htm">回到目录</a><a href="#top">回到页首</a><a href="00000003.htm">下一篇</a></h1></center><center><h1>BBS 水木清华站∶精华区</h1></center></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -