1     //********************************************************** 
2     //Set it all up
3     void os_init_api(void)
4     {
5         SleepThreadPtr      = SleepThread;
6         CreateThreadPtr     = CreateThread;
7         SuspendThreadPtr    = SuspendThread;
8         ResumeThreadPtr     = ResumeThread;
9         TerminateThreadPtr  = TerminateThread;
10        FindThreadPtr       = FindThread;
11
12        CreateSemaphorePtr  = CreateSemaphore;
13        WaitSemaphorePtr    = WaitSemaphore;
14        SignalSemaphorePtr  = SignalSemaphore;
15
16        SendMessagePtr      = SendMessage;
17        ReceiveMessagePtr   = ReceiveMessage;
18    }
19    void os_init_structures(void)
20    {
21        register char i;
22        os_thread *temp_thread, *prev_thread;
23        os_semaphore *temp_semaphore, *prev_semaphore;
24       os_threadsem *temp_threadsem;
25       os_message *temp_message;
26
27       g_threadcount = 0;
28
29       // initialize list of threads
30        g_freethreads = &g_allthreads[0];
31        prev_thread = NULL;
32        temp_thread = g_freethreads;
33       for (i = 1; i < THREAD_COUNT; ++i)
34       {
35            temp_thread->next = &g_allthreads[i];
36          temp_thread->prev = prev_thread;
37          temp_thread->threadID = i;
38
39          prev_thread = temp_thread;
40          temp_thread = temp_thread->next;
41       }
42       temp_thread->threadID = i;
43       temp_thread->prev = prev_thread;
44       temp_thread->next = NULL;
45
46       // initialize list of semaphores
47        g_freesemaphores = &g_allsemaphores[0];
48        prev_semaphore = NULL;
49        temp_semaphore = g_freesemaphores;
50       for (i = 1; i < SEMAPHORE_COUNT; ++i)
51       {
52            temp_semaphore->next = &g_allsemaphores[i];
53          temp_semaphore->prev = prev_semaphore;
54
55          prev_semaphore = temp_semaphore;
56          temp_semaphore = temp_semaphore->next;
57       }
58       temp_semaphore->prev = prev_semaphore;
59       temp_semaphore->next = NULL;
60
61       // initialize list of thread/semaphore holders
62        g_freethreadsems = &g_allthreadsems[0];
63        temp_threadsem = g_freethreadsems;
64       for (i = 1; i < THREADSEM_COUNT; ++i)
65       {
66            temp_threadsem->next = &g_allthreadsems[i];
67          temp_threadsem = temp_threadsem->next;
68       }
69       temp_threadsem->next = NULL;
70
71       // initialize list of message holders
72        g_freemessages = &g_allmessages[0];
73        temp_message = g_freemessages;
74       for (i = 1; i < MESSAGE_COUNT; ++i)
75       {
76            temp_message->next = &g_allmessages[i];
77          temp_message = temp_message->next;
78       }
79       temp_threadsem->next = NULL;
80
81       // allocate the stack
82       g_stkCurrent = g_stkStart = &g_stkBlock[0];
83       g_stkEnd = g_stkStart + TOTAL_STACK_SIZE;
84    }
85    void os_initialize(void)
86    {
87        UCHAR *sd_swstack, *sd_hwstack;
88
89        // set up UART   
90        UCSRB = 0x18;
91        UBRRL = 51;
92        /*UCSRB = 0x18;
93        UBRRL = 0x40;  //set baud rate to 1200
94        UBRRH = UBRRH | 0x03; 
95        UCSRA=0x02;
96        UCSRB=0x18;
97        UCSRC=0x86;
98        UBRRH=0x01;
99        UBRRL=0xCD;*/
100
101       // set up Timer0 for scheduling every 10ms
102       TCNT0 = 0x00;
103       OCR0  = 15.6 * 10;
104       TIMSK = 0x02;
105       TCCR0 = 0b00001101;
106
107       DDRC = 0xFF;
108
109       os_init_api();
110      os_init_structures();
111
112       // create some uart semaphores
113      g_uart_t_semaphore = CreateSemaphore(1);
114      g_uart_r_semaphore = CreateSemaphore(1);
115
116       // create the SD card thread
117      g_currthread = CreateThread(sdthread, 255, 150, 150);
118
119      // We never want to free the sd threads stack
120      g_stkStart += 300;
121
122      sd_swstack = g_currthread->swstack;
123      sd_hwstack = g_currthread->hwstack;
124
125       #asm
126           ; Load new HW stack pointer, low first
127           OUT   SPL,R18
128           OUT   SPH,R19
129
130           ; Load new data stack pointer, low first
131           MOV         R28,R16
132           MOV         R29,R17
133       #endasm
134
135
136       // OUT SREG, R0      will enable interrupts, so CPU control will
137       // yield here to the other thread. It will return when control
138       // is switched back to the null thread.
139       #asm
140           POP      R0
141           OUT      SREG,R0
142           POP      R31
143           POP      R30
144           POP      R27
145           POP      R26
146           POP      R25
147           POP      R24
148           POP      R23
149           POP      R22
150           POP      R21
151           POP      R20
152           POP      R19
153           POP      R18
154           POP      R17
155           POP      R16
156           POP      R15
157           POP      R14
158           POP      R13
159           POP      R12
160           POP      R11
161           POP      R10
162           POP      R9
163           POP      R8
164           POP      R7
165           POP      R6
166           POP      R5
167           POP      R4
168           POP      R3
169           POP      R2
170           POP      R1
171           POP      R0
172
173           RETI
174       #endasm
175   }