实验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、 程序:*****
*
cise 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; pdata = pdata;
OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL(); for(;;){
if(x > 10){ x = 0; }
PC_DispChar(x, y, *(char*)pdata,,DISP_BGND_BLACK + DISP_F
#endif
Exer/***
ﻩOSStatInit();
ﻩﻩy = y + 2;
GND_WHITE);
x = x + 1; ﻩ ﻩ ﻩ} }
if(PC_GetKey(&key) == 1){ if(key == 0x1B){ ﻩPC_DOSReturn(); }
ﻩﻩOSTimeDlyHMSM(0,0,1,0);
}
void main(void){
char * ch = "M"; PC_DOSSaveReturn();
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); ﻩOSInit();
ﻩPC_VectSet(uCOS, OSCtxSw);
ﻩOSTaskCreate(MyTask, ch, &MyTaskStk[TASK_STK_SIZE-1], 0); ﻩOSStart(); } 2、
程序源代码: /******** * 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); OS_EXIT_CRITICAL(); if(x > 10){ ﻩ ﻩ ﻩ}
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGN
x = 0;
y = y + 2;
ﻩPC_SetTickRate(OS_TICKS_PER_SEC); ﻩfor(;;){
D_WHITE);
ﻩﻩx = x + 1; ﻩﻩ ﻩ} }
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); 1], 1);
for(;;){
x = 0;
ﻩﻩif(x > 10){
OS_EXIT_CRITICAL(); OSStatInit();
ﻩif(PC_GetKey(&key) == 1){ ﻩ } ﻩ}
ﻩif(key == 0x1B){ ﻩPC_DOSReturn();
ﻩﻩOSTimeDlyHMSM(0,0,1,0);
ﻩOSTaskCreate(MyTask2, ch, &MyTask2Stk[My_TASK2_STK_SIZE -
ﻩﻩﻩy = y + 2; ﻩﻩ} ﻩ }
void main(void){ 0);
} 3、
OSStart(); char * ch = \"M\";
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); ﻩOSInit();
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DI
SP_FGND_WHITE);
ﻩx = x + 1; ﻩ}
ﻩOSTimeDlyHMSM(0,0,1,0); }
if(PC_GetKey(&key) == 1){ ﻩ}
PC_DOSReturn();
ﻩﻩif(key == 0x1B){
ﻩOSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1],
程序: /******** * 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); ﻩ ﻩ ﻩ ﻩﻩﻩ} ﻩ ﻩ} }
void MyTask1(void *pdata){
ﻩ}
OSTimeDlyHMSM(0,0,1,0);
}
ﻩif(cnt == 40){
}
OSTaskResume(0);
if(x > 10){ ﻩﻩx = 0; ﻩﻩy = y + 2; }
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FG ﻩ
x = x + 1;
if(PC_GetKey(&key) == 1){
if(key == 0x1B){ PC_DOSReturn();
ND_WHITE);
char * ch2 = \"Y\";
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR ﻩcpu_sr; #endif ﻩpdata = pdata; ﻩ ﻩﻩ ﻩ ﻩ ﻩ ﻩﻩ ﻩ ﻩﻩ} }
void main(void){ ﻩchar * ch = \"M\";
OSInit();
ﻩPC_DOSSaveReturn();
ﻩPC_VectSet(uCOS, OSCtxSw); 0);
OSStart();
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1],
BLACK);
ﻩcnt ++; }
OSTimeDlyHMSM(0,0,1,0); OS_ENTER_CRITICAL(); PC_VectSet(0X08, OSTickISR); OS_EXIT_CRITICAL(); OSStatInit();
OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_SIZE-1], 1);
if(x > 10){ x = 0; }
ﻩPC_SetTickRate(OS_TICKS_PER_SEC);
ﻩfor(;;){
y = y + 2;
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + ﻩx = x + 1;
if(PC_GetKey(&key) == 1){ ﻩif(key == 0x1B){
PC_DOSReturn(); }
DISP_FGND_WHITE);
} 4、
程序: /********
* 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(;;){
if(x > 10){
ﻩﻩﻩx = 0;
ﻩ y = y + 2; ﻩ }
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK P_FGND_WHITE);
ﻩﻩx = x + 1; if(PC_GetKey(&key) == 1){ ﻩif(key == 0x1B){
PC_DOSReturn();
ﻩﻩﻩ} ﻩﻩ}
OSTimeDlyHMSM(0,0,1,0);
ﻩ}
}
+ DIS
void MyTask1(void *pdata){ char * ch2 = \"Y\"; #if OS_CRITICAL_METHOD == 3 ﻩOS_CPU_SR #endif
pdata = pdata; OS_ENTER_CRITICAL();
PC_SetTickRate(OS_TICKS_PER_SEC); OSStatInit();
OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_S
cpu_sr;
ﻩPC_VectSet(0X08, OSTickISR); ﻩOS_EXIT_CRITICAL();
IZE-1], 1);
ﻩfor(;;){
cnt = cnt + 1; if(cnt == 5){ OSSchedLock(); }
else if(cnt==10){ OSSchedUnlock(); }
if(x > 10){ ﻩ x = 0; ﻩ y = y + 2;
ﻩﻩ}
ﻩﻩPC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE);
ﻩ x = x + 1; ﻩ} }
void main(void){ ﻩchar * ch = \"M";
ﻩif(PC_GetKey(&key) == 1){ ﻩﻩif(key == 0x1B){ ﻩ}
OSTimeDlyHMSM(0,0,1,0); ﻩ PC_DOSReturn(); }
ﻩ
0);
OSInit();
PC_DOSSaveReturn(); PC_VectSet(uCOS, OSCtxSw);
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
OSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1],
ﻩOSStart(); } 5、
程序代码如下: /******** * 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(;;){
if(OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ){ OSTaskDel(OS_PRIO_SELF); break; }
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){ ﻩﻩ ﻩﻩ }
void MyTask1(void *pdata){ char * ch2 = \"Y"; #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();
OSTaskCreate(MyTask2, ch2, &MyTask2Stk[My_TASK2_STK_SIZE-1], 1); ﻩOSStatInit(); ﻩfor(;;){
cnt = cnt + 1; if(cnt == 10){
while(OSTaskDelReq(0) != OS_TASK_NOT_EXIST){ OSTimeDly(1); } }
}
if(key == 0x1B){ ﻩPC_DOSReturn(); }
ﻩﻩﻩ}
ﻩﻩOSTimeDlyHMSM(0,0,1,0);
ﻩﻩif(x > 10){
ﻩ}
ﻩx = 0; ﻩﻩy = y + 2;
ﻩﻩPC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK + DISP_FGND_WHITE);
ﻩx = x + 1;
ﻩﻩif(key == 0x1B){
}
ﻩﻩif(PC_GetKey(&key) == 1){ ﻩﻩﻩﻩPC_DOSReturn(); ﻩ ﻩﻩ}
ﻩﻩOSTimeDlyHMSM(0,0,1,0); ﻩ} }
void main(void){
char * ch = \"M\"; ﻩOSInit();
ﻩPC_DOSSaveReturn(); ﻩPC_VectSet(uCOS, OSCtxSw); 0);
}
注:有程序得要求附上程序源代码,有图表得要有截图并有相应得文字说明与分析 七、实验小结
给出本次实验得体会,如学会了什么,遇到哪些问题,如何解决这些问题,存在哪些有待改进得地方。
OSStart();
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
ﻩOSTaskCreate(MyTask1, ch, &MyTask1Stk[My_TASK1_STK_SIZE-1],
实验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(22,4,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);
sprintf(s,"%d\;
PC_DispStr(31,d1+5,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
ﻩﻩPC_DispStr(18,4,s0,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 MyTask(void *data); void main (void) {
char* s_M="M";
OSInit(); /* Initialize uC/OS-II */
P
C
_D
O
S
S
a
v
eR
e
turn(
/* 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);
);
OSStart(); /* Start multitasking */ }
void MyTask(void *pdata) { #i
f
OS_CRITICAL_
M
E
T
H
O
D
==
3
/* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr; #endif
pdata = pdata; /* Prevent piler warning */ OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR); PC_SetTickRate(OS_TICKS_PER_SEC); OS_EXIT_CRITICAL();
OSStatInit(); for (;;) { ﻩif(x>10) ﻩ}
PC_DispChar(x,y,*(char*)pdata,DISP_BGND_BLACK+DISP_FGNx+=1;
D_WHITE);
ﻩif(PC_GetKey(&key) == 1) {
ﻩﻩif(key == 0x1B) ﻩﻩ{ ﻩ} } }
2、程序:OS_COPU_C、c #if OS_CPU_HOOKS_EN > 0
OSTimeDlyHMSM(0,0,1,0); ﻩ}
PC_DOSReturn();
{
y+=2;
ﻩﻩx=0;
extern BOOLEAN InterKey; INT16U InterCtr = 0;
void OSTimeTickHook (void) {
if(InterCtr == 10000) {
InterKey = 1; }
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;
ﻩﻩ
ﻩ
//字符显示位置
ﻩ//声明任务
ﻩ//定义任务堆栈区
//用于退出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( ); ﻩ
//定义要显示得字符
ﻩﻩ//初始化uCOS_II
//安装uCOS_II中断
PC_DOSSaveReturn( );ﻩﻩ ﻩ//保存Dos环境 PC_VectSet(uCOS, OSCtxSw); ﻩﻩ OSTaskCreate( ﻩ
ﻩMyTask, s_M,
//创建任务MyTask
//设置任务堆栈栈顶指针
ﻩ//给任务传递参数
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
ﻩ&MyTaskStk[TASK_STK_SIZE - 1],
0ﻩﻩ ﻩﻩ//任务得优先级别为0
ﻩ//启动多任务管理
ﻩﻩ); ﻩ }
OSStart( );ﻩﻩﻩ
void MyTask (void *pdata) {
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, ﻩ ﻩ
ﻩﻩ//创建任务MyTask
ﻩs_Y,ﻩﻩﻩﻩﻩ//给任务传递参数 1 ﻩ
// MyTask得优先级别为1
//初始化统计任务
ﻩ//安装时钟中断向量
//设置时钟频率
PC_SetTickRate(OS_TICKS_PER_SEC); ﻩ
ﻩﻩ&YouTaskStk[TASK_STK_SIZE - 1],ﻩﻩ//设置任务堆栈栈顶指针 ﻩﻩ);
OSTaskCreate(
ﻩ
InterTask, ﻩﻩ//创建任务MyTask
//给任务传递参数
ﻩﻩﻩs_H,
ﻩ&InterTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针 2ﻩﻩﻩﻩ// MyTask得优先级别为2 ﻩ);
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)
{
//恢复Dos环境
}
ﻩPC_DOSReturn( ); ﻩ} } }
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;
}
ﻩﻩ//字符得显示位置
OSTimeDlyHMSM(0, 0, 3, 0);ﻩﻩﻩ//等待3秒
PC_DispChar( ﻩﻩx, y,
ﻩ*(char*)pdata,
);
//等待1秒
ﻩﻩDISP_BGND_BLACK+DISP_FGND_WHITE ﻩ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 (x>50) ﻩ
{
y+=2;
ﻩ ﻩﻩx=0; ﻩ ﻩ ﻩ
ﻩ} PC_DispChar( ﻩ ﻩ);
ﻩPC_DispStr(5,6,s,DISP_BGND_BLACK+DISP_FGND_WHITE);
x += 1;
}
//OSIntNesting--;
//等待1秒
x, y,ﻩﻩﻩ//字符得显示位置
DISP_BGND_BLACK+DISP_FGND_WHITE *(char*)pdata, if(InterKey)
ﻩInterKey=FALSE;
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) { ﻩ{ ﻩ
sprintf(s,\"%5d\t);
ﻩPC_DispStr(d,l+4,s,DISP_BGND_BLACK+DISP_FGND_WHITE); ﻩd+=6;ﻩ }
if(OSTCBPrioTbl[2]->OSTCBDly == 1)
ﻩtt+=1;
} #endif Test、c
#include "includes、h"
#define TASK_STK_SIZE 512ﻩ
ﻩ//任务堆栈长度
//定义任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE];ﻩ INT16S key;ﻩﻩ INT8Uﻩ x=0,y=0;
ﻩﻩ//用于退出uCOS_II得键ﻩ
ﻩﻩ//字符显示位置
//声明任务 //声明任务
OS_STK YouTaskStk[TASK_STK_SIZE]; ﻩ//定义任务堆栈区
void MyTask(void *data);ﻩ void YouTask(void *data); ﻩ void main (void) {
char* s_M="M\";ﻩﻩ OSInit();ﻩﻩ
//定义要显示得字符
ﻩﻩ//初始化uCOS_II
//安装uCOS_II中断
PC_DOSSaveReturn();ﻩﻩ ﻩ//保存Dos环境 PC_VectSet(uCOS, OSCtxSw);ﻩﻩ OSTaskCreate(MyTask, ﻩﻩs_M,ﻩ ﻩ ﻩ }
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);ﻩ OS_EXIT_CRITICAL();
OSStatInit(); ﻩﻩﻩ//初始化uCOS_II得统计任务 OSTaskCreate(YouTask,ﻩﻩ //创建任务MyTask
s_Y,ﻩ
ﻩ//给任务传递参数
//安装uCOS_II时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩﻩ//设置uCOS_II时钟频率
ﻩ
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
//创建任务MyTask
//给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针 0); ﻩﻩﻩ//使任务MyTask得优先级别为0
ﻩ//启动uCOS_II得多任务管理
OSStart();ﻩﻩ
ﻩﻩ&YouTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶指针
ﻩ2);
//使任务MyTask得优先级别为2
for (;;) { if (x>50) ﻩ{
x=0; ﻩ y+=2; }
PC_DispChar(x, y,ﻩ ﻩﻩ*(char*)pdata,
ﻩDISP_BGND_BLACK+DISP_FGND_WHITE );
x++;
ﻩ{
if (key == 0x1B)
{
PC_DOSReturn(); } }
OSTimeDly(300);ﻩﻩ//延时100个时钟节拍 } }
void YouTask (void *pdata) {
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; for (;;) {
if (x>50) ﻩ}
PC_DispChar(x, y,ﻩ
//显示字符得位置
{ x=0; y+=2;
//显示字符得位置
if(y>1) OSTimeDlyResume(2); ﻩ //取消YouTask任务得延时
ﻩif (PC_GetKey(&key) == TRUE)
ﻩ*(char*)pdata,
DISP_BGND_BLACK+DISP_FGND_WHITE );
x += 1;
} } 4、
OSTimeDly(500); ﻩ//延时500个时钟节拍
#include \"includes、h\"
#define TASK_STK_SIZE 512ﻩ INT16S key; INT32U stime; INT8U x=0;ﻩﻩ ﻩ
void MyTask(void *data); void main (void) {
OSInit();
ﻩ
//初始化uCOS_II
//保存Dos环境
//安装uCOS_II中断
PC_DOSSaveReturn(); ﻩ
ﻩﻩ//声明一个任务
ﻩﻩﻩ//用于退出uCOS_II得键ﻩ
ﻩ//任务堆栈长度
ﻩ//定义任务堆栈区
OS_STK TaskStartStk[TASK_STK_SIZE];
PC_VectSet(uCOS, OSCtxSw);
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSTaskCreate(MyTask, ﻩﻩ//创建任务MyTask
ﻩ(void*)0,
ﻩﻩ
ﻩ//给任务传递参数
ﻩﻩ&TaskStartStk[TASK_STK_SIZE - 1],//设置任务堆栈栈顶指针 ﻩﻩ0); }
void MyTask (void *pdata) {
char s[5];
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR); OS_EXIT_CRITICAL();
OSStatInit();ﻩﻩﻩ//初始化uCOS_II得统计任务
//安装uCOS_II时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ//设置uCOS_II时钟频率
//使任务MyTask得优先级别为0
//启动uCOS_II得多任务管理
OSStart();ﻩﻩﻩ
for (;;) {
if (x==10) ﻩ{
ﻩ OSTimeSet(10); ﻩ} ﻩﻩs, ﻩ{
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) { ﻩOSInit();
InitTimer0();
ﻩ
//运行次数
//等待
ﻩDISP_BGND_BLACK+DISP_FGND_WHITE ); //如果按下Esc键则退出uCOS_II if (PC_GetKey(&key) == TRUE) ﻩﻩx += 1;
stime=OSTimeGet(); PC_DispStr(5, 2,ﻩ
//在x,y位置显示s中得字符
ﻩsprintf(s,\"%5d\stime);
}
InitSerial();ﻩﻩ
OSTaskCreate(TASK1,(void *)0,&TASK1STK[0],1); OSTaskCreate(TASK2,(void *)0,&TASK2STK[0],2); OSTaskCreate(TASK3,(void *)0,&TASK3STK[0],3);
ﻩ//创建三个任务
ﻩOSStart();
void TASK1(void *ppdata) {
ﻩﻩppdata=ppdata; ﻩﻩ{
ﻩﻩﻩUart0_print(\"task1 is actived、\\n\");ﻩ ﻩ ﻩ }
void TASK2(void *ppdata) { ﻩﻩ ﻩﻩ }
void TASK3(void *ppdata) { ﻩ ﻩ
ﻩppdata = ppdata;
{
Uart0_print("task3 is actived、\\n\");
ﻩﻩfor(;;)
ﻩ ﻩ ﻩ}
ppdata=ppdata; for(;;) {
ﻩ
Uart0_print(\"task2 is actived、\\n\"); OSIdleCtr=OSIdleCtr;
ﻩﻩOSIdleCtr=OSIdleCtr; }
OSTimeDlyHMSM(0,0,1,0); ﻩET0=1; ﻩﻩfor(;;)
//Uart0_printR(\"%d\n\ (WORD)OSIdleCtr); OSTimeDlyHMSM(0,0,1,0);ﻩ
ﻩ//Uart0_printR(\"%d\\n\ORD)OSIdleCtr);
OSIdleCtr=OSIdleCtr; ﻩﻩOSTimeDlyHMSM(0,0,1,0);
}
}
七、实验小结
本次实验对中断得处理过程等有了更深一步得了解,对与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、在应用程序中定义一个全局变量ac_key来作为信号量,并根据该信号量得状态来访问共享资源s,以解决实验1中得冲突问题。
3、
在实验2中,把使用得信号量改为互斥型信号量,然后运行该程序并观察其运行
结果。(不做) 三、实验方法
包括实验方法、原理、技术、方案等。 四、实验步骤
1.将BC45文件夹拷贝到C分区根目录下。 2.将software文件夹拷贝到任意分区根目录下。 3、 分别完成实验1、2、3。 五、实验结果
1、实验运行结果如下:
2、实验运
行结果如下:
3、实验运行结果如下:
六、实验结论
对实验数据与结果进行分析描述,给出实验取得得成果与结论。 1、核心代码如下:
/************************Test************************************/
#include "includes、h\"
#define TASK_STK_SIZE 512ﻩﻩﻩ//任务堆栈长度 OS_STK MyTaskStk[TASK_STK_SIZE]; INT16S key; char *s=\"\";
ﻩ ﻩ
//定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE];ﻩ//定义任务堆栈区
ﻩ//用于退出uCOS_II得键
//字符显示位置
//声明任务 ﻩ//声明任务
INT8Uﻩ y1=0,y2=0;ﻩ
ﻩ//定义要显示得字符
void MyTask(void *data);ﻩﻩ
void YouTask(void *data);ﻩ ﻩ void main (void) {
OSInit( );
ﻩ
/************************主函数**********************************/
ﻩﻩ ﻩ//初始化uCOS_II
//保存Dos环境
PC_DOSSaveReturn( );ﻩﻩ
PC_VectSet(uCOS, OSCtxSw); ﻩﻩ//安装uCOS_II中断 PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); OSTaskCreate(MyTask,
ﻩ ﻩ//创建任务MyTask
ﻩ(void*)0, ﻩ ﻩ ﻩ//给任务传递参数
ﻩ }
ﻩ&MyTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶指针 0);
ﻩﻩ
//使任务得优先级别为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); ﻩ
//初始化统计任务
OSTaskCreate(YouTask, ﻩﻩﻩﻩ//创建任务YouTask
//给任务传递参数
ﻩ&YouTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶指针
ﻩﻩ //使任务得优先级别为2
//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ//设置uCOS_II时钟频率
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( ); } }
OSTimeDly(200); } }
/************************任务YouTask******************************/ void YouTask (void *pdata) {
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
ﻩ
ﻩ//等待200个时钟节拍
INT8U err; pdata = pdata; for (;;)
{
s="YouTask visit data s\"; ﻩ ﻩ ﻩ
ﻩPC_DispStr(28, ++y2,ﻩﻩﻩﻩ//显示字符串
s,
//置OSTime为0
DISP_BGND_BLACK+DISP_FGND_WHITE );
ﻩOSTimeSet(0);ﻩﻩ ﻩ ﻩ }ﻩ
{ ﻩ ﻩﻩﻩs,
ﻩ
ﻩ
ﻩﻩwhile(OSTime<500)
PC_DispStr(55, y2,ﻩ ﻩ//显示字符串
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;
ﻩﻩﻩﻩ//用于退出uCOS_II得键
ﻩ
//字符显示位置
INT8U y1=0,y2=0;ﻩﻩﻩ
BOOLEAN ac_key;ﻩﻩﻩﻩ ﻩ//定义信号量 char* s=\"原始数据\"; ﻩﻩﻩﻩ //定义要显示得字符 void MyTask(void *data);ﻩ void YouTask(void *data); void main (void) {
OSInit( ); ﻩﻩﻩﻩ ﻩﻩ//初始化uCOS_II ac_key=1;
ﻩﻩ
//设置信号量初值 ﻩ//保存Dos环境
ﻩ//安装uCOS_II中断 //创建任务MyTask
PC_DOSSaveReturn( );ﻩ
ﻩﻩﻩ//声明任务 ﻩ
ﻩ
//声明任务
/************************主函数*********************************/
PC_VectSet(uCOS, OSCtxSw);ﻩ OSTaskCreate(MyTask, ﻩ
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
ﻩ
ﻩ(void*)0,
ﻩ
ﻩ//给任务传递参数
ﻩ&MyTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶指针
}
ﻩ0); ﻩ ﻩ //使任务得优先级别为0
ﻩ//启动uCOS_II得多任务管理
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,
ﻩ
ﻩﻩ//初始化uCOS_II得统计任务 ﻩ
//创建任务MyTask
//设置任务堆栈栈顶指针
OSTaskCreate(YouTask, ﻩ
ﻩ
//安装uCOS_II时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC); //设置uCOS_II时钟频率
ﻩﻩﻩﻩ //给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1],
ﻩ//使任务得优先级别为2
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; ﻩ
ﻩﻩ}
ﻩ//如果按下Esc键则退出uCOS_II ﻩ ﻩ
if (PC_GetKey(&key) == TRUE) {
if (key == 0x1B) ﻩ ﻩ{
PC_DOSReturn( ); } }ﻩ
OSTimeDly(20); ﻩ } }
/************************任务YouTask***************************
ﻩ//等待20个时钟节拍
*/
void YouTask (void *pdata) {
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
INT8U err; pdata = pdata; for (;;) {
if(ac_key)
ﻩ
{
ac_key=FALSE; ﻩ
//使信号量为无信号
ﻩs=\"YouTask visit data s\"; ﻩﻩﻩPC_DispStr(28, ++y2, ﻩﻩ//显示字符串 ﻩ ﻩ ﻩ ﻩ ﻩ ﻩ ﻩﻩ}
OSTimeDly(10); } }
/************************End**************************************/
ﻩﻩ //等待10个时钟节拍
ﻩ{ ﻩ
PC_DispStr(55, y2, ﻩ//显示字符串
ﻩs,
ﻩs,
ﻩﻩDISP_BGND_BLACK+DISP_FGND_WHITE );
OSTimeSet(0);ﻩ
//置OSTime为0
ﻩwhile(OSTime<500)
ﻩﻩﻩ DISP_BGND_BLACK+DISP_FGND_WHITE );
}ﻩﻩ
ﻩﻩac_key=TRUE;ﻩ ﻩﻩ//发信号
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环境
PC_DOSSaveReturn( );ﻩ ﻩ
PC_VectSet(uCOS, OSCtxSw);ﻩﻩﻩﻩ//安装uCOS_II中断 PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); Mutexp = OSMutexCreate (1,&err);ﻩ OSTaskCreate(StartTask, ﻩ
(void*)0,ﻩ
//给任务传递参数
ﻩ//定义信号量
ﻩ//创建任务StartTask
&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( );ﻩﻩ
ﻩ//初始化统计任务
//创建任务Task1
//设置任务堆栈栈顶
OSTaskCreate(Task1, ﻩ
//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ //设置uCOS_II时钟频率
(void*)0,ﻩ ﻩ//给任务传递参数
ﻩ&Task1Stk[TASK_STK_SIZE - 1],
ﻩﻩ3);ﻩﻩﻩﻩ//使任务得优先级别为3
OSTaskCreate(Task2,ﻩ ﻩﻩ//创建任务Task2 ﻩﻩ(void*)0, ﻩ
ﻩﻩ4);ﻩﻩ
//给任务传递参数
ﻩ&Task2Stk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶
//使任务得优先级别为4
OSTaskCreate(Task3,ﻩﻩ ﻩ//创建任务Task3
ﻩ(void*)0, ﻩ
//给任务传递参数
ﻩﻩ&Task3Stk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶 ﻩﻩ5); ﻩﻩ //使任务得优先级别为5 for (;;) { ﻩ
//如果按下Esc键则退出uCOS_II {
if (PC_GetKey(&key) == TRUE)
if (key == 0x1B) ﻩ {
PC_DOSReturn( ); } }
OSTimeDlyHMSM(0, 0, 3, 0);ﻩ//等待3秒 } }
/************************任务Task1*******************************/
void Task1 (void *pdata) {
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; for (;;) { {
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);ﻩ //发送信号量 }
OSTimeDlyHMSM(0, 0, 0, 200);ﻩﻩ//等待200毫秒 } }
/************************任务Task2******************************/ void Task2 (void *pdata) {
OSTimeDlyHMSM(0, 0, 0, 300); ﻩ//等待300毫秒
#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, ﻩ ﻩ ﻩ{
ﻩﻩOS_Sched();
}
Times=0; s3,
DISP_BGND_BLACK+DISP_FGND_WHITE );
for(Times;Times<20000000;Times++)
ﻩOSMutexPost(Mutexp);ﻩ //发送信号量
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 YouTaskStk[TASK_STK_SIZE]; INT16S key; ﻩ void *msg_p;
ﻩ
ﻩ
ﻩ ﻩ
INT8Uﻩ y1=0,y2=0;ﻩ
ﻩﻩ
ﻩﻩ
ﻩ
ﻩ//定义任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE];ﻩ ﻩﻩ//定义任务堆栈区
ﻩ//定义任务堆栈区
ﻩ//用于退出得键
//字符显示位置
//消息邮箱
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);ﻩﻩﻩ OSTaskCreate(StartTask,ﻩ ﻩﻩﻩﻩ(void*)0,ﻩﻩﻩﻩ
ﻩ
ﻩﻩ 0);
ﻩﻩ ﻩ
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK);
ﻩﻩﻩ //创建任务MyTask
//给任务传递参数
//使任务得优先级别为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);ﻩ ﻩﻩ//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩﻩﻩ//设置uCOS_II时钟频率 OS_EXIT_CRITICAL( ); OSStatInit( ); ﻩ
ﻩﻩ ﻩ(void*)0,ﻩ
ﻩﻩ
1);ﻩ ﻩﻩ
ﻩ
//初始化统计任务
OSTaskCreate(MyTask,ﻩ
ﻩ//创建任务MyTask
ﻩﻩﻩﻩ//给任务传递参数 ﻩ ﻩ
//使任务得优先级别为1
//创建任务YouTask
//给任务传递参数 //使任务得优先级别为2
&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; ﻩfor (;;)
{
//等待3秒
PC_DispStr(5, ++y1, ﻩ ﻩ ﻩ ﻩ ﻩ ﻩ ﻩﻩ}
{ ﻩ ﻩ
PC_DispStr(15,y1, ﻩﻩmsg_p, ﻩ ﻩ"MyTask\",
ﻩ//显示字符串
ﻩDISP_BGND_BLACK+DISP_FGND_WHITE );
if(msg_p!=(void*) 0) ﻩﻩﻩ //请求消息
ﻩﻩﻩﻩ//显示收到得消息
ﻩ
ﻩ
//使消息邮箱为空
ﻩ//等待1秒
ﻩﻩﻩ DISP_BGND_BLACK+DISP_FGND_RED ); 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,
ﻩ
ﻩ\"YouTask\",
ﻩﻩﻩ //显示字符串
ﻩﻩﻩ//定义消息
ﻩﻩ ﻩDISP_BGND_BLACK+DISP_FGND_WHITE ); 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秒
ﻩﻩ} ﻩﻩ
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 YouTask(void *data); void main (void) {
OSInit( );ﻩ ﻩ
void MyTask(void *data); ﻩﻩﻩ//声明任务
/************************主函数*********************************/
//初始化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,ﻩﻩﻩ ﻩ(void*)0, ﻩﻩﻩ //给任务传递参数
ﻩ&StartTaskStk[TASK_STK_SIZE - 1], ﻩ//设置任务堆栈栈顶 ﻩ0); }
/***********************任务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);ﻩﻩ//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩﻩ//设置uCOS_II时钟频率 OS_EXIT_CRITICAL( );
OSStatInit( ); ﻩﻩ //初始化统计任务
OSTaskCreate(MyTask,ﻩﻩﻩ//创建任务MyTask
ﻩ(void*)0,ﻩ
ﻩ
ﻩ//给任务传递参数
&MyTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶
//使任务得优先级别为3
//给任务传递参数
ﻩﻩ ﻩ//使任务得优先级别为0
OSStart( ); ﻩﻩﻩﻩﻩ//启动多任务管理
//创建任务StartTask
ﻩﻩ3);
OSTaskCreate(YouTask,ﻩﻩ //创建任务YouTask ﻩﻩ(void*)0,
&YouTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶
ﻩﻩ4);ﻩ {
ﻩ//使任务得优先级别为4
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" ,Times);
OSMboxPost(Str_Box,s); Str_Box->OSEventPtr,//s,
DISP_BGND_BLACK+DISP_FGND_WHITE );*/ Times++;
//发送消息
/*PC_DispStr(10,++y,
OSTimeDlyHMSM(0, 0, 1, 0); //等待1秒 } }
/************************任务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); PC_DispStr(10,++y, ﻩﻩss,
DISP_BGND_BLACK+DISP_FGND_WHITE );ﻩ
OSTimeDlyHMSM(0, 0, 1, 0);ﻩ //等待1秒 } }
/************************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]; OS_STK YouTaskStk[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_EVENT *Str_Q;ﻩ
void StartTask(void *data);ﻩ ﻩ void YouTask(void *data);ﻩ void main (void) {
OSInit( );
ﻩ
void MyTask(void *data);ﻩ ﻩﻩ//声明任务
ﻩ//声明任务
/************************主函数*********************************/
ﻩﻩ//初始化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( ); ﻩ ﻩ
ﻩﻩﻩ//初始化统计任务
ﻩ//创建任务MyTask
OSTaskCreate(MyTask,
ﻩ(void*)0,ﻩ ﻩ//给任务传递参数
ﻩ&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶 3);ﻩ
ﻩ//使任务得优先级别为3
ﻩ//创建任务YouTask
ﻩ//给任务传递参数
//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩﻩ//设置uCOS_II时钟频率
OSTaskCreate(YouTask,ﻩ
(void*)0,
ﻩ&YouTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶
ﻩﻩ4);ﻩﻩ ﻩ//使任务得优先级别为4 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);ﻩ//向消息队列插入一个消息 OSQPostFront(Str_Q,s);ﻩ//向消息队列插入一个消息 ﻩs="this is 5 time!\";
OSQPostFront(Str_Q,s);ﻩ//向消息队列插入一个消息
ﻩﻩs=\"this is 4 time!\";
ﻩﻩ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);ﻩ//等待1秒 } }
/************************任务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 (;;) { }
/************************End***********************************
ss=OSQPend(Str_Q,0,&err); ﻩ//请求消息队列 OSTimeDlyHMSM(0, 0, 2, 0);ﻩ
//等待1秒
PC_DispStr(10,++y,ss,DISP_BGND_BLACK+DISP_FGND_GREEN ); }
ss=OSQPend(Str_Q,0,&err); ﻩ//请求消息队列 OSTimeDlyHMSM(0, 0, 2, 0); //等待1秒
PC_DispStr(10,++y,ss,DISP_BGND_BLACK+DISP_FGND_RED ); }
***/
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) {
ﻩunsigned char i; ﻩwhile(--count != 0)
ﻩfor(i = 0; i < 125; i++); }
void main(void) {
ﻩOSInit(); }
void TASK1(void *ppdata) { ﻩ ﻩﻩ{
ﻩﻩﻩ//P1=~0x03;
ppdata=ppdata;
ET0=1; InitTimer0();
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); InitSerial();
ﻩOSStart();
ﻩﻩfor(;;)
ﻩ ﻩ ﻩ }
P3 = 0xFF;
hello = P3 | 0xC3;
ﻩOSMboxPost(Str_Box,&hello);
ﻩﻩUart0_print(\"task 1 is actived、\\n\"); OSTimeDlyHMSM(0,0,1,0);
//OSTimeDly(50); }
void TASK2(void *ppdata) { ﻩﻩ ﻩ ﻩ ﻩ ﻩ ﻩ ﻩ }
七、实验小结
ﻩ这次两个题目一个就是对消息队列得应用,互相传递多个消息得机制,多了一层指针。ﻩppdata=ppdata; ﻩ ﻩﻩ ﻩﻩ ﻩﻩ ﻩ ﻩ ﻩ ﻩ
for(;;) {
ﻩ//P1=~0x18;ﻩ ﻩINT8U *ok; switch(*ok){
case 0xDF: break; P1 = 0x3F; ﻩﻩcase 0xEF: P1 = 0xCF; ﻩ
break; case 0xF7: ﻩﻩP1 = 0xF7; ﻩﻩﻩbreak; ﻩ
ﻩP1 = 0xFC;
ok = OSMboxPend(Str_Box,20,&err);
ﻩﻩﻩ case 0xFB:
ﻩﻩﻩbreak; default: ﻩ
ﻩP1 = 0xFF; }
ﻩUart0_print(\"task 2 is actived、、\\n\");
ﻩOSTimeDlyHMSM(0,0,1,0);
}
而第二个实验综合性比较强,要涉及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_MEM *IntBuffer; INT8U IntPart[50][];
OS_STK MyTaskStk[TASK_STK_SIZE]; ﻩﻩ//定义任务堆栈区
INT8U *IntBlkPtr;
INT16S key; ﻩﻩﻩﻩ //用于退出得键 char*s1=\"MyTask is running\"; INT8U err;
ﻩﻩﻩﻩﻩ
ﻩ
ﻩ
//声明任务 ﻩﻩ//声明起始任务
INT8U y=0;ﻩﻩﻩﻩﻩﻩ//字符显示位置ﻩ
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,ﻩ
(void*)0,
ﻩ ﻩ
ﻩ//创建任务StartTask
//设置任务堆栈栈顶
//给任务传递参数
&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( );ﻩﻩ
ﻩ(void*)0,
ﻩ//初始化统计任务
//创建任务MyTask
//设置任务堆栈栈顶
OSTaskCreate(MyTask, ﻩ
ﻩ//给任务传递参数
ﻩ//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ //设置uCOS_II时钟频率
&MyTaskStk[TASK_STK_SIZE - 1],
ﻩﻩ3);ﻩﻩﻩﻩ//使任务得优先级别为3 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 (;;) {
IntBlkPtr=OSMemGet ( ﻩﻩ
IntBuffer, ﻩ );
//内存分区得指针
&err
//错误信息
*IntBlkPtr=10; ﻩPC_DispStr(*IntBlkPtr,++y, ﻩ ﻩﻩs1,
DISP_BGND_BLACK+DISP_FGND_BLUE );
//内存块所属内存分区得指针
OSMemPut (
ﻩ//待释放内存块得指针
//等待1秒
s1,
ﻩDISP_BGND_BLACK+DISP_FGND_GREEN ); *IntBlkPtr=20; //IntBlkPtr++;
ﻩPC_DispStr(*IntBlkPtr,++y,
ﻩﻩIntBuffer, ﻩ ﻩﻩIntBlkPtrﻩ
ﻩ);
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 YouTaskStk[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 IntPart[8][6]; INT8U *IntBlkPtr;ﻩ 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 PC_DOSSaveReturn( );ﻩﻩﻩ PC_VectSet(uCOS, OSCtxSw);
/************************主函数*********************************/
//保存Dos环境
ﻩ
//安装uCOS_II中断
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); IntBuffer = OSMemCreate(IntPart,8,6,&err);ﻩﻩ//创建内存分区 OSTaskCreate(StartTask,
(void*)0,
ﻩ//创建任务StartTask
ﻩ//给任务传递参数
&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); ﻩ//安装时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ //设置uCOS_II时钟频率 OS_EXIT_CRITICAL( ); OSStatInit( );
(void*)0,
ﻩ
//初始化统计任务
ﻩ//创建任务MyTask
OSTaskCreate(MyTask,
//给任务传递参数
ﻩﻩ&MyTaskStk[TASK_STK_SIZE - 1], //设置任务堆栈栈顶 ﻩ ﻩ
ﻩ3);
ﻩ//使任务得优先级别为3
//创建任务YouTask
OSTaskCreate(YouTask, ﻩ
(void*)0,ﻩﻩﻩ//给任务传递参数
ﻩﻩ//使任务得优先级别为4
//给任务传递参数
&YouTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶 4);
OSTaskCreate(HerTask, ﻩﻩ//创建任务HerTask ﻩﻩ(void*)0, ﻩ ﻩ
5);ﻩﻩ
&HerTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶
//使任务得优先级别为5
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 (;;) { ﻩ ﻩﻩ
PC_DispStr(10,++y,
s1,
DISP_BGND_BLACK+DISP_FGND_RED );
//等待3秒
ﻩIntBlkPtr=OSMemGet ( ﻩﻩ//请求内存块
ﻩIntBuffer,ﻩ //内存分区得指针
//错误信息
&err
ﻩﻩﻩ);
OSMemQuery ( ﻩﻩIntBuffer,
);
//待查询得内存控制块得指针
&MemInfo
ﻩsprintf(s,\"%d\",MemInfo、OSFreeList); ﻩ ﻩ ﻩ}
Times++;
//等待1秒
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、OSFreeList);
ﻩPC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_YELLOW ); ﻩsprintf(s,\"%d\",MemInfo、OSNUsed);
PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_YELLOW );
//释放内存块 ﻩﻩ//内存分区得指针
IntBuffer, ); ﻩ
ﻩOSMemPut (ﻩ ﻩ
PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_YELLOW ); IntBlkPtr=OSMemGet ( ﻩ IntBuffer,
);
IntBuffer, ﻩ //待查询得内存控制块得指针 &MemInfo
&errﻩ ﻩ//错误信息
//请求内存块
//内存分区得指针
PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_RED ); sprintf(s,\"%d\",MemInfo、OSNUsed);
PC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_RED ); if(Times>4) {
OSMemPut (ﻩ
ﻩ//释放内存块 //内存分区得指针
ﻩﻩﻩIntBuffer,ﻩﻩ
ﻩ);
ﻩIntBlkPtrﻩﻩﻩ//待释放内存块得指针
OSMemQuery (
IntBlkPtrﻩﻩ //待释放内存块得指针
OSTimeDlyHMSM(0, 0, 2, 0);ﻩﻩ//等待2秒 } }
/************************任务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 ( ﻩﻩ//请求内存块 &errﻩ );
ﻩIntBuffer, ﻩ //待查询得内存控制块得指针 ﻩ&MemInfo ﻩ);
sprintf(s,\"%d\",MemInfo、OSFreeList);
PC_DispStr(30,y,s,DISP_BGND_BLACK+DISP_FGND_GREEN );
ﻩ//错误信息
ﻩﻩﻩIntBuffer, ﻩ//内存分区得指针
OSMemQuery (
ﻩsprintf(s,\"%d\",MemInfo、OSNUsed);
ﻩPC_DispStr(40,y,s,DISP_BGND_BLACK+DISP_FGND_GREEN ); ﻩ
OSMemPut ( IntBuffer,ﻩ
ﻩﻩ//释放内存块 //内存分区得指针
ﻩﻩIntBlkPtr ﻩ //待释放内存块得指针
ﻩﻩ);ﻩ } }
OSTimeDlyHMSM(0, 0, 1, 0);ﻩ//等待1秒
/************************End**************************************/
3、实验核心代码如下:
/************************Test*************************************/ #include \"includes、h" #include <stdio、h> #include //任务堆栈长度 OS_STK StartTaskStk[TASK_STK_SIZE];ﻩﻩ //定义任务堆栈区 OS_STK MyTaskStk[TASK_STK_SIZE];ﻩﻩ //定义任务堆栈区 OS_STK YouTaskStk[TASK_STK_SIZE]; ﻩ INT16S key; char*s; int intﻩc2; int c3; c1; ﻩ //定义任务堆栈区 //用于退出得键 INT8U err; ﻩﻩ ﻩﻩﻩ INT8U y=0; ﻩﻩ INT8U Times=0; OS_MEM *IntBuffer; int *IntBlkPtr; ﻩ ﻩ ﻩ//定义内存控制块指针 //划分分区及内存块 int IntPart[8][6]; ﻩ OS_MEM_DATA MemInfo;ﻩﻩ void StartTask(void *data);ﻩﻩ ﻩ//声明起始任务 void MyTask(void *data); ﻩ //声明任务 //声明任务 void YouTask(void *data); void main (void) { OSInit( ); ﻩ //初始化uCOS_II //安装uCOS_II中断 PC_DOSSaveReturn( );ﻩﻩﻩ //保存Dos环境 PC_VectSet(uCOS, OSCtxSw); ﻩ PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); IntBuffer = OSMemCreate(IntPart,8,6,&err);ﻩ //创建内存分区 OSTaskCreate(StartTask, ﻩﻩ (void*)0, ﻩﻩﻩ //给任务传递参数 //创建任务StartTask ﻩ //字符显示位置 /************************主函数*********************************/ ﻩ&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( ); ﻩﻩﻩ//初始化统计任务 OSTaskCreate(MyTask, ﻩ ﻩ (void*)0, ﻩ //创建任务MyTask //给任务传递参数 ﻩ//安装时钟中断向量 //设置uCOS_II时钟频率 PC_SetTickRate(OS_TICKS_PER_SEC);ﻩ //启动多任务管理 &MyTaskStk[TASK_STK_SIZE - 1],ﻩ//设置任务堆栈栈顶 //使任务得优先级别为3 ﻩ //创建任务YouTask ﻩ//给任务传递参数 ﻩﻩ3);ﻩ ﻩ 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);ﻩ//等待3秒 } } /************************任务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); //请求内存块 //内存分区得指针 &err ﻩﻩ//错误信息 ﻩ ﻩ ﻩﻩﻩ ﻩ IntBuffer, ﻩﻩ ﻩﻩIntBlkPtr=OSMemGet ( ﻩ ); ﻩc1=rand(); sprintf(s,\"%x\",c1); PC_DispStr(35,10+(y++),s,DISP_BGND_BLACK+DISP_FGND_R ED );ﻩ 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) { OSTimeDlyHMSM(0, 0, 1, 0);ﻩﻩ//等待1秒 #if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif pdata = pdata; for (;;) { OW ); ﻩﻩ OSMemPut(IntBuffer,IntBlkPtr); //等待1秒 ﻩ ﻩy=0; ﻩ OSTimeDlyHMSM(0, 0, 1, 0); } } /************************End**************************************/ sprintf(s,\"%x",*IntBlkPtr); PC_DispStr(35,10+(y++),s,DISP_BGND_BLACK+DISP_FGND_YELL 七、实验小结 ﻩ本次实验就是对于内存分区得操作,对于UC/OS得内存管理与信号量,消息队列以及消息邮箱得操作类似,UC/OS与c中得malloc分配内存方式不同,就是固定得区间,便于管理。经过此次实验对UC/os得内存分区操作有了进一步得了解。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igat.cn 版权所有 赣ICP备2024042791号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务