ucosII嵌入式实时操作系统实验
发布时间:2024-11-18
发布时间:2024-11-18
嵌入式实时操作系统
嵌入式实时操作系统实验报告
系 别 计算机与电子系 专业班级 电子0901班 学生姓名 高傲 指导教师 黄向宇 提交日期 2012 年 4 月 1 日
嵌入式实时操作系统
一、实验目的
1.熟悉并掌握基于uC/OS-II的开发工具、工程管理工具 2.了解uC/OS-II的文件结构、文件之间的依赖关系 。 3.掌握创建多任务的方法及对任务进行相关操作的技巧。
二、实验内容
1.建立并熟悉Borland C 编译及调试环境
2.使用课本配套光盘中的例程运行并修改,观察多任务的运行状态,尝试对其中的任务进行挂起并恢复、删除及查询等操作,观察运行结果.
3.完成课后练习题,P92页13-17题,至少完成其中任意两题。
三、实验原理
1.编译环境
Turbo C是Borland公司开发的DOS下16位C语言集成开发工具。有2.0和3.0版本,2.0只支持C语言编译不支持鼠标操作,而3.0版本可以支持C/C++两种语言编译,而且还支持鼠标和//注释方式;TC2.0是80年代开发的,使用了很多年一直到现在WINDOWS系统才逐渐退出舞台。Turbo C2.0不仅是一个快捷、高效的编译程序,同时还有一个易学、易用的集成开发环境。使用Turbo C2.0无需独立地编辑、编译和连接程序,就能建立并运行C语言程序。因为这些功能都组合在Turbo 2.0的集成开发环境内,并且可以通过一个简单的主屏幕使用这些功能。
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要
嵌入式实时操作系统
后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。
Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。
而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。
makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。
2. uC/OS-II 文件体系 uC/OS-II 包括三个部分:
1)核心代码部分,这部分代码与处理器无关,包括七个源代码文件和一个头文件,这七个源代码文件负责的功能分别是内核管理、事件管理、消息队列管理、存储管理、消息管理、信号量处理、任务调度和定时管理。2)设置代码部分,包括两个头文件,用来配置事件控制块的数目以及是否包含消息管理相关代码等。3)处理器相关的移植代码部分,这部分包括一个头文件,一个汇编文件和一个C 代码文件,在uC/OS-II 的移植过程中,用户所需要关注的就是这部分文件。
3. uC/OS-II 任务的创建,OSTaskCreate()
想让µC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过
传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate() 或 OSTaskCreateExt()。OSTaskCreate()与µC/OS是向下兼容的,OSTaskCreateExt()是OSTaskCreate()的扩展版本,提供了一些附加的功能。用两个函数中的任何一个都可以建立任务。任务可以在多任务调度开始前建立,也可以在其它任务的执行过程中被建立。在开始多任务调度(即调用OSStart())前,用户必须建立至
嵌入式实时操作系统
少一个任务。任务不能由中断服务程序(ISR)来建立。
OSTaskCreate()的代码如程序清单 L4.1所述。从中可以知道,
OSTaskCreate()需要四个参数:task是任务代码的指针,pdata是当任务开始执行时传递给任务的参数的指针,ptos是分配给任务的堆栈的栈顶指针(参看4.02,任务堆栈),prio是分配给任务的优先级。
程序清单 L4.1 OSTaskCreate()
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) {
void *psp; INT8U err;
if (prio > OS_LOWEST_PRIO) { return (OS_PRIO_INVALID); }
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { (2) OSTCBPrioTbl[prio] = (OS_TCB *)1; OS_EXIT_CRITICAL();
(3)
(1)
(4)
psp = (void *)OSTaskStkInit(task, pdata, ptos, 0); (5) err = OSTCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); (6) if (err == OS_NO_ERR) { OS_ENTER_CRITICAL(); OSTaskCtr++;
(8)
(9)
(7)
OSTaskCreateHook(OSTCBPrioTbl[prio]); OS_EXIT_CRITICAL(); if (OSRunning) { OSSched(); } } else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; OS_EXIT_CRITICAL();
(10) (11)
(12)
嵌入式实时操作系统
}
return (err); } else {
OS_EXIT_CRITICAL(); return (OS_PRIO_EXIST); } }
挂起任务,OSTaskSuspend()
有时候将任务挂起是很有用的。挂起任务可通过调用OSTaskSuspend()
函数来完成。被挂起的任务只能通过调用OSTaskResume()函数来恢复。任务挂起是一个附加功能。也就是说,如果任务在被挂起的同时也在等待延时的期满,那么,挂起操作需要被取消,而任务继恢复任务,OSTaskResume()
在上一节中曾提到过,被挂起的任务只有通过调用OSTaskResume()才能
恢复。OSTaskResume()函数的代码如程序清单 L4.17所示。因为OSTaskSuspend()不能挂起空闲任务,所以必须得确认用户的应用程序不是在恢复空闲任务[L4.17(1)]。注意,这个测试也可以确保用户不是在恢复优先级为OS_PRIO_SELF的任务(OS_PRIO_SELF被定义为0xFF,它总是比OS_LOWEST_PRIO大)。续等待延时期满,并转入就绪状态。任务可以挂起自己或者其它任务。 获得有关任务的信息,OSTaskQuery()
用户的应用程序可以通过调用OSTaskQuery()来获得自身或其它应用任
务的信息。实际上,OSTaskQuery()获得的是对应任务的OS_TCB中内容的拷贝。用户能访问的OS_TCB的数据域的多少决定于用户的应用程序的配置(参看OS_CFG.H)。由于µC/OS-Ⅱ是可裁剪的,它只包括那些用户的应用程序所要求的属性和功能。
改变任务的优先级,OSTaskChangePrio()
在用户建立任务的时候会分配给任务一个优先级。在程序运行期间,用
户可以通过调用OSTaskChangePrio()来改变任务的优先级。换句话说,就是µC/OS-Ⅱ允许用户动态的改变任务的优先级。
嵌入式实时操作系统
四、实验步骤
1. 准备实验环境
先在C盘上建一个名称为bc31的目录,然后到互联网上下载一个Borland C++3.1并安装到目录bc31中(因为书中的代码是用Borland C++3.1编译的),接着再把实验程序文件夹Software复制到C盘上。
BC31实验环境的建立步骤如下
:
嵌入式实时操作系统
嵌入式实时操作系统
嵌入式实时操作系统
2. 打开实验例程
1)运行C:\SOFTWARE\SOFTWARE\uCOS-II\例2-9\Bc31\TEST.exe, 观察运行结果;
运行结果如下
:
2)分析整个实验文件目录结构及实验参考程序。
实验文件目录结构:一个实验例程包含一个bc31文件,bc31文件又包含有5个代码有关文件:LST,OBJ,SOURCE,TEST,WORK等。其中OBJ里面包含有源程序编译后的相关文件。SOURCE里面包含了源文件和相关的配置文件,可以在里面修改源文件,TEST里面含有编译后的测试文件和MAKETEST可以对修改后的源程序进行
嵌入式实时操作系统
编译,而后生成新的可执行文件TEST.exe。(具体做法为先删掉旧文件,修改好文件确认无误后用MAKETEST再进行编译即可生成新的可执行文件)。
3)按照课后习题要求编写程序并编译运行 1.课后习题第13题源程序:
#include "includes.h" #define TASK_STK_SIZE 512
//任务堆栈长度 OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 OS_STK HisTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
INT16S key;
//用于退出uCOS_II的键 INT8U x=0,y=0;
//字符显示位置
INT8U time=0;
void MyTask(void *data); //声明任务 void YouTask(void *data);
//声明任务
void HisTask(void *data); /************************
主函*********************************************/
void main (void) {
char* s_M="M"; //定义要显示的字符 OSInit();
//初始化uCOS_II PC_DOSSaveReturn();
//保存Dos环境 PC_VectSet(uCOS, OSCtxSw);
//安装uCOS_II中断
OSTaskCreate(MyTask,
//创建任务MyTask
s_M,
//给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针
0);
//使任务MyTask的优先级别为0
OSStart();
//启动uCOS_II的多任务管理
数
嵌入式实时操作系统
}
/***********************
MyTask*******************************************/
void MyTask (void *pdata) {
char* s_Y="Y";
//定义要显示的字符
任
务
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR);
//安装uCOS_II时钟中断向量
//设置uCOS_II时钟频率
PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); OSStatInit();
//初始化uCOS_II的统计任务
//创建任务MyTask
OSTaskCreate(YouTask,
s_Y,
//给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针 2);
//使任务MyTask的优先级别为2
for (;;) { if (x>50)
{ x=0; y+=2;
}
PC_DispChar(x, y,
*(char*)pdata,
//显示字符的位置
嵌入式实时操作系统
x += 1;
//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) {
if (key == 0x1B)
{
PC_DOSReturn(); } }
OSTimeDlyHMSM(0, 0, 2, 0); } }
void YouTask (void *pdata) {
char* s_Y="H";
//定义要显示的字符
//创建任务MyTask
//等待
OSTaskCreate(HisTask,
s_Y,
//给任务传递参数
&HisTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针 3);
//使任务MyTask的优先级别为0
for (;;) { if (x>50)
{ x=0; y+=2;
}
PC_DispChar(x, y,
*(char*)pdata,
//显示字符的位置
嵌入式实时操作系统
x += 1;
//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE)
{
if (key == 0x1B)
{
PC_DOSReturn(); } }
OSTimeDlyHMSM(0, 0, 4, 0); //等待
} }
/************************
任
YouTask*****************************************/
void HisTask (void *pdata) {
char* s_Y="G";
//定义要显示的字符
OSTaskCreate(MyTask,
//创建任务MyTask
s_Y,
//给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
4);
//使任务MyTask的优先级别为4
for (;;) { if (x>50) { x=0;
y+=2;
}
务
嵌入式实时操作系统
PC_DispChar(x, y, //显示字符的位置
*(char*)pdata,
DISP_BGND_BLACK+DISP_FGND_WHITE );
x += 1;
//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE)
{
if (key == 0x1B)
{
PC_DOSReturn(); } }
OSTimeDlyHMSM(0, 0, 6, 0); //等待
} }
2.课后习题第15题源程序: #include "includes.h" #define TASK_STK_SIZE 512
//任务堆栈长度
OS_STK MyTaskStk[TASK_STK_SIZE];
//定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区OS_STK HerTaskStk[TASK_STK_SIZE]; //定义任务堆栈区INT16S key;
//用于退出uCOS_II的键 INT8U x=0,y=0;
//字符显示位置
void MyTask(void *data); //声明任务
void YouTask(void *data); //声明任务 void HerTask(void *data);
//声明任务
/************************
主
函
数
嵌入式实时操作系统
*********************************************/
void main (void) {
char* s_M="M"; //定义要显示的字符 OSInit();
//初始化uCOS_II PC_DOSSaveReturn();
//保存Dos环境 PC_VectSet(uCOS, OSCtxSw);
//安装uCOS_II中断
OSTaskCreate(MyTask,
//创建任务MyTask
s_M,
//给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针
0);
//使任务MyTask的优先级别为0
OSStart();
//启动uCOS_II的多任务管理
}
/***********************
任MyTask*******************************************/
void MyTask (void *pdata) {
char* s_Y="Y"; //定义要显示的字符 char* s_H="H";
//定义要显示的字符
char* s="You and Her Tasks delete themselve at the right time";
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR);
//安装uCOS_II时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC); //设置uCOS_II时钟频率
OS_EXIT_CRITICAL();
务
嵌入式实时操作系统
OSStatInit(); //初始化uCOS_II的统计任务
//创建任务YouTask
OSTaskCreate(YouTask,
s_Y,
//给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针 1); //使任务YouTask的优先级别为1
//创建任务HerTask
OSTaskCreate(HerTask,
s_H,
//给任务传递参数
&HerTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针 2);
//使任务HerTask的优先级别为2
for (;;) { if(x>18) {
while(OSTaskDelReq(1)!=OS_TASK_NOT_EXIST&&OSTaskDelReq(2)!=OS_TASK_NOT_EXIST)
{
PC_DispStr(10, 6,
s,
DISP_BGND_BLACK+DISP_FGND_RED );
//显示字符的位置
OSTimeDly(1); } }
if (x>50)
{ x=0; y+=2;
} PC_DispChar(x, y,
*(char*)pdata,
DISP_BGND_BLACK+DISP_FGND_RED );
//显示字符的位置