百家汽车网
您的当前位置:首页ucosII实验报告

ucosII实验报告

来源:百家汽车网


实验1《任务的创建、删除、挂起、恢复》

实验学时: 2 实验地点: 二综x203 实验日期: 2013/12/13

一、实验目的

1.实验环境的建立 2.任务的接口函数的应用 二、实验内容

1.设计一个只有一个任务Task1,当程序运行后任务的工作就是每秒在显示器上显示一个字符“M”。

2. 在任务Task1中在创建一个任务Task2 。当程序运行后,任务Task1的工作在显示器上显示一个字符“M”;Task2 则是在显示器上显示字符 “Y”。

3. 要求任务Task2运行20次后,挂起任务Task1;任务Task2运行40次后,恢复任务Task1。

4. 当任务Task1运行5次时,用函数OSSchedLock()对调度器进行加锁;而当任务Task1运行到第10次时,再用函数OSSchedUnlock()对调度器进行解锁,并运行该程序。

5. 使任务Task1能删除任务Task2。 三、实验方法

包括实验方法、原理、技术、方案等。 四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 分别完成实验1、2、3、4、5 五、实验结果

1. DOS窗口每秒显示一个字符“M”。每行显示10个“M”字符,行与行的间隔是一行。按ESC键程序退出

2. DOS窗口交替显示字符\"M\"和“Y”,每隔一秒显示一次。每行显示10个字符,行与行之间的间隔是一行。 按ESC键程序退出

3.DOS窗口开始交替显示字符\"M\"和“Y”,显示20次以后,Task1挂起,只显示“Y”,当Task2运行40次以后,Task1恢复,然后开始Task1,Task2交替运行。

4.DOS窗口开始交题显示字符\"M\"和“Y”,显示5次以后,Task1将任务调度器上锁,此时只有“M”打印,当Task1运行10次后,Task1,Task2开始交替运行。

5.DOS窗口开始交替显示字符“M”和“Y”,显示10次后,只显示“Y” 六、实验结论

对实验数据和结果进行分析描述,给出实验取得的成果和结论。

1.

程序:/******** * Exercise 2 - 1 * author: csu chenan * time: 2013 - 12 - 12 ********/

#include \"includes.h\"

#define TASK_STK_SIZE 256

OS_STK MyTaskStk[TASK_STK_SIZE]; INT16S key; INT8U x = 0, y = 0;

void MyTask(void *pdata){ #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); OSStatInit(); for(;;){ if(x > 10){ x = 0; y = y + 2;

}

PC_DispChar(x, y,

*(char*)pdata,,DISP_BGND_BLACK

DISP_FGND_WHITE);

x = x + 1;

if(PC_GetKey(&key) == 1){

+

}

}

}

if(key == 0x1B){ }

PC_DOSReturn();

OSTimeDlyHMSM(0,0,1,0);

void main(void){ } 2.

OSStart();

OSTaskCreate(MyTask, ch, &MyTaskStk[TASK_STK_SIZE-1], 0); PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSInit(); char * ch = \"M\";

程序源代码: /******** * Exercise 2 - 2 * author: csu chenan

* time: 2013 - 12 - 13 ********/

#include \"includes.h\"

#define My_TASK1_STK_SIZE 256 #define My_TASK2_STK_SIZE 256

OS_STK MyTask1Stk[My_TASK1_STK_SIZE]; OS_STK MyTask2Stk[My_TASK2_STK_SIZE];

INT16S key; INT8U x = 0, y = 0;

void MyTask2(void *pdata){ #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL(); PC_VectSet(0x80, OSTickISR);

PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); for(;;){ if(x > 10){ x = 0; y = y + 2;

}

PC_DispChar(x, y,

*(char*)pdata,

DISP_FGND_WHITE);

x = x + 1;

if(PC_GetKey(&key) == 1){ if(key == 0x1B){ PC_DOSReturn();

}

DISP_BGND_BLACK

+

}

OSTimeDlyHMSM(0,0,1,0);

}

}

void MyTask1(void *pdata){ #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

char *ch = \"Y\"; pdata = pdata;

OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask2, ch, &MyTask2Stk[My_TASK2_STK_SIZE - 1], 1); for(;;){ if(x > 10){ x = 0; y = y + 2;

}

PC_DispChar(x, y,

*(char*)pdata,

DISP_BGND_BLACK

DISP_FGND_WHITE);

x = x + 1;

if(PC_GetKey(&key) == 1){ if(key == 0x1B){ PC_DOSReturn();

}

}

OSTimeDlyHMSM(0,0,1,0);

}

}

+

void main(void){ } 3.

OSStart();

OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1], 0); PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSInit(); char * ch = \"M\";

程序: /******** * Exercise 2 - 3 * author: csu chenan * time: 2013 - 12 - 13 ********/

#include \"includes.h\"

#define My_TASK1_STK_SIZE 256 #define My_TASK2_STK_SIZE 256

OS_STK MyTask1Stk[My_TASK1_STK_SIZE];

OS_STK MyTask2Stk[My_TASK2_STK_SIZE];

INT16S key; INT8U x = 0, y = 0; INT16U cnt = 0;

void MyTask2(void *pdata){ #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; for(;;){ cnt += 1;

if(cnt == 20){ OSTaskSuspend(0);

}

if(cnt == 40){ OSTaskResume(0);

} if(x > 10){ x = 0; y = y + 2;

}

PC_DispChar(x, y,

DISP_FGND_WHITE);

x = x + 1;

if(PC_GetKey(&key) == 1){ if(key == 0x1B){ PC_DOSReturn();

}

}

OSTimeDlyHMSM(0,0,1,0);

}

}

void MyTask1(void *pdata){ char * ch2 = \"Y\";

*(char*)pdata,

DISP_BGND_BLACK

+

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_SIZE-1], 1); for(;;){ if(x > 10){ x = 0; y = y + 2;

}

PC_DispChar(x, y,

*(char*)pdata,

DISP_BGND_BLACK

DISP_FGND_WHITE);

x = x + 1;

if(PC_GetKey(&key) == 1){ if(key == 0x1B){ PC_DOSReturn();

}

} cnt ++;

OSTimeDlyHMSM(0,0,1,0);

}

}

void main(void){ char * ch = \"M\"; OSInit();

PC_DOSSaveReturn();

PC_VectSet(uCOS, OSCtxSw);

+

} 4.

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1], 0); OSStart();

程序: /******** * Exercise 2 - 3 * author: csu chenan * time: 2013 - 12 - 13 ********/

#include \"includes.h\"

#define My_TASK1_STK_SIZE 256 #define My_TASK2_STK_SIZE 256

OS_STK MyTask1Stk[My_TASK1_STK_SIZE]; OS_STK MyTask2Stk[My_TASK2_STK_SIZE];

INT16S key;

