到cpu_sr这个变量来保存程序状态字
OS_CPU_SR cpu_sr; //定义cpu_sr这个变量 #endif
pdata = pdata; // 这句可以不写,仅仅只是为了防止编译器报错 OS_ENTER_CRITICAL(); //进入临界段(关中断) PC_VectSet(0x08, OSTickISR); // 安装uCOS_II时钟中断向量
PC_SetTickRate(OS_TICKS_PER_SEC); // 设置uCOS_II时钟频率 OS_EXIT_CRITICAL(); //退出临界段(开中断) OSStatInit(); // 创建和初始化uCOS_II的统计任务(这条语句一定不能掉,不然会扣很多分的)
OSTaskCreate(YouTask, s_Y, &YouTaskStk[TASK_STK_SIZE - 1], 2);
//在MyTask任务中创建YouTask任务,优先级为2
for (;;) {
if(times>85) //如果MyTask任务的运行次数大于了85次,就要求YouTask任务删除它自己(这个数值也是由题目规定的,题目要求
{ // MyTask运行多少次后删除YouTask就将此处改成多少
while( OSTaskDelReq(2) != OS_TASK_NOT_EXIST)
// 要注意OSTaskDelReq后括号中的2,这个数值是所要删除的任务的
{ //优先级,要删除哪个任务就在此处填入该任务的优先级,该程序中,优先级2对应的任务为YouTask
PC_DispStr(10, 8, s, DISP_FGND_YELLOW+DISP_BGND_BLUE);
//在屏幕上的第10列、第8行显示s所代表的字符 // 串,s在上面已经定义了。(这些DOS窗口的打印函数在书本附录A[page263]都有介绍)
OSTimeDly(1);
}
}
if(x>50) //当一行打印的字符数大于了50个后,换行,换到该行下面的第二行(因为y=y+2),然后从行首开始打印(因为x=0)
{
x=0; y+=2;
}
times+=1; //每运行一次times加1,以记录下MyTask任务的运行次数
if(times==10) OSSchedLock(); //当MyTask运行10次后,给调度器加锁,这个数值由题目的要求给定
if(times==80) OSSchedUnlock(); //当MyTask运行80次后,给调度器解锁,这个数值也由题目的要求给定
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK+DISP_FGND_WHITE); //在x、y指定的位置打印字符”M” x += 1; // 将列加1,为打印下一字符准备好位置
OSTimeDlyHMSM(0, 0, 3, 0); //等待3秒钟,此处的时间也由题目给定,若要求是延时多少
17
ms或tick,就应该使用函数OSTimeDly()
} }
void YouTask(void* pdata) {
char* s1=\ char* s2=\
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif pdata=pdata; for(;;) {
if(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ) //YouTask利用函数OSTaskDelReq()来查看自己是否被别人要求删除, { //如果是,
PC_DispStr(10, 10, s1, DISP_FGND_WHITE+DISP_BGND_BLACK);//则在指定位置打印字符串s1
OSTimeDlyHMSM(0, 0, 15, 0); //等待15s(此处看题目有没有这个要求,若没有,则可不写 PC_DispStr(10, 12, s2, DISP_FGND_WHITE+DISP_BGND_BLACK); //在指定位置打印字符串s2
OSTaskDel(OS_PRIO_SELF); //自己将自己删除 }
if(x>50) {
x=0; y+=2; }
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK+DISP_FGND_WHITE ); //在没有被删除时,仍然打印字符”Y” x += 1;
OSTimeDlyHMSM(0, 0, 1, 0); } } 二、编写一个uC/OS-II应用程序,要求:(1) 包含3个用户任务(MyTask、YouTask和InterTask),优先级分别为0、1、2,并把MyTask作为起始任务;(2) 任务InterTask由时钟节拍中断服务程序中的钩子函数在被调用10000次时使用一个信号变量InterKey激活,其他时候不活动; (3) 当程序打印完第一行字符后,取消YouTask任务的延时。 #include \
#define TASK_STK_SIZE 512 //任务堆栈长度
OS_STK MyTaskStk[TASK_STK_SIZE]; //定义任务堆栈区 OS_STK YouTaskStk[TASK_STK_SIZE]; OS_STK InterTaskStk[TASK_STK_SIZE]; INT8U x=0, y=0;
BOOLEAN InterKey=FALSE; //这个标志变量用来激活InterTask任务
18
char* s=\void MyTask(void* pdata); void YouTask(void* pdata); void InterTask(void* pdata);
void main (void) {
char* s_M=\
OSInit(); //初始化uCOS_II
PC_DOSSaveReturn(); //保存Dos环境
PC_VectSet(uCOS, OSCtxSw); //安装uCOS_II中断
OSTaskCreate(MyTask, s_M, &MyTaskStk[TASK_STK_SIZE - 1],0); //注意优先级要设置为题目的要求
OSStart(); //启动uCOS_II }
void MyTask (void *pdata) {
char* s_Y=\ char* s_H=\
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata;
OS_ENTER_CRITICAL(); PC_VectSet(0x08, OSTickISR); //安装uCOS_II时钟中断向量 PC_SetTickRate(OS_TICKS_PER_SEC); //设置uCOS_II时钟频率 OS_EXIT_CRITICAL(); OSStatInit(); //初始化uCOS_II的统计任务
OSTaskCreate(YouTask, s_Y, &YouTaskStk[TASK_STK_SIZE - 1], 1); //注意优先级要设置为题目的要求
OSTaskCreate(InterTask, s_H, &InterTaskStk[TASK_STK_SIZE - 1], 2); //注意优先级要设置为题目的要求 for (;;) {
if(x>50) { x=0; y+=2; }
if(y>1) OSTimeDlyResume(1);//打印完第1行字符后,取消YouTask任务的延时,注意括号中的数值,一定要是被取消延时的任务的
//优先级,此处的1是YouTask任务的优先级。这条语句一定不能掉
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK+DISP_FGND_WHITE); //打印字
19
符”M” x += 1;
OSTimeDly(100); //延时100ms或100个tick,此处的值根据题目要求更改,没有要求的话可以就使用这个 } }
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; }
PC_DispChar(x, y, *(char*)pdata, DISP_BGND_BLACK+DISP_FGND_WHITE ); //打印字符”Y”
x += 1;
OSTimeDly(500); //此处的值根据题目要求更改,没有要求的话可以就使用这个 } }
void InterTask(void* pdata) {
#if OS_CRITICAL_METHOD == 3 OS_CPU_SR cpu_sr; #endif
pdata = pdata; for(;;) {
if(InterKey) //如果InterKey标志的值为真,则: {
if(x>50) {
x=0; y+=2; }
20