嵌入式操作系统实验指导书.docx
- 文档编号:9347160
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:22
- 大小:37.62KB
嵌入式操作系统实验指导书.docx
《嵌入式操作系统实验指导书.docx》由会员分享,可在线阅读,更多相关《嵌入式操作系统实验指导书.docx(22页珍藏版)》请在冰豆网上搜索。
嵌入式操作系统实验指导书
嵌入式操作系统实验指导书
1实验目的
通过实验,读者可以了解嵌入式实时操作系统µC_OS-II的内核机制和运行原理,包括信号量、队列、内存、时钟等。
在各个实验中具体介绍了µCOS-II的相关函数。
读者在做实验的同时能够结合理论知识加以分析,了解各个函数的作用和嵌入式应用程序的设计方法,最终对整个µCOS和嵌入式操作系统的应用有较为清楚的认识。
2操作系统简介
2.1µC/OS-II概述
µC/OS-II是一个抢占式实时多任务内核。
µC/OS-II是用ANSI的C语言编写的,包含一小部分汇编语言代码,使之可以提供给不同架构的微处理器使用。
至今,从8位到64位,µC/OS-II已经在40多种不同架构的微处理器上使用。
世界上已经有数千人在各个领域中使用µC/OS,这些领域包括:
照相机行业、航空业、医疗器械、网络设备、自动提款机以及工业机器人等。
µC/OS-II全部以源代码的方式提供给读者,大约有5500行。
CPU相关的部分使用的是针对Intel80x86微处理器的代码。
µC/OS-II可以在PC机上开发和测试,且很容易地移植到不同架构的嵌入式微处理器上。
2.2µC/OS-II的特点
1、源代码:
µC/OS-II全部以源代码的方式提供给使用者(约5500行)。
该源码清晰易读,结构协调,且注解详尽,组织有序;
2、可移植(portable):
µC/OS-II的源代码绝大部分是用移植性很强的ANSIC写的,与微处理器硬件相关的部分是用汇编语言写的。
µC/OS-II可以移植到许许多多不同的微处理器上,条件是:
该微处理器具有堆栈指针,具有CPU内部寄存器入栈、出栈指令,使用的C编译器必须支持内嵌汇编,或者该C语言可扩展和可链接汇编模块,使得关中断和开中断能在C语言程序中实现;
3、可固化(ROMable):
µC/OS-II是为嵌入式应用而设计的,意味着只要具备合适的系列软件工具(C编译、汇编、链接以及下载/固化)就可以将µC/OS-II嵌入到产品中作为产品的一部分;
4、可裁减(scalable):
可以只使用µC/OS-II中应用程序需要的系统服务。
可裁减性是靠条件编译实现的,只需要在用户的应用程序中定义那些µC/OS-II中的功能应用程序需要的部分就可以了;
5、可抢占性(preemptive):
µC/OS-II是完全可抢占型的实时内核,即µC/OS-II总是运行就绪条件下优先级最高的任务;
6、多任务:
µC/OS-II可以管理64个任务。
赋予每个任务的优先级必须是不相同的,这就是说µC/OS-II不支持时间片轮转调度法(该调度法适用于调度优先级平等的任务);
7、可确定性:
绝大多数µC/OS-II的函数调用和服务的执行时间具有可确定性。
也就是说用户能知道µC/OS-II的函数调用与服务执行了多长时间。
进而可以说,除了函数OSTimeTick()和某些事件标志服务,µC/OS-II系统服务的执行时间不依赖于用户应用程序任务数目的多少;
8、任务栈:
每个任务都有自己单独的栈。
µC/OS-II允许每个任务有不同的栈空间,以便降低应用程序对RAM的需求;
9、系统服务:
µC/OS-II提供许多系统服务,比如信号量、互斥信号量、事件标志、消息邮箱、消息队列、时间管理等等;
10、中断管理:
中断可以使正在执行的任务暂时挂起。
如果优先级更高的任务被该中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,中断嵌套层数可以达255层;
11、稳定性和可靠性:
µC/OS-II的每一种功能、每一个函数以及每一行代码都经过了考验和测试,具有足够的安全性与稳定性,能用于与人性命攸关、安全性条件极为苛刻的系统中。
2.3µC/OS-II主要源代码文件介绍
µC/OS-II的源代码具体包括以下的文件:
PC.C:
源文件PC.H包含了对函数和环境的一些定义。
OS_CORE.COS_FLAG.COS_MBOX.COS_MEM.COS_MUTEX.COS_Q.COS_SEM.COS_TASK.COS_TIME.CµCOS-II.CµCOS-II.H:
这些文件是µC/OS-II中所有与处理器类型无关部分的源代码。
OS_CPU_A.SOS_CPU_C.C
OS_CPU.H:
这些文件是与处理器类型相关部分的源代码,在本实验系统中是面向80x86处理器的。
INCLUDES.H给整个内核库提供了总体的include文件。
OS_CFG..H:
µC/OS-II的配置文件,定义使用µC/OS-II中的哪些功能。
实验1任务的基本管理
1实验目的
✓理解任务管理的基本原理,了解任务的各个基本状态及其变迁过程;
✓掌握µC/OS-II中任务管理的基本方法(创建、启动、挂起、解挂任务);
✓熟练使用µC/OS-II任务管理的基本系统调用。
2实验内容
2.1实验设计
要求设计Task0、Task1两个任务:
任务Task0不断地挂起自己,再被任务Task1解挂,两个任务不断地切换执行。
图1
注意:
图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。
通过本实验,可以清晰地了解到任务在各个时刻的状态以及状态变迁的原因。
2.1.1系统的运行流程
整个应用的运行流程如图1所示,其描述如下:
(1)main()函数;
(2)main()函数调用OSInit()函数对µC/OS-II内核进行初始化,调用OSTaskCreate创建起始任务TaskStart;
(3)main()函数调用函数OSStart()启动µC/OS-II内核的运行,开始多任务的调度,执行当前优先级最高的就绪任务TaskStart;
(4)TaskStart完成如下工作:
a、安装时钟中断并初始化时钟,创建2个应用任务;
b、挂起自己(不再被其它任务唤醒),系统切换到当前优先级最高的就绪任务Task0。
之后整个系统的运行流程如下:
●t1时刻,Task0开始执行,它运行到t2时刻挂起自己;
●t2时刻,系统调度处于就绪状态的优先级最高任务Task1执行,它在t3时刻唤醒Task0,后者由于优先级较高而抢占CPU;
●Task0执行到t4时刻又挂起自己,内核调度Task1执行;
●Task1运行至t5时刻再度唤醒Task0;
●……
2.1.2µC/OS-Ⅱ中的任务描述
一个任务通常是一个无限的循环,由于任务的执行是由操作系统内核调度的,因此任务是绝不会返回的,其返回参数必须定义成void。
在μC/OS-Ⅱ中,当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就会被抢占,高优先级任务会立刻得到CPU的控制权(在系统允许调度和任务切换的前提下)。
μC/OS-Ⅱ可以管理多达64个任务,但目前版本的μC/OS-Ⅱ有两个任务已经被系统占用了(即空闲任务和统计任务)。
必须给每个任务赋以不同的优先级,任务的优先级号就是任务编号(ID),优先级可以从0到OS_LOWEST_PR10-2。
优先级号越低,任务的优先级越高。
μC/OS-Ⅱ总是运行进入就绪态的优先级最高的任务。
2.2操作系统配置
操作系统配置的目的在于根据应用的需要,对操作系统的功能和规模进行设置,以便优化对系统存储空间的使用。
配置的方法为修改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_TASKS3/*最多可以创建3个任务*/
#defineOS_LOWEST_PRIO14/*任务优先级不可以大于14*/
#defineOS_TASK_IDLE_STK_SIZE1024/*空闲任务堆栈大小*/
#defineOS_TASK_STAT_EN1/*是否允许使用统计任务*/
#defineOS_TASK_STAT_STK_SIZE1024/*统计任务堆栈大小*/
#defineOS_FLAG_EN0/*是否允许使用事件标志功能*/
#defineOS_FLAG_WAIT_CLR_EN1/*是否允许等待清除事件标志*/
#defineOS_FLAG_ACCEPT_EN1/*是否允许使用OSFlagAccept()*/
#defineOS_FLAG_DEL_EN1/*是否允许使用OSFlagDel()*/
#defineOS_FLAG_QUERY_EN1/*是否允许使用OSFlagQuery()*/
#defineOS_MBOX_EN0/*是否允许使用邮箱功能*/
#defineOS_MBOX_ACCEPT_EN1/*是否允许使用OSMboxAccept()*/
#defineOS_MBOX_DEL_EN1/*是否允许使用OSMboxDel()*/
#defineOS_MBOX_POST_EN1/*是否允许使用OSMboxPost()*/
#defineOS_MBOX_POST_OPT_EN1/*是否允许使用OSMboxPostOpt()*/
#defineOS_MBOX_QUERY_EN1/*是否允许使用OSMboxQuery()*/
#defineOS_MEM_EN0/*是否允许使用内存管理的功能*/
#defineOS_MEM_QUERY_EN1/*是否允许使用OSMemQuery()*/
#defineOS_MUTEX_EN0/*是否允许使用互斥信号量的功能*/
#defineOS_MUTEX_ACCEPT_EN1/*是否允许使用OSMutexAccept()*/
#defineOS_MUTEX_DEL_EN1/*是否允许使用OSMutexDel()*/
#defineOS_MUTEX_QUERY_EN1/*是否允许使用OSMutexQuery()*/
#defineOS_Q_EN0/*是否允许使用队列功能*/
#defineOS_Q_ACCEPT_EN1/*是否允许使用OSQAccept()*/
#defineOS_Q_DEL_EN1/*是否允许使用OSQDel()*/
#defineOS_Q_FLUSH_EN1/*是否允许使用OSQFlush()*/
#defineOS_Q_POST_EN1/*是否允许使用OSQPost()*/
#defineOS_Q_POST_FRONT_EN1/*是否允许使用OSQPostFront()*/
#defineOS_Q_POST_OPT_EN1/*是否允许使用OSQPostOpt()*/
#defineOS_Q_QUERY_EN1/*是否允许使用OSQQuery()*/
#defineOS_SEM_EN0/*是否允许使用信号量功能*/
#defineOS_SEM_ACCEPT_EN1/*是否允许使用OSSemAccept()*/
#defineOS_SEM_DEL_EN1/*是否允许使用OSSemDel()*/
#defineOS_SEM_QUERY_EN1/*是否允许使用OSSemQuery()*/
#defineOS_TASK_CHANGE_PRIO_EN0/*是否允许使用OSTaskChangePrio()*/
#defineOS_TASK_CREATE_EN1/*是否允许使用OSTaskCreate()*/
#defineOS_TASK_CREATE_EXT_EN1/*是否允许使用OSTaskCreateExt()*/
#defineOS_TASK_DEL_EN1/*是否允许使用OSTaskDel()*/
#defineOS_TASK_SUSPEND_EN1/*是否允许使用OSTaskSuspend()andOSTaskResume()*/
#defineOS_TASK_QUERY_EN1/*是否允许使用OSTaskQuery()*/
#defineOS_TIME_DLY_HMSM_EN0/*是否允许使用OSTimeDlyHMSM()*/
#defineOS_TIME_DLY_RESUME_EN1/*是否允许使用OSTimeDlyResume()*/
#defineOS_TIME_GET_SET_EN1/*是否允许使用OSTimeGet()和OSTimeSet()*/
#defineOS_SCHED_LOCK_EN1/*是否允许使用OSSchedLock()和OSSchedUnlock()*/
#defineOS_TICKS_PER_SEC200/*设置每秒之内的时钟节拍数目*/
2.3提示
main()函数是我们编写实现应用程序的起点。
首先需要在main()函数里创建起始任务TaskStart:
OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],4);
TaskStart任务
TaskStart任务负责安装操作系统的时钟中断服务例程、初始化操作系统时钟,并创建所有的应用任务.
具体负责应用任务创建的TaskStartCreateTasks函数代码如下,它创建了两个应用任务Task0和Task1:
staticvoidTaskStartCreateTasks(void)
{
INT8Ui;
for(i=0;i TaskData[i]=i;/*Eachtaskwilldisplayitsownletter*/ } OSTaskCreate(Task0,(void*)&TaskData[i],&TaskStk[i][TASK_STK_SIZE-1],5); OSTaskCreate(Task1,(void*)&TaskData[i],&TaskStk[1][TASK_STK_SIZE-1],6); } TaskStart任务完成上述操作后将自己挂起,操作系统将调度当前优先级最高的应用任务Task0运行。 应用任务 应用任务Task0运行后将自己挂起,之后操作系统就会调度处于就绪状态的优先级最高的任务,具体代码如下: voidTask0(void*pdata) { INT8Ui; INT8Uerr; i=*(int*)pdata; for(;;){ ……/*此处为输出信息,显示任务运行的状态*/ err=OSTaskSuspend(5);/*suspenditself*/ } } 应用任务Task1运行后将Task0唤醒,使其进入到就绪队列中: voidTask1(void*pdata) { INT8Ui; INT8Uerr; i=*(int*)pdata; for(;;){ OSTimeDly(150); ……/*此处为输出信息,显示任务运行的状态*/ OSTimeDly(150); err=OSTaskResume(5);/*resumetask0*/ } } 实验2消息信箱 1实验目的 掌握消息邮箱的创建,学会向消息邮箱发送消息,掌握消息邮箱的请求及查询。 2实验内容 2.1实验设计 设计一个应用程序,该程序有MyTask和YouTask两个任务,在MyTask中用一个变量Times记录任务MyTask运行次数,并将其作为消息用邮箱Str_Box发给任务YouTask,并由任务YouTask显示出来。 2.2提示 源代码 #include"includes.h" #defineTASK_STK_SIZE512 OS_STKStartTaskStk[TASK_STK_SIZE]; OS_STKMyTaskStk[TASK_STK_SIZE]; OS_STKYouTaskStk[TASK_STK_SIZE]; INT16Skey; char*s; char*ss; INT8Uerr; INT8Uy=0; INT32UTimes=0; OS_EVENT*Str_Box; voidStartTask(void*pdata); voidMyTask(void*pdata); voidYouTask(void*pdata); voidmain(void) { OSInit(); PC_DOSSaveReturn(); PC_VectSet(uCOS,OSCtxSw); Str_Box=OSMboxCreate((void*)0); OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE-1],0); OSStart(); } voidStartTask(void*pdata) { #ifOS_CRITICAL_METHOD==3 OS_CPU_SRcpu_sr; #endif pdata=pdata; OS_ENTER_CRITICAL(); PC_VectSet(0x08,OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); OSStatInit(); OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE-1],2); OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE-1],1); for(;;) { if(PC_GetKey(&key)==TRUE){ if(key==0x1B){ PC_DOSReturn(); } } OSTimeDlyHMSM(0,0,3,0); } } voidMyTask(void*pdata) { #ifOS_CRITICAL_METHOD==3 OS_CPU_SRcpu_sr; #endif pdata=pdata; for(;;) { sprintf(s,"%d",Times); OSMboxPost(Str_Box,s); Times++; OSTimeDlyHMSM(0,0,1,0); } } voidYouTask(void*pdata) { #ifOS_CRITICAL_METHOD==3 OS_CPU_SRcpu_sr; #endif pdata=pdata; for(;;) { ss=OSMboxPend(Str_Box,10,&err); PC_DispStr(10,++y,ss,DISP_BGND_BLACK+DISP_FGND_WHITE); OSTimeDlyHMSM(0,0,1,0); } } 实验3消息队列 1实验目的 掌握嵌入式实时操作系统µC/OS-II中消息队列机制的基本原理和使用方法。 2实验内容 2.1实验设计 设计两个实验任务,通过消息队列在任务间传递数据: 任务TA1以随机或固定时间间隔依次将数据1、2、3、...发送至消息队列q1,每次发送一个数据。 TA2以随机(或固定)时间间隔将随机数据发送至q1。 TA3从消息队列q1中每次接收一个数据: 如果数据来自TA1,则计算出所有已接收的来自TA1的数据之和,然后延时;如果数据来自TA2,则将数据输出到屏幕,然后延时(模拟处理数据所需的时间);调整发送数据和处理数据的速度,观察发送速度大于处理速度的结果。 2.2操作系统配置 修改uC_OS-II/OS_CFG.h: #defineOS_MAX_TASKS 3 /*最多可以创建3个任务*/ #defineOS_LOWEST_PRIO 16 /*任务优先级不可以大于14*/ #defineOS_TASK_CREATE_EN1 /*允许使用OSTaskCreate()*/ #defineOS_TASK_SUSPEND_EN 1 /*允许使用OSTaskSuspend()andOSTaskResume()*/ 相关系统调用: OSTaskCreate(): 建立一个新任务 OSQCreate(): 建立一个消息队列 OSQPend(): 等待消息 OSQPostFront(): 向消息队列发送消息 OSQPost(): 向消息队列发送消息 ·OSTaskCreate(): 建立一个新任务 ·OSTaskSuspend(): 无条件挂起一个任务 ·OSTaskResume(): 唤醒一个挂起的任务 ·OSTimeDly(): 将一个任务延时若干个时钟节拍 2.3提示 源代码 #include"../ucos-ii/includes.h"/*uC/OSinterface*/ #include"string.h" //#include"includes.h" #defineTASK_STK_SIZE512 #defineN_MESSAGES128 OS_STKTaskStartStk[TASK_STK_SIZE];/*TaskStart任务堆栈*/ OS_STKTA1Stk[TASK_STK_SIZE]; OS_STKTA2Stk[TASK_STK_SIZE]; OS_STKTA3Stk[TASK_STK_SIZE]; OS_EVENT*Str_Q; voidTaskStart(void*data); voidTA1(void*pdata); voidTA2(void*pdata); voidTA3(void*pdata); INT8Uerr; INT8Utotal=0; charbuf[128]; void*ql[N_MESSAGES]; typedefstruct{ intlist; intnum; }Mess; voidMain(void) { //Target_Init(); ARMTargetInit(); OSInit(); Str_Q=OSQCreate(&ql[0],N_MESSAGES); OSTaskCreate(TaskStart,(void*)0,&TaskStartStk[TASK_STK_SIZE-1],0); ARMTargetStart();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 操作系统 实验 指导书