FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/nucleus/demo/demo.c @ 143:afceeeb2cba1
Our nuc-fw is destined to become gsm-fw, so I went ahead and did the big hg mv
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Tue, 12 Nov 2013 05:35:48 +0000 |
parents | nuc-fw/nucleus/demo/demo.c@85994b210f6a |
children |
comparison
equal
deleted
inserted
replaced
142:15d5977390c2 | 143:afceeeb2cba1 |
---|---|
1 /* Include Nucleus C-Library file */ | |
2 //#include "ncl\inc\nu_ncl.h" | |
3 | |
4 /* Include necessary Nucleus PLUS files. */ | |
5 #include "nucleus.h" | |
6 | |
7 /* Define serial output/input functionality. To disable serial I/O, | |
8 replace NU_TRUE with NU_FALSE */ | |
9 | |
10 #define NU_SERIAL_OUTPUT NU_TRUE | |
11 #define NU_SERIAL_INPUT NU_TRUE | |
12 | |
13 #if (NU_SERIAL_OUTPUT) | |
14 #include "nu_sd.h" /* Nucleus Serial Driver interface */ | |
15 #endif | |
16 | |
17 /* Define Application data structures. */ | |
18 | |
19 NU_TASK Task_0; | |
20 NU_TASK Task_1; | |
21 NU_TASK Task_2; | |
22 NU_TASK Task_3; | |
23 NU_TASK Task_4; | |
24 NU_TASK Task_5; | |
25 NU_QUEUE Queue_0; | |
26 NU_SEMAPHORE Semaphore_0; | |
27 NU_EVENT_GROUP Event_Group_0; | |
28 NU_MEMORY_POOL System_Memory; | |
29 | |
30 | |
31 /* Allocate global counters. */ | |
32 UNSIGNED Task_Time; | |
33 UNSIGNED Task_2_messages_received; | |
34 UNSIGNED Task_2_invalid_messages; | |
35 UNSIGNED Task_1_messages_sent; | |
36 NU_TASK *Who_has_the_resource; | |
37 UNSIGNED Event_Detections; | |
38 | |
39 #if (NU_SERIAL_OUTPUT) | |
40 NU_SERIAL_PORT port; | |
41 #endif | |
42 | |
43 #ifdef NU_FIQ_DEMO | |
44 UINT32 FIQ_Count; | |
45 #endif | |
46 | |
47 extern UNSIGNED TMD_System_Clock; | |
48 | |
49 /* Define prototypes for function references. */ | |
50 VOID task_0(UNSIGNED argc, VOID *argv); | |
51 VOID task_1(UNSIGNED argc, VOID *argv); | |
52 VOID task_2(UNSIGNED argc, VOID *argv); | |
53 VOID task_3_and_4(UNSIGNED argc, VOID *argv); | |
54 VOID task_5(UNSIGNED argc, VOID *argv); | |
55 CHAR buffer[12]; /* temp buffer for Itoa conversion */ | |
56 INT n; /* strlen */ | |
57 | |
58 | |
59 | |
60 /* Define the Application_Initialize routine that determines the initial | |
61 Nucleus PLUS application environment. */ | |
62 | |
63 void Application_Initialize(void *first_available_memory) | |
64 { | |
65 | |
66 VOID *pointer; | |
67 STATUS status; | |
68 | |
69 /* Create a system memory pool that will be used to allocate task stacks, | |
70 queue areas, etc. */ | |
71 status = NU_Create_Memory_Pool(&System_Memory, "SYSMEM", | |
72 first_available_memory, 25000, 50, NU_FIFO); | |
73 if (status != NU_SUCCESS) | |
74 { | |
75 ERC_System_Error(status); | |
76 } | |
77 | |
78 /* Create each task in the system. */ | |
79 | |
80 /* Create task 0. */ | |
81 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
82 status = NU_Create_Task(&Task_0, "TASK 0", task_0, 0, NU_NULL, pointer, 2000, 1, 20, | |
83 NU_PREEMPT, NU_START); | |
84 if (status != NU_SUCCESS) | |
85 { | |
86 ERC_System_Error(status); | |
87 } | |
88 | |
89 /* Create task 1. */ | |
90 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
91 status = NU_Create_Task(&Task_1, "TASK 1", task_1, 0, NU_NULL, pointer, 2000, 10, 5, | |
92 NU_PREEMPT, NU_START); | |
93 if (status != NU_SUCCESS) | |
94 { | |
95 ERC_System_Error(status); | |
96 } | |
97 | |
98 /* Create task 2. */ | |
99 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
100 status = NU_Create_Task(&Task_2, "TASK 2", task_2, 0, NU_NULL, pointer, 2000, 10, 5, | |
101 NU_PREEMPT, NU_START); | |
102 if (status != NU_SUCCESS) | |
103 { | |
104 ERC_System_Error(status); | |
105 } | |
106 | |
107 /* Create task 3. Note that task 4 uses the same instruction area. */ | |
108 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
109 status = NU_Create_Task(&Task_3, "TASK 3", task_3_and_4, 0, NU_NULL, pointer, | |
110 2000, 5, 0, NU_PREEMPT, NU_START); | |
111 if (status != NU_SUCCESS) | |
112 { | |
113 ERC_System_Error(status); | |
114 } | |
115 | |
116 /* Create task 4. Note that task 3 uses the same instruction area. */ | |
117 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
118 status = NU_Create_Task(&Task_4, "TASK 4", task_3_and_4, 0, NU_NULL, pointer, | |
119 2000, 5, 0, NU_PREEMPT, NU_START); | |
120 if (status != NU_SUCCESS) | |
121 { | |
122 ERC_System_Error(status); | |
123 } | |
124 | |
125 /* Create task 5. */ | |
126 NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND); | |
127 status = NU_Create_Task(&Task_5, "TASK 5", task_5, 0, NU_NULL, pointer, 2000, 7, 0, | |
128 NU_PREEMPT, NU_START); | |
129 if (status != NU_SUCCESS) | |
130 { | |
131 ERC_System_Error(status); | |
132 } | |
133 | |
134 | |
135 /* Create communication queue. */ | |
136 NU_Allocate_Memory(&System_Memory, &pointer, 100*sizeof(UNSIGNED), | |
137 NU_NO_SUSPEND); | |
138 status = NU_Create_Queue(&Queue_0, "QUEUE 0", pointer, 100, NU_FIXED_SIZE, 1, | |
139 NU_FIFO); | |
140 if (status != NU_SUCCESS) | |
141 { | |
142 ERC_System_Error(status); | |
143 } | |
144 | |
145 /* Create synchronization semaphore. */ | |
146 status = NU_Create_Semaphore(&Semaphore_0, "SEM 0", 1, NU_FIFO); | |
147 if (status != NU_SUCCESS) | |
148 { | |
149 ERC_System_Error(status); | |
150 } | |
151 | |
152 /* Create event flag group. */ | |
153 status = NU_Create_Event_Group(&Event_Group_0, "EVGROUP0"); | |
154 if (status != NU_SUCCESS) | |
155 { | |
156 ERC_System_Error(status); | |
157 } | |
158 | |
159 | |
160 } | |
161 | |
162 /* Define the system timer task. More complicated systems might use a | |
163 routine like this to perform periodic message sending and other time | |
164 oriented functions. */ | |
165 | |
166 | |
167 void task_0(UNSIGNED argc, VOID *argv) | |
168 { | |
169 | |
170 STATUS status; | |
171 | |
172 | |
173 #if (NU_SERIAL_OUTPUT) | |
174 CHAR msg[40]; | |
175 INT i; | |
176 | |
177 CHAR ch; | |
178 #endif /* NU_SERIAL_OUTPUT */ | |
179 | |
180 | |
181 #if (NU_SERIAL_OUTPUT) | |
182 /* Init the serial port. */ | |
183 port.com_port = DEFAULT_UART_PORT; | |
184 port.baud_rate = DEFAULT_UART_BAUD; | |
185 port.data_bits = DEFAULT_UART_DATA; | |
186 port.stop_bits = DEFAULT_UART_STOP; | |
187 port.parity = DEFAULT_UART_PARITY; | |
188 port.data_mode = DEFAULT_UART_MODE; | |
189 port.communication_mode = SERIAL_MODE; | |
190 port.sd_buffer_size = DEFAULT_UART_BUFFER; | |
191 | |
192 status = NU_SD_Init_Port (&port); | |
193 if (status != NU_SUCCESS) | |
194 { | |
195 ERC_System_Error(status); | |
196 } | |
197 | |
198 #endif /* NU_SERIAL_OUTPUT */ | |
199 | |
200 | |
201 /* Access argc and argv just to avoid compilation warnings. */ | |
202 status = (STATUS) argc + (STATUS) argv; | |
203 | |
204 /* Set the clock to 0. This clock ticks every 18 system timer ticks. */ | |
205 Task_Time = 0; | |
206 | |
207 while(1) | |
208 { | |
209 | |
210 /* Sleep for 100 timer ticks. The value of the tick is programmable | |
211 in INT.S and is relative to the speed of the target system. */ | |
212 NU_Sleep(100); | |
213 | |
214 #if (NU_SERIAL_OUTPUT) | |
215 NU_SD_Put_String("\n\r****************************************", &port); | |
216 NU_SD_Put_String("***************************************\n\r", &port); | |
217 NU_SD_Put_String(NU_Release_Information(), &port); | |
218 NU_SD_Put_String("\n\r", &port); | |
219 | |
220 NU_SD_Put_String("****************************************", &port); | |
221 NU_SD_Put_String("***************************************\n\n\r", &port); | |
222 NU_SD_Put_String("System Variable Status: \n\n\r", &port); | |
223 | |
224 strcpy(msg, "Task 0 time: "); | |
225 sprintf(buffer, "%lu", Task_Time); | |
226 n = strlen(buffer); | |
227 if (n>=8) | |
228 { | |
229 strcat(msg, buffer); | |
230 strcat(msg, "\n\r"); | |
231 } | |
232 else | |
233 { | |
234 for (i=0;i<(8-n);i++) | |
235 strcat(msg, " "); | |
236 strcat(msg, buffer); | |
237 strcat(msg, "\n\r"); | |
238 } | |
239 | |
240 NU_SD_Put_String(msg, &port); | |
241 | |
242 strcpy(msg, "Event detections: "); | |
243 sprintf(buffer, "%lu", Event_Detections); | |
244 n = strlen(buffer); | |
245 if (n>=8) | |
246 { | |
247 strcat(msg, buffer); | |
248 strcat(msg, "\n\n\n\r"); | |
249 } | |
250 else | |
251 { | |
252 for (i=0;i<(8-n);i++) | |
253 strcat(msg, " "); | |
254 strcat(msg, buffer); | |
255 strcat(msg, "\n\n\n\r"); | |
256 } | |
257 | |
258 NU_SD_Put_String(msg, &port); | |
259 | |
260 strcpy(msg, "Task 1 messages sent: "); | |
261 sprintf(buffer, "%lu", Task_1_messages_sent); | |
262 n = strlen(buffer); | |
263 if (n>=8) | |
264 { | |
265 strcat(msg, buffer); | |
266 strcat(msg, "\n\r"); | |
267 } | |
268 else | |
269 { | |
270 for (i=0;i<(8-n);i++) | |
271 strcat(msg, " "); | |
272 strcat(msg, buffer); | |
273 strcat(msg, "\n\r"); | |
274 } | |
275 | |
276 NU_SD_Put_String(msg, &port); | |
277 | |
278 strcpy(msg, "Task 2 messages received: "); | |
279 sprintf(buffer, "%lu", Task_2_messages_received); | |
280 n = strlen(buffer); | |
281 if (n>=8) | |
282 { | |
283 strcat(msg, buffer); | |
284 strcat(msg, "\n\n\r"); | |
285 } | |
286 else | |
287 { | |
288 for (i=0;i<(8-n);i++) | |
289 strcat(msg, " "); | |
290 strcat(msg, buffer); | |
291 strcat(msg, "\n\n\r"); | |
292 } | |
293 | |
294 NU_SD_Put_String(msg, &port); | |
295 | |
296 strcpy(msg, "Task 2 invalid messages: "); | |
297 sprintf(buffer, "%lu", Task_2_invalid_messages); | |
298 n = strlen(buffer); | |
299 if (n>=8) | |
300 { | |
301 strcat(msg, buffer); | |
302 strcat(msg, "\n\n\r"); | |
303 } | |
304 else | |
305 { | |
306 for (i=0;i<(8-n);i++) | |
307 strcat(msg, " "); | |
308 strcat(msg, buffer); | |
309 strcat(msg, "\n\n\r"); | |
310 } | |
311 | |
312 NU_SD_Put_String(msg, &port); | |
313 | |
314 if (Who_has_the_resource == &Task_3) | |
315 NU_SD_Put_String("Who has the resource: Task 3", &port); | |
316 else if (Who_has_the_resource == &Task_4) | |
317 NU_SD_Put_String("Who has the resource: Task 4", &port); | |
318 else | |
319 NU_SD_Put_String("Who has the resource: Nobody", &port); | |
320 NU_SD_Put_String("\n\n\n\r", &port); | |
321 | |
322 strcpy(msg, "Timer Interrupts: "); | |
323 sprintf(buffer, "%lu", TMD_System_Clock); | |
324 n = strlen(buffer); | |
325 if (n>=8) | |
326 { | |
327 strcat(msg, buffer); | |
328 strcat(msg, "\n\n\r"); | |
329 } | |
330 else | |
331 { | |
332 for (i=0;i<(8-n);i++) | |
333 strcat(msg, " "); | |
334 strcat(msg, buffer); | |
335 strcat(msg, "\n\n\r"); | |
336 } | |
337 | |
338 NU_SD_Put_String(msg, &port); | |
339 | |
340 NU_SD_Put_String("Buffer: ", &port); | |
341 | |
342 #if (NU_SERIAL_INPUT) | |
343 while (NU_SD_Data_Ready(&port)) | |
344 { | |
345 ch = NU_SD_Get_Char(&port); | |
346 NU_SD_Put_Char(ch, &port); | |
347 } | |
348 #endif /* NU_SERIAL_INPUT */ | |
349 | |
350 | |
351 NU_SD_Put_String("\n\n\r", &port); | |
352 | |
353 | |
354 #endif /* NU_SERIAL_OUTPUT */ | |
355 /* Increment the time. */ | |
356 Task_Time++; | |
357 | |
358 /* Set an event flag to lift the suspension on task 5. */ | |
359 status = NU_Set_Events(&Event_Group_0, 1, NU_OR); | |
360 | |
361 } | |
362 | |
363 } | |
364 | |
365 | |
366 /* Define the queue sending task. Note that the only things that cause | |
367 this task to suspend are queue full conditions and the time slice | |
368 specified in the configuration file. */ | |
369 | |
370 void task_1(UNSIGNED argc, VOID *argv) | |
371 { | |
372 | |
373 STATUS status; | |
374 UNSIGNED Send_Message; | |
375 | |
376 /* Access argc and argv just to avoid compilation warnings. */ | |
377 status = (STATUS) argc + (STATUS) argv; | |
378 | |
379 /* Initialize the message counter. */ | |
380 Task_1_messages_sent = 0; | |
381 | |
382 /* Initialize the message contents. The receiver will examine the | |
383 message contents for errors. */ | |
384 Send_Message = 0; | |
385 | |
386 while(1) | |
387 { | |
388 | |
389 /* Send the message to Queue_0, which task 2 reads from. Note | |
390 that if the destination queue fills up this task suspends until | |
391 room becomes available. */ | |
392 status = NU_Send_To_Queue(&Queue_0, &Send_Message, 1, NU_SUSPEND); | |
393 | |
394 /* Determine if the message was sent successfully. */ | |
395 if (status == NU_SUCCESS) | |
396 Task_1_messages_sent++; | |
397 | |
398 /* Modify the contents of the next message to send. */ | |
399 Send_Message++; | |
400 } | |
401 } | |
402 | |
403 | |
404 /* Define the queue receiving task. Note that the only things that cause | |
405 this task to suspend are queue empty conditions and the time slice | |
406 specified in the configuration file. */ | |
407 | |
408 void task_2(UNSIGNED argc, VOID *argv) | |
409 { | |
410 | |
411 STATUS status; | |
412 UNSIGNED Receive_Message; | |
413 UNSIGNED received_size; | |
414 UNSIGNED message_expected; | |
415 | |
416 /* Access argc and argv just to avoid compilation warnings. */ | |
417 status = (STATUS) argc + (STATUS) argv; | |
418 | |
419 /* Initialize the message counter. */ | |
420 Task_2_messages_received = 0; | |
421 | |
422 /* Initialize the message error counter. */ | |
423 Task_2_invalid_messages = 0; | |
424 | |
425 /* Initialize the message contents to expect. */ | |
426 message_expected = 0; | |
427 | |
428 while(1) | |
429 { | |
430 | |
431 /* Retrieve a message from Queue_0, which task 1 writes to. Note | |
432 that if the source queue is empty this task suspends until | |
433 something becomes available. */ | |
434 status = NU_Receive_From_Queue(&Queue_0, &Receive_Message, 1, | |
435 &received_size, NU_SUSPEND); | |
436 | |
437 /* Determine if the message was received successfully. */ | |
438 if (status == NU_SUCCESS) | |
439 Task_2_messages_received++; | |
440 | |
441 /* Check the contents of the message against what this task | |
442 is expecting. */ | |
443 if ((received_size != 1) || | |
444 (Receive_Message != message_expected)) | |
445 Task_2_invalid_messages++; | |
446 | |
447 /* Modify the expected contents of the next message. */ | |
448 message_expected++; | |
449 } | |
450 } | |
451 | |
452 | |
453 /* Tasks 3 and 4 want a single resource. Once one of the tasks gets the | |
454 resource, it keeps it for 100 clock ticks before releasing it. During | |
455 this time the other task suspends waiting for the resource. Note that | |
456 both task 3 and 4 use the same instruction areas but have different | |
457 stacks. */ | |
458 | |
459 void task_3_and_4(UNSIGNED argc, VOID *argv) | |
460 { | |
461 | |
462 STATUS status; | |
463 | |
464 /* Access argc and argv just to avoid compilation warnings. */ | |
465 status = (STATUS) argc + (STATUS) argv; | |
466 | |
467 /* Loop to allocate and deallocate the resource. */ | |
468 while(1) | |
469 { | |
470 | |
471 /* Allocate the resource. Suspend until it becomes available. */ | |
472 status = NU_Obtain_Semaphore(&Semaphore_0, NU_SUSPEND); | |
473 | |
474 /* If the status is successful, show that this task owns the | |
475 resource. */ | |
476 if (status == NU_SUCCESS) | |
477 { | |
478 | |
479 Who_has_the_resource = NU_Current_Task_Pointer(); | |
480 | |
481 /* Sleep for 100 ticks to cause the other task to suspend on | |
482 the resource. */ | |
483 NU_Sleep(100); | |
484 | |
485 /* Release the semaphore. */ | |
486 NU_Release_Semaphore(&Semaphore_0); | |
487 } | |
488 } | |
489 } | |
490 | |
491 | |
492 /* Define the task that waits for the event to be set by task 0. */ | |
493 | |
494 void task_5(UNSIGNED argc, VOID *argv) | |
495 { | |
496 | |
497 STATUS status; | |
498 UNSIGNED event_group; | |
499 | |
500 /* Access argc and argv just to avoid compilation warnings. */ | |
501 status = (STATUS) argc + (STATUS) argv; | |
502 | |
503 /* Initialize the event detection counter. */ | |
504 Event_Detections = 0; | |
505 | |
506 /* Continue this process forever. */ | |
507 while(1) | |
508 { | |
509 /* Wait for an event and consume it. */ | |
510 status = NU_Retrieve_Events(&Event_Group_0, 1, NU_OR_CONSUME, | |
511 &event_group, NU_SUSPEND); | |
512 | |
513 /* If the status is okay, increment the counter. */ | |
514 if (status == NU_SUCCESS) | |
515 { | |
516 Event_Detections++; | |
517 | |
518 } | |
519 } | |
520 } | |
521 | |
522 | |
523 #ifdef NU_FIQ_DEMO | |
524 void FIQ_LISR(VOID) | |
525 { | |
526 FIQ_Count++; | |
527 } | |
528 #endif | |
529 | |
530 |