INT8U x = 0, y = 0; INT16U cnt = 0;

void MyTask2(void *pdata){ #if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr; #endif

}

void MyTask1(void *pdata){ char * ch2 = \"Y\"; #if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr; pdata = pdata; OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_SIZE-1], 1); for(;;){ #endif

pdata = pdata; for(;;){ }

if(x > 10){ }

PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE); x = x + 1;

if(PC_GetKey(&key) == 1){ }

OSTimeDlyHMSM(0,0,1,0);

if(key == 0x1B){ }

PC_DOSReturn(); x = 0; y = y + 2;

cnt = cnt + 1; if(cnt == 5){ OSSchedLock(); }

else if(cnt==10){ OSSchedUnlock();

} }

void main(void){ } 5.

OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1], 0); OSStart();

OSInit();

PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); char * ch = \"M\"; }

if(x > 10){ }

PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE); x = x + 1;

if(PC_GetKey(&key) == 1){ }

OSTimeDlyHMSM(0,0,1,0);

if(key == 0x1B){ }

PC_DOSReturn(); x = 0; y = y + 2;

程序代码如下: /******** * Exercise 2 - 3 * author: csu chenan * time: 2013 - 12 - 13 ********/

#include \"includes.h\"

#define My_TASK1_STK_SIZE 256 #define My_TASK2_STK_SIZE 256

OS_STK MyTask1Stk[My_TASK1_STK_SIZE]; OS_STK MyTask2Stk[My_TASK2_STK_SIZE];

INT16S key;

INT8U x = 0, y = 0; INT16U cnt = 0;

void MyTask2(void *pdata){ #if OS_CRITICAL_METHOD == 3

pdata = pdata; for(;;){

OS_CPU_SR cpu_sr; #endif

if(OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ){ OSTaskDel(OS_PRIO_SELF); break;

} }

void MyTask1(void *pdata){ char * ch2 = \"Y\"; #if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr; pdata = pdata; OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();

OSStatInit();

OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_SIZE-1], 1); for(;;){ #endif

}

if(x > 10){ }

PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE); x = x + 1;

if(PC_GetKey(&key) == 1){ }

OSTimeDlyHMSM(0,0,1,0);

if(key == 0x1B){ }

PC_DOSReturn(); x = 0; y = y + 2;

cnt = cnt + 1; if(cnt == 10){

while(OSTaskDelReq(0) != OS_TASK_NOT_EXIST){ OSTimeDly(1); } }

if(x > 10){

x = 0;

}

}

}

y = y + 2;

PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE); x = x + 1;

if(PC_GetKey(&key) == 1){ }

OSTimeDlyHMSM(0,0,1,0);

if(key == 0x1B){ }

PC_DOSReturn();

void main(void){ }

注:有程序的要求附上程序源代码,有图表的要有截图并有相应的文字说明和分析 七、实验小结

给出本次实验的体会,如学会了什么,遇到哪些问题,如何解决这些问题,存在哪些有待改进的地方。

char * ch = \"M\";

OSInit();

PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1], 0); OSStart();

实验2《时钟节拍及时间管理函数》

实验学时: 2 实验地点: 综合实验楼x201 实验日期: 2013/12/15

一、实验目的

1.实验环境的建立

2.多任务环境下中断机制及时间API的应用 二、实验内容

1.在OS_CPU_C.C文件中按如下代码定义函数OSTimeTickHook(),然后运行并查看运行结果。实现显示系统在每发生500次时钟中断期间,调度器进行任务调度的次数。

2.设计一个有3个任务的应用程序。这3个任务分别是:MyTask、YouTask、和InterTask。其中任务InterTask是在时钟节拍中断服务程序中用钩子函数OSTimeTickHook()中断了10000次时使用一个信号变量InterKey激活的。运行并分析由中断服务程序激活任务的工作特点。

3. 设计一个应用,在任务MyTask中调用函数OSTimeDlyResume()取消任务YouTask的延时。为了观察任务YouTask的延时时间的变化,在钩子函数OSTimeTickHook()输出了任务YouTask在延时时间到时的时钟节拍数。

4. 设计一个应用程序,在任务中调用OSTimeGet()函数获得并显示系统的时钟节拍数OSTime。当任务运行10s时,调用函数OSTimeSet()将OSTime的值设为10。

5. 在KEIL模拟开发环境下,将顺序执行的程序改为多任务运行,并跟踪程序或设置断点观察多任务系统执行流程。 三、实验方法

包括实验方法、原理、技术、方案等。 四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 安装KEIL2集成开发环境。 4. 分别完成实验1、2、3、4、5 五、实验结果

记录实验输出数据和结果。 1.

2.

3.

4.

5.

六、实验结论

对实验数据和结果进行分析描述,给出实验取得的成果和结论。 1. OS_CPU_C.c

#if OS_CPU_HOOKS_EN > 0

INT16U d=0; INT16U d1=0;

void OSTimeTickHook (void) {

char* s0 = \"500\"; char* s1 = \"Per\";

char* s2 = \"Times Interrupt Attemper Times\"; char s[8];

if(d == 500) {

PC_DispStr(14,4,s1,DISP_BGND_BLACK+DISP_FGND_WHITE); PC_DispStr(18,4,s0,DISP_BGND_BLACK+DISP_FGND_WHITE); PC_DispStr(22,4,s2,DISP_BGND_BLACK+DISP_FGND_WHITE); sprintf(s,\"%d\

PC_DispStr(31,d1+5,s,DISP_BGND_BLACK+DISP_FGND_WHITE); d = 0; d1 += 1;

} d += 1; } #endif

#include \"includes.h\"

#define TASK_STK_SIZE 512 OS_STK MyTaskStk[TASK_STK_SIZE]; INT16S key; INT8U x=0,y=0; void main (void) {

char* s_M=\"M\"; */

PC_DOSSaveReturn(); /* Save environment to return to DOS */

PC_VectSet(uCOS, OSCtxSw); /* Install uC/OS-II's context switch vector */

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSTaskCreate(MyTask,s_M, &MyTaskStk[TASK_STK_SIZE - 1], 0); */ }

