PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
app_mail_A.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(sender_A);
59 ESOS_USER_TASK(recipient_A);
60 
61 // GLOBALs go here
62 // Generally, the user-created semaphores will be defined/allocated here
63 static uint8_t psz_CRNL[3]= {0x0D, 0x0A, 0};
64 
65 
66 // timer globals
67 uint32_t u32_myT1Count = 0;
68 uint8_t LED1 = TRUE;
69 uint8_t LED2 = TRUE;
70 
71 struct stTask* pst_MyTasks[3];
72 
73 /*
74  * Simulate the timer ISR found on a MCU
75  * The PC doesn't have a timer ISR, so this task will periodically
76  * call the timer services callback instead.
77  * USED ONLY FOR DEVELOPMENT AND TESTING ON PC.
78  * Real MCU hardware doesn't need this task
79  */
80 ESOS_USER_TASK( __simulated_isr ) {
82  while (TRUE) {
83  // call the ESOS timer services callback just like a real H/W ISR would
84  __esos_tmrSvcsExecute();
86 
87  } // endof while(TRUE)
88  ESOS_TASK_END();
89 } // end child_task
90 
91 
92 /************************************************************************
93  * User supplied functions
94  ************************************************************************
95  */
96 
97 /*
98  * Returns a random number with a value between the two arguments.
99  *
100  * /todo Yes, I know this routine is cheesy. But, it works and
101  * I am in a really big hurry right now.
102  */
103 
104 uint32_t randomNumInRange(uint32_t u32_lo, uint32_t u32_hi) {
105  uint32_t u32_d1, u32_d2, u32_d4, u32_ret;
106  UINT32 U32_temp;
107 
108  while (TRUE) {
109  u32_d4 = esos_GetRandomUint32();
110  u32_ret = u32_lo + u32_d4;
111  if (u32_ret <= u32_hi) return u32_ret;
112 
113  U32_temp._uint32 = u32_d4;
114  u32_d2 = U32_temp.u16LoWord ^ U32_temp.u16HiWord;
115  u32_ret = u32_lo + u32_d2;
116  if (u32_ret <= u32_hi) return u32_ret;
117 
118  u32_d1 = U32_temp.u8LoLsb ^ U32_temp.u8LoMsb ^ U32_temp.u8HiLsb ^ U32_temp.u8HiMsb;
119  u32_ret = u32_lo + u32_d1;
120  if (u32_ret <= u32_hi) return u32_ret;
121  } //endwhile
122 } //end randomNumInRange
123 
124 
125 // user-created timer callback
126 ESOS_USER_TIMER( swTimerCounter ) {
127  u32_myT1Count++;
128 } //endof swTimerCounter
129 
130 // user-created timer callback
131 ESOS_USER_TIMER( swTimerLED ) {
132  LED2 = !LED2;
133  printf("\a");
134  fflush(stdout);
135 } //endof swTimerLED
136 
137 
138 /**********************************************************
139 **
140 ** a few tasks to send mail messages to each other
141 **
142 ************************************************************/
143 
144 ESOS_USER_TASK( sender_A ) {
145  uint32_t u32_rnd;
146  static uint8_t u8_cnt;
147  static ESOS_TASK_HANDLE hTask, hTask16, hTask32;
148  static MAILMESSAGE st_Message;
149 
150  ESOS_TASK_BEGIN();
151  u8_cnt=0;
152  // store handle to our recipient ESOS task
153  hTask = esos_GetTaskHandle( recipient_A );
154 
155  while (TRUE) {
156  // create/fill in the local copy of the message
157  // we will send a single uint8 as data payload
158  ESOS_TASK_MAKE_MSG_UINT8(st_Message, u8_cnt);
159 
160  // ESOS task mailboxes are stored locally in each task.
161  // Therefore, the "sender" task must "WAIT" until the
162  // recipient task has enough space in their mailbox
164 
165  // recipient has mailbox space, so send message
166  printf("sender_A sending MESSAGE %d\n", u8_cnt);
167  ESOS_TASK_SEND_MESSAGE(hTask, &st_Message);
168 
169  // wait some random delay before we send another message
170  u32_rnd = 1+(0x0F & esos_GetRandomUint32());
171  u32_rnd <<= 8;
172  ESOS_TASK_WAIT_TICKS( u32_rnd);
173 
174  u8_cnt++;
175  if (u8_cnt>50) u8_cnt=0;
176 
177 
178  } // endof while(TRUE)
179  ESOS_TASK_END();
180 } // end sender_A()
181 
182 //TASK that does nothing but check its mail
183 ESOS_USER_TASK( recipient_A ) {
184  uint32_t u32_rnd;
185  uint8_t u8_x;
186  static uint8_t u8_cnt;
187  static MAILMESSAGE stMsg;
188  static ESOS_TASK_HANDLE hSenderA;
189 
190  ESOS_TASK_BEGIN();
191  hSenderA = esos_GetTaskHandle( sender_A );
192  while (TRUE) {
193  // check for mail
195  u8_cnt=0;
196 
197  // keep reading mail until mailbox is empty
198  while ( ESOS_TASK_IVE_GOT_MAIL() ) {
199  // make local copy of message (frees up mailbox memory)
200  __esos_ReadMailMessage(__pstSelf, &stMsg );
201 
202  // read the message to determine the sender... then
203  // read contents and "postmark" timestamp (in ESOS system ticks)
204  printf("Got a message from ");
205  if ( ESOS_IS_TASK_SENDER(hSenderA, stMsg) ) {
206  printf("sender_A");
207  } else {
208  printf("UNKNOWN task: (%d)", ESOS_GET_MSG_FROMTASK(stMsg) );
209  }
210  printf (" containing %d enroute time = %d ms\n", stMsg.au8_Contents[0], esos_GetSystemTick()-stMsg.u32_Postmark );
211  } //endof while()
212  } // endof while(TRUE)
213  ESOS_TASK_END();
214 } // end recipient_A()
215 
216 
217 
218 /******************************************************************************
219  * Function: void user_init(void)
220  *
221  * PreCondition: None
222  *
223  * Input: None
224  *
225  * Output: None
226  *
227  * Side Effects: None
228  *
229  * Overview: user_init is a centralized initialization routine where
230  * the user can setup their application. It is called
231  * automagically by ES_OS during the operating system
232  * initialization.
233  *
234  * Note: The user should set up any state machines and init
235  * all application variables. They can also turn on
236  * any needed peripherals here.
237  *
238  * The user SHALL NOT mess with the interrupt hardware
239  * directly!!! The ES_OS must be aware of the interrupts
240  * and provides osXXXXXXX functions for the user to use.
241  * Using these ES_OS-provided functions, the user may
242  * (and probably should) initialize, register, and enable
243  * interrupts in this routine.
244  *
245  * Furthermore, the user should register AT LEAST one
246  * user application task here (via esos_RegisterTask) or
247  * the ES_OS scheduler will have nothing to schedule
248  * to run when this function returns.
249  *
250  *****************************************************************************/
251 void user_init(void) {
252  uint16_t* pu16_ptr;
253  uint16_t u16_junk;
254  ESOS_TMR_HANDLE tmrhnd_t1,tmrhnd_t2,tmrhnd_t3;
255 
256  __esos_unsafe_PutString( HELLO_MSG );
257 
258  /*
259  * Now, let's get down and dirty with ESOS and our user tasks
260  *
261  * Once tasks are registered, they will start executing in
262  * the ESOS scheduler.
263  */
264 
265  // register our little ESOS task to mimic MCU's TIMER T1 IRQ which kicks off
266  // the ESOS S/W timers when they expire
267  esos_RegisterTask( __simulated_isr );
268 
269  /* ====================================================================
270  * REGISTER SOME USER TASKS
271  * ====================================================================
272  */
273 
274 
275 // here are several combinations of tasks that should work together
276 
277  //esos_RegisterTimer( swTimerLED, 1000 );
278  esos_RegisterTask( sender_A );
279  esos_RegisterTask( recipient_A );
280 
281 
282 } // end user_init()