各任务间的堆栈空间变换
2015-08-28 15:55
399 查看
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define tasknumsize 3
#define ramsize 128
uint idata wait[tasknumsize];
uchar taskrdy=0xff,curtask,nxttask;
void cswitch();
void waitdly(uint dly);
void taskA()
{
uchar temp,i;
while(1)
{
temp=0x01;
for(i=0;i<8;i++)
{
P1=temp;
temp=temp<<1;
waitdly(10);
}
}
}
void taskB()
{
while(1)
{
P2+=1;
waitdly(20);
}
}
void taskC()
{
while(1)
{
P3+=2;
waitdly(50);
}
}
void * const func[tasknumsize]={taskA,taskB,taskC};
uchar idata *stk[tasknumsize+1];
void initstarttask()
{
uchar idata *sspp,i;
sspp=(uchar idata *)SP+1; //需要指向堆栈的下一个空位处,51为满增堆栈.
stk[0]=(uchar idata *)SP+1;
stk[tasknumsize] = (uchar idata *)(ramsize);
*sspp++=((uint)(func[0]))%256;
*sspp=((uint)(func[0]))/256;
SP=(uchar)sspp;
sspp=(uchar idata *)(ramsize-1);
for(i=tasknumsize-1;i>0;i--)
{
*sspp--=((uint)(func[i]))/256;
stk[i]=sspp;
*sspp--=((uint)(func[i]))%256;
}
}
void inittimer0()
{
TMOD=0x01;//方式1,16位模式,不会自动清零。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
EA=1;
ET0=1;
}
main()
{
inittimer0();
initstarttask(); //main函数中最后调用的这个函数是不会将函数的返回地址压入到堆栈中
}
void cswitch()
{
uchar idata *sp1,idata *sp2;
uchar temp,svsp,i;
temp=taskrdy;
for(nxttask=0;nxttask<tasknumsize;nxttask++)
{
if((temp & 0x80)!=0)
break;
temp=temp<<1;
}
if(nxttask==tasknumsize)
nxttask=0;
svsp=(uchar)SP;
sp1=(uchar *)SP+1;
sp2=stk[curtask+1];
temp=(uchar)stk[nxttask+1];
if(nxttask>curtask)
{
while(sp2!=(uchar idata *)temp) //堆栈空间变换
{
*sp1++=*sp2++;
}
SP=(uchar)sp1-1;
temp=stk[curtask+1]-(uchar idata *)svsp-1;
for(i=curtask+1;i<nxttask+1;i++)
{
stk[i]-=temp;
}
}
if(nxttask<curtask)
{
sp1--;sp2--;
while(sp1!=((uchar idata *)temp-1)) //堆栈空间变换
{
*sp2--=*sp1--;
}
SP=(uchar)stk[nxttask+1]-1;
temp=stk[curtask+1]-(uchar idata *)svsp-1;
for(i=nxttask+1;i<curtask+1;i++)
{
stk[i]+=temp;
}
}
if(nxttask==curtask)
SP=svsp;
curtask=nxttask;
}
void waitdly(uint dly)
{
wait[curtask]=dly;
while(wait[curtask]!=0)
{
taskrdy &= ~(0x80>>curtask);
cswitch();
}
}
void timer0() interrupt 1
{
uchar t;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
for(t=0;t<tasknumsize;t++)
{
if(wait[t]>0)
{
wait[t]--;
if(wait[t]==0)
taskrdy |= (0x80>>t);
}
}
}
#define uint unsigned int
#define uchar unsigned char
#define tasknumsize 3
#define ramsize 128
uint idata wait[tasknumsize];
uchar taskrdy=0xff,curtask,nxttask;
void cswitch();
void waitdly(uint dly);
void taskA()
{
uchar temp,i;
while(1)
{
temp=0x01;
for(i=0;i<8;i++)
{
P1=temp;
temp=temp<<1;
waitdly(10);
}
}
}
void taskB()
{
while(1)
{
P2+=1;
waitdly(20);
}
}
void taskC()
{
while(1)
{
P3+=2;
waitdly(50);
}
}
void * const func[tasknumsize]={taskA,taskB,taskC};
uchar idata *stk[tasknumsize+1];
void initstarttask()
{
uchar idata *sspp,i;
sspp=(uchar idata *)SP+1; //需要指向堆栈的下一个空位处,51为满增堆栈.
stk[0]=(uchar idata *)SP+1;
stk[tasknumsize] = (uchar idata *)(ramsize);
*sspp++=((uint)(func[0]))%256;
*sspp=((uint)(func[0]))/256;
SP=(uchar)sspp;
sspp=(uchar idata *)(ramsize-1);
for(i=tasknumsize-1;i>0;i--)
{
*sspp--=((uint)(func[i]))/256;
stk[i]=sspp;
*sspp--=((uint)(func[i]))%256;
}
}
void inittimer0()
{
TMOD=0x01;//方式1,16位模式,不会自动清零。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
EA=1;
ET0=1;
}
main()
{
inittimer0();
initstarttask(); //main函数中最后调用的这个函数是不会将函数的返回地址压入到堆栈中
}
void cswitch()
{
uchar idata *sp1,idata *sp2;
uchar temp,svsp,i;
temp=taskrdy;
for(nxttask=0;nxttask<tasknumsize;nxttask++)
{
if((temp & 0x80)!=0)
break;
temp=temp<<1;
}
if(nxttask==tasknumsize)
nxttask=0;
svsp=(uchar)SP;
sp1=(uchar *)SP+1;
sp2=stk[curtask+1];
temp=(uchar)stk[nxttask+1];
if(nxttask>curtask)
{
while(sp2!=(uchar idata *)temp) //堆栈空间变换
{
*sp1++=*sp2++;
}
SP=(uchar)sp1-1;
temp=stk[curtask+1]-(uchar idata *)svsp-1;
for(i=curtask+1;i<nxttask+1;i++)
{
stk[i]-=temp;
}
}
if(nxttask<curtask)
{
sp1--;sp2--;
while(sp1!=((uchar idata *)temp-1)) //堆栈空间变换
{
*sp2--=*sp1--;
}
SP=(uchar)stk[nxttask+1]-1;
temp=stk[curtask+1]-(uchar idata *)svsp-1;
for(i=nxttask+1;i<curtask+1;i++)
{
stk[i]+=temp;
}
}
if(nxttask==curtask)
SP=svsp;
curtask=nxttask;
}
void waitdly(uint dly)
{
wait[curtask]=dly;
while(wait[curtask]!=0)
{
taskrdy &= ~(0x80>>curtask);
cswitch();
}
}
void timer0() interrupt 1
{
uchar t;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
for(t=0;t<tasknumsize;t++)
{
if(wait[t]>0)
{
wait[t]--;
if(wait[t]==0)
taskrdy |= (0x80>>t);
}
}
}
相关文章推荐
- SpringMvc访问静态资源的方法
- 反转单链表
- Cocoapods无法更新第三库至最新的解决方法
- phpcms筛选功能
- hdu 4731 2013成都赛区网络赛 找规律
- 当IDENTITY_INSERT设置为OFF时不能向表插入显示值。(源:MSSQLServer,错误码:544)
- AndroidStudio常用快捷键
- 网易杭州研发中心-算法工程师面经
- Using NSURLConnection 使用NSURLConnection 官方文档翻译(二)
- iOS 企业应用的发布要点
- 内核临时页表建立
- zzuli OJ 1027: 判断水仙花数
- zzuli OJ 1026: 字符类型判断
- UE4 Metal Rendering API
- C语言中常用的库函数
- hdoj-2015 偶数求和【水】
- 51操作系统之延时实现源代码
- C语言变量存储区域 进程内存布局
- Unable to resolve target 'android-XX' 类似的错误。
- 加入购物车的飞入效果