void MyTask(void *pdata) {

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif

void MyTask(void *data);

OSInit(); /* Initialize uC/OS-II

OSStart(); /* Start multitasking

pdata = pdata; /* Prevent compiler warning */

OS_ENTER_CRITICAL();

PC_VectSet(0x08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();

OSStatInit(); for (;;) { } }

2.程序:OS_COPU_C.c #if OS_CPU_HOOKS_EN > 0

extern BOOLEAN InterKey; INT16U InterCtr = 0;

void OSTimeTickHook (void)

if(x>10) { }

PC_DispChar(x,y,*(char*)pdata,DISP_BGND_BLACK+DISP_FGND_WHITE); x+=1;

if(PC_GetKey(&key) == 1) { }

OSTimeDlyHMSM(0,0,1,0);

if(key == 0x1B) { }

PC_DOSReturn(); x=0; y+=2;

{

if(InterCtr == 10000) { }

InterCtr++; } #endif Test.c

#include \"includes.h\"

#define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK MyTaskStk[TASK_STK_SIZE]; OS_STK YouTaskStk[TASK_STK_SIZE]; OS_STK InterTaskStk[TASK_STK_SIZE]; INT16S key;

INT8U x=0,y=0;

InterKey = 1;

//用于退出uCOS_II的键 //字符显示位置 //声明任务 //声明任务 //声明任务

BOOLEAN InterKey=FALSE; void MyTask(void *data); void YouTask(void *data); void InterTask(void *data); void main (void) {

char* s_M=\"M\"; OSInit( );

//定义要显示的字符 //保存Dos环境

//安装uCOS_II中断

//初始化uCOS_II

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate( }

void MyTask (void *pdata)

MyTask, s_M, 0 );

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

//创建任务MyTask //给任务传递参数

//设置任务堆栈栈顶指针

&MyTaskStk[TASK_STK_SIZE - 1],

//任务的优先级别为0

//启动多任务管理

OSStart( );

{

char* s_Y=\"Y\";

char* s_H=\"H\";

//定义要显示的字符

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL( ); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( ); OSStatInit( ); OSTaskCreate(

YouTask, s_Y, 1 );

InterTask, s_H, 2 );

//创建任务MyTask

//创建任务MyTask //给任务传递参数

//设置任务堆栈栈顶指针

// MyTask的优先级别为1

//初始化统计任务

//安装时钟中断向量

//设置时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

&YouTaskStk[TASK_STK_SIZE - 1],

OSTaskCreate(

//给任务传递参数 // MyTask的优先级别为2

&InterTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针

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( );

//恢复Dos环境

}

//等待3秒

} }

}

OSTimeDlyHMSM(0, 0, 3, 0);

void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; for (;;) {

if (x>50)

{ x=0; y+=2;

}

x, y,

//字符的显示位置

PC_DispChar(

*(char*)pdata,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//等待1秒

x += 1;

OSTimeDlyHMSM(0, 0, 1, 0); } }

char*s=\"Running a task for interrupt demand: InterTask\"; void InterTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

if(InterKey) {

if (x>50) {

x=0; y+=2;

}

} PC_DispChar(

x, y,

//字符的显示位置

*(char*)pdata,

DISP_BGND_BLACK+DISP_FGND_WHITE ); x += 1;

PC_DispStr(5,6,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

InterKey=FALSE; //OSIntNesting--;

//等待1秒

OSTimeDlyHMSM(0, 0, 1, 0); } } 3. 程序:

#if OS_CPU_HOOKS_EN > 0

INT8U d=0; INT8U l=0; INT16U tt=1; char s[5];

void OSTimeTickHook (void) {

if(OSTCBPrioTbl[2]->OSTCBDly == 1) {

sprintf(s,\"%5d\

PC_DispStr(d,l+4,s,DISP_BGND_BLACK+DISP_FGND_WHITE);

}

d+=6;

} tt+=1;

#endif Test.c

#include \"includes.h\"

#define TASK_STK_SIZE 512

OS_STK MyTaskStk[TASK_STK_SIZE]; OS_STK YouTaskStk[TASK_STK_SIZE]; INT16S key;

void MyTask(void *data); void YouTask(void *data); void main (void) {

char* s_M=\"M\";

OSInit();

PC_DOSSaveReturn();

//保存Dos环境

//安装uCOS_II中断

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate(MyTask,

OSStart(); }

void MyTask (void *pdata)

//启动uCOS_II的多任务管理

s_M, 0);

//初始化uCOS_II

//定义要显示的字符

//声明任务 //声明任务

INT8U x=0,y=0;

//定义任务堆栈区 //定义任务堆栈区

//任务堆栈长度

//用于退出uCOS_II的键 //字符显示位置

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

//创建任务MyTask //给任务传递参数

&MyTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针

//使任务MyTask的优先级别为0

{

char* s_Y=\"Y\";

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL();

OSStatInit();

s_Y, 2);

//初始化uCOS_II的统计任务

//创建任务MyTask

OSTaskCreate(YouTask,

//安装uCOS_II时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

//定义要显示的字符

//给任务传递参数

//使任务MyTask的优先级别为2

&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针

for (;;) { if (x>50)

{ x=0; y+=2;

}

if(y>1) OSTimeDlyResume(2); PC_DispChar(x, y,

*(char*)pdata,

DISP_BGND_BLACK+DISP_FGND_WHITE );

x++;

//显示字符的位置

//取消YouTask任务的延时

{ {

if (PC_GetKey(&key) == TRUE)

if (key == 0x1B) PC_DOSReturn(); } }

OSTimeDly(300); } }

void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) { if (x>50)

{ x=0; y+=2; }

//显示字符的位置 //延时100个时钟节拍

PC_DispChar(x, y,

*(char*)pdata,

DISP_BGND_BLACK+DISP_FGND_WHITE );

x += 1;

//延时500个时钟节拍

} } 4.

OSTimeDly(500);

#include \"includes.h\"

#define TASK_STK_SIZE 512 INT16S key; INT32U stime; INT8U x=0; void main (void) {

OSInit();

//初始化uCOS_II

//声明一个任务

//用于退出uCOS_II的键

//任务堆栈长度

//定义任务堆栈区

OS_STK TaskStartStk[TASK_STK_SIZE];

void MyTask(void *data);

PC_DOSSaveReturn();

//保存Dos环境

//安装uCOS_II中断

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate(MyTask, }

void MyTask (void *pdata) { char s[5];

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL();

(void*)0, 0);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

//创建任务MyTask

//给任务传递参数

//使任务MyTask的优先级别为0

//启动uCOS_II的多任务管理

&TaskStartStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针

OSStart();

PC_VectSet(0x08, OSTickISR); //安装uCOS_II时钟中断向量 PC_SetTickRate(OS_TICKS_PER_SEC); //设置uCOS_II时钟频率 OS_EXIT_CRITICAL(); OSStatInit(); for (;;) {

if (x==10)

{

OSTimeSet(10); }

stime=OSTimeGet(); sprintf(s,\"%5d\ PC_DispStr(5, 2,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE );

x += 1;

//在x,y位置显示s中的字符

//初始化uCOS_II的统计任务

//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) {

if (key == 0x1B)

{

PC_DOSReturn(); } }

OSTimeDlyHMSM(0, 0, 1, 0); } } 5.

#include \"includes.h\" #include \"serial.h\"

#define MAXSTKSIZE 512

void TASK1(void *ppdata); void TASK2(void *ppdata); void TASK3(void *ppdata);

OS_STK TASK1STK[MAXSTKSIZE]; OS_STK TASK2STK[MAXSTKSIZE]; OS_STK TASK3STK[MAXSTKSIZE];

