51单片机操作系统.docx

上传人:b****4 文档编号:12378022 上传时间:2023-04-18 格式:DOCX 页数:15 大小:31.41KB
下载 相关 举报
51单片机操作系统.docx_第1页
第1页 / 共15页
51单片机操作系统.docx_第2页
第2页 / 共15页
51单片机操作系统.docx_第3页
第3页 / 共15页
51单片机操作系统.docx_第4页
第4页 / 共15页
51单片机操作系统.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

51单片机操作系统.docx

《51单片机操作系统.docx》由会员分享,可在线阅读,更多相关《51单片机操作系统.docx(15页珍藏版)》请在冰豆网上搜索。

51单片机操作系统.docx

51单片机操作系统

嵌入式实时操作系统,可以充分的利用单片机的资源,提高CPU使用效率。

操作系统最主要就是实现任务的调度、管理。

同时对于实时操作系统来说响应时间很重要。

操作系统编写最主要就是用到了堆栈SP于RET指令。

这两个东西怎么用呢?

其实在我们每次调用函数的时候都会自动将函数的断点地址(执行函数调用时的PC)压入到SP中,而从函数中返回时其实是利用RET指令将断点弹回到PC(程序指针)中。

所以利用堆栈和RET指令就可以实现简单的任务的切换。

这么说肯定挺模糊的,接下来一步一步解释。

首先,要知道任务是一个死循环。

如下面所示,可以看出两个任务都是死循环,按照以往的情况,程序是跳不出来的,只能在while

(1)中无限执行。

那怎么才可以实现从task0到task1的切换呢?

 

其实如果我们能够改变PC的值是不是就可以改变程序执行顺序了。

任务的调度切换就是利用改变PC的值来改变程序执行顺序的。

其次,就是要解决如何实现PC值的正确变换问题,如何让PC指向我们需要执行的地方。

这就是通过堆栈来实现的。

我们可以为每个任务建立一个堆栈用于保存任务PC的值,以及任务寄存器的值。

这样每次进行任务切换时只要从相应的堆栈中取出PC和寄存器的值就可以实现任务的调度了。

在程序中于寄存器相关的程序使用在C语言中嵌入汇编来实现的。

因为直接使用C语言不能直接控制寄存器。

在本程序中,入栈和出栈是通过汇编实现的。

一个简单的操作系统如下所示,只能实现简单的任务调度,延时。

必须注意,空闲任务(Idle)必须建立,否则会出错。

#include

#defineOSEnterCritical()EA=0

#defineOSExitCritical()EA=1

#defineEnterInt()EA=0;

#defineuintunsignedshortint

#defineucharunsignedchar

#defineMAX_Tasks3

#defineFalse0

#defineTure1

#defineMaxPrio2

#defineIdlePrioMaxPrio

#defineOS_Task_Create_Error1

#defineOS_Delet_Task_Error2

#defineOS_Delet_Task_Not_Exit3

#defineOS_Resume_Idle_Error4

#defineOS_Resume_Task_Error5

typedefstruct

{

ucharOSStackTop;//SP

ucharOSSuspend;

ucharOSTCBDly;//delaytime

}OSTCB;

ucharcodeOSMapTbl[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

OSTCBOSTCBTbl[MAX_Tasks];

volatileucharOSRdyTbl;

volatileucharOSIntNesting;//用于中断锁死

volatileucharOSSchNesting;//任务切换上锁

volatileucharOSRuning=False;

volatileucharOSStartStack[MAX_Tasks][20];

volatileucharOSPoint[MAX_Tasks][2];

volatileucharOSPrioCur;

//volatileucharOSTaskPend;

OSInit()

{

//uchari;

EA=0;

ET0=1;

TMOD=0x01;

TH0=0xB1;

TL0=0xE0;

OSRdyTbl=0;

OSIntNesting=0;

OSSchNesting=0;

}

//PCL,PCH,ACC,B,DPL,DPH,PSW,R0-R7

uchar*OSStackInit(uinttask,uchar*ptr,ucharOSPrio)

{

uchar*stk;

stk=ptr;

OSPoint[OSPrio][0]=task;

OSPoint[OSPrio][1]=task>>8;

*(stk++)=OSPoint[OSPrio][0];

*(stk++)=OSPoint[OSPrio][1];

*(stk++)=0x00;//ACC

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk++)=0x00;

*(stk)=0x00;

returnstk;

}

ucharOSTaskCreate(uinttask,uchar*ptr,ucharOSPrio)

{

uchar*psp;

OSEnterCritical();

if(OSPrio<=MaxPrio)//创建的任务优先级有效

{

psp=OSStackInit(task,ptr,OSPrio);//初始化堆栈

OSRdyTbl|=OSMapTbl[OSPrio];

OSTCBTbl[OSPrio].OSStackTop=psp;

OSTCBTbl[OSPrio].OSSuspend=0;

OSTCBTbl[OSPrio].OSTCBDly=0;

}

else

{

OSExitCritical();

returnOS_Task_Create_Error;

}

OSExitCritical();

}

/*=====================================================

任务调度函数

入口参数:

函数说明:

进入函数后,先进行堆栈保护,然后查找最高优先

级任务运行

======================================================*/

voidOSSchedule()

