ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:127.26KB ,
资源ID:6912594      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6912594.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(操作系统课程设计报告.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

操作系统课程设计报告.docx

1、操作系统课程设计报告操作系统课程设计报告专业班级: 计科1106班 姓 名: 李育洪、胡 壮 刘春林、邓程峰 指导老师: 李 玺 设计时间: 2014年6月 第一章 概论3第二章 设计的基本概念和原理4第三章 总体设计6第四章 详细设计8第五章 系统的测试和运行18第六章 系统的使用说明20第七章 课程设计总结21第八章 参考资料22第一章 概论1.1 课程设计的内容本次课程设计我们是四个人的小组,我们选择的是第三个题目,题目的描述如下:在uC/OS操作系统中增加一个简单的文件系统, 要求如下:(1) 熟悉并分析uc/os操作系统(2) 设计并实现一个简单的文件系统(3) 可以是存放在内存的虚

2、拟文件系统,也可以是存放在磁盘的实际文件系统(4) 编写测试代码,测试对文件的相关操作:建立,读写等1.2 课程设计的目的操作系统课程主要讲述的内容是多道操作系统的原理与技术,与其它计算机原理、编译原理、汇编语言、计算机网络、程序设计等专业课程关系十分密切。本课程设计的目的综合应用学生所学知识,建立系统和完整的计算机系统概念,理解和巩固操作系统基本理论、原理和方法,掌握操作系统开发的基本技能。1.3 要解决的主要问题通过对题目的分析,以及对相关资料的查阅,我们决定为C/OS-II写一个FAT32文件系统。那么,我们要解决的主要问题就有:1) 掌握C/OS-II的基本原理,并能在C/OS-II上

3、用C语言进行程序设计;2) C/OS-II开发环境的建立。由于我们没有嵌入式的硬件设备,所以在PC上进行开发。于是就需要把C/OS-II一直到windows下,用VC+作为开发环境;3) 了解FAT32文件系统的底层细节。必须要有FAT32这种文件系统的详细说明。4) 手动实现FAT32文件系统。5) 测试。必须保证文件系统能在C/OS-II下运行。第二章 设计的基本概念和原理2.1 C/OS-II简介C/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,

4、该系统源代码开放、整洁、一致,注释详尽,适合系统开发。 C/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。C/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信,CPU的移植等5个部分。1) 核心部分是操作系统的处理核心,包括操作系统初始化、操作系统运行、中断进出的前导、时钟节拍、任务调度、事件处理等多部分。能够维持系统基本工作的部分都在这里。2) 任务处理部分任务处理部分中的内容都是与任务的操作密切相关的。包括任务的建立、删除、挂起、恢复等等。因为C/OS-II是以任务为基本单位调度的,所以这部分内容也相当重要。3)

5、 时钟部分C/OS-II中的最小时钟单位是timetick(时钟节拍)。任务延时等操作是在这里完成的。4) 任务同步和通信部分为事件处理部分,包括信号量、邮箱、邮箱队列、事件标志等部分;主要用于任务间的互相联系和对临界资源的访问。5) 与CPU的接口部分是指C/OS-II针对所使用的CPU的移植部分。由于C/OS-II是一个通用性的操作系统,所以对于关键问题上的实现,还是需要根据具体CPU的具体内容和要求作相应的移植。这部分内容由于牵涉到SP等系统指针,所以通常用汇编语言编写。主要包括中断级任务切换的底层实现、任务级任务切换的底层实现、时钟节拍的产生和处理、中断的相关处理部分等内容。2.2 C

6、/OS-II在VC+下的移植为了开发环境的方便,需要将C/OS-II移植到VC+上。移植主要有三步,下面作简要说明。详细的方法可以参考嵌入式实时操作系统C/OS原理与实践一书。1) VC下时钟的获得可以使用采用软件定时器来模拟时钟中断。这里我们采用的是timeSetEvent()函数。这个函数很简单,不需要消息循环,定时精度为ms级,主要应用在多媒体定时方面,能够在非常精确的时间间隔内完成一个事件、函数或过程的调用。可以通过调用timeSetEvent()函数,将需要周期性执行的任务定义在LpTimeProc回调函数中,从而完成所需处理的事件。调用这个函数后会增加一个线程,时间一到则在这个线程