INT8U times=1;

void main(void) {

InitTimer0();

OSStart();

InitSerial();

//创建三个任务

OSTaskCreate(TASK1,(void *)0,&TASK1STK[0],1); OSTaskCreate(TASK2,(void *)0,&TASK2STK[0],2); OSTaskCreate(TASK3,(void *)0,&TASK3STK[0],3);

OSInit();

//运行次数

//等待

}

void TASK1(void *ppdata) { }

void TASK2(void *ppdata) { }

void TASK3(void *ppdata) {

ppdata = ppdata; for(;;) {

Uart0_print(\"task3 is actived.\\n\");

//Uart0_printR(\"%d\\n\OSIdleCtr=OSIdleCtr; OSTimeDlyHMSM(0,0,1,0);

ppdata=ppdata; for(;;) { }

Uart0_print(\"task2 is actived.\\n\");

//Uart0_printR(\"%d\\n\OSIdleCtr=OSIdleCtr; OSTimeDlyHMSM(0,0,1,0);

for(;;) { }

Uart0_print(\"task1 is actived.\\n\"); OSIdleCtr=OSIdleCtr; OSTimeDlyHMSM(0,0,1,0); ppdata=ppdata; ET0=1;

}

}

七、实验小结

本次实验对中断的处理过程等有了更深一步的了解,对与uc/OS的中断机制有了比较详细的了解。实验中通过对uc/os时钟中断的使用,对uc/OS的时钟等有了比较深入的了解同时在做实验的过程中,对于UC/OS的工作原理有了很深的了解。对UC/OS的程序编写也更熟悉了。

实验3《信号量应用》

实验学时: 2 实验地点: 综二实验室x201 实验日期: 2013/12/16

一、实验目的

1.实验环境的建立

2.任务的通信机制之信号量应用及解决优先级反转 二、实验内容

1.设计应用程序中有2个用户任务:MyTask和YouTask。这两个任务都要访问同一个共享资源s,但YouTask访问s需要的时间长一些(本例中使用了一个循环来模拟访问的时间),而MyTask访问s的时间要短一些,这样就不可避免的出现了在任务YouTask访问s期间,任务MyTask也来访问s,从而出现了干扰,观察干扰现象,解释原因。

2.3.

访问共享资源s,以解决实验1中的冲突问题。 果。(不做) 三、实验方法

包括实验方法、原理、技术、方案等。 四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 分别完成实验1、2、3。 五、实验结果

1.实验运行结果如下:

在应用程序中定义一个全局变量ac_key来作为信号量,并根据该信号量的状态来 在实验2中,把使用的信号量改为互斥型信号量,然后运行该程序并观察其运行结

2.实验运行结果如下:

3.实验运行结果如下:

六、实验结论

对实验数据和结果进行分析描述,给出实验取得的成果和结论。 1.核心代码如下:

/************************Test************************************/ #include \"includes.h\"

#define TASK_STK_SIZE 512

OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 INT16S key; INT8U char *s=\"\";

//用于退出uCOS_II的键 //字符显示位置

y1=0,y2=0;

//任务堆栈长度

//定义要显示的字符

void MyTask(void *data);

//声明任务 //声明任务

void YouTask(void *data); void main (void) {

OSInit( );

/************************主函数**********************************/

//初始化uCOS_II

PC_DOSSaveReturn( ); //保存Dos环境 //安装uCOS_II中断 //创建任务MyTask

//给任务传递参数

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate(MyTask, }

(void*)0, 0);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针

//使任务的优先级别为0 //启动多任务管理

OSStart( );

/***********************任务MyTask********************************/

void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

INT8U err;

pdata = pdata; OS_ENTER_CRITICAL( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( ); OSStatInit( );

(void*)0, 2);

//初始化统计任务 //创建任务YouTask //给任务传递参数

OSTaskCreate(YouTask,

//安装时钟中断向量 //设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针

//使任务的优先级别为2

for (;;) {

s=\"MyTask visit data s\";

PC_DispStr(5, ++y1,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE);

//显示字符串

//如果按下Esc键则退出uCOS_II

if (PC_GetKey(&key) == TRUE) {

if (key == 0x1B)

{

PC_DOSReturn( ); } } } }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

INT8U err; pdata = pdata; for (;;)

{

s=\"YouTask visit data s\";

PC_DispStr(28, ++y2,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//置OSTime为0

//显示字符串

//等待200个时钟节拍

OSTimeDly(200);

OSTimeSet(0); { }

while(OSTime<500)

PC_DispStr(55, y2,

s,

DISP_BGND_BLACK+DISP_FGND_YELLOW );

//等待10个时钟节拍

//显示字符串

OSTimeDly(10); } }

/************************End**************************************/

2.实验核心代码如下:

/************************Test**************************************/ #include \"includes.h\"

#define TASK_STK_SIZE 512

OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 OS_STK YouTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 INT16S key; INT8U

//用于退出uCOS_II的键 //字符显示位置

y1=0,y2=0;

//任务堆栈长度

BOOLEAN ac_key;

//定义信号量

char* s=\"原始数据\";

//定义要显示的字符

//声明任务 //声明任务

void MyTask(void *data);

void YouTask(void *data); void main (void) {

OSInit( ); ac_key=1;

/************************主函数*********************************/

//初始化uCOS_II

//设置信号量初值 //保存Dos环境 //安装uCOS_II中断 //创建任务MyTask

//给任务传递参数

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate(MyTask,

OSStart( ); }

(void*)0, 0);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针

//使任务的优先级别为0 //启动uCOS_II的多任务管理

/***********************任务MyTask********************************/

void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif INT8U err;

pdata = pdata; OS_ENTER_CRITICAL( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( ); OSStatInit( );

(void*)0, 2);

//初始化uCOS_II的统计任务 //创建任务MyTask //给任务传递参数

OSTaskCreate(YouTask,

//安装uCOS_II时钟中断向量 //设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶指针

//使任务的优先级别为2

for (;;) {

if(ac_key)

{

ac_key=FALSE;

//使信号量无效 //显示字符的位置

s=\"MyTask visit data s\";

PC_DispStr(5, ++y1,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE); ac_key=TRUE;

//发信号

}

if (PC_GetKey(&key) == TRUE) {

//如果按下Esc键则退出uCOS_II

if (key == 0x1B)

{

PC_DOSReturn( ); } } } }

/************************任务YouTask****************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

INT8U err; pdata = pdata; for (;;) {

if(ac_key)

{ }

//等待10个时钟节拍

ac_key=FALSE;

//使信号量为无信号 //显示字符串

//等待20个时钟节拍

OSTimeDly(20);

s=\"YouTask visit data s\";

PC_DispStr(28, ++y2,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//置OSTime为0

OSTimeSet(0); { }

while(OSTime<500)

PC_DispStr(55, y2,

s,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//发信号

//显示字符串

ac_key=TRUE;

OSTimeDly(10); } }

/************************End**************************************/

3.实验核心代码如下:

/************************Test*************************************/ #include \"includes.h\" #define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK Task1Stk[TASK_STK_SIZE]; OS_STK Task2Stk[TASK_STK_SIZE]; OS_STK Task3Stk[TASK_STK_SIZE]; INT16S key;

char*s1=\"Task1 running\"; char*s2=\"Task2 running\"; char*s3=\"Task3 running\"; char*ss=\"Task1 desire sem\"; INT8U err; INT8U y=0;

//字符显示位置

//定义事件控制块

//声明起始任务 //声明任务 //声明任务 //声明任务

//用于退出的键

INT32U Times=0; OS_EVENT *Mutexp;

void StartTask(void *data); void Task1(void *data); void Task2(void *data); void Task3(void *data); void main (void) {

OSInit( );

/************************主函数*********************************/

//初始化uCOS_II //保存Dos环境

//安装uCOS_II中断

//定义信号量

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); Mutexp = OSMutexCreate (1,&err); OSTaskCreate(StartTask, }

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

//创建任务StartTask

//设置任务堆栈栈顶

(void*)0, 0);

//给任务传递参数

&StartTaskStk[TASK_STK_SIZE - 1],

//使任务的优先级别为0

//启动多任务管理

OSStart( );

pdata = pdata; OS_ENTER_CRITICAL( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( );

(void*)0, 3);

//初始化统计任务

//创建任务Task1

//设置任务堆栈栈顶

OSTaskCreate(Task1,

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

//给任务传递参数

&Task1Stk[TASK_STK_SIZE - 1],

//使任务的优先级别为3

//创建任务Task2

//设置任务堆栈栈顶

//给任务传递参数

OSTaskCreate(Task2,

(void*)0, 4);

&Task2Stk[TASK_STK_SIZE - 1],

//使任务的优先级别为4

//创建任务Task3

//设置任务堆栈栈顶

//给任务传递参数

OSTaskCreate(Task3,

(void*)0, 5);

&Task3Stk[TASK_STK_SIZE - 1],

//使任务的优先级别为5

for (;;) {

//如果按下Esc键则退出uCOS_II

if (PC_GetKey(&key) == TRUE) {

if (key == 0x1B)

{

PC_DOSReturn( ); } }

OSTimeDlyHMSM(0, 0, 3, 0); } }

/************************任务Task1*******************************/ void Task1 (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

OSTimeDlyHMSM(0, 0, 0, 300); {

//等待300毫秒 //等待3秒

PC_DispStr(10,++y,

ss,

DISP_BGND_BLACK+DISP_FGND_YELLOW );

//请求信号量

OSMutexPend(Mutexp,0,&err);

PC_DispStr(10,++y,

s1,

DISP_BGND_BLACK+DISP_FGND_RED );

OSMutexPost(Mutexp); //发送信号量

//等待200毫秒

}

OSTimeDlyHMSM(0, 0, 0, 200); } }

/************************任务Task2******************************/ void Task2 (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;)

{ PC_DispStr(10,++y,

s2,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//等待100毫秒

OSTimeDlyHMSM(0, 0, 0, 100); } }

/************************任务Task3******************************/ void Task3 (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;)

{

OSMutexPend(Mutexp,0,&err); //请求信号量 PC_DispStr(10,++y,

s3,

DISP_BGND_BLACK+DISP_FGND_WHITE );

for(Times;Times<20000000;Times++)

{ } Times=0;

OSMutexPost(Mutexp);

//发送信号量

OS_Sched();

OSTimeDlyHMSM(0, 0, 0, 100); //等待100毫秒 } }

/************************End**************************************/

七、实验小结

本次实验是对任务之间的共享资源访问的方法。三个实验,循序渐进,第一个实验是导出共享资源会导致的问题,数据不稳定,第二个实验用一个全局变量来解决了这个问题,第三个实验用互斥信号量解决问题。以前在操作系统的课上学习过信号量的相关知识,但是没有这么具体,经过这三个实验,从发现问题到解决问题对以前的知识了解的更加具体,透彻了。通过实验对信号量的机制有了很深的理解,对信号量的操作也比较熟悉了

实验4《消息邮箱应用》

实验学时: 2 实验地点: 201 实验日期: 2013/12/13

一、实验目的

1.实验环境的建立

2.任务的通信机制之消息邮箱应用 二、实验内容

1.设计一个利用消息邮箱进行通信的例子:有两个任务MyTask和YouTask。由于任务YouTask要向任务MyTask发送消息,因此定义了一个全局的指针变量msg_p作为邮箱来传递消息的指针。

2.

设计一个应用程序,该程序有两个任务MyTask和YouTask。在任务MyTask中用一

个变量Times记录任务MyTask的运行次数,并将其作为消息用邮箱Str_Box发给任务YouTask,且由任务YouTask显示出来。 三、实验方法

按照步骤进行运行 四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 分别完成实验1、2 五、实验结果

1.实验运行结果如下:

2.实验运行结果如下:

六、实验结论 1.实验核心代码如下:

/************************Test*************************************/

#include \"includes.h\" #define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区 //用于退出的键 //字符显示位置

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; OS_STK YouTaskStk[TASK_STK_SIZE]; INT16S key; INT8U void *msg_p;

y1=0,y2=0;

//消息邮箱 //声明起始任务

//声明任务 //声明任务

void StartTask(void *data); void MyTask(void *data); void YouTask(void *data); void main (void) {

OSInit( );

/************************主函数*********************************/

//初始化uCOS_II //安装uCOS_II中断 //创建任务MyTask //给任务传递参数

PC_DOSSaveReturn( ); //保存Dos环境

PC_VectSet(uCOS, OSCtxSw); OSTaskCreate(StartTask,

(void*)0,

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

&StartTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶

}

0);

//使任务的优先级别为0 //启动多任务管理

OSStart( );

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; OS_ENTER_CRITICAL( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( );

//初始化统计任务 //给任务传递参数 //使任务的优先级别为1 //创建任务YouTask //给任务传递参数 //使任务的优先级别为2

OSTaskCreate(MyTask,

(void*)0, 1);

//创建任务MyTask

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

OSTaskCreate(YouTask,

(void*)0, 2);

&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

for (;;) {

//如果按下Esc键则退出uCOS_II

if (PC_GetKey(&key) == TRUE) {

if (key == 0x1B)

{

PC_DOSReturn( ); } }

OSTimeDlyHMSM(0, 0, 3, 0); } }

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

//等待3秒

for (;;)

//显示字符串

{ PC_DispStr(5, ++y1,

if(msg_p!=(void*) 0) { }

//等待1秒

PC_DispStr(15,y1,

msg_p,

//显示收到的消息

DISP_BGND_BLACK+DISP_FGND_RED );

//使消息邮箱为空

//请求消息

\"MyTask\",

DISP_BGND_BLACK+DISP_FGND_WHITE );

msg_p=(void*) 0;

OSTimeDlyHMSM(0, 0, 1, 0); } }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