{

uchari;

OSEnterCritical();

#pragmaasm

PUSHACC

PUSHB

PUSHDPH

PUSHDPL

PUSHPSW

PUSH0

PUSH7

PUSH1

PUSH2

PUSH3

PUSH4

PUSH5

PUSH6

#pragmaendasm

OSTCBTbl[OSPrioCur].OSStackTop=SP;

if(OSRdyTbl)//如果就续表中有任务

{

for(i=0;i

{

if((OSRdyTbl&OSMapTbl[i])&&(!

OSTCBTbl[i].OSSuspend))//任务优先级最高且未被挂起

{

OSPrioCur=i;

break;

}

}

}

SP=OSTCBTbl[OSPrioCur].OSStackTop;

#pragmaasm

POP6;

POP5;

POP4;

POP3;

POP2;

POP1;

POP7;

POP0;

POPPSW;

POPDPL;

POPDPH;

POPB;

POPACC;

#pragmaendasm

OSExitCritical();

}

voidOSStart()

{

TR0=1;

EA=1;

while

(1);

}

/*=========================================================

延时若干个系统时钟

入口参数:

延时系统时间个数

===========================================================*/

voidOSDelay(uchartime)

{

if(time==0)//延时为0,返回

return;

OSEnterCritical();

OSTCBTbl[OSPrioCur].OSTCBDly=time;

OSTCBTbl[OSPrioCur].OSSuspend=1;

OSExitCritical();

OSSchedule();

}

/*=========================================================

任务删除函数

入口参数:

为被删除任务优先级

函数说明:

将任务从就绪表中删除

===========================================================*/

ucharOSTaskDelet(ucharpriority)

{

OSEnterCritical();

if(priority>=IdlePrio)

{

OSExitCritical();

returnOS_Delet_Task_Error;

}

if(!

(OSRdyTbl&OSMapTbl[priority]))

{

OSExitCritical();

returnOS_Delet_Task_Not_Exit;

}

OSRdyTbl&=~(OSMapTbl[priority]);

OSExitCritical();

if(priority

{

OSSchedule();

}

}

/*=========================================================

任务恢复函数

入口参数:

恢的任务优先级

函数说明:

恢复被OSTaskDelet()删除的任务

===========================================================*/

ucharOSTaskResume(ucharpriority)

{

OSEnterCritical();

if(priority==IdlePrio)//恢复的任务不能为空闲任务,为空闲任务返回错误标志

{

OSExitCritical();

returnOS_Resume_Idle_Error;

}

if((!

(OSRdyTbl&OSMapTbl[priority]))&&(priority>=0))

{

OSRdyTbl|=(OSMapTbl[priority]);

}

else//返回的任务不存在,返回错误标志

{

OSExitCritical();

returnOS_Resume_Task_Error;

}

OSExitCritical();

if(priority

{

OSSchedule();

}

}

/*===============================================================

定时器0用于产生系统时钟,这里每过20ms中断一次。

===============================================================*/

voidtimer0()interrupt1

{

uchari;

EA=0;

TR0=0;

TH0=0xB1;

TL0=0xE0;

if(OSRuning==Ture)//如果不是第一次调度则保护任务堆栈,有部分堆栈进入中断时自动完成

{//定时器自动保护的堆栈可通过反汇编查看,以此确定堆栈的安排顺序

__asmPUSH1

__asmPUSH2

__asmPUSH3

__asmPUSH4

__asmPUSH5

__asmPUSH6

OSTCBTbl[OSPrioCur].OSStackTop=SP;

}

else//第一次进入则将OSRuning置位

{

OSRuning=Ture;

}

if(OSRuning==Ture)//如在运行,

{

for(i=0;i

{

if((OSRdyTbl&OSMapTbl[i])&&OSTCBTbl[i].OSTCBDly)//如果任务需要延时,将任务延时参数减一

{

OSTCBTbl[i].OSTCBDly--;

if(OSTCBTbl[i].OSTCBDly==0)

{

OSTCBTbl[i].OSSuspend=0;

}

}

}

for(i=0;i

{

if((OSRdyTbl&OSMapTbl[i])&&(!

OSTCBTbl[i].OSSuspend))//查找优先级最高的且未挂起的任务

{

OSPrioCur=i;

break;

}

}

SP=OSTCBTbl[OSPrioCur].OSStackTop;

#pragmaasm

POP6;

POP5;

POP4;

POP3;

POP2;

POP1;

/*POP7;

POP0;

POPPSW;

POPDPH;

POPDPL;

POPACC;*/

#pragmaendasm

}

TR0=1;

EA=1;

}

voidIdle()

{

while

(1);

}

voidtask0()

{

uchartemp=0x01,i;

while

(1)

{

for(i=0;i<8;i++)

{

P1=~temp;

temp<<=1;

OSDelay(10);

}

temp=0x01;

}

}

voidtask1()

{

uchari=0,j=0;

while

(1)

{

for(i=0;i<16;i++)

{

P3=j;

OSDelay(20);

j++;

}

j=0;

}

}

intmain()

{

OSInit();

OSTaskCreate(&Idle,&OSStartStack[2],IdlePrio);

OSTaskCreate(&task1,&OSStartStack[1],1);

OSTaskCreate(&task0,&OSStartStack[0],0);

OSStart();

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1