The user has the option of supplying a pointer to a block of memory that contains extra parameters for the task, or that pointer can be used as a value as well.
t | pointer to the task control block | |
task | pointer to function that will be the task | |
stack | pointer to memory block to use as stack | |
stacksize | size of stack in number of longs | |
priority | task priority | |
name | tag to identify task control block for debug purposes | |
arg | argument to be passed to function...it chan either be | |
a | value, or a pointer to some data |
pq.c
// This file is compiled with WinAVR version 4.1.2 // // These routines mess with the stack // // you must use either of these optimizations: // -O1 // -O3 // -O2 // // Whatever you do, do NOT use -O0....it will NOT work // // ///////////////////////////////////////////////////////////////////////////////////////// #include "task.h" #include "pq.h" #include "HeapManager.h" TCB *CurrentTask; TCB *NextTask; int OsRunning; HEAP_BLOCK *pStackHeap; PQ ActiveTasks; //-------------------------------------------------------------------------- // Stack allocation functions //-------------------------------------------------------------------------- static void *AllocStack(size_t len) { // return malloc(len); return HeapAlloc(pStackHeap,len); } unsigned StackHeapAvailiable(void) { return HeapFreeSpace(pStackHeap); } /* static void FreeStack(void *p) { HeapFree(pStackHeap,p); } */ void CreateTask(TCB *t, void (*task)(void *), int stacksize,int priority,char *name,void *arg) { char *stk; char sr; char *stack; int i; stack = AllocStack(stacksize); for(i=0;i<stacksize;++i) stack[i] = 0xcd; sr = Disable(); if(t) { t->TcbSwaps = 0; t->stacksize = stacksize; t->priority = priority; t->TimeStamp = 0; t->name = name; t->stacktop = stack; t->next = (TCB *)0; t->list = (TCB *)0; stk = stack + stacksize-1; *stk-- = (char)LO( (unsigned)task);/* return address */ *stk-- = (char)HI( (unsigned)task); *stk-- = 0; //top byte of address is 0...bummer *stk-- = 31; /* r31 = 0 */ *stk-- = 0x80; /* SREG Interrupts enabled */ *stk-- = 30; /* r30 = 0 */ *stk-- = 29; /* r29 = 0 */ *stk-- = 28; /* r28 = 0 */ *stk-- = 27; /* r27 = 0 */ *stk-- = 26; /* r26 = 0 */ *stk-- = (char)HI( (unsigned)arg); /* r25 = 0 */ *stk-- = (char)LO( (unsigned)arg); /* r24 = 0 */ *stk-- = 23; /* r23 = 0 */ *stk-- = 22; /* r22 = 0 */ *stk-- = 21; /* r21 = 0 */ *stk-- = 20; /* r20 = 0 */ *stk-- = 19; /* r19 */ *stk-- = 18; /* r18 */ *stk-- = 17; /* r17 */ *stk-- = 16; /* r16 */ *stk-- = 15; /* r15 */ *stk-- = 14; /* r14 */ *stk-- = 13; /* r13 */ *stk-- = 12; /* r12 */ *stk-- = 11; /* r11 */ *stk-- = 10; /* r10 */ *stk-- = 9; /* r9 */ *stk-- = 8; /* r8 */ *stk-- = 7; /* r7 */ *stk-- = 6; /* r6 */ *stk-- = 5; /* r5 */ *stk-- = 4; /* r4 */ *stk-- = 3; /* r3 */ *stk-- = 2; /* r2 */ *stk-- = 0; /* r1 must be ZERO */ *stk-- = 0; /* r0 */ t->stack = stk; } Enable(sr); }