char*s=\" a message from YouTask\"; pdata = pdata; for (;;) {

PC_DispStr(40, ++y2,

if(OSTimeGet( )>500 && msg_p==(void*) 0)

{

msg_p=s;

//发送消息

PC_DispStr(50,y2,

\"YouTask send a message\", DISP_BGND_BLACK+DISP_FGND_RED );

//等待1秒

\"YouTask\",

DISP_BGND_BLACK+DISP_FGND_WHITE );

//显示字符串

//定义消息

}

OSTimeDlyHMSM(0, 0, 2, 0); } }

/************************End**************************************/

2.核心代码如下:

/************************Test*************************************/

#include \"includes.h\" #define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; OS_STK YouTaskStk[TASK_STK_SIZE]; INT16S key; char*s; char*ss; INT8U err; INT8U y=0;

//字符显示位置

//声明起始任务 //声明任务 //声明任务

//用于退出的键

INT32U Times=0; OS_EVENT *Str_Box;

void StartTask(void *data); void MyTask(void *data);

void YouTask(void *data); void main (void) {

OSInit( );

/************************主函数*********************************/

//初始化uCOS_II //保存Dos环境

//安装uCOS_II中断

//创建互斥型信号量

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); Str_Box = OSMboxCreate ((void*)0); OSTaskCreate(StartTask, }

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; OS_ENTER_CRITICAL( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( );

(void*)0,

//初始化统计任务 //创建任务MyTask

OSTaskCreate(MyTask,

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

(void*)0, 0);

//创建任务StartTask

//设置任务堆栈栈顶

//给任务传递参数

&StartTaskStk[TASK_STK_SIZE - 1],

//使任务的优先级别为0

//启动多任务管理

OSStart( );

//给任务传递参数

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶 3);

