cadier 发表于 2012-5-11 22:51:07

自己画了个avr的RTOS,但有点问题麻烦大家帮忙看看~

本帖最后由 cadier 于 2012-5-11 22:54 编辑

整个的环境为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;

unsigned char TaskID=0;
unsigned char TaskRunID=0;
unsigned int OSTaskStackTop;

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=(unsigned int)pStack;
}

void OSStartTask(void)
{
SP=OSTaskStackTop+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=SP;
if(TaskRunID>=TaskID) TaskRunID=0;
SP=OSTaskStackTop;

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);
OSTaskCreate(Task2,&Stack);

OSStartTask();
}



Task2运行的时候只要_delay_ms()的值小于5时,LED就会常亮,大于5时就常灭。
将Task2延时改为
for(unsigned char i=0;i<1000;i++)
{ _delay_ms(4);}
也是没法延时,好像局部变量在切换后清零了,仔细看了下堆栈的操作也应该没问题,各位前辈麻烦指点一小下下!!!

xivisi 发表于 2012-5-12 07:59:43

没有 看你的代码,仅从症状描述看

“延时超过一个时间片(5ms)后的指令就没办法执行”

PC指针恢复不正确。

“局部变量好像也在切换任务后归零了”

寄存器 压栈 或者出栈错误

cadier 发表于 2012-5-13 17:18:15

楼上先谢谢啊!

但有一段asm("RJMP OSSched")   其他帖子上都是 asm("JMP OSSched")atmega48没有JMP,用RJMP会不会有影响??

还有说是GCC优化选择 -Os(原话:优化设置:-0s,其他形式下需要改变入栈与出栈代码) 这是啥意思,要到哪设置,是不是makefile 中的优化等级 s 级啊??

这个星期一直纠结在这上面,OSSched()中的入栈和出栈我也其他贴比对了,没问题。还是说atmega48的入栈和出栈有特殊要求?

跪谢能解决问题的前辈啊~
页: [1]
查看完整版本: 自己画了个avr的RTOS,但有点问题麻烦大家帮忙看看~