void task_load(unsigned int fn, unsigned char tid){
task_sp[tid] = task_stack[tid] + 1;//这里保存的是&task_stack[tid][1]
task_stack[tid][0] = (unsigned int)fn & 0xff;//保存函数16位地址低字节
task_stack[tid][1] = (unsigned int)fn >> 8; //保存函数16位地址高字节
}
task_load(task1, 0);//执行的结果task_stack[tid][0]=task1低字节,task_stack[tid][1]=task1高字节
我理解task_sp[tid] = task_stack[tid] + 1可以改为task_sp[tid] = &task_stack[tid][1],因为task_stack[tid] + 1实质上就是&task_stack[tid][0]+1
这里为什么加1是51单片机的特性所决定的,堆栈操作是从高往低压栈,程序指针是两个字节,所以要设为高字节地址
1.
#define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}os_start(0)的操作为堆栈SP的内容指向task0
调用os_start(0)的结果
task_id = tid;
SP = task_sp[tid];堆栈的内容指向task1
return;这里返回则跳进task1执行
2.
void task1(){
static unsigned char i;
i = 0;
while(1)
{
stra = strb;
if(++i == sizeof(stra))
i = 0;
task_switch();//执行到这里任务切换
//这里为address_1
}
}
3.
void task_switch(){//task_id为0
task_sp[task_id] = SP;//此时堆栈最新压入内容为address_1,task_sp[0]保存address_1
if(++task_id == MAX_TASKS)
task_id = 0;
SP = task_sp[task_id];//取得task2的地址,不一定为函数的起始地址
}//这里返回到 task2中,初始为task2入口地址
4.
void task2(){
static unsigned char i;i = 0;
while(1){
stra = strb;
if(++i == sizeof(stra))
i = 0;
task_switch();//执行到这里任务切换
//这里为address_2
}
}
5.
void task_switch(){//task_id为1
task_sp[task_id] = SP;//此时堆栈最新压入内容为address_2,task_sp[1]保存address_2
if(++task_id == MAX_TASKS)
task_id = 0;
SP = task_sp[task_id];//取得task3的地址,不一定为函数的起始地址
}//这里返回到 task3中,初始为task3入口地址
6.
void task3(){
unsigned char i;
while(1){
i = sizeof(stra);
do{
stra[i-1] = strb[i-1];
}while(--i);
task_switch();//执行到这里任务切换
//这里为address_2
}
}
7.
void task_switch(){//task_id为2
task_sp[task_id] = SP;//此时堆栈最新压入内容为address_3,task_sp[1]保存address_2
if(++task_id == MAX_TASKS)
task_id = 0;
SP = task_sp[task_id];//取得task1的地址,不一定为函数的起始地址
}//这里返回到 task1中,实际上返回到address_1
接下来循环进行同样的操作,我想应该能大致明白整个过程了吧