嵌入式操作系统实验报告.docx
- 文档编号:7214050
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:27
- 大小:705.66KB
嵌入式操作系统实验报告.docx
《嵌入式操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《嵌入式操作系统实验报告.docx(27页珍藏版)》请在冰豆网上搜索。
嵌入式操作系统实验报告
实验一嵌入式开发环境的建立
一、实验目的
通过此实验系统,读者可以了解嵌入式实时操作系统uC/OS-II的内核机制和运行原理。
本实验系统展示了uC/OS-II各方面的管理功能,包括信号量、队列、内存、时钟等。
在各个实验中具体介绍了uC/OS-II的相关函数。
读者在做实验的同时能够结合理论知识加以分析,了解各个函数的作用和嵌入式应用程序的设计方法,最终对整个uC/OS-II和嵌入式操作系统的应用有较为清楚的认识。
二、实验步骤
1.安装集成开发环境LambdaEDU
集成开发环境LambdaEDU的安装文件夹为LambdaEDU,其中有一个名为“Setup.exe”
的文件,直接双击该文件便可启动安装过程。
具体的安装指导请看“LambdaEDU安装手
册.doc”文件。
当LambdaEDU安装完毕之后,我们看到的是一个空的界面,现在就开始一步一步地将
我们的实验项目建立并运行起来。
2.建立项目
为了我们的实验运行起来,需要建立1个项目基于x86虚拟机的标准应用项目。
通过点
击“文件”、“新建”、“项目”开始根据向导创建一个项目。
在随后出现的对话框中选择“Tool/标准应用项目”,点击下一步,开始创建一个标准的
可执行的应用程序项目。
在随后出现的对话框中填入项目名称“ucos_x86_demo”。
点击“下一步”。
选择“pc386uC/OS-II应用(x86)”作为该项目的应用框架。
点击“下一步”
选择“pc386_elf_tra_debug”作为该项目的基本配置。
点击“完成”。
新创建的项目“ucos_x86_demo”将会被添加到项目列表。
src文件夹下保存了该项目中
包含的源文件。
ucos2文件夹中包含了移植到x86虚拟机的全部代码。
init.c文件是基于ucos2
和本虚拟机的一个应用程序。
在进行ucos2内核实验中,只需要替换init.c文件,即可。
文
件名不限,但是文件名中最好不要使用英文符号和数字以外的其他字符,
3.构建项目
到这里,项目配置全部完成。
接下来就可以进行构建项目了。
第一次构建本项目,在此项目上点击右键,选择“重建BSP及项目”。
即可开始构建。
之后弹出的对话框显示了构建的进度。
可以点击“在后台运行”,以隐藏该对话框
在构建的同时,在右下角的“构建信息”视图输出构建过程中的详细信息:
注:
“重新构建”将本项目中的全部源代码进行一次完全的编译和连接,花费时间较多。
“构建项目”则仅仅将新修改过的源代码进行编译和连接,花费时间最少。
“重建BSP及项
目”,不但要完成“重新构建”的全部工作,另外还要编译与该项目有关的的LambdaEDU
中内置的部分代码,花费时间最多。
但是在项目刚建立后,第一次构建时需要选择“重建
BSP及项目”。
以后的构建中选择“重新构建”或“构建项目”即可。
另外,在替换了源代
码中的文件后,需要选择“重新构建”来完成该项目的构建。
4.配置虚拟机和目标机代理
(1)制作X86启动盘
在LambdaEDU中依次点击“工具”、“Bochs”、“制作虚拟机启动映象”。
对启动盘进行一些参数设置后(如下图所示),系统将自动为你生成一个PC虚拟机的
启动盘映像。
(2)配置虚拟机
选择使用的网络适配器(网卡)后,点击“确定”完成配置。
注意:
如果计算机上有多网卡,请将其他网卡停用(包括VMware虚拟机添加的虚拟
网卡)。
(3)创建目标机代理
配置好虚拟机后,创建目标机代理:
点击LambdaEDU左下方窗口中绿色的十字符号,
在弹出的窗口中选择“基于TA的连接方式”,并点击“下一步”。
在弹出的“新目标机连接配置中”的这些参数,应该与之前制作启动盘时设置的参数一
致。
注意:
名字:
输入目标机的名字(缺省是default),注意如果和现有目标机重名的话,改个名
字。
连接类型:
默认选择UDP
IP地址:
这里输入目标机(在本实验系统中是虚拟机)的IP地址;
最后点击“确定”,在目标机管理窗口中,可以看到新增加了一个名为default的目标机
节点
(4)调试应用
启动虚拟机。
虚拟机启动后的画面如下(其中显示的IP地址创建虚拟机启动盘时填入的IP地址)中
设置的IP地址):
在成功完成构建的项目ucos_x86_demo中的“pc386_elf_tra_debug”上点击鼠标右键,
在弹出的菜单中选择“调试”,启动调试器调试生成的程序:
第一次进行调试/运行,需要选择目标机,如下图,选择“Default”,点击“确定”,开
始向目标机(虚拟机)下载应用程序。
程序下载完成后,会弹出一个“确认透视图切换”对话框,选择“是”,切换到调试透
视图。
调试的界面如下:
点击绿色的按钮,全速运行。
注意:
全速运行后,程序不能够被暂停和停止。
三、实验过程中遇到的问题及体会
在设置IP地址时,要求该IP地址与本计算机在同一个子网中,同时要求该IP地址没有被网络上其他计算机使用。
此外,通过构建开发环境,处次体验到了嵌入式开发工作的乐趣。
实验二任务的基本管理
一、实验目的
1.理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程;
2.掌握uC/OS-II中任务管理的基本方法(创建、启动、挂起、解挂任务);
3.熟练使用uC/OS-II任务管理的基本系统调用。
二、实验原理及程序结构
1.实验设计
为了展现任务的各种基本状态及其变迁过程,本实验设计了Task0、Task1两个任务:
任务Task0不断地挂起自己,再被任务Task1解挂,两个任务不断地切换执行。
通过本实验,读者可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。
2.运行流程
描述如下:
(1)系统经历一系列的初始化过程后进入boot_card()函数,在其中调用ucBsp_init()进
行板级初始化后,调用main()函数;
(2)main()函数调用OSInit()函数对uC/OS-II内核进行初始化,调用OSTaskCreate创
建起始任务TaskStart;
(3)main()函数调用函数OSStart()启动uC/OS-II内核的运行,开始多任务的调度,执
行当前优先级最高的就绪任务TaskStart;
(4)TaskStart完成如下工作:
a、安装时钟中断并初始化时钟,创建2个应用任务;
b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任务Task0。
之后整个系统的运行流程如下:
●t1时刻,Task0开始执行,它运行到t2时刻挂起自己;
●t2时刻,系统调度处于就绪状态的优先级最高任务Task1执行,它在t3时刻唤醒Task0,后者由于优先级较高而抢占CPU;
●Task0执行到t4时刻又挂起自己,内核调度Task1执行;
●Task1运行至t5时刻再度唤醒Task0;
●……
3.µC/OS-Ⅱ中的任务描述
一个任务通常是一个无限的循环,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成void。
在μC/OS-Ⅱ中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就会被抢占,高优先级任务会立刻得到CPU的控制权(在系统允许调度和任务切换的前提下)。
μC/OS-Ⅱ可以管理多达64个任务,但目前版本的μC/OS-Ⅱ有两个任务已经被系统占用了(即空闲任务和统计任务)。
必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从0到OS_LOWEST_PR10-2。
优先级号越低,任务的优先级越高。
μC/OS-Ⅱ总是运行进入就绪态的优先级最高的任务。
4.源程序说明
(1)TaskStart任务
TaskStart任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所
有的应用任务:
UCOS_CPU_INIT();/*InstalluC/OS-II'sclocktickISR*/
UCOS_TIMER_START();/*Timer初始化*/
TaskStartCreateTasks();/*Createalltheapplicationtasks*/
OSTaskSuspend(OS_PRIO_SELF);
具体负责应用任务创建的TaskStartCreateTasks函数代码如下,它创建了两个应用任务
Task0和Task1:
voidTaskStartCreateTasks(void)
{
INT8Ui;
for(i=0;i { TaskData[i]=i;//Eachtaskwilldisplayitsowninformation } OSTaskCreate(Task0,(void*)&TaskData[0],&TaskStk[0][TASK_STK_SIZE-1],5); OSTaskCreate(Task1,(void*)&TaskData[1],&TaskStk[1][TASK_STK_SIZE-1],6); } TaskStart任务完成上述操作后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0运行。 (2)应用任务 应用任务Task0运行后将自己挂起,之后操作系统就会调度处于就绪状态的优先级最高的任务,具体代码如下: voidTask0(void*pdata) { INT8Ui; INT8Uerr; i=*(int*)pdata; for(;;) { printf("Applicationtasksswitched%dtimes! \n\r",++count); printf("TASK_0ISRUNNING..............................................................\n\r"); printf("task_1issuspended! \n\r"); printf("**************************************************\n\r"); err=OSTaskSuspend(5);//suspenditself } } 应用任务Task1运行后将Task0唤醒,使其进入到就绪队列中: voidTask1(void*pdata) { INT8Ui; INT8Uerr; i=*(int*)pdata; for(;;) { OSTimeDly(150); printf("Applicationtasksswitched%dtimes! \n\r",++count); printf("task_0issuspended! \n\r"); printf("TASK_1ISRUNNING..............................................................\n\r"); printf("**************************************************\n\r"); OSTimeDly(150); err=OSTaskResume(5);/*resumetask0*/ } } 三、运行及观察应用输出信息 按照本实验手册第一部分所描述的方法建立应用项目并完成构建,当我们在 LambdaEDU调试器的控制下运行构建好的程序后,将看到在μC/OS-Ⅱ内核的调度管理下, 两个应用任务不断切换执行的情形: 四、本实验中用到的µC/OS-Ⅱ相关函数 4.1OSTaskCreate() OSTaskCreate()建立一个新任务。 任务的建立可以在多任务环境启动之前,也可以在 正在运行的任务中建立。 中断处理程序中不能建立任务。 一个任务必须为无限循环结构,且 不能有返回点。 OSTaskCreate()是为与先前的μC/OS版本保持兼容,新增的特性在OSTaskCreateExt ()函数中。 无论用户程序中是否产生中断,在初始化任务堆栈时,堆栈的结构必须与CPU中断后 寄存器入栈的顺序结构相同。 详细说明请参考所用处理器的手册。 函数原型: INT8UOSTaskCreate(void(*task)(void*pd), void*pdata, OS_STK*ptos, INT8Uprio ); 参数说明: task是指向任务代码首地址的指针。 pdata指向一个数据结构,该结构用来在建立任务时向任务传递参数。 ptos为指向任务堆栈栈顶的指针。 任务堆栈用来保存局部变量,函数参数,返回地址 以及任务被中断时的CPU寄存器内容。 任务堆栈的大小决定于任务的需要及预计的中断嵌 套层数。 计算堆栈的大小,需要知道任务的局部变量所占的空间,可能产生嵌套调用的函数,及中断嵌套所需空间。 如果初始化常量OS_STK_GROWTH设为1,堆栈被设为从内存高地址向低地址增长,此时ptos应该指向任务堆栈空间的最高地址。 反之,如果OS_STK_GROWTH设为0,堆栈将从内存的低地址向高地址增长。 prio为任务的优先级。 每个任务必须有一个唯一的优先级作为标识。 数字越小,优先级越高。 返回值: OSTaskCreate()的返回值为下述之一: ●OS_NO_ERR: 函数调用成功。 ●OS_PRIO_EXIST: 具有该优先级的任务已经存在。 ●OS_PRIO_INVALID: 参数指定的优先级大于OS_LOWEST_PRIO。 ●OS_NO_MORE_TCB: 系统中没有OS_TCB可以分配给任务了。 注意: 任务堆栈必须声明为OS_STK类型。 在任务中必须调用μC/OS提供的下述过程之一: 延时等待、任务挂起、等待事件发生 (等待信号量,消息邮箱、消息队列),以使其他任务得到CPU。 用户程序中不能使用优先级0,1,2,3,以及OS_LOWEST_PRIO-3, OS_LOWEST_PRIO-2,OS_LOWEST_PRIO-1,OS_LOWEST_PRIO。 这些优先级μC/OS系统 保留,其余的56个优先级提供给应用程序。 4.2OSTaskSuspend() OSTaskSuspend()无条件挂起一个任务。 调用此函数的任务也可以传递参数 OS_PRIO_SELF,挂起调用任务本身。 当前任务挂起后,只有其他任务才能唤醒。 任务挂起 后,系统会重新进行任务调度,运行下一个优先级最高的就绪任务。 唤醒挂起任务需要调用 函数OSTaskResume()。 任务的挂起是可以叠加到其他操作上的。 例如,任务被挂起时正在进行延时操作,那么 任务的唤醒就需要两个条件: 延时的结束以及其他任务的唤醒操作。 又如,任务被挂起时正 在等待信号量,当任务从信号量的等待对列中清除后也不能立即运行,而必须等到被唤醒后。 函数原型: INT8UOSTaskSuspend(INT8Uprio); 参数说明: prio为指定要获取挂起的任务优先级,也可以指定参数OS_PRIO_SELF,挂起任务本 身。 此时,下一个优先级最高的就绪任务将运行。 返回值: OSTaskSuspend()的返回值为下述之一: ●OS_NO_ERR: 函数调用成功。 ●OS_TASK_SUSPEND_IDLE: 试图挂起µC/OS-II中的空闲任务(Idletask)。 此为非法操作。 ●OS_PRIO_INVALID: 参数指定的优先级大于OS_LOWEST_PRIO或没有设定 ●OS_PRIO_SELF的值。 ●OS_TASK_SUSPEND_PRIO: 要挂起的任务不存在。 注意: 在程序中OSTaskSuspend()和OSTaskResume()应该成对使用。 用OSTaskSuspend()挂起的任务只能用OSTaskResume()唤醒。 4.3OSTaskResume() OSTaskResume()唤醒一个用OSTaskSuspend()函数挂起的任务。 OSTaskResume ()也是唯一能“解挂”挂起任务的函数。 函数原型: INT8UOSTaskResume(INT8Uprio); 参数说明: prio指定要唤醒任务的优先级。 返回值: OSTaskResume()的返回值为下述之一: ●OS_NO_ERR: 函数调用成功。 ●OS_TASK_RESUME_PRIO: 要唤醒的任务不存在。 ●OS_TASK_NOT_SUSPENDED: 要唤醒的任务不在挂起状态。 ●OS_PRIO_INVALID: 参数指定的优先级大于或等于OS_LOWEST_PRIO。 五、实验过程中遇到的问题及体会 实验过程中体会到了嵌入式开发的乐趣,对上课老师所讲的内容有了进一步的认识与理解。 实验三信号量: 哲学家就餐问题的实现 一、实验目的 掌握在基于嵌入式实时操作系统uC/OS-II的应用中,任务使用信号量的一般原理。 通 过经典的哲学家就餐实验,了解如何利用信号量来对共享资源进行互斥访问。 二、实验原理及程序结构 1.实验设计 掌握在基于嵌入式实时操作系统uC/OS-II的应用中,任务使用信号量的一般原理。 通 过经典的哲学家就餐实验,了解如何利用信号量来对共享资源进行互斥访问。 2.源程序说明 五个哲学家任务(ph1、ph2、ph3、ph4、ph5)主要有两种过程: 思考(即睡眠一段时 间)和就餐。 每个哲学家任务在就餐前必须申请并获得一左一右两支筷子,就餐完毕后释放 这两支筷子。 五个哲学家围成一圈,每两人之间有一支筷子。 一共有五支筷子,在该实验中 用了五个互斥信号量来代表。 每个任务的代码都一样,如下所示: voidTask(void*pdata) { INT8Uerr; INT8Ui; INT8Uj; i=*(int*)pdata; j=(i+1)%5; uC/OS-II实验指导书 -47- for(;;) { TaskThinking2Hungry(i); OSSemPend(fork[i],0,&err); OSSemPend(fork[j],0,&err);/*Acquiresemaphorestoeat*/ TaskEat(i); OSSemPost(fork[j]); OSSemPost(fork[i]);/*Releasesemaphore*/ OSTimeDly(200);/*Delay10clocktick*/ } } 操作系统配置 修改uC_OS-II/OS_CFG.h: : : : #defineOS_MAX_EVENTS10/*最多可以有10个事件*/ #defineOS_MAX_FLAGS5/*最多可以有5个事件标志*/ #defineOS_MAX_MEM_PART5/*最多可以划分5个内存块*/ #defineOS_MAX_QS2/*最多可以使用2个队列*/ #defineOS_MAX_TASKS8/*最多可以创建8个任务*/ #defineOS_LOWEST_PRIO14/*任务优先级不可以大于14*/ #defineOS_TASK_IDLE_STK_SIZE1024/*空闲任务堆栈大小*/ #defineOS_TASK_STAT_EN1/*是否允许使用统计任务*/ #defineOS_TASK_STAT_STK_SIZE1024/*统计任务堆栈大小*/ #defineOS_FLAG_EN1/*是否允许使用事件标志功能*/ #defineOS_FLAG_WAIT_CLR_EN1/*是否允许等待清除事件标志*/ #defineOS_FLAG_ACCEPT_EN1/*是否允许使用OSFlagAccept()*/ #defineOS_FLAG_DEL_EN1/*是否允许使用OSFlagDel()*/ #defineOS_FLAG_QUERY_EN1/*是否允许使用OSFlagQuery()*/ #defineOS_MBOX_EN0/*是否允许使用邮箱功能*/ #defineOS_MEM_EN0/*是否允许使用内存管理的功能*/ #defineOS_MUTEX_EN0/*是否允许使用互斥信号量的功能*/ #defineOS_Q_EN0/*是否允许使用队列功能*/ #defineOS_SEM_EN1/*是否允许使用信号量功能*/ #defineOS_SEM_ACCEPT_EN1/*是否允许使用OSSemAccept()*/ #defineOS_SEM_DEL_EN1/*是否允许使用OSSemDel()*/ #defineOS_SEM_QUERY_EN1/*是否允许使用OSSemQuery()*/ #defineOS_TASK_CHANGE_PRIO_EN1/*是否允许使用 OSTaskChangePrio()*/ #defineOS_TASK_CREATE_EN1/*是否允许使用OSTaskCreate()*/ #defineOS_TASK_CREATE_EXT_EN1/*是否允许使用OSTaskCreateExt()*/ #defineOS_TASK_DEL_EN1/*是否允许使用OSTaskDel()*/ #defineOS_TASK_SUSPEND_EN1/*是否允许使用OSTaskSuspend()and OSTaskResume()*/ #defineOS_TASK_QUERY_EN1/*是否允许使用OSTaskQuery()*/ #defineOS_TIME_DLY_HMSM_EN1/*是否允许使用 OSTimeDlyHMSM()*/ #defineOS_TIME_DLY_RESUME_EN1/*是否允许使用 OSTimeDlyResume()*/ #defineOS_TIME_GET_SET_EN1/*是否允许使用OSTimeGet()和 OSTimeSet()*/ #defineOS_SCHED_LOCK_EN1/*是否允许使用OSSchedLock()和
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 操作系统 实验 报告