7、中调用回调函数,对于主线程来说,非常类似外部中断调用,我们需要的正是这样的效果。2) 模拟时钟中断的产生中断指的是中止当前的事务,处理别的更要紧的事情。我们通过软件定时器来模拟产生uC/OS-II的时钟中断,但timeSetEvent()函数调用定时回调函数是和主线程同时被windows操作系统调度的,并没有起到中断的作用。所以在调用定时回调函数的时候必须停止主线程的运行,退出回调函数则恢复主线程的运行,自然这些事情可以都放在定时回调函数,也就是uC/OS-II的时钟中断处理函数中完成。Windows下要挂起一个线程的运行,首先要得到这个线程的句柄,然后调用SuspendThread(hang

8、dler)和ResumeThread(handler)就可以挂起和继续执行线程。3) 任务切换任务切换,其实做的是任务的上下文切换,在其他CPU上非常容易分辨出任务的上下文,一般就是CPU上的相应寄存器,那么在VC下呢?从简单考虑,我们选择了不带浮点运算的上下文环境,因此任务的上下文和uC/OS-II在80x86上移植的上下文很相近,不同点只是段寄存器不用保存,因为在VC下任务其实只是在同一个线程中切换,而且在保护模式下段寄存器的概念已变,其值在同一个线程中是不会变的。2.3 FAT32文件系统格式FAT32是Windows系统硬盘分区格式的一种。这种格式采用32位的文件分配表,使其对磁盘的管

9、理能力大大增强,突破了FAT16对每一个分区的容量只有2 GB的限制。由于现在的硬盘生产成本下降,其容量越来越大,运用FAT32的分区格式后,我们可以将一个大硬盘定义成一个分区而不必分为几个分区使用,大大方便了对磁盘的管理。目前已被性能更优异的NTFS分区格式所取代。一个FAT文件系统包括四个不同的部分:保留扇区、FAT区域、根目录区域、数据区域。对于FAT32的具体说明可以参考微软官网上关于FAT32的白皮书,网址:。第三章 总体设计嵌入式文件系统由于功能和作用与普通桌面操作系统的文件系统不同,导致了二者在体系结构上具有很大的差异性。在普通桌面操作系统中,文件系统不仅要管理文件,提供文件系统

10、调用API,还要管理各种设备,支持对设备和文件操作的一致性(即要像操作文件一样来操作各种I/O设备)。在嵌入式文件系统中,这种规则发生了很大的变化。在某些情况下,嵌入式系统可以针对特殊的目的来进行定制,特别是随着ASOS(为应用定制的嵌入式操作系统)的发展,对嵌入式操作系统的系统功能规整性、可伸缩性及其灵活性提出了更高的要求。基于以上的考虑,我们采用了下图所示的嵌入式文件系统体系结构,该结构定义的文件系统从上到下有三个层次:第一层为API层、第二层为中间转换层、下层为介质驱动层。第一层:API层。API层是文件系统和用户应用程序之间的接口,它有一个标准C函数库,其中包含有诸如打开文件(f_op

11、en)、写文件(f_write)等函数。本层的功能是将用户调用传送给中间转换层。这是整个系统设计的核心,也是嵌入式文件系统中用户唯一可见的部分。第二层:中间转换层。中间转换层要为文件系统的实现提供与硬件无关的统一接口,是文件系统结构规整性的基础。中间转换层包含有文件系统子层及逻辑块子层,其中文件系统子层将文件操作解释到逻辑块子层,然后文件系统调用逻辑块子层并根据不同的设备定义出相应的设备驱动程序;逻辑块子层主要是同步对设备驱动程序的访问,向上提供友好界面。第三层:介质驱动层。介质驱动层是访问硬件的最低端的程序,该程序的结构要能够便于实现对硬件的访问。本层的功能主要是完成对介质的访问。本层的重要

