ESOS32
ESOSOn32-bitProcessors
app_timer.c
Go to the documentation of this file.
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 #include "esos_pc.h"
34 #include "esos_pc_stdio.h"
35 
36 #include <stdio.h>
37 #include <sys/select.h>
38 #include <termios.h>
39 #include <unistd.h>
40 
41 
42 
43 // DEFINEs go here
44 
45 /*
46  * PROTOTYPEs go here
47  *
48  */
49 uint32_t randomNumInRange(uint32_t u32_lo, uint32_t u32_hi);
50 
51 
52 // GLOBALs go here
53 // Generally, the user-created semaphores will be defined/allocated here
54 volatile uint32_t u32_T2Count;
55 volatile uint32_t u32_T3Count;
56 static uint8_t psz_T2Is[]="T2 is ";
57 static uint8_t psz_T3Is[]="T3 is ";
58 static uint8_t psz_Enabled[]="enabled.";
59 static uint8_t psz_Disabled[]="disabled.";
60 static uint8_t psz_CRNL[3]= {0x0D, 0x0A, 0};
61 
62 
63 // timer globals
64 uint32_t u32_myT1Count = 0;
65 uint8_t LED1 = TRUE;
66 uint8_t LED2 = TRUE;
67 
68 struct stTask* pst_MyTasks[3];
69 
70 /************************************************************************
71  * User supplied functions
72  ************************************************************************
73  */
74 
75 // Simulate the timer ISR on a MCU
76 // The PC doesn't have a timer ISR, so this task will periodically
77 // call the timer services callback instead.
78 // USED ONLY FOR DEVELOPMENT AND TESTING!
79 ESOS_USER_TASK( __simulated_isr ) {
80  static uint32_t u32_count, u32_tick;
81 
82  ESOS_TASK_BEGIN(pstTask);
83  u32_count = 0;
84  while (TRUE) {
85  // call the ESOS timer services callback like the ISR would
86  __esos_tmrSvcsExecute();
87  ESOS_TASK_WAIT_TICKS( pstTask, 1 );
88 
89  } // endof while(TRUE)
90  ESOS_TASK_END(pstTask);
91 } // end child_task
92 
93 uint32_t randomNumInRange(uint32_t u32_lo, uint32_t u32_hi) {
94  uint32_t u32_d1, u32_d2, u32_d4, u32_ret;
95  UINT32 U32_temp;
96 
97  while (TRUE) {
98  u32_d4 = esos_GetRandomUint32();
99  u32_ret = u32_lo + u32_d4;
100  if (u32_ret <= u32_hi) return u32_ret;
101 
102  U32_temp._uint32_t = u32_d4;
103  u32_d2 = U32_temp.u16LoWord ^ U32_temp.u16HiWord;
104  u32_ret = u32_lo + u32_d2;
105  if (u32_ret <= u32_hi) return u32_ret;
106 
107  u32_d1 = U32_temp.u8LoLsb ^ U32_temp.u8LoMsb ^ U32_temp.u8HiLsb ^ U32_temp.u8HiMsb;
108  u32_ret = u32_lo + u32_d1;
109  if (u32_ret <= u32_hi) return u32_ret;
110  } //endwhile
111 } //end randomNumInRange
112 
113 
114 // user-created timer callback
115 ESOS_USER_TIMER( swTimerCounter ) {
116  u32_myT1Count++;
117 } //endof swTimerCounter
118 
119 // user-created timer callback
120 ESOS_USER_TIMER( swTimerLED ) {
121  // LED2 = !LED2;
122  if (LED2)
123  printf("\a");
124  else
125  printf("\a");
126  fflush(stdout);
127  LED2 = !LED2;
128 } //endof sw_Timer_LED
129 
130 uint32_t u32_cnt1, u32_cnt2, u32_cnt3;
131 
132 // user-created timer callback
133 ESOS_USER_TIMER( swTimerPrintA ) {
134 
135  printf("A:%d\n", u32_cnt1++);
136  fflush(stdout);
137 } //endof sw_Timer_LED
138 
139 ESOS_USER_TIMER( swTimerPrintB ) {
140 
141  printf("B:%d\n", u32_cnt2++);
142  fflush(stdout);
143 } //endof sw_Timer_LED
144 
145 ESOS_USER_TIMER( swTimerPrintC ) {
146 
147  printf("C:%d\n", u32_cnt3++);
148  fflush(stdout);
149 } //endof sw_Timer_LED
150 
151 ESOS_USER_TASK( task1 ) {
152  uint32_t u32_rnd;
153 
154  ESOS_TASK_BEGIN(pstTask);
155  while (TRUE) {
156  u32_rnd = 100*randomNumInRange(1, 30);
157  printf("T1 (%d)\n", u32_rnd);
158  ESOS_TASK_WAIT_TICKS(pstTask, u32_rnd);
159  } // endof while(TRUE)
160  ESOS_TASK_END(pstTask);
161 } // end task1()
162 
163 ESOS_USER_TASK( task2 ) {
164  uint32_t u32_rnd;
165 
166  ESOS_TASK_BEGIN(pstTask);
167  while (TRUE) {
168  u32_rnd = 100*randomNumInRange(1, 30);
169  printf("T2 (%d)\n", u32_rnd);
170  ESOS_TASK_WAIT_TICKS(pstTask, u32_rnd);
171  } // endof while(TRUE)
172  ESOS_TASK_END(pstTask);
173 } // end task1()
174 
175 ESOS_USER_TASK( task3 ) {
176  uint32_t u32_rnd;
177 
178  ESOS_TASK_BEGIN(pstTask);
179  while (TRUE) {
180  u32_rnd = 100*randomNumInRange(1, 30);
181  printf("T3 (%d)\n", u32_rnd);
182  ESOS_TASK_WAIT_TICKS(pstTask, u32_rnd);
183  } // endof while(TRUE)
184  ESOS_TASK_END(pstTask);
185 } // end task1()
186 
187 ESOS_USER_TASK( task_LED ) {
188  ESOS_TASK_BEGIN(pstTask);
189  while (TRUE) {
190  // LED2 = !LED2;
191  ESOS_TASK_WAIT_TICKS(pstTask, 1000);
192  printf("\a\a");
193  fflush(stdout);
194  } // endof while(TRUE)
195  ESOS_TASK_END(pstTask);
196 } // end upper_case()
197 
198 // user task to randomly turn on and off some timer service
199 //
200 ESOS_USER_TASK( random_tmr ) {
201  static uint32_t u32_RandomNumber;
202  static uint8_t u8_RandomNumber;
203  static uint8_t u8_Count;
204  static ESOS_TMR_HANDLE tmrhnd_t1;
205  UINT32 U32_Temp;
206 
207  ESOS_TASK_BEGIN(pstTask);
208  while (TRUE) {
209  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 5000, 15000 ) );
211  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
212  ESOS_TASK_WAIT_ON_SEND_STRING( "starting timer 1 (");
215  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
217  tmrhnd_t1 = esos_RegisterTimer( swTimerCounter, 500 );
218  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 5000, 15000 ) );
220  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
221  ESOS_TASK_WAIT_ON_SEND_STRING( "stopping timer 1 by handle (");
224  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
226  esos_UnregisterTimer( tmrhnd_t1 );
227 
228  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 5000, 15000 ) );
230  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
231  ESOS_TASK_WAIT_ON_SEND_STRING( "starting timer 1 (");
234  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
236  tmrhnd_t1 = esos_RegisterTimer( swTimerCounter, 500 );
237  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 5000, 15000 ) );
239  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
240  ESOS_TASK_WAIT_ON_SEND_STRING( "stopping timer 1 by function (");
243  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
245  esos_UnregisterTimer( esos_GetTimerHandle( swTimerCounter) );
246 
247  } // endof while(TRUE)
248  ESOS_TASK_END(pstTask);
249 } // end child_task
250 
251 // user task to randomly turn on and off some timer service
252 //
253 ESOS_USER_TASK( random_tmr_dbg ) {
254  static uint32_t u32_RandomNumber;
255  static uint8_t u8_RandomNumber;
256  static uint8_t u8_Count;
257  static ESOS_TMR_HANDLE tmrhnd_t1;
258  static ESOS_TMR_HANDLE tmrhnd_ret;
259  UINT32 U32_Temp;
260 
261  ESOS_TASK_BEGIN(pstTask);
262  while (TRUE) {
263  ESOS_TASK_WAIT_TICKS(pstTask, 1*1000 );
264  u32_myT1Count = 0;
266  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
267  ESOS_TASK_WAIT_ON_SEND_STRING( "starting timer 10s/0.1 (");
270  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
272  // our simulated ISR only runs at 100ms intervals
273  tmrhnd_t1 = esos_RegisterTimer( swTimerCounter, 1 );
274  ESOS_TASK_WAIT_TICKS(pstTask, 10*1000 );
276  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
277  ESOS_TASK_WAIT_ON_SEND_STRING( "stopping timer 1 by handle (");
280  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
282  esos_UnregisterTimer( tmrhnd_t1 );
283 
284  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 1*1000, 10*1000 ) );
285  u32_myT1Count = 0;
287  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
288  ESOS_TASK_WAIT_ON_SEND_STRING( "starting timer 10s/0.2 (");
291  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
293  // our simulated ISR only runs at 100ms interval
294  tmrhnd_t1 = esos_RegisterTimer( swTimerCounter, 2 );
295  ESOS_TASK_WAIT_TICKS(pstTask, 10*1000 );
297  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
298  ESOS_TASK_WAIT_ON_SEND_STRING( "stopping timer 1 by function (");
301  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
303  esos_UnregisterTimer( esos_GetTimerHandle( swTimerCounter) );
304 
305  ESOS_TASK_WAIT_TICKS(pstTask, randomNumInRange( 1*1000, 10*1000 ) );
306  u32_myT1Count = 0;
308  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
309  ESOS_TASK_WAIT_ON_SEND_STRING( "starting timer 10s/0.15 (");
312  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
314  // our simulated ISR only runs at 100ms intervals
315  tmrhnd_t1 = esos_RegisterTimer( swTimerCounter, 1 );
316  ESOS_TASK_WAIT_TICKS(pstTask, 5*1000 );
317  tmrhnd_ret = esos_ChangeTimerPeriod( tmrhnd_t1, 2 );
318  if (tmrhnd_ret == ESOS_TMR_FAILURE) {
320  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
321  ESOS_TASK_WAIT_ON_SEND_STRING( "change period failed");
322  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
324  } //endif
325  ESOS_TASK_WAIT_TICKS(pstTask, 5*1000 );
327  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
328  ESOS_TASK_WAIT_ON_SEND_STRING( "stopping timer 1 by function (");
331  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
333  esos_UnregisterTimer( esos_GetTimerHandle( swTimerCounter) );
334 
335 
336  } // endof while(TRUE)
337  ESOS_TASK_END(pstTask);
338 } // end child_task
339 
340 ESOS_USER_TASK( upper_case ) {
341  static uint8_t u8_char;
342 
343  ESOS_TASK_BEGIN(pstTask);
344  while (TRUE) {
346  ESOS_TASK_SIGNAL_BUSY_IN_COMM();
347  ESOS_TASK_WAIT_ON_GET_UINT8( u8_char );
349  if ((u8_char >= 'a') && (u8_char <= 'z') )
350  u8_char = u8_char - 'a' + 'A';
352  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
355  } // endof while(TRUE)
356  ESOS_TASK_END(pstTask);
357 } // end upper_case()
358 
359 ESOS_USER_TASK( upper_case2 ) {
360  static uint8_t u8_i;
361  static uint8_t au8_x[257];
362  static uint8_t au8_y[257];
363 
364  ESOS_TASK_BEGIN(pstTask);
365  while (TRUE) {
367  ESOS_TASK_SIGNAL_BUSY_IN_COMM();
370  u8_i = 0;
371  while (TRUE) {
372  if ((au8_x[u8_i] >= 'a') && (au8_x[u8_i] <= 'z') )
373  au8_y[u8_i] = au8_x[u8_i] - 'a' + 'A';
374  else
375  au8_y[u8_i] = au8_x[u8_i];
376  if (au8_x[u8_i] == 0) break;
377  u8_i++;
378  }
380  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
383  } // endof while(TRUE)
384  ESOS_TASK_END(pstTask);
385 } // end upper_case()
386 
387 
388 ESOS_USER_TASK( reverse_string ) {
389  static uint8_t u8_char;
390  \
391  static char* sz_in[257];
392  static char* sz_out[257];
393 
394  ESOS_TASK_BEGIN(pstTask);
395  while (TRUE) {
397  ESOS_TASK_SIGNAL_BUSY_IN_COMM();
400  reverseString( sz_in, sz_out );
402  ESOS_TASK_SIGNAL_BUSY_OUT_COMM();
406  } // endof while(TRUE)
407  ESOS_TASK_END(pstTask);
408 } // end upper_case()
409 
420 void reverseString(char *psz_s1, char *psz_s2) {
421  char *psz_s1end;
422  if (!(*psz_s1)) {
423  *psz_s2 = 0; //psz_s1 is empty, return.
424  return;
425  }
426  psz_s1end = psz_s1;
427  //find end of first string
428  while (*psz_s1end) psz_s1end++;
429  psz_s1end--; //backup one to first non-zero byte
430  //now copy to S2 in reverse order
431  while (psz_s1end != psz_s1) {
432  *psz_s2 = *psz_s1end;
433  psz_s1end--;
434  psz_s2++;
435  }
436  //copy last byte
437  *psz_s2 = *psz_s1end;
438  psz_s2++;
439  //mark end of string
440  *psz_s2 = 0;
441 }
442 
443 /******************************************************************************
444  * Function: void user_init(void)
445  *
446  * PreCondition: None
447  *
448  * Input: None
449  *
450  * Output: None
451  *
452  * Side Effects: None
453  *
454  * Overview: user_init is a centralized initialization routine where
455  * the user can setup their application. It is called
456  * automagically by ES_OS during the operating system
457  * initialization.
458  *
459  * Note: The user should set up any state machines and init
460  * all application variables. They can also turn on
461  * any needed peripherals here.
462  *
463  * The user SHALL NOT mess with the interrupt hardware
464  * directly!!! The ES_OS must be aware of the interrupts
465  * and provides osXXXXXXX functions for the user to use.
466  * Using these ES_OS-provided functions, the user may
467  * (and probably should) initialize, register, and enable
468  * interrupts in this routine.
469  *
470  * Furthermore, the user should register AT LEAST one
471  * user application task here (via esos_RegisterTask) or
472  * the ES_OS scheduler will have nothing to schedule
473  * to run when this function returns.
474  *
475  *****************************************************************************/
476 void user_init(void) {
477  uint16_t* pu16_ptr;
478  uint16_t u16_junk;
479  ESOS_TMR_HANDLE tmrhnd_t1,tmrhnd_t2,tmrhnd_t3;
480 
481  __esos_hw_PutString( HELLO_MSG );
482 
483  /*
484  * Now, let's get down and dirty with ESOS and our user tasks
485  *
486  * Once tasks are registered, they will start executing in
487  * the ESOS scheduler.
488  */
489 
490  // register our ESOS task to mimic MCU's TIMER T1 IRQ which kicks off
491  // the ESOS S/W timers
492  esos_RegisterTask( __simulated_isr );
493 
494 
495  // here are several combinations of tasks that should work together
496 #if 0
497  esos_RegisterTask( random_tmr);
498 #endif
499 #if 0
500  esos_RegisterTask( random_tmr_dbg);
501 #endif
502 #if 0
503  esos_RegisterTask( upper_case );
504  tmrhnd_t2 = esos_RegisterTimer( swTimerCounter, 500 );
505 #endif
506 #if 0
507  esos_RegisterTask( upper_case2 );
508  tmrhnd_t2 = esos_RegisterTimer( swTimerLED, 1000 );
509 #endif
510 #if 0
511  esos_RegisterTask( reverse_string );
512  esos_RegisterTask( task_LED );
513 #endif
514 #if 0
515  esos_RegisterTask( reverse_string );
516  tmrhnd_t2 = esos_RegisterTimer( sw_Timer_LED, 1000 );
517 #endif
518 #if 0
519  esos_RegisterTask( upper_case2 );
520  esos_RegisterTimer( swTimerLED);
521  tmrhnd_t1 = esos_RegisterTimer( swTimerPrintA, 400 );
522  tmrhnd_t2 = esos_RegisterTimer( swTimerPrintB, 500 );
523  tmrhnd_t3 = esos_RegisterTimer( swTimerPrintC, 750 );
524 #endif
525 #if 1
526  esos_RegisterTimer( swTimerLED);
527  esos_RegisterTask( task1 );
528  esos_RegisterTask( task2 );
529  esos_RegisterTask( task3 );
530 #endif
531 
532 
533 
534 
535 
536 } // end user_init()
_UINT32::u8LoLsb
uint8_t u8LoLsb
Definition: all_generic.h:236
_UINT32::u8LoMsb
uint8_t u8LoMsb
Definition: all_generic.h:238
esos_RegisterTimer
ESOS_TMR_HANDLE esos_RegisterTimer(void(*timername)(void), uint32_t u32_period)
Definition: esos.c:422
ESOS_TASK_WAIT_TICKS
#define ESOS_TASK_WAIT_TICKS(u32_duration)
Definition: esos_task.h:375
esos_GetRandomUint32
uint32_t esos_GetRandomUint32(void)
Definition: esos_utils.c:100
_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_GetTimerHandle
ESOS_TMR_HANDLE esos_GetTimerHandle(void(*pfnTmrFcn)(void))
Definition: esos.c:472
_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
user_init
void user_init(void)
Definition: app_timer.c:476
esos.h
ESOS_TASK_END
#define ESOS_TASK_END()
Definition: esos_task.h:271
esos_ChangeTimerPeriod
uint8_t esos_ChangeTimerPeriod(ESOS_TMR_HANDLE hnd_timer, uint32_t u32_period)
Definition: esos.c:499
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_UnregisterTimer
uint8_t esos_UnregisterTimer(ESOS_TMR_HANDLE hnd_timer)
Definition: esos.c:451
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_TASK_RELEASE_IN_COMM
#define ESOS_TASK_RELEASE_IN_COMM()
Definition: esos_comm.h:257
esos_RegisterTask
ESOS_TASK_HANDLE esos_RegisterTask(uint8_t(*taskname)(ESOS_TASK_HANDLE pstTask))
Definition: esos.c:126