PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
app_semaphore1.c
Go to the documentation of this file.
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 /** \file
31  * ESOS application program to where two tasks increment a counter local to
32  * each task. Tasks run forever. However, task1 will delay for a random
33  * length of time after each counter increment. task2 will increment its
34  * counter only after every 5th increment of task1's counter.
35  * \note Application demonstrates signaling synchronization using ESOS semaphores
36  */
37 
38 // INCLUDEs go here (First include the main esos.h file)
39 // After that, the user can include what they need
40 #include "esos.h"
41 #ifdef __linux
42 #include "esos_pc.h"
43 #include "esos_pc_stdio.h"
44 
45 // INCLUDE these so that printf() and our PC hacks work
46 #include <stdio.h>
47 #include <sys/select.h>
48 #include <termios.h>
49 #include <unistd.h>
50 #else
51 #include "esos_pic24.h"
52 #include "esos_pic24_rs232.h"
53 #endif
54 
55 // DEFINEs go here
56 #ifndef __linux
57 #define CONFIG_LED1() CONFIG_RB15_AS_DIG_OUTPUT()
58 #define LED1 _LATB15
59 #else
60 #define CONFIG_LED1() printf("called CONFIG_LED1()\n");
61 uint8_t LED1 = TRUE; // LED1 is initially "on"
62 #endif
63 
64 // PROTOTYPEs go here
65 
66 // GLOBALs go here
67 // Generally, the user-created semaphores will be defined/allocated here
68 char psz_CRNL[3]= {0x0D, 0x0A, 0};
69 char psz_T1[] = "Task 1: ";
70 char psz_T2[] = "Task 2: ";
71 
72 ESOS_SEMAPHORE( sem_T2CanRun );
73 
74 #ifdef __linux
75 /*
76  * Simulate the timer ISR found on a MCU
77  * The PC doesn't have a timer ISR, so this task will periodically
78  * call the timer services callback instead.
79  * USED ONLY FOR DEVELOPMENT AND TESTING ON PC.
80  * Real MCU hardware doesn't need this task
81  */
82 ESOS_USER_TASK( __simulated_isr ) {
84  while (TRUE) {
85  // call the ESOS timer services callback just like a real H/W ISR would
86  __esos_tmrSvcsExecute();
88 
89  } // endof while(TRUE)
90  ESOS_TASK_END();
91 } // end child_task
92 #endif
93 
94 /************************************************************************
95  * User supplied functions
96  ************************************************************************
97  */
98 
99 /*
100  * return an uint32_t that can be used for a reasonable delay
101  * should not be too short (~255 ticks) and not too long (~4096 ticks)
102  */
103 inline uint32_t getRandomDelay() {
104  return ((esos_GetRandomUint32() & 0x0FFF)|0x100);
105 }
106 
107 /*
108  * An ESOS software timer callback function strobe the heartbeat LED.
109  *
110  * Toggles LED1 everytime the callback is called. Exact period is
111  * determined by application when this timer callback function is
112  * registered with ESOS. See \ref esos_RegisterTimer
113  * Application can change timer period on-the-fly with \ref esos_ChangeTimerPeriod
114  *
115  * \note Since this heartbeat is performed in an ESOS software
116  * timer callabck, a flashing LED indicates that the ESOS system
117  * tick ISR is being called properly. If the LED quits flashing,
118  * then the ESOS system tick has ceased working. This probably indicates
119  * some catastrophic failure of the system. However, the cause could
120  * be poorly-behaved user code that is manipulating the hardware registers
121  * with the timer or interrupt enables directly. ESOS provides functions
122  * to change state of interrupts and user code should never modify the
123  * hardware used by ESOS to implement the system tick.
124  * \hideinitializer
125  */
126 
127 // user-created timer callback
128 ESOS_USER_TIMER( swTimerLED ) {
129  LED1 = !LED1;
130 #ifdef __linux
131  if (LED1) {
132  printf("\a");
133  fflush(stdout);
134  }
135 #endif
136 } //endof swTimerLED
137 
138 /* == task1 ==
139  * Print out a counter value local to this task, then delay
140  * for a random period of time. (Delays range from approx.
141  * 0.25 - 4.1 seconds)
142  */
143 ESOS_USER_TASK(task1) {
144  static uint8_t u8_cnt=0;
145 
146  ESOS_TASK_BEGIN();
147  while (TRUE) {
151  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
153  ESOS_SIGNAL_SEMAPHORE(sem_T2CanRun, 1);
154  u8_cnt++;
155  ESOS_TASK_WAIT_TICKS( getRandomDelay() );
156  } // endof while(TRUE)
157  ESOS_TASK_END();
158 } // end task1()
159 
160 /* == task2 ==
161  * Wait for a signal from task1, then
162  * Print out a counter value local to this task
163  */
164 ESOS_USER_TASK(task2) {
165  static uint8_t u8_cnt=0;
166 
167  ESOS_TASK_BEGIN();
168  while (TRUE) {
169  ESOS_TASK_WAIT_SEMAPHORE(sem_T2CanRun, 5);
173  ESOS_TASK_WAIT_ON_SEND_STRING( psz_CRNL );
175  u8_cnt++;
176  } // endof while(TRUE)
177  ESOS_TASK_END();
178 } // end task1()
179 
180 
181 /****************************************************
182  * user_init()
183  ****************************************************
184  */
185 void user_init(void) {
186 
187  // Call the hardware-provided routines to print the
188  // HELLO_MSG to the screen. Must use this call because
189  // the ESOS communications subsystems is not yet fully
190  // initialized, since this call is in user_init()
191  //
192  // In general, users should call hardware-specific
193  // function like this.
194  __esos_unsafe_PutString( HELLO_MSG );
195 
196 #ifdef __linux
197  // register our little ESOS task to mimic MCU's TIMER T1 IRQ which kicks off
198  // the ESOS S/W timers when they expire
199  esos_RegisterTask( __simulated_isr );
200 #endif
201 
202  // configure our hardware to support to support our application
203  CONFIG_LED1();
204 
205  // initialize the semaphore (initially blocking)
206  ESOS_INIT_SEMAPHORE( sem_T2CanRun, 0 );
207 
208  // user_init() should register at least one user task
209  esos_RegisterTask(task1);
210  esos_RegisterTask(task2);
211 
212  // register our callback function with ESOS to create a software timer
213  esos_RegisterTimer( swTimerLED, 250 );
214 
215 } // end user_init()