12、任务就是提供统一的设备驱动程序接口。根据文件系统的层次结构,可以将该文件系统分成三大功能块:API接口模块、中间转换模块、设备驱动模块。其中API接口模块主要完成文件的基本操作,包含有文件的生成、删除、打开、关闭、文件读、文件写等。中间转换模块主要完成对存取权限的检查、介质的选择、逻辑到物理的转换。设备驱动模块完成存储介质的驱动程序,包含有一个驱动程序函数表和介质读、介质写、检查状态、执行特定命令等驱动程序。第四章 详细设计总体设计完成之后,就可以几种精力进行详细设计。根据总体设计划分的模块,一个模块一个模块进行详细设计。4.1 文件系统对外提供的主要接口1、FRESULT f_open (F

13、IL*, const char*, BYTE);函数功能:打开或者创建一个文件2、FRESULT f_read (FIL*, BYTE*, WORD, WORD*);函数功能:读一个文件3、FRESULT f_close (FIL*);函数功能:关闭一个文件4、FRESULT f_opendir (DIR*, const char*);函数功能:读一个目录中的目录项5、FRESULT f_readdir (DIR*, FILINFO*);函数功能:读取目录的内容6、FRESULT f_stat (const char*, FILINFO*);函数功能:获取文件的状态7、FRESULT f_mo

14、untdrv ();函数功能:初始化文件系统8、FRESULT f_write (FIL*, const BYTE*, WORD, WORD*);函数功能:写文件9、FRESULT f_sync (FIL*);函数功能:同步文件缓冲区的内容到磁盘中10、FRESULT f_delete(const char*);函数功能:删除一个文件或者目录11、FRESULT f_mkdir (const char*);函数功能:创建一个目录这就是文件系统提供的全部功能,灵活地运用上述函数,就可以编写出复杂的应用程序。4.2 文件系统的主要数据结构1)UCFS结构体/* 文件系统结构体,保存文件系统的有关信

15、息 */typedef struct BYTE fs_type; / 文件系统类型 BYTE files; / 当前已打开的文件的数目 BYTE sects_clust; / 每个簇的扇区数 BYTE n_fats; / FAT表的数目 WORD n_rootdir; / 根目录数(在FAT32中为0) BYTE winflag; / 标记文件是否被改动过,为1时要回写 BYTE pad1; / 站位,字节对齐 DWORD sects_fat; / 每个FAT表所占的扇区数 DWORD max_clust; / 总的簇数 DWORD fatbase; / FAT区的起始扇区 DWORD dir

16、base; / 根目录区的起始扇区 DWORD database; / 数据区的起始扇区 DWORD winsect; / 当前缓冲区中存储的扇区号 BYTE win512; / 单个扇区缓存 UCFS;UCFS结构体记录了文件系统的所有信息,有了这个结构体,就可以方便地访问文件系统的每一部分。2)DIR结构体/目录结构体,表示一个目录typedef struct DWORD sclust; / 起始簇 DWORD clust; / 当前簇 DWORD sect; / 当前扇区 WORD index; / 当前索引 DIR;作为目录项的指针,既可以用于记录一个特定文件在目录中的位置,又可以用于

17、记录在目录中当前目录项指针的位置(类似于文件指针)。3) FIL结构体/文件结构体,表示一个文件typedef struct DWORD fptr; / 文件读写指针 DWORD fsize; / 文件大小 DWORD org_clust; / 文件起始簇 DWORD curr_clust; / 当前簇(fsize=0时为0) DWORD curr_sect; / 当前扇区 DWORD dir_sect; / 此文件的目录项所在的扇区 BYTE* dir_ptr; / 指向文件目录项的指针 BYTE* buffer; / 文件读写缓冲区 BYTE flag; / 文件状态标识 BYTE sec

18、t_clust; / 当前簇中剩余的扇区数 FIL;记录普通文件(不是目录文件)的详细信息,比如文件对应的目录项位置,文件起始簇号,文件指针,文件大小等。4) FILINFO结构体/文件信息的结构体,也可以表示目录,用fattrib区分typedef struct _FILINFO DWORD fsize; / 文件大小 WORD fdate; / 文件修改日期 WORD ftime; / 文件修改时间 BYTE fattrib; / 文件属性 char fname13; / 文件名 (8.3 格式) FILINFO;5) win512数组位于 FATFS 结构体中,作为目录项或者 FAT 分

19、配表的读写缓冲区。它不是某一个文件专有的缓冲区,而是整个文件系统的公共读写缓冲区。6) buffer指针buffer 是一个指向 512 字节缓冲区的指针,位于 FIL 结构体中,也就相当于是 FIL 中有一个 512 字节缓冲区的成员。此 512 字节的缓冲区,是一个文件的专有缓冲区。用于当文件的读写没有按照 512 字节对齐的时候,作为磁盘与用户读写缓冲区之间的临时缓冲区。4.3 各个函数的详细实现1)move_window函数原型:BOOL move_window ( DWORD sector ) 函数功能:win操作函数(DBR、FAT 表、目录项) 读取新的扇区内容到临时缓冲区 wi