//使任务的优先级别为3

//创建任务YouTask

//给任务传递参数

OSTaskCreate(YouTask,

(void*)0, 4);

&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

//使任务的优先级别为4

for (;;) {

//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) { {

if (key == 0x1B) PC_DOSReturn(); } }

OSTimeDlyHMSM(0, 0, 3, 0); } }

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

sprintf(s,\"%d\" ,Times); OSMboxPost(Str_Box,s);

Str_Box->OSEventPtr,//s,

DISP_BGND_BLACK+DISP_FGND_WHITE );*/

//等待1秒 //发送消息

//等待3秒

/*PC_DispStr(10,++y,

Times++;

OSTimeDlyHMSM(0, 0, 1, 0); } }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

ss=OSMboxPend(Str_Box,10,&err);

ss,

DISP_BGND_BLACK+DISP_FGND_WHITE );

//等待1秒

PC_DispStr(10,++y,

OSTimeDlyHMSM(0, 0, 1, 0); } }

/************************End**************************************/

七、实验小结

本次实验二个题目,对消息邮箱的应用,和信号量不同的是传递的是一个全局的指针变量,指针指向要传递的消息。其余没有太多不同。消息邮箱的操作和信号量的操作类似,用于任务间消息传递。

实验5《消息队列应用》

实验学时: 2 实验地点: 201 实验日期: 2013/12/15

一、实验目的

1.实验环境的建立

2.任务的通信机制之消息队列应用 二、实验内容

1.设计一个应用消息队列进行通信的应用程序,运行该程序并观察其运行结果。 2. 在KEIL开发环境下,用多任务及某种事件机制实现按下键盘时可以控制对应的LED亮灭: 按下P3.2键盘时P1.0、P1.1对应的LED点亮,按下P3.3键盘时P1.2、P1.3对应的LED点亮,按下P3.4键盘时P1.4、P1.5对应的LED点亮,按下P3.5键盘时P1.6、P1.7对应的LED点亮,没有键盘按下时,LED全灭。 三、实验方法

按照步骤进行运行 四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 安装KEIL2集成开发环境及其插件。 4. 分别完成实验1、2 五、实验结果

1.实验运行结果如下:

2.实验运行结果如下:

六、实验结论 1.核心代码如下:

/************************Test*************************************/ #include \"includes.h\"

#define TASK_STK_SIZE 512 #define N_MESSAGES 128

//任务堆栈长度 //定义消息队列长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; INT16S key; char*ss; char*s; INT8U flag=1;

void *MsgGrp[N_MESSAGES]; INT8U err; INT8U y=0;

INT8U times=0;

OS_STK YouTaskStk[TASK_STK_SIZE];

//用于退出的键

//定义消息指针数组

//字符显示位置 //定义事件控制块

//声明起始任务 //声明任务 //声明任务

OS_EVENT *Str_Q;

void StartTask(void *data); void MyTask(void *data); void YouTask(void *data); void main (void) {

OSInit( );

/************************主函数*********************************/

//初始化uCOS_II

//保存Dos环境

//安装uCOS_II中断

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

Str_Q = OSQCreate (&MsgGrp[0],N_MESSAGES); OSTaskCreate(StartTask, }

(void*)0, 0);

//给任务传递参数

//创建消息队列

//创建任务StartTask

//设置任务堆栈栈顶

&StartTaskStk[TASK_STK_SIZE - 1],

//使任务的优先级别为0

//启动多任务管理

OSStart( );

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL( ); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

//OSStatInit( );

(void*)0, 3);

//初始化统计任务

//创建任务MyTask

OSTaskCreate(MyTask,

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

//给任务传递参数 //使任务的优先级别为3

//创建任务YouTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为4

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

OSTaskCreate(YouTask,

(void*)0, 4);

&YouTaskStk[TASK_STK_SIZE - 1],

OSQFlush(Str_Q); for (;;) { if(flag)

{

s=\"this is 1 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 2 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 3 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 4 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 5 time!\";

}

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 6 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 s=\"this is 7 time!\";

OSQPostFront(Str_Q,s); //向消息队列插入一个消息 flag=0;

//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) { {

if (key == 0x1B) PC_DOSReturn(); } }

OSTimeDlyHMSM(0, 0, 2, 0); } }

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) { }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; for (;;) {

ss=OSQPend(Str_Q,0,&err); //请求消息队列 OSTimeDlyHMSM(0, 0, 2, 0); //等待1秒

PC_DispStr(10,++y,ss,DISP_BGND_BLACK+DISP_FGND_RED ); }

//等待1秒

}

ss=OSQPend(Str_Q,0,&err); //请求消息队列 OSTimeDlyHMSM(0, 0, 2, 0);

//等待1秒

PC_DispStr(10,++y,ss,DISP_BGND_BLACK+DISP_FGND_GREEN ); }

