打印
[AVR单片机]

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

[复制链接]
1811|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cadier|  楼主 | 2012-5-13 16:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
整个的环境为  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);}
也是没法延时,好像局部变量在切换后清零了,仔细看了下堆栈的操作也应该没问题,各位前辈麻烦指点一小下下!!!

相关帖子

沙发
cyw183846168| | 2012-7-4 08:57 | 只看该作者
大哥你好歹加几条注释啊,这么大段的程序没注释谁看啊!!

使用特权

评论回复
板凳
airwill| | 2012-7-5 09:33 | 只看该作者
AVR 的寄存器太多也有缺陷, RTOS 的切换消耗太多的内存空间用于保存寄存器.

使用特权

评论回复
地板
ayb_ice| | 2012-7-5 11:09 | 只看该作者
AVR 的寄存器太多也有缺陷, RTOS 的切换消耗太多的内存空间用于保存寄存器.
airwill 发表于 2012-7-5 09:33

确实
感觉设计芯片的人脑袋有些问题

使用特权

评论回复
5
xtldw| | 2014-9-12 17:47 | 只看该作者
我仔细的看了你的程序  肯定是堆栈处理的问题,在运行的过程中  SP=0  然后复位了,你的所有变量变0   我也不知道你现在做好了没有  我也是个菜鸟   有兴趣可以QQ  314187849  联系一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1

帖子

0

粉丝