整个的环境为 winavr20100110 atmega48
看了几个帖子,照猫画虎写了个时间片轮番调度的程序,但有些小问题。具体情况是系统能正常的切换任务,但各个任务中的延时没**常进行,试了下延时超过一个时间片(5ms)后的指令就没办法执行,而且局部变量好像也在切换任务后归零了。我对单片机也是半瓶水,耽误大家一点时间给小弟指导指导,麻烦了!程序具体如下:
#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>
#define TASK_NUM 4
#define TASK_STACK_SIZE 50
#define TOTAL_TASK_STACK TASK_NUM*TASK_STACK_SIZE
unsigned char Stack[TOTAL_TASK_STACK];
unsigned char TaskID=0;
unsigned char TaskRunID=0;
unsigned int OSTaskStackTop[TASK_NUM];
void OSTaskCreate(void(*Task)(void),unsigned char *pStack)
{
unsigned char i;
*pStack--=(unsigned int)Task;
*pStack--=(unsigned int)Task>>8;
*pStack--=0x00; //R1
*pStack--=0x00; //R0
*pStack--=0x80; //SREG
for(i=0;i<30;i++)
{*pStack--=0x00;}
OSTaskStackTop[TaskID++]=(unsigned int)pStack;
}
void OSStartTask(void)
{
SP=OSTaskStackTop[0]+33;
TCNT0=0xB2;
asm("reti" "\t");
}
void OSSched(void)
{
asm volatile("PUSH R1""\t");
asm volatile("PUSH R0""\t");
asm volatile("IN R0,0x3F""\t");
asm volatile("PUSH R0""\t");
asm volatile("CLR R1""\t");
asm volatile("PUSH R2""\t");
asm volatile("PUSH R3""\t");
asm volatile("PUSH R4""\t");
asm volatile("PUSH R5""\t");
asm volatile("PUSH R6""\t");
asm volatile("PUSH R7""\t");
asm volatile("PUSH R8""\t");
asm volatile("PUSH R9""\t");
asm volatile("PUSH R10""\t");
asm volatile("PUSH R11""\t");
asm volatile("PUSH R12""\t");
asm volatile("PUSH R13""\t");
asm volatile("PUSH R14""\t");
asm volatile("PUSH R15""\t");
asm volatile("PUSH R16""\t");
asm volatile("PUSH R17""\t");
asm volatile("PUSH R18""\t");
asm volatile("PUSH R19""\t");
asm volatile("PUSH R20""\t");
asm volatile("PUSH R21""\t");
asm volatile("PUSH R22""\t");
asm volatile("PUSH R23""\t");
asm volatile("PUSH R24""\t");
asm volatile("PUSH R25""\t");
asm volatile("PUSH R26""\t");
asm volatile("PUSH R27""\t");
asm volatile("PUSH R28""\t");
asm volatile("PUSH R29""\t");
asm volatile("PUSH R30""\t");
asm volatile("PUSH R31""\t");
OSTaskStackTop[TaskRunID++]=SP;
if(TaskRunID>=TaskID) TaskRunID=0;
SP=OSTaskStackTop[TaskRunID];
asm volatile("POP R31""\t");
asm volatile("POP R30""\t");
asm volatile("POP R29""\t");
asm volatile("POP R28""\t");
asm volatile("POP R27""\t");
asm volatile("POP R26""\t");
asm volatile("POP R25""\t");
asm volatile("POP R24""\t");
asm volatile("POP R23""\t");
asm volatile("POP R22""\t");
asm volatile("POP R21""\t");
asm volatile("POP R20""\t");
asm volatile("POP R19""\t");
asm volatile("POP R18""\t");
asm volatile("POP R17""\t");
asm volatile("POP R16""\t");
asm volatile("POP R15""\t");
asm volatile("POP R14""\t");
asm volatile("POP R13""\t");
asm volatile("POP R12""\t");
asm volatile("POP R11""\t");
asm volatile("POP R10""\t");
asm volatile("POP R9""\t");
asm volatile("POP R8""\t");
asm volatile("POP R7""\t");
asm volatile("POP R6""\t");
asm volatile("POP R5""\t");
asm volatile("POP R4""\t");
asm volatile("POP R3""\t");
asm volatile("POP R2""\t");
asm volatile("POP R0""\t");
asm volatile("OUT 0x3f,R0""\t");
asm volatile("POP R0""\t");
asm volatile("POP R1""\t");
TCNT0=0xB2;
asm("reti" "\t");
}
void Timer0_init(void)
{
TCCR0B=0x00;
TCNT0=0xB2;
TIMSK0=0x01;
TCCR0A=0x00;
TCCR0B=0x03;
sei();
}
SIGNAL(SIG_OVERFLOW0)
{
asm("RJMP OSSched");
}
void Task1(void)
{
while(1)
{
DDRC=0b00000001;
PORTC=0b00000001;
}
}
void Task2(void)
{
while(1)
{
DDRC=0b00000010;
PORTC=0b00000000;
_delay_ms(500);
PORTC=0b00000010;
_delay_ms(500);
}
}
int main(void)
{
Timer0_init();
OSTaskCreate(Task1,&Stack[49]);
OSTaskCreate(Task2,&Stack[99]);
OSStartTask();
}
Task2运行的时候只要_delay_ms()的值小于5时,LED就会常亮,大于5时就常灭。
将Task2延时改为
for(unsigned char i=0;i<1000;i++)
{ _delay_ms(4);}
也是没法延时,好像局部变量在切换后清零了,仔细看了下堆栈的操作也应该没问题,各位前辈麻烦指点一小下下!!! |