20、n 同步 win中的内容到磁盘注意: 如果读取新的扇区号就是现在存储在 win中的扇区号,就什么也不操作 如果不同,则根据情况同步 win到磁盘中,并且将新扇区中的内容读取到 win中 如果 sector 为 0,则函数功能变为同步 win到磁盘中,不会读取 0 扇区的内容到 win输入参数:sector 要读取扇区的扇区号 与其他函数的关系:此函数被下列函数直接或间接调用第一类:操作 FAT 表 get_cluster put_cluster remove_chain create_chain 第二类:操作 MBR、DBR check_fs 第三类:操作目录项所在扇区(目录的数据空间) tr

21、ace_path程序的实现方法:首先判断要读取的扇区号是否与当前缓存在 win中的扇区号一致。倘若一致,则无需执行任何操作。倘若不一致,再判断缓存在 win中的内容是否被修改过,如果修改过,就需要更新到磁盘,最后还要把新扇区中的内容加载到 win中。当传入参数0时,0 与当前缓存在 win的扇区号肯定不一样,所以一定会同步 win内容到磁盘中。2)f_mountdrv函数原型:FRESULT f_mountdrv()函数功能:初始化磁盘;初始化UcFs对象,记录物理磁盘的相关参数。函数实现方法:首先调用磁盘初始化函数,对磁盘进行初始化。然后读取物理磁盘 0 号扇区的内容,判断是否是 DBR 扇

22、区。如果不是 DBR 扇区,那么肯定就是 MBR 扇区,再从 MBR 扇区中获取 DBR 扇区的地址,将 DBR 扇区的内容调取到 win中。接下来从 win中,填充 UCFS 类型的系统对象,这样物理磁盘和文件系统的参数就被保存到了这个对象中。以后,程序就可以从全局变量-UcFs 类型的变量,访问文件系统的每一个区域。3)f_open函数原型:FRESULT f_open (FIL *fp, const char *path, BYTE mode)函数功能:以指定的方式打开或者新建一个文件。如果打开或者创建成功,会填充 fp 指向的文件信息变量(包含文件的目录项确切位置和文件的信息)。函数参

23、数:fp 指向文件信息变量的指针 path 指向文件的路径 mode 打开方式输出参数:FR_OK 打开或者创建成功其他值 打开或者创建失败函数实现方法:1 以只读的方式打开一个已经存在的文件首先调用函数 trace_path 搜索文件系统中是否存在目标文件,如果不存在就返回失败;如果存在就返回文件的目录项位置(dirscan、dir),并且将目录项所在扇区的内容加载到 win中。接下来就是从 win中,将文件目录项的参数稍作转化后传入 FIL 类型的变量中。到此,一个文件就算完整的打开了。注意打开文件并不是打开文件的内容,而是文件的目录项,知道了文件的目录项就知道了如何去查看文件的内容。以后

24、,通过 FIL 类型的变量就可以操作对应的文件。 新建一个文件 首先调用函数 trace_path 搜索文件系统中是否存在目标文件,因为是新建文件肯定不存在。那么不存在的文件就返回新建文件当前文件夹的目录指针位置(dirscan、dir)-第一个空目录项所在位置,并且将当前目录指针所在扇区的内容加载到 win中。首先给新建文件在当前文件夹中预定一个目录项位置,然后填入新建文件的目录项初始值(文件名、扩展名、属性、创建时间、更新时间)到 win中。注意这里并不会将新建文件目录项所在扇区同步到磁盘中,只有当调用 f_sync 函数时才会将文件的目录项所在扇区同步到磁盘。创建一个新文件,只会在其上一

25、层目录中添加对应的目录项并初始化,并不会给文件分配数据空间,当然文件的大小肯定是 0。 重建一个文件 首先调用函数 trace_path 搜索文件系统中是否存在目标文件,因为是重建文件肯定存在。那么就返回文件的目录项位置(dirscan、dir),并且将目录项所在扇区的内容加载到 win中。重建首先将文件的簇链删除,然后设置文件起始位置和文件大小为空,还需要初始化文件的属性、创建时间和修改时间。这里的修改都只是在 win中进行的,并没有同步到磁盘。只有当调用 f_sync 函数时才会将文件的目录项所在扇区同步到磁盘。重建文件更改了原来文件在目录中的目录项信息,重建文件并没有分配簇,也就是没有分

