实验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 #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的内存分区操作有了进一步的了解。
因篇幅问题不能全部显示,请点此查看更多更全内容