/************************End**************************************/

2.实验核心代码如下:

#include \"includes.h\" #include \"serial.h\"

#define MAXSTKSIZE 512

void TASK1(void *ppdata); void TASK2(void *ppdata); void TASK3(void *ppdata);

OS_STK TASK1STK[MAXSTKSIZE]; OS_STK TASK2STK[MAXSTKSIZE]; //OS_STK TASK3STK[MAXSTKSIZE];

OS_EVENT *Str_Box; INT8U err; INT8U hello;

void Delay(unsigned int count) {

while(--count != 0) }

void main(void) {

for(i = 0; i < 125; i++); unsigned char i;

}

OSInit(); InitTimer0();

InitSerial();

Str_Box = OSMboxCreate ((void*)0);

OSTaskCreate(TASK1,(void *)0,&TASK1STK[0],0); OSTaskCreate(TASK2,(void *)0,&TASK2STK[0],1); //OSTaskCreate(TASK3,(void *)0,&TASK3STK[0],2); OSStart();

void TASK1(void *ppdata) { }

void TASK2(void *ppdata) {

ppdata=ppdata;

}

Uart0_print(\"task 1 is actived.\\n\"); OSTimeDlyHMSM(0,0,1,0); //OSTimeDly(50);

ppdata=ppdata; ET0=1; for(;;) {

//P1=~0x03;

P3 = 0xFF; hello = P3 | 0xC3;

OSMboxPost(Str_Box,&hello);

}

for(;;) { }

//P1=~0x18; INT8U *ok;

ok = OSMboxPend(Str_Box,20,&err); switch(*ok){ }

Uart0_print(\"task 2 is actived..\\n\"); OSTimeDlyHMSM(0,0,1,0);

case 0xDF:

P1 = 0x3F; break; P1 = 0xCF; break; P1 = 0xF7; break; P1 = 0xFC; break; P1 = 0xFF;

case 0xEF:

case 0xF7:

case 0xFB:

default:

七、实验小结

这次两个题目一个是对消息队列的应用,互相传递多个消息的机制,多了一层指针。

而第二个实验综合性比较强,要涉及uart接口的读取,gpio接口的应用等,还有要想如何设计自己的任务,开始没有什么思路,最后在老师的启发下终于完成实验,熟悉了keil下的编程。

实验6《内存管理应用》

实验学时: 2 实验地点: 201 实验日期: 2013/12/17

一、实验目的

1.实验环境的建立

2.多任务环境下内存管理方法 二、实验内容

1.设计一个含有一个任务的应用程序,该任务负责打印两个起始显示位置不同的相同字符串。要求在任务中申请一个内存块,并把存放字符串显示起始位置的数据变量定义在该内存块中。

2. 设计一个含有3个任务的应用程序,这3个任务分别是MyTask、YouTask和HerTask。在应用程序中创建一个动态内存分区,该分区有8个内存块,每个内存块的长度为6个字节。应用程序的任务YouTask和HerTask都在任务运行后请求一个内存块,随后就释放它。任务MyTask也在任务运行后请求一个内存块,但是要在任务MyTask运行6次后,才释放它所申请的内存块。 为了了解内存分区变化的情况,编写代码来观察分区头指针和已被使用内存块的个数。

3.设计一个有两个任务的应用程序,其中一个任务用来进行两个随机数的加法运算,另一个任务则用来显示结果,要求加法运算的和存放在动态内存中。 三、实验方法

按照步骤进行运行

四、实验步骤

1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3. 分别完成实验1、2、3 五、实验结果

1.实验运行结果如下:

2.实验运行结果如下: 3.实

验运行结果如下:

六、实验结论

1.实验核心代码如下:

/************************Test*************************************/

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区

#include \"includes.h\"

#define TASK_STK_SIZE 512

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; OS_MEM *IntBuffer; INT8U IntPart[50][]; INT8U *IntBlkPtr; INT16S key; INT8U err; INT8U y=0;

//用于退出的键

//字符显示位置

//声明任务

//声明起始任务

char*s1=\"MyTask is running\";

void StartTask(void *data); void MyTask(void *data); void main (void) {

OSInit( );

/************************主函数*********************************/

//初始化uCOS_II

//保存Dos环境

//安装uCOS_II中断

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); IntBuffer = OSMemCreate(IntPart,50,,&err); OSTaskCreate(StartTask, }

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL( );

(void*)0, 0);

//创建任务StartTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为0

//启动多任务管理

&StartTaskStk[TASK_STK_SIZE - 1],

OSStart( );

PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( );

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

//初始化统计任务

//创建任务MyTask

OSTaskCreate(MyTask,

(void*)0, 3);

//给任务传递参数 //使任务的优先级别为3

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

for (;;) {

//如果按下Esc键则退出uCOS_II

if (PC_GetKey(&key) == TRUE) {

if (key == 0x1B)

{

PC_DOSReturn( ); } }

OSTimeDlyHMSM(0, 0, 3, 0); } }

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; for (;;) {

IntBlkPtr=OSMemGet (

IntBuffer, &err );

//内存分区的指针 //错误信息

//等待3秒

*IntBlkPtr=10;

PC_DispStr(*IntBlkPtr,++y,

s1,

DISP_BGND_BLACK+DISP_FGND_GREEN );

*IntBlkPtr=20; //IntBlkPtr++;

PC_DispStr(*IntBlkPtr,++y,

s1,

DISP_BGND_BLACK+DISP_FGND_BLUE );

OSMemPut (

IntBuffer, IntBlkPtr );

//等待1秒

//内存块所属内存分区的指针 //待释放内存块的指针

} }

OSTimeDlyHMSM(0, 0, 1, 0);

/************************End**************************************/

2.实验核心代码如下:

/************************Test*************************************/ #include \"includes.h\"

#define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; OS_STK HerTaskStk[TASK_STK_SIZE]; INT16S key; char*s;

char*s1=\"MyTask\"; char*s2=\"YouTask\"; char*s3=\"HerTask\"; INT8U err; INT8U y=0;

INT8U Times=0; OS_MEM *IntBuffer; INT8U *IntBlkPtr;

//声明起始任务 //声明任务 //声明任务 //声明任务

//定义内存控制块指针 //划分分区及内存块

INT8U IntPart[8][6]; OS_MEM_DATA MemInfo; void StartTask(void *data); void MyTask(void *data); void YouTask(void *data); void HerTask(void *data); void main (void) {

OSInit( );

//初始化uCOS_II

//保存Dos环境

//安装uCOS_II中断

PC_DOSSaveReturn( );

//字符显示位置

OS_STK YouTaskStk[TASK_STK_SIZE];

//用于退出的键

/************************主函数*********************************/

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);

IntBuffer = OSMemCreate(IntPart,8,6,&err); OSTaskCreate(StartTask, }

