|
我是AVR新手,移植Small RTOS是学AVR做的第一件事,欢迎测试,期待高手指点。
更新:修复EN_OSStkChk BUG
根据AVR实际情况,改动原版Small RTOS51的地方:
1.任务切换保存全部32个寄存器,SREG,Os_Enter_Sum和返回地址(共36字节),不区分任务快速切换和一般任务切换,OSCtxSw()和OSIntCtxSw()为同一函数。
#define OSIntCtxSw() OSCtxSw() //在OS_CPU.h。
2.空闲任务OSIdle()也有自己一份堆栈。
3.不是将所有剩余SRAM空间分配给系统堆栈,系统堆栈空间大小由自己设定
#define OS_STACK_SIZE 512 //在OS_CPU.h,系统堆栈空间大小(包括空闲任务OSIdle的堆栈)
4.新加EN_OSStkChk,在OS_CPU.h里,#define EN_OSStkChk 1
根据两个全局变量OS_Stk_Null,OS_Stk_Min_Null查看切换任务时系统堆栈剩余大小。可以参考此值调整OS_STACK_SIZE大小。
5.非系统管理中断(不受OS_ENTER_CRICITAL()影响)用法:
打开非系统管理中断编译开关
#define EN_SP2 1 //在OS_CPU.h
定义非系统管理中断预留堆栈大小
#define Sp2Space 32 //在OS_CPU.h
改写三个宏
OS_ENTER_CRITICAL():打开总中断,关闭系统管理中断(包括系统时钟中断),Os_Enter_Sum加一
OS_ENTER_EXIT ():Os_Enter_Sum减一,如果为0,则打开总中断,打开系统管理中断(包括系统时钟中断)
OS_SET_INT打开总中断(R0暂存SREG,将R0最高位置位即可,不要直接操作SREG),打开系统管理中断(包括系统时钟中断),不需要对Os_Enter_Sum减一操作,
注意:非系统管理中断中不能再开中断。
测试例子12个任务控制12个LED闪烁,硬件连线:
PORTB0-------------------LED0 //20ms闪烁一次
PORTB1-------------------LED1 //40ms闪烁一次
PORTB2-------------------LED2 //80ms闪烁一次
PORTB3-------------------LED3 //160ms闪烁一次
PORTB4-------------------LED4 //320ms闪烁一次
PORTB5-------------------LED5 //640ms闪烁一次
PORTB6-------------------LED6 //1.28s闪烁一次
PORTB7-------------------LED7 //2.56s闪烁一次
PORTD0-------------------LED8 //5.12s闪烁一次
PORTD1-------------------LED9 //10.24s闪烁一次
PORTD2-------------------LED10 //20.48s闪烁一次
PORTD3-------------------LED11 //40.96s闪烁一次
#include "config.h"
#define LED_PORT0 PORTB
#define LED_DDR0 DDRB
#define LED_PORT1 PORTD
#define LED_DDR1 DDRD
void Task0(void)
{
LED_PORT0=0XFF;
LED_DDR0=0XFF;
LED_PORT1=0X0F;
LED_DDR1=0X0F;
while(1)
{
OSWait(K_TMO,OS_TICKS_PER_SEC/50);
LED_PORT0^=_BV(0); //20ms闪烁一次
OSSendSignal(1);
}
}
void Task1(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(1); //40ms闪烁一次
OSSendSignal(2);
}
}
void Task2(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(2); //80ms闪烁一次
OSSendSignal(3);
}
}
void Task3(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(3); //160ms闪烁一次
OSSendSignal(4);
}
}
void Task4(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(4); //320ms闪烁一次
OSSendSignal(5);
}
}
void Task5(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(5); //640ms闪烁一次
OSSendSignal(6);
}
}
void Task6(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0);
}
LED_PORT0^=_BV(6); //1.28s闪烁一次
OSSendSignal(7);
}
}
void Task7(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0); //2.56s闪烁一次
}
LED_PORT0^=_BV(7);
OSSendSignal(8);
}
}
void Task8(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0); //5.12s闪烁一次
}
LED_PORT1^=_BV(0);
OSSendSignal(9);
}
}
void Task9(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0); //10.24s闪烁一次
}
LED_PORT1^=_BV(1);
OSSendSignal(10);
}
}
void Task10(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0); //20.48s闪烁一次
}
LED_PORT1^=_BV(2);
OSSendSignal(11);
}
}
void Task11(void)
{
uint8 i;
while(1)
{
for(i=0;i<2;i++)
{
OSWait(K_SIG,0); //40.96s闪烁一次
}
LED_PORT1^=_BV(3);
}
}
点击此处下载armok01154097.rar
-----此内容被ATmega8515于2007-05-14,21:16:33编辑过
-----此内容被ATmega8515于2007-05-14,21:42:03编辑过 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|