|
本帖最后由 zouzhichao 于 2013-6-9 15:01 编辑
代码如下,4个线程
#include <avr\io.h>
#include <avr\interrupt.h>
#include <util\delay.h>
#define int8_ char
#define uint8_ unsigned char
#define int16_ short
#define uint16_ unsigned short
#define int32_ long
#define uint32_ unsigned long
#define PUSH()\
{\
asm volatile(\
"push r2\n\t"\
"push r3\n\t"\
"push r4\n\t"\
"push r5\n\t"\
"push r6\n\t"\
"push r7\n\t"\
"push r8\n\t"\
"push r9\n\t"\
"push r10\n\t"\
"push r11\n\t"\
"push r12\n\t"\
"push r13\n\t"\
"push r14\n\t"\
"push r15\n\t"\
"push r16\n\t"\
"push r17\n\t"\
"push r19\n\t"\
"push r26\n\t"\
"push r27\n\t"\
"push r28\n\t"\
"push r29\n\t"\
: : );\
}
#define POP()\
{\
asm volatile(\
"pop r29\n\t"\
"pop r28\n\t"\
"pop r27\n\t"\
"pop r26\n\t"\
"pop r19\n\t"\
"pop r17\n\t"\
"pop r16\n\t"\
"pop r15\n\t"\
"pop r14\n\t"\
"pop r13\n\t"\
"pop r12\n\t"\
"pop r11\n\t"\
"pop r10\n\t"\
"pop r9\n\t"\
"pop r8\n\t"\
"pop r7\n\t"\
"pop r6\n\t"\
"pop r5\n\t"\
"pop r4\n\t"\
"pop r3\n\t"\
"pop r2\n\t"\
: : );\
}
#define OsTaskStateSave(pTask)\
{\
PUSH();\
(pTask)->StackPoint = (uint8_*)SP;\
}
#define OsTaskStateLoad(pTask)\
{\
SP = (uint16_)((pTask)->StackPoint);\
POP();\
}
#define OsTaskRun(pTask)\
{\
SP = (uint16_)((pTask)->StackPoint);\
POP();\
asm volatile(\
"pop r31\n\t"\
"pop r30\n\t"\
"pop r25\n\t"\
"pop r24\n\t"\
"pop r23\n\t"\
"pop r22\n\t"\
"pop r21\n\t"\
"pop r20\n\t"\
"pop r18\n\t"\
"pop r0\n\t"\
"out __SREG__, r0\n\t"\
"pop r0\n\t"\
"pop r1\n\t"\
: : );\
return;\
}
typedef struct tagTASK
{
int8_ (*TaskFunction)(int16_ Para);
uint8_* StackPoint;
uint8_ Stack[128];
uint8_ Flag;
}TASK;
int8_ OsTaskInit(int8_ (*TaskFun)(int16_ Para), int16_ TaskFunPara, TASK *Task)
{
Task->TaskFunction = TaskFun;
Task->StackPoint = (uint8_*)Task->Stack + sizeof(Task->Stack) - 1;
*(Task->StackPoint--) = (uint8_)((uint16_)(Task->TaskFunction)); /* Put task start address on top of stack */
*(Task->StackPoint--) = (uint8_)(((uint16_)(Task->TaskFunction)) >> 8);
*(Task->StackPoint--) = 0x00; /* R1 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R0 = 0x00 */
*(Task->StackPoint--) = 0x80; /* SREG = Interrupts enabled */
*(Task->StackPoint--) = 0x00; /* R18 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R20 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R21 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R22 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R23 = 0x00 */
*(Task->StackPoint--) = (uint8_)TaskFunPara; /* Simulate call to function with argument */
*(Task->StackPoint--) = (uint8_)(TaskFunPara >> 8); /* R24, R25 contains argument pointer pdata */
*(Task->StackPoint--) = 0x00; /* R30 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R31 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R2 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R3 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R4 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R5 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R6 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R7 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R8 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R9 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R10 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R11 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R12 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R13 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R14 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R15 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R16 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R17 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R19 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R26 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R27 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R28 = 0x00 */
*(Task->StackPoint--) = 0x00; /* R29 = 0x00 */
return 0;
}
int8_ OsTickInit(void)
{
cli(); //disable all interrupts
TCCR0 = 0x00; //stop
TCNT0 = 0x00; //set count
OCR0 = 0x0E; //set compare
TCCR0 = 0x05; //start timer
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
sei(); //re-enable interrupts
return 0;
}
int8_ TaskFun0(int16_ Para)
{
for ( ; ; )
{
_delay_us(20);
PORTA ^= 0x01;
}
return 0;
}
int8_ TaskFun1(int16_ Para)
{
for ( ; ; )
{
_delay_us(20);
PORTA ^= 0x02;
}
return 0;
}
int8_ TaskFun2(int16_ Para)
{
for ( ; ; )
{
_delay_us(20);
PORTA ^= 0x04;
}
return 0;
}
int8_ TaskFun3(int16_ Para)
{
for ( ; ; )
{
_delay_us(20);
PORTA ^= 0x08;
}
return 0;
}
static TASK Task[4];
static uint8_t ID = 0;
int main()
{
DDRA |= 0xff;
PORTA ^= 0xff;
OsTaskInit(TaskFun0, 10, &Task[0]);
OsTaskInit(TaskFun1, 1, &Task[1]);
OsTaskInit(TaskFun2, 2, &Task[2]);
OsTaskInit(TaskFun3, 3, &Task[3]);
OsTickInit();
OsTaskRun(&Task[0]);
for ( ; ; )
;
return 0;
}
ISR(TIMER0_OVF_vect)
{
OsTaskStateSave(&Task[ID]);
if (4 == ++ID)
ID = 0;
OsTaskStateLoad(&Task[ID]);
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|