(void*)0, 0);

//创建内存分区

//创建任务StartTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为0

//启动多任务管理

&StartTaskStk[TASK_STK_SIZE - 1],

OSStart( );

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL( ); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( );

//初始化统计任务

//创建任务MyTask

OSTaskCreate(MyTask,

(void*)0, 3);

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

//给任务传递参数 //使任务的优先级别为3

//创建任务YouTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为4

//创建任务HerTask

//给任务传递参数 //使任务的优先级别为5

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

OSTaskCreate(YouTask,

(void*)0, 4);

&YouTaskStk[TASK_STK_SIZE - 1],

OSTaskCreate(HerTask,

(void*)0, 5);

&HerTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

for (;;) {

//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) { {

if (key == 0x1B) PC_DOSReturn( ); } }

OSTimeDlyHMSM(0, 0, 3, 0); }

//等待3秒

}

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

sprintf(s,\"%d\",MemInfo.OSNUsed);

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_RED ); if(Times>4) { } Times++;

//等待1秒

OSMemPut (

//释放内存块

IntBuffer, IntBlkPtr );

//内存分区的指针 //待释放内存块的指针

PC_DispStr(10,++y,

s1,

DISP_BGND_BLACK+DISP_FGND_RED );

//请求内存块

IntBlkPtr=OSMemGet (

IntBuffer, &err );

//待查询的内存控制块的指针 //内存分区的指针 //错误信息

OSMemQuery (

IntBuffer, &MemInfo );

sprintf(s,\"%d\",MemInfo.OSFreeList);

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_RED );

OSTimeDlyHMSM(0, 0, 1, 0); } }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr;

#endif

pdata = pdata; for (;;) {

sprintf(s,\"%d\",MemInfo.OSNUsed);

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_YELLOW ); OSMemPut (

//释放内存块

IntBuffer, IntBlkPtr );

//等待2秒

//内存分区的指针 //待释放内存块的指针

IntBlkPtr=OSMemGet (

IntBuffer, &err );

//待查询的内存控制块的指针

//请求内存块

PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_YELLOW );

//内存分区的指针 //错误信息

OSMemQuery (

IntBuffer, &MemInfo );

sprintf(s,\"%d\",MemInfo.OSFreeList);

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_YELLOW );

OSTimeDlyHMSM(0, 0, 2, 0); } }

/************************任务HerTask******************************/ void HerTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_GREEN ); IntBlkPtr=OSMemGet (

IntBuffer, &err );

//待查询的内存控制块的指针

//请求内存块

//内存分区的指针 //错误信息

OSMemQuery (

IntBuffer,

&MemInfo );

sprintf(s,\"%d\",MemInfo.OSFreeList);

PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_GREEN ); sprintf(s,\"%d\",MemInfo.OSNUsed);

PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_GREEN ); OSMemPut (

//释放内存块

IntBuffer, IntBlkPtr );

//内存分区的指针 //待释放内存块的指针

//等待1秒

OSTimeDlyHMSM(0, 0, 1, 0); } }

/************************End**************************************/

3.实验核心代码如下:

/************************Test*************************************/ #include \"includes.h\" #include #include

#define TASK_STK_SIZE 512

//任务堆栈长度

//定义任务堆栈区 //定义任务堆栈区 //定义任务堆栈区

OS_STK StartTaskStk[TASK_STK_SIZE]; OS_STK MyTaskStk[TASK_STK_SIZE]; INT16S key; char*s; int c1; int c2; int c3;

INT8U err; INT8U y=0;

INT8U Times=0; OS_MEM *IntBuffer; int IntPart[8][6]; int *IntBlkPtr;

//声明起始任务 //声明任务 //声明任务

//定义内存控制块指针 //划分分区及内存块

//字符显示位置

OS_STK YouTaskStk[TASK_STK_SIZE];

//用于退出的键

OS_MEM_DATA MemInfo; void StartTask(void *data); void MyTask(void *data); void YouTask(void *data);

/************************主函数*********************************/ void main (void) {

OSInit( );

//初始化uCOS_II //保存Dos环境

//安装uCOS_II中断

//创建内存分区

PC_DOSSaveReturn( );

PC_VectSet(uCOS, OSCtxSw);

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); IntBuffer = OSMemCreate(IntPart,8,6,&err); OSTaskCreate(StartTask, }

/***********************任务StartTask*******************************/ void StartTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

OS_ENTER_CRITICAL( ); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL( );

OSStatInit( ); for (;;) {

//如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) { {

//初始化统计任务

//创建任务MyTask

OSTaskCreate(MyTask,

(void*)0, 3);

//安装时钟中断向量

//设置uCOS_II时钟频率

PC_SetTickRate(OS_TICKS_PER_SEC);

(void*)0, 0);

//创建任务StartTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为0

//启动多任务管理

&StartTaskStk[TASK_STK_SIZE - 1],

OSStart( );

//给任务传递参数 //使任务的优先级别为3

//创建任务YouTask

//设置任务堆栈栈顶

//给任务传递参数 //使任务的优先级别为4

&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶

OSTaskCreate(YouTask,

(void*)0, 4);

&YouTaskStk[TASK_STK_SIZE - 1],

if (key == 0x1B) PC_DOSReturn( );

} }

OSTimeDlyHMSM(0, 0, 3, 0); } }

/************************任务MyTask*******************************/ void MyTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata;

for (;;) {

PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); IntBlkPtr=OSMemGet (

//请求内存块

//内存分区的指针

//错误信息

&err

IntBuffer,

//等待3秒

); c1=rand(); sprintf(s,\"%x\",c1);

PC_DispStr(35,10+(y++),s,DISP_BGND_BLACK+DISP_FGND_RED );

c2=rand(); sprintf(s,\"%x\",c2);

PC_DispStr(35,10+(y++),s,DISP_BGND_BLACK+DISP_FGND_GREEN ); c3=c1+c2; *IntBlkPtr = c3; } }

/************************任务YouTask******************************/ void YouTask (void *pdata) {

#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif

pdata = pdata; for (;;) {

sprintf(s,\"%x\",*IntBlkPtr);

PC_DispStr(35,10+(y++),s,DISP_BGND_BLACK+DISP_FGND_YELLOW );

OSTimeDlyHMSM(0, 0, 1, 0);

//等待1秒

} }

OSMemPut(IntBuffer,IntBlkPtr); y=0;

//等待1秒

OSTimeDlyHMSM(0, 0, 1, 0);

/************************End**************************************/

七、实验小结

本次实验是对于内存分区的操作,对于UC/OS的内存管理和信号量,消息队列以及消息邮箱的操作类似,UC/OS与c中的malloc分配内存方式不同,是固定的区间,便于管理。经过此次实验对UC/os的内存分区操作有了进一步的了解。

因篇幅问题不能全部显示,请点此查看更多更全内容