26、配数据空间。4)f_read函数原型:FRESULT f_read (FIL *fp, BYTE *buff, WORD btr, WORD *br)函数功能:文件读操作输入参数:fp 文件信息指针 buff 指向用户缓冲区 btr 准备读取的字节数 br 指向实际读取字节数的变量输出参数:FRESULT 成功与否备注:函数在读取文件内容后,还会移动文件指针到下一此读写操作的起点。函数的实现方法:读文件的情况有些复杂,不同的情况有不同的处理方法。开始读的时候,文件指针并没有位于扇区边界上(512 字节对齐),读取的跨度为 3 个簇。 首先读没有对齐扇区的剩余内容,其实这个内容在以前的函数(以前

27、的函数移动了文件指针)已经将这个扇区的内容加载到了 buffer 中。所以,直接从缓冲区 buffer 中读取此扇区文件指针以后的剩余内容到用户缓冲区。 接下来,读取第一个簇的剩余一个扇区的内容到用户缓冲区。通过 get_cluster 函数从 FAT 表中,获取第二个簇链的位置。然后一次性的将一个簇链的所有扇区内容读取到用户缓冲区中。再通过 get_cluster 函数从 FAT 表中,获取第三个簇链的位置。然后将第三个簇链的第一个扇区内容读取到用户缓冲区中。 最后,将最后所需要读取剩余内容所在的扇区(剩余部分不够一个扇区)读取到 buffer 中,然后再从 buffer 中读取所需要的剩余

28、内容到用户缓冲区中。到这里为止,整个读取操作已经完成。由于 buffer 中还有一部分内容没读,假设继续调用函数 f_read 函数读取数据,那么肯定先从这个 buffer 缓冲区中将文件指针以后的扇区剩余内容读取到用户缓冲区。5)f_write函数原型:FRESULT f_write(FIL *fp,const BYTE *buff,WORD btw, WORD *bw)函数功能 :文件写操作,只对文件的数据区进行写入,并没有更新对应的目录项。 输入参数:fp 文件信息指针 buff 指向读取的用户缓冲区 btw 准备写入的字节数 bw 返回实际写入的字节数 输出参数:FRESULT 成功与

29、否备注:函数在写完文件内容后,还会移动文件指针到下一此读写操作的起点。函数的实现方法:写文件的情况与读取文件内容类似。开始写的时候,文件指针并没有位于扇区边界上(512 字节对齐),写入数据的跨度为 3 个簇。首先写入没有对齐扇区的剩余内容,其实这个内容在以前的函数(以前的函数移动了文件指针)已经将这个扇区的内容加载到了 buffer 中。所以,将用户缓冲区中对应的内容写入到 buffer 中(从文件指针开始到 buffer 结束的这部分空间)。然后再将 buffer 中的内容写入到磁盘对应的扇区。 接下来,将用户缓冲区写入到第一个簇的剩余一个扇区中。通过 creat_chain 函数从 FA

30、T 表中,获取第二个簇链的位置(如果是文件有剩余簇链则使用文件的剩余簇链,如果已经用完则重新从 FAT 表中搜索一个空的簇链连接到此文件中,也就是更改了文件的大小)。然后一次性的将用户缓冲区写入到第二个簇链的所有扇区中。再通过get_cluster 函数从 FAT 表中,获取第三个簇链的位置。然后将用户缓冲区写入到第三个簇链的第一个扇区中。 最后,将最后所需要写入剩余内容所在的扇区(剩余部分不够一个扇区)读取到 buffer 中,然后再将用户缓冲区中剩余内容写入到 buffer 中。到这里为止,整个读取操作已经完成。注意这里并没有将 buffer 的内容写入到磁盘中。当调用 f_sync 函数的时候才会将 buffer 的内容同步到磁盘。 在函数返回之前,还需要判断文件大小是否更改了,如果大小更改了则要更新文件的大小,并将 FA_WRITTEN记录到文件的 flag 中。这样做的目的是为了当执行 f_sync 时,可

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1