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