PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
app_example.c
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #define ESOS_USE_IRQS
31 
32 // INCLUDEs go here (First include the main esos.h file)
33 // After that, the user can include what they need
34 #include "esos.h"
35 #ifdef __linux
36 #include "esos_pc.h"
37 #include "esos_pc_stdio.h"
38 #else
39 #include "esos_pic24.h"
40 #include "esos_pic24_rs232.h"
41 #endif
42 
43 // INCLUDE these so our printf and other PC hacks work
44 #include <stdio.h>
45 #include <sys/select.h>
46 #include <termios.h>
47 #include <unistd.h>
48 
49 // DEFINEs go here
50 
51 /*
52  * PROTOTYPEs go here
53  *
54  */
55 void reverseString(char *psz_s1, char *psz_s2);
56 uint32_t randomNumInRange(uint32_t u32_lo, uint32_t u32_hi);
57 
58 ESOS_USER_TASK(mailtaskA);
59 ESOS_USER_TASK(mailtaskAA);
60 ESOS_USER_TASK(mailtaskB);
61 ESOS_USER_TASK(mailtaskC);
62 ESOS_USER_TASK(mailtask0);
63 ESOS_USER_TASK(mailtask1);
64 ESOS_USER_TASK(mailtask2);
65 
66 ESOS_USER_TASK(mailtaskMSGA);
67 ESOS_USER_TASK(mailtaskMSG0);
68 ESOS_USER_TASK(mailtaskMSG1);
69 
70 // GLOBALs go here
71 // Generally, the user-created semaphores will be defined/allocated here
72 static uint8_t psz_CRNL[3]= {0x0D, 0x0A, 0};
73 
74 
75 // timer globals
76 uint32_t u32_myT1Count = 0;
77 uint8_t LED1 = TRUE;
78 uint8_t LED2 = TRUE;
79 
80 ESOS_SEMAPHORE(sem_BCanRun);
81 ESOS_SEMAPHORE(sem_CCanRun);
82 ESOS_SEMAPHORE(sem_mutex);
83 
84 struct stTask* pst_MyTasks[3];
85 
86 /*
87  * Simulate the timer ISR found on a MCU
88  * The PC doesn't have a timer ISR, so this task will periodically
89  * call the timer services callback instead.
90  * USED ONLY FOR DEVELOPMENT AND TESTING ON PC.
91  * Real MCU hardware doesn't need this task
92  */
93 ESOS_USER_TASK( __simulated_isr ) {
95  while (TRUE) {
96  // call the ESOS timer services callback just like a real H/W ISR would
97  __esos_tmrSvcsExecute();
99 
100  } // endof while(TRUE)
101  ESOS_TASK_END();
102 } // end child_task
103 
104 
105 /************************************************************************
106  * User supplied functions
107  ************************************************************************
108  */
109 
110 /*
111  * Returns a random number with a value between the two arguments.
112  *
113  * /todo Yes, I know this routine is cheesy. But, it works and
114  * I am in a really big hurry right now.
115  */
116 
117 uint32_t randomNumInRange(uint32_t u32_lo, uint32_t u32_hi) {
118  uint32_t u32_d1, u32_d2, u32_d4, u32_ret;
119  UINT32 U32_temp;
120 
121  while (TRUE) {
122  u32_d4 = esos_GetRandomUint32();
123  u32_ret = u32_lo + u32_d4;
124  if (u32_ret <= u32_hi) return u32_ret;
125 
126  U32_temp._uint32 = u32_d4;
127  u32_d2 = U32_temp.u16LoWord ^ U32_temp.u16HiWord;
128  u32_ret = u32_lo + u32_d2;
129  if (u32_ret <= u32_hi) return u32_ret;
130 
131  u32_d1 = U32_temp.u8LoLsb ^ U32_temp.u8LoMsb ^ U32_temp.u8HiLsb ^ U32_temp.u8HiMsb;
132  u32_ret = u32_lo + u32_d1;
133  if (u32_ret <= u32_hi) return u32_ret;
134  } //endwhile
135 } //end randomNumInRange
136 
137 
138 // user-created timer callback
139 ESOS_USER_TIMER( swTimerCounter ) {
140  u32_myT1Count++;
141 } //endof swTimerCounter
142 
143 // user-created timer callback
144 ESOS_USER_TIMER( swTimerLED ) {
145  LED2 = !LED2;
146  printf("\a");
147  fflush(stdout);
148 } //endof swTimerLED
149 
150 // user-created timer callback
151 ESOS_USER_TIMER( swTimerPrintA ) {
152  static uint32_t u32_cnt;
153 
154  printf("A:%d\n", u32_cnt++);
155  fflush(stdout);
156 } //endof swTimerPrintA
157 
158 ESOS_USER_TIMER( swTimerPrintB ) {
159  static uint32_t u32_cnt;
160 
161  printf("B:%d\n", u32_cnt++);
162  fflush(stdout);
163 } //endof swTimerPrintB
164 
165 ESOS_USER_TIMER( swTimerPrintC ) {
166  static uint32_t u32_cnt;
167 
168  printf("C:%d\n", u32_cnt++);
169  fflush(stdout);
170 } //endof swTimerPrintC
171 
172 /* ======================================
173  * Three tasks to run cooperatively.
174  * They used printf() since I want the routines
175  * to fit a screen. Plus, this is for the PC
176  * so we can tolerate printf()'s hugeness.
177  * ======================================
178  */
179 ESOS_USER_TASK( task1 ) {
180  uint32_t u32_rnd;
181 
182  ESOS_TASK_BEGIN();
183  while (TRUE) {
184  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
185  u32_rnd <<= 8;
186  printf("T1 (%d)\n", u32_rnd);
187  ESOS_TASK_WAIT_TICKS( u32_rnd);
188  } // endof while(TRUE)
189  ESOS_TASK_END();
190 } // end task1()
191 
192 ESOS_USER_TASK( task2 ) {
193  uint32_t u32_rnd;
194 
195  ESOS_TASK_BEGIN();
196  while (TRUE) {
197  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
198  u32_rnd <<= 9;
199  printf("T2 (%d)\n", u32_rnd);
200  ESOS_TASK_WAIT_TICKS( u32_rnd);
201  } // endof while(TRUE)
202  ESOS_TASK_END();
203 } // end task2()
204 
205 ESOS_USER_TASK( task3 ) {
206  uint32_t u32_rnd;
207 
208  ESOS_TASK_BEGIN();
209  while (TRUE) {
210  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
211  u32_rnd <<= 10;
212  printf("T3 (%d)\n", u32_rnd);
213  ESOS_TASK_WAIT_TICKS( u32_rnd);
214  } // endof while(TRUE)
215  ESOS_TASK_END();
216 } // end task3()
217 
218 /* ======================================
219  * Three tasks to run cooperatively.
220  * They used printf() since I want the routines
221  * to fit a screen. Plus, this is for the PC
222  * so we can tolerate printf()'s hugeness.
223  * ======================================
224  */
225 ESOS_USER_TASK( taskSemA ) {
226  uint32_t u32_rnd;
227  static u8_cnt;
228 
229  ESOS_TASK_BEGIN();
230  u8_cnt = 0;
231  while (TRUE) {
232  u8_cnt++;
233  if (u8_cnt == 10) {
234  ESOS_SIGNAL_SEMAPHORE( sem_BCanRun, 1 );
235  }
236  if (u8_cnt == 20) {
237  ESOS_SIGNAL_SEMAPHORE( sem_CCanRun, 1 );
238  }
239  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
240  u32_rnd <<= 7;
241  printf("taskSemA %d (%d)\n", u8_cnt, u32_rnd);
242  ESOS_TASK_WAIT_TICKS( u32_rnd);
243  } // endof while(TRUE)
244  ESOS_TASK_END();
245 } // end taskSemA()
246 
247 ESOS_USER_TASK( taskSemB ) {
248  uint32_t u32_rnd;
249  static u8_cnt;
250 
251  ESOS_TASK_BEGIN();
252  u8_cnt = 0;
253  ESOS_TASK_WAIT_SEMAPHORE( sem_BCanRun, 1 );
254  while (TRUE) {
255  u8_cnt++;
256  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
257  u32_rnd <<= 8;
258  printf("taskSemB %d (%d)\n", u8_cnt, u32_rnd);
259  ESOS_TASK_WAIT_TICKS( u32_rnd);
260  } // endof while(TRUE)
261  ESOS_TASK_END();
262 } // end taskSemB()
263 
264 ESOS_USER_TASK( taskSemC ) {
265  uint32_t u32_rnd;
266  static u8_cnt;
267 
268  ESOS_TASK_BEGIN();
269  u8_cnt = 0;
270  ESOS_TASK_WAIT_SEMAPHORE( sem_CCanRun, 1 );
271  while (TRUE) {
272  u8_cnt++;
273  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
274  u32_rnd <<= 8;
275  printf("taskSemC %d (%d)\n", u8_cnt, u32_rnd);
276  ESOS_TASK_WAIT_TICKS( u32_rnd);
277  } // endof while(TRUE)
278  ESOS_TASK_END();
279 } // end taskSemC()
280 
281 
282 ESOS_USER_TASK( taskMutexA ) {
283  uint32_t u32_rnd;
284  static u8_cnt;
285 
286  ESOS_TASK_BEGIN();
287  u8_cnt = 0;
288  while (TRUE) {
289  ESOS_TASK_WAIT_SEMAPHORE( sem_mutex, 1);
290  u8_cnt++;
291  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
292  u32_rnd <<= 8;
293  printf("taskMutexA %d (%d)\n", u8_cnt, u32_rnd);
294  ESOS_SIGNAL_SEMAPHORE( sem_mutex, 1);
295  ESOS_TASK_WAIT_TICKS( u32_rnd);
296  } // endof while(TRUE)
297  ESOS_TASK_END();
298 } // end taskMutexA()
299 
300 
301 ESOS_USER_TASK( taskMutexB ) {
302  uint32_t u32_rnd;
303  static u8_cnt;
304 
305  ESOS_TASK_BEGIN();
306  u8_cnt = 0;
307  while (TRUE) {
308  ESOS_TASK_WAIT_SEMAPHORE( sem_mutex, 1);
309  u8_cnt++;
310  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
311  u32_rnd <<= 8;
312  printf("taskMutexB %d (%d)\n", u8_cnt, u32_rnd);
313  ESOS_SIGNAL_SEMAPHORE( sem_mutex, 1);
314  ESOS_TASK_WAIT_TICKS( u32_rnd );
315  } // endof while(TRUE)
316  ESOS_TASK_END();
317 } // end taskMutexB()
318 
319 
320 /*
321  * A beeping/blinking ESOS task
322  *
323  * Downers to using a task..... Can't easily
324  * change the timer period. A S/W timer is
325  * a bit more flexible and more responsive.
326  * But, a S/W timer can wreak much more havoc
327  * than its task counterpart.
328  */
329 ESOS_USER_TASK( task_LED ) {
330  ESOS_TASK_BEGIN();
331  while (TRUE) {
332  LED2 = !LED2;
333  ESOS_TASK_WAIT_TICKS( 1000);
334  printf("\a");
335  fflush(stdout);
336  } // endof while(TRUE)
337  ESOS_TASK_END();
338 } // end upper_case()
339 
340 /*
341  * task to access and print the global variable
342  * incremented by SW/ timer. If the task were
343  * modify this variable, we'd need a semaphore.
344  * As it stands, this task only reads it, so we're
345  * safe.
346  */
347 ESOS_USER_TASK( query_swTmrCnt ) {
348  static uint8_t u8_char;
349 
350  ESOS_TASK_BEGIN();
351  while (TRUE) {
354  ESOS_TASK_WAIT_ON_GET_UINT8( u8_char );
356  if (u8_char == ' ') {
362  } //endif()
363  } // endof while(TRUE)
364  ESOS_TASK_END();
365 } // end upper_case()
366 
367 /*
368  * Read "in" stream and make it upper-case one
369  * character at a time.
370  */
371 ESOS_USER_TASK( upper_case ) {
372  static uint8_t u8_char;
373 
374  ESOS_TASK_BEGIN();
375  while (TRUE) {
378  ESOS_TASK_WAIT_ON_GET_UINT8( u8_char );
380  if ((u8_char >= 'a') && (u8_char <= 'z') )
381  u8_char = u8_char - 'a' + 'A';
386  } // endof while(TRUE)
387  ESOS_TASK_END();
388 } // end upper_case()
389 
390 /*
391  * Read "in" stream and make it upper-case the whole
392  * string at a time. The ESOS comm system will return
393  * an in-string to us when it hits a zero-terminator or
394  * a suitable return/linefeed character.
395  */
396 ESOS_USER_TASK( upper_case2 ) {
397  static uint8_t u8_i;
398  static uint8_t au8_x[257];
399  static uint8_t au8_y[257];
400 
401  ESOS_TASK_BEGIN();
402  while (TRUE) {
407  u8_i = 0;
408  while (TRUE) {
409  if ((au8_x[u8_i] >= 'a') && (au8_x[u8_i] <= 'z') )
410  au8_y[u8_i] = au8_x[u8_i] - 'a' + 'A';
411  else
412  au8_y[u8_i] = au8_x[u8_i];
413  if (au8_x[u8_i] == 0) break;
414  u8_i++;
415  }
420  } // endof while(TRUE)
421  ESOS_TASK_END();
422 } // end upper_case()
423 
424 /*
425  * Read "in" stream and reverses it
426  */
427 ESOS_USER_TASK( reverse_string ) {
428  static uint8_t u8_char;
429  static char sz_in[257];
430  static char sz_out[257];
431 
432  ESOS_TASK_BEGIN();
433  while (TRUE) {
438  reverseString( sz_in, sz_out );
444  } // endof while(TRUE)
445  ESOS_TASK_END();
446 } // end upper_case()
447 
448 /*
449  * Inputs a string, outputs the reverse. This file is used
450  * in three MPLAB projects:
451  * reverse_string.mcp - polled RX, TX I/O
452  * uartrx_fifo.mcp - interrupt RX, polled TX I/O
453  * uartrxtx_fifo.mcp - interrupt RX, interrupt TX I/O
454  * Interrupt RX inChar1() is selected by defining UART1_RX_INTERRUPT macro
455  * Interrupt TX outChar1() is selected by defining UART1_TX_INTERRUPT macro
456  * These macros are defined in their respective MPLAB projects.
457 */
458 void reverseString(char *psz_s1, char *psz_s2) {
459  char *psz_s1end;
460  if (!(*psz_s1)) {
461  *psz_s2 = 0; //psz_s1 is empty, return.
462  return;
463  }
464  psz_s1end = psz_s1;
465  //find end of first string
466  while (*psz_s1end) psz_s1end++;
467  psz_s1end--; //backup one to first non-zero byte
468  //now copy to S2 in reverse order
469  while (psz_s1end != psz_s1) {
470  *psz_s2 = *psz_s1end;
471  psz_s1end--;
472  psz_s2++;
473  }
474  //copy last byte
475  *psz_s2 = *psz_s1end;
476  psz_s2++;
477  //mark end of string
478  *psz_s2 = 0;
479 }
480 
481 /**********************************************************
482 **
483 ** a few tasks to send mail messages to each other
484 **
485 ************************************************************
486 */
487 ESOS_USER_TASK( mailtask0 ) {
488  uint32_t u32_rnd;
489  static uint8_t u8_cnt;
490  static ESOS_TASK_HANDLE hTask, hTask16, hTask32;
491 
492  ESOS_TASK_BEGIN();
493  u8_cnt=0;
494  hTask = esos_GetTaskHandle( mailtaskA );
495  hTask16 = esos_GetTaskHandle( mailtaskB );
496  hTask32 = esos_GetTaskHandle( mailtaskC );
497 
498  while (TRUE) {
499  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
500  u32_rnd <<= 8;
502  printf("T0 sending %d %d\n", u8_cnt, __pstSelf->u16_taskID);
503 
504  __esos_CB_WriteUINT8( hTask->pst_Mailbox->pst_CBuffer, u8_cnt );
505  // ESOS_TASK_WRITE_MAILBOX_BYTE(hTask, u8_cnt );
506 
507  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(hTask16, sizeof(uint16_t));
508  printf("T0 sending %d %d\n", 10000+u8_cnt, __pstSelf->u16_taskID);
509  __esos_CB_WriteUINT16( hTask16->pst_Mailbox->pst_CBuffer, 10000+u8_cnt );
510 
511  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(hTask32, sizeof(uint32_t));
512  printf("T0 sending %d %d\n", 1000000+u8_cnt, __pstSelf->u16_taskID);
513  __esos_CB_WriteUINT32( hTask32->pst_Mailbox->pst_CBuffer, 1000000+u8_cnt );
514 
515  u8_cnt++;
516  if (u8_cnt>50) u8_cnt=0;
517  ESOS_TASK_WAIT_TICKS( u32_rnd);
518  } // endof while(TRUE)
519  ESOS_TASK_END();
520 } // end mailtask0()
521 
522 
523 ESOS_USER_TASK( mailtask1 ) {
524  uint32_t u32_rnd;
525  static uint8_t u8_cnt;
526  static ESOS_TASK_HANDLE hTask, hTask16, hTask32;
527 
528  ESOS_TASK_BEGIN();
529  hTask = esos_GetTaskHandle( mailtaskA );
530  hTask16 = esos_GetTaskHandle( mailtaskB );
531  hTask32 = esos_GetTaskHandle( mailtaskC );
532 
533  u8_cnt = 0;
534  while (TRUE) {
535  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
536  u32_rnd <<= 8;
538  printf("T1 sending %d %d\n", 100+u8_cnt, __pstSelf->u16_taskID);
539 
540  __esos_CB_WriteUINT8(hTask->pst_Mailbox->pst_CBuffer, 100+u8_cnt );
541  // ESOS_TASK_WRITE_MAILBOX_BYTE(hTask, 100+u8_cnt );
542 
543  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(hTask16, sizeof(uint16_t));
544  printf("T1 sending %d %d\n", 20000+u8_cnt, __pstSelf->u16_taskID);
545  __esos_CB_WriteUINT16( hTask16->pst_Mailbox->pst_CBuffer, 20000+u8_cnt );
546 
547  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(hTask32, sizeof(uint32_t));
548  printf("T1 sending %d %d\n", 2000000+u8_cnt, __pstSelf->u16_taskID);
549  __esos_CB_WriteUINT32( hTask32->pst_Mailbox->pst_CBuffer, 2000000+u8_cnt );
550 
551  u8_cnt++;
552  if (u8_cnt>50) u8_cnt=0;
553  ESOS_TASK_WAIT_TICKS( u32_rnd);
554  } // endof while(TRUE)
555  ESOS_TASK_END();
556 } // end mailtask1()
557 
558 ESOS_USER_TASK( mailtask2 ) {
559  uint32_t u32_rnd;
560  static uint8_t u8_cnt;
561  static ESOS_TASK_HANDLE hTask, hTask16;
562 
563 
564  ESOS_TASK_BEGIN();
565  hTask = esos_GetTaskHandle( mailtaskA );
566  hTask16 = esos_GetTaskHandle (mailtaskB );
567  u8_cnt = 0;
568  while (TRUE) {
569  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
570  u32_rnd <<= 8;
572  printf("T2 sending %d %d\n", 200+u8_cnt, __pstSelf->u16_taskID);
573 
574  __esos_CB_WriteUINT8(hTask->pst_Mailbox->pst_CBuffer, 200+u8_cnt );
575  // ESOS_TASK_WRITE_MAILBOX_BYTE(hTask, 200+u8_cnt );
576 
577  ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(hTask16, sizeof(uint16_t));
578  printf("T2 sending %d %d\n", 30000+u8_cnt, __pstSelf->u16_taskID);
579  __esos_CB_WriteUINT16( hTask16->pst_Mailbox->pst_CBuffer, 30000+u8_cnt );
580 
581  //ESOS_TASK_WAIT_ON_TASKS_MAILBOX_HAS_AT_LEAST(esos_GetTaskHandle(mailtaskC), sizeof(uint32_t));
582  //printf("T2 sending %d %d\n", 3000000+u8_cnt, __pstSelf->u16_taskID);
583  //__esos_CB_WriteUINT32( esos_GetTaskHandle(mailtaskC)->pst_Mailbox->pst_CBuffer, 3000000+u8_cnt );
584 
585  u8_cnt++;
586  if (u8_cnt>50) u8_cnt=0;
587  ESOS_TASK_WAIT_TICKS( u32_rnd);
588  } // endof while(TRUE)
589  ESOS_TASK_END();
590 } // end mailtask2()
591 
592 //TASK that doesn't check mail very often
593 ESOS_USER_TASK( mailtaskA ) {
594  uint32_t u32_rnd;
595  uint8_t u8_x;
596  static uint8_t u8_cnt;
597 
598  ESOS_TASK_BEGIN();
599  while (TRUE) {
600  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
601  u32_rnd <<= 10;
602  ESOS_TASK_WAIT_TICKS( u32_rnd );
604  u8_cnt=0;
605  while ( ESOS_TASK_IVE_GOT_MAIL() ) {
606  u8_cnt++;
607 
608  u8_x = __esos_CB_ReadUINT8( __pstSelf->pst_Mailbox->pst_CBuffer );
609  //u8_x = __esos_ReadMailboxUINT8( __pstSelf->pst_Mailbox );
610 
611  if (TRUE) {
612  printf("mailtaskA got mail.... %3d %d\n", u8_x, __pstSelf->pst_Mailbox->pst_CBuffer->u16_Count);
613  } else {
614  printf("mailtaskA got mail.... %3d %d\n", u8_x, u8_cnt);
615  } //endif
616  } //endof while()
617  } // endof while(TRUE)
618  ESOS_TASK_END();
619 } // end mailtaskA()
620 
621 //TASK that does nothing but repeatedly check its mailbox
622 ESOS_USER_TASK( mailtaskAA ) {
623  uint32_t u32_rnd;
624  uint8_t u8_x;
625 
626  ESOS_TASK_BEGIN();
627  while (TRUE) {
629 
630  u8_x = __esos_CB_ReadUINT8( __pstSelf->pst_Mailbox->pst_CBuffer );
631  // u8_x = __esos_ReadMailboxUINT8( __pstSelf->pst_Mailbox );
632 
633  printf("mailtaskAA got mail.... %d\n", u8_x);
634  } // endof while(TRUE)
635  ESOS_TASK_END();
636 } // end mailtaskAA()
637 
638 //TASK that does nothing but repeatedly check its mailbox
639 ESOS_USER_TASK( mailtaskB ) {
640  uint32_t u32_rnd;
641  uint8_t u8_x;
642  uint16_t u16_x;
643 
644  ESOS_TASK_BEGIN();
645  while (TRUE) {
647 
648  u16_x = __esos_CB_ReadUINT16( __pstSelf->pst_Mailbox->pst_CBuffer );
649  printf("mailtaskB got mail.... %d\n", u16_x);
650  } // endof while(TRUE)
651  ESOS_TASK_END();
652 } // end mailtaskB()
653 
654 //TASK that does nothing but repeatedly check its mailbox
655 ESOS_USER_TASK( mailtaskC ) {
656  uint32_t u32_x;
657  uint8_t u8_x;
658 
659  ESOS_TASK_BEGIN();
660  while (TRUE) {
662 
663  u32_x = __esos_CB_ReadUINT32( __pstSelf->pst_Mailbox->pst_CBuffer );
664  printf("mailtaskC got mail.... %d\n", u32_x);
665  ESOS_TASK_WAIT_TICKS( 1000 );
666 
667  } // endof while(TRUE)
668  ESOS_TASK_END();
669 } // end mailtaskC()
670 
671 ESOS_USER_TASK( mailtaskMSG0 ) {
672  uint32_t u32_rnd;
673  static uint8_t u8_cnt;
674  static ESOS_TASK_HANDLE hTask, hTask16, hTask32;
675  static MAILMESSAGE st_Message;
676 
677  ESOS_TASK_BEGIN();
678  u8_cnt=0;
679  hTask = esos_GetTaskHandle( mailtaskMSGA );
680 
681  while (TRUE) {
682  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
683  u32_rnd <<= 8;
684 
685  ESOS_TASK_MAKE_MSG_UINT8(st_Message, u8_cnt);
686  /* create a random (50-50) message that wants ACK */
687  if ( (u8_cnt % 5) ==0 ) {
688  st_Message.u8_flags |= ESOS_MAILMESSAGE_REQUEST_ACK;
689  }
691  if (st_Message.u8_flags & ESOS_MAILMESSAGE_REQUEST_ACK) {
692  printf("T0 sending MESSAGE with ACK request %3d\n", u8_cnt);
693  ESOS_TASK_SEND_MESSAGE_WAIT_DELIVERY(hTask, &st_Message);
694  } else {
695  printf("T0 sending MESSAGE %3d\n", u8_cnt);
696  ESOS_TASK_SEND_MESSAGE(hTask, &st_Message);
697  ESOS_TASK_WAIT_TICKS( u32_rnd);
698  }
699  u8_cnt++;
700  if (u8_cnt>=100) u8_cnt=0;
701  } // endof while(TRUE)
702  ESOS_TASK_END();
703 } // end mailtaskMSG0()
704 
705 ESOS_USER_TASK( mailtaskMSG1 ) {
706  uint32_t u32_rnd;
707  static uint8_t u8_cnt;
708  static ESOS_TASK_HANDLE hTask, hTask16, hTask32;
709  static MAILMESSAGE st_Message;
710 
711  ESOS_TASK_BEGIN();
712  u8_cnt=100;
713  hTask = esos_GetTaskHandle( mailtaskMSGA );
714 
715  while (TRUE) {
716  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
717  u32_rnd <<= 7;
718 
719  ESOS_TASK_MAKE_MSG_UINT8(st_Message, u8_cnt);
720  /* create a random (50-50) message that wants ACK */
721  if ( (u8_cnt % 3) ==0 ) {
722  st_Message.u8_flags |= ESOS_MAILMESSAGE_REQUEST_ACK;
723  }
725  if (st_Message.u8_flags & ESOS_MAILMESSAGE_REQUEST_ACK) {
726  printf("T1 sending MESSAGE with ACK request %3d\n", u8_cnt);
727  ESOS_TASK_SEND_MESSAGE_WAIT_DELIVERY(hTask, &st_Message);
728  } else {
729  printf("T1 sending MESSAGE %3d\n", u8_cnt );
730  ESOS_TASK_SEND_MESSAGE(hTask, &st_Message);
731  ESOS_TASK_WAIT_TICKS( u32_rnd);
732  }
733  u8_cnt++;
734  if (u8_cnt>=200) u8_cnt=100;
735  } // endof while(TRUE)
736  ESOS_TASK_END();
737 } // end mailtaskMSG1()
738 
739 
740 //TASK that doesn't check mail very often
741 ESOS_USER_TASK( mailtaskMSGA ) {
742  uint32_t u32_rnd;
743  uint8_t u8_x;
744  static uint8_t u8_cnt;
745  static MAILMESSAGE stMsg;
746  static ESOS_TASK_HANDLE hMSG0, hMSG1;
747 
748  ESOS_TASK_BEGIN();
749  hMSG0 = esos_GetTaskHandle(mailtaskMSG0);
750  hMSG1 = esos_GetTaskHandle(mailtaskMSG1);
751  while (TRUE) {
752  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
753  u32_rnd <<= 10;
754  ESOS_TASK_WAIT_TICKS( u32_rnd );
756  u8_cnt=0;
757  while ( ESOS_TASK_IVE_GOT_MAIL() ) {
758  __esos_ReadMailMessage(__pstSelf, &stMsg );
759  //PRINTF_MESSAGE( stMsg);
760  printf("Got a message from ");
761  if ( ESOS_IS_TASK_SENDER( hMSG0, stMsg) ) {
762  printf("mailtaskMSG0");
763  } else if ( ESOS_IS_TASK_SENDER(hMSG1, stMsg) ) {
764  printf("mailtaskMSG1");
765  } else {
766  printf("UNKNOWN");
767  }
768  printf (" containing %3d delivery time = %d ms\n", stMsg.au8_Contents[0], esos_GetSystemTick()-stMsg.u32_Postmark );
769  } //endof while()
770  } // endof while(TRUE)
771  ESOS_TASK_END();
772 } // end mailtaskMSGA()
773 
774 
775 
776 /******************************************************************************
777  * Function: void user_init(void)
778  *
779  * PreCondition: None
780  *
781  * Input: None
782  *
783  * Output: None
784  *
785  * Side Effects: None
786  *
787  * Overview: user_init is a centralized initialization routine where
788  * the user can setup their application. It is called
789  * automagically by ES_OS during the operating system
790  * initialization.
791  *
792  * Note: The user should set up any state machines and init
793  * all application variables. They can also turn on
794  * any needed peripherals here.
795  *
796  * The user SHALL NOT mess with the interrupt hardware
797  * directly!!! The ES_OS must be aware of the interrupts
798  * and provides osXXXXXXX functions for the user to use.
799  * Using these ES_OS-provided functions, the user may
800  * (and probably should) initialize, register, and enable
801  * interrupts in this routine.
802  *
803  * Furthermore, the user should register AT LEAST one
804  * user application task here (via esos_RegisterTask) or
805  * the ES_OS scheduler will have nothing to schedule
806  * to run when this function returns.
807  *
808  *****************************************************************************/
809 void user_init(void) {
810  uint16_t* pu16_ptr;
811  uint16_t u16_junk;
812  ESOS_TMR_HANDLE tmrhnd_t1,tmrhnd_t2,tmrhnd_t3;
813 
814  __esos_unsafe_PutString( HELLO_MSG );
815 
816  /*
817  * Now, let's get down and dirty with ESOS and our user tasks
818  *
819  * Once tasks are registered, they will start executing in
820  * the ESOS scheduler.
821  */
822 
823  // register our little ESOS task to mimic MCU's TIMER T1 IRQ which kicks off
824  // the ESOS S/W timers when they expire
825  esos_RegisterTask( __simulated_isr );
826 
827  /* ====================================================================
828  * REGISTER SOME USER TASKS
829  * ====================================================================
830  */
831 
832 
833 // here are several combinations of tasks that should work together
834 #if 0
835  esos_RegisterTask( upper_case );
836 #endif
837 #if 0
838  tmrhnd_t1 = esos_RegisterTimer( swTimerLED, 500 );
839 #endif
840 #if 0
841  esos_RegisterTask( upper_case );
842  tmrhnd_t1 = esos_RegisterTimer( swTimerLED, 500 );
843 #endif
844 #if 0
845  esos_RegisterTask( query_swTmrCnt );
846  tmrhnd_t1 = esos_RegisterTimer( swTimerLED, 500 );
847  tmrhnd_t2 = esos_RegisterTimer( swTimerCounter, 10 );
848 #endif
849 #if 0
850  esos_RegisterTask( upper_case2 );
851  tmrhnd_t1 = esos_RegisterTimer( swTimerLED, 1000 );
852 #endif
853 #if 0
854  esos_RegisterTask( reverse_string );
855  tmrhnd_t1 = esos_RegisterTimer( swTimerLED, 1000 );
856 #endif
857 #if 0
858  esos_RegisterTimer( swTimerLED, 1000 );
859  esos_RegisterTask( task1 );
860  esos_RegisterTask( task2 );
861  esos_RegisterTask( task3 );
862 #endif
863 #if 0
864  esos_RegisterTask( reverse_string );
865  esos_RegisterTask( task_LED );
866 #endif
867 #if 0
868  esos_RegisterTask( upper_case2 );
869  esos_RegisterTask( task_LED );
870  tmrhnd_t1 = esos_RegisterTimer( swTimerPrintA, 400 );
871  tmrhnd_t2 = esos_RegisterTimer( swTimerPrintB, 500 );
872  tmrhnd_t3 = esos_RegisterTimer( swTimerPrintC, 750 );
873 #endif
874 
875 // The whole enchilada! Well, maybe not a whole one, but a big one!
876 #if 0
877  esos_RegisterTask( query_swTmrCnt );
878  esos_RegisterTimer( swTimerCounter, 10 );
879  esos_RegisterTimer( swTimerLED, 1000 );
880  tmrhnd_t1 = esos_RegisterTimer( swTimerPrintA, 400 );
881  tmrhnd_t2 = esos_RegisterTimer( swTimerPrintB, 500 );
882  tmrhnd_t3 = esos_RegisterTimer( swTimerPrintC, 750 );
883  esos_RegisterTask( task1 );
884  esos_RegisterTask( task2 );
885  esos_RegisterTask( task3 );
886 #endif
887 
888 // Another big enchilada
889 #if 0
890  esos_RegisterTask( reverse_string );
891  esos_RegisterTimer( swTimerLED, 1000 );
892  tmrhnd_t1 = esos_RegisterTimer( swTimerPrintA, 400 );
893  tmrhnd_t2 = esos_RegisterTimer( swTimerPrintB, 500 );
894  tmrhnd_t3 = esos_RegisterTimer( swTimerPrintC, 750 );
895  esos_RegisterTask( task1 );
896  esos_RegisterTask( task2 );
897  esos_RegisterTask( task3 );
898 #endif
899 
900 #if 0
901  ESOS_INIT_SEMAPHORE(sem_BCanRun, 0);
902  ESOS_INIT_SEMAPHORE(sem_CCanRun, 0);
903  esos_RegisterTask( taskSemA );
904  esos_RegisterTask( taskSemB );
905  esos_RegisterTask( taskSemC );
906 #endif
907 
908 #if 0
909  // test code based on mutex semaphore problem
910  // described by Jeff Brantley
911  ESOS_INIT_SEMAPHORE(sem_mutex, 1);
912  esos_RegisterTask( taskMutexA );
913  esos_RegisterTask( taskMutexB );
914 #endif
915 
916 #if 0
917  esos_RegisterTimer( swTimerLED, 1000 );
918  esos_RegisterTask( mailtaskA );
919  esos_RegisterTask( mailtaskAA );
920  esos_RegisterTask( mailtaskB );
921  esos_RegisterTask( mailtaskC );
922  esos_RegisterTask( mailtask0 );
923  esos_RegisterTask( mailtask1 );
924  esos_RegisterTask( mailtask2 );
925 #endif
926 
927 #if 1
928  //esos_RegisterTimer( swTimerLED, 1000 );
929  esos_RegisterTask( mailtaskMSGA );
930  esos_RegisterTask( mailtaskMSG0 );
931  esos_RegisterTask( mailtaskMSG1 );
932 #endif
933 
934 
935 } // end user_init()