PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
esos.h
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 // Documentation for this file. If the \file tag isn't present,
31 // this file won't be documented.
32 /** \file
33  * Embedded Systems Operating System (ESOS)
34  *
35  */
36 
37 #ifndef ESOS_H
38 #define ESOS_H
39 
40 #ifndef BUILT_ON_ESOS
41 #define BUILT_ON_ESOS
42 #endif
43 
44 
45 // Include all the files we need
46 //#include "user_config.h" // get the user's configuration requests
47 #include "all_generic.h"
48 #include "esos_task.h" // defines ESOS tasks and semaphores
49 
50 // PUT THESE HERE FOR NOW. They belong somewhere else
51 // in the long-run.
52 //
53 // PC versions do NOT have IRQs (yet) so do NOT define the variables
54 #ifndef __linux
55 #define ESOS_USE_IRQS
56 #endif
57 #define ESOS_USE_SERIAL_PORT
58 
59 /**
60 * Define the constants and structures required for our little
61 * embedded systems operating system
62 */
63 #if defined(ESOS_USE_BULK_CDC_USB) || defined(ESOS_USE_SERIAL_PORT)
64 #include "esos_comm.h"
65 #endif // USE_USB or USE_SERIAL
66 
67 #ifdef ESOS_USE_IRQS
68 /*
69 * user wants IRQ support, so prototype the required IRQ functions
70 */
71 #include "esos_irq.h"
72 #endif //ESOS_USE_IRQS
73 
74 #ifdef ESOS_RUNS_ON_REAL_OS
75 // computers running a host OS (windoze/Linux/etc) expect
76 // their applications to return and return a value
77 // so define a return type for main and create a return statement
78 // also, multitasking OS-es will want some CPU time for other
79 // applications, so sleep some (10ms = 10000us) should be enough
80 typedef int main_t;
81 #define OS_END return(1)
82 #define OS_ITERATE usleep(10000)
83 #else
84 // hardware w/o a hosting OS will never return. So main_t
85 // must be void return type and hang-up when done!
86 // (Of course, real hardware apps should never be done.)
87 typedef int main_t;
88 #define OS_END while(1)
89 #define OS_ITERATE
90 #endif
91 
92 /*
93  * Create the ESOS structures we need
94  */
95 struct stTimer {
96  void (*pfn)(void);
97  uint32 u32_period;
98  uint32 u32_cntDown;
99 };
100 
101 // Define masks for the user to use for their flags
102 /** Mask for a global user flag provided by ESOS
103  * \hideinitializer
104  */
105 #define ESOS_USER_FLAG_0 BIT0
106 /** Mask for a global user flag provided by ESOS
107  * \hideinitializer
108  */
109 #define ESOS_USER_FLAG_1 BIT1
110 /** Mask for a global user flag provided by ESOS
111  * \hideinitializer
112  */
113 #define ESOS_USER_FLAG_2 BIT2
114 /** Mask for a global user flag provided by ESOS
115  * \hideinitializer
116  */
117 #define ESOS_USER_FLAG_3 BIT3
118 /** Mask for a global user flag provided by ESOS
119  * \hideinitializer
120  */
121 #define ESOS_USER_FLAG_4 BIT4
122 /** Mask for a global user flag provided by ESOS
123  * \hideinitializer
124  */
125 #define ESOS_USER_FLAG_5 BIT5
126 /** Mask for a global user flag provided by ESOS
127  * \hideinitializer
128  */
129 #define ESOS_USER_FLAG_6 BIT6
130 /** Mask for a global user flag provided by ESOS
131  * \hideinitializer
132  */
133 #define ESOS_USER_FLAG_7 BIT7
134 /** Mask for a global user flag provided by ESOS
135  * \hideinitializer
136  */
137 #define ESOS_USER_FLAG_8 BIT8
138 /** Mask for a global user flag provided by ESOS
139  * \hideinitializer
140  */
141 #define ESOS_USER_FLAG_9 BIT9
142 /** Mask for a global user flag provided by ESOS
143  * \hideinitializer
144  */
145 #define ESOS_USER_FLAG_A BIT10
146 /** Mask for a global user flag provided by ESOS
147  * \hideinitializer
148  */
149 #define ESOS_USER_FLAG_B BIT11
150 /** Mask for a global user flag provided by ESOS
151  * \hideinitializer
152  */
153 #define ESOS_USER_FLAG_C BIT12
154 /** Mask for a global user flag provided by ESOS
155  * \hideinitializer
156  */
157 #define ESOS_USER_FLAG_D BIT13
158 /** Mask for a global user flag provided by ESOS
159  * \hideinitializer
160  */
161 #define ESOS_USER_FLAG_E BIT14
162 /** Mask for a global user flag provided by ESOS
163  * \hideinitializer
164  */
165 #define ESOS_USER_FLAG_F BIT15
166 
167 
168 /**
169  * Declaration of an user-defined timer callback (for ESOS timer services)
170  *
171  * This macro is used to declare a user-timer. All timers using ESOS timer
172  * services must be declared with this macro.
173  *
174  * \param timername The name of the software timer to create.
175  * \note You are really creating a C function implementing the user timer callback.
176  * Since ESOS timer serivces calls this callback function at the appropriate time,
177  * this function cannot be passed arguments and cannot return values
178  * \hideinitializer
179  */
180 #define ESOS_USER_TIMER(timername) void timername(void)
181 
182 /**
183  * Handle to a software timer in the ESOS timer service.
184  *
185  * \sa ESOS_USER_TIMER
186  * \sa esos_RegisterTimer
187  * \sa esos_UnregisterTimer
188  * \sa esos_GetTimerHandle
189  * \sa esos_ChangeTimerPeriod
190  *
191  * \hideinitializer
192  */
194 
195 /*
196  * Now define the public user function prototypes that are
197  * always available regardless of the user_config settings
198  */
199 /**
200  * User-provided function to initialize user's hardware configuration
201  * register user tasks.
202  *
203  * \note All ESOS applications <em>MUST</em> provide this function.
204  * \note This function <em>MUST</em> register at least one ESOS task.
205  *
206  * \note user_init() is a centralized initialization routine where
207  * the user can setup their application. It is called
208  * automagically by ES_OS during the operating system
209  * initialization.
210  *
211  * \note User should set up any state machines and init
212  * all application variables. They can also turn on
213  * any needed peripherals here.
214  *
215  * \note User <em>shall not</em> mess with the interrupt hardware
216  * directly!!! The ESOS must be aware of the interrupts
217  * and provides esos_XXXXXXX functions for the user to use.
218  * Using these ESOS-provided functions, the user may
219  * (and probably should) initialize, register, and enable
220  * interrupts in this routine.
221  *
222  * \note Furthermore, the user should register AT LEAST one
223  * user application task here via \ref esos_RegisterTask
224  * or the ES_OS scheduler will have nothing to schedule
225  * to run when this function returns.
226  * \hideinitializer
227  */
228 
229 void user_init( void );
230 ESOS_TASK_HANDLE esos_RegisterTask( uint8 (*pfn_TaskFcn)(struct stTask *pst_Task) );
231 uint8 esos_UnregisterTask( uint8 (*pfn_TaskFcn)(struct stTask *pst_Task) ) ;
234 
235 // prototypes for ESOS software timers
236 ESOS_TMR_HANDLE esos_RegisterTimer( void (*pfnTmrFcn)(void), uint32 u32_period );
238 ESOS_TMR_HANDLE esos_GetTimerHandle( void (*pfnTmrFcn)(void) );
239 uint8 esos_ChangeTimerPeriod( ESOS_TMR_HANDLE hnd_timer, uint32 u32_period );
240 
241 // The user must provide the HW-specific way of getting a 32bit 1.0ms tick
242 void __esos_hw_InitSystemTick(void);
243 uint32 __esos_hw_GetSystemTickCount(void);
244 
245 /**
246  * Get the current value of the ESOS system tick counter
247  * In the current implementation of ESOS, a tick equal 1.0ms.
248  * Therefore, the value returned by this function is approximately
249  * equal to the number of milliseconds since the since was last
250  * reset.
251  * \return The \ref uint32 value of current value of the ESOS
252  * system tick counter
253  * \note This counter value will roll-over every 49.7 days.
254  * \hideinitializer
255  */
256 #define esos_GetSystemTick() __esos_hw_GetSystemTickCount()
257 uint16 __esos_hasTickDurationPassed(uint32 u32_startTick, uint32 u32_period);
258 void __esos_tmrSvcsExecute(void);
259 
260 void __esos_InitCommSystem(void);
261 
262 
263 /*
264  * expose these ESOS system variables to allow macro access
265  * intead of fcn access
266  */
267 extern uint8 __esos_u8UserTasksRegistered;
268 extern uint16 __esos_u16UserFlags, __esos_u16SystemFlags;
269 
270 /**
271  * Get the current number of user task registered with the
272  * ESOS scheduler.
273  * \return The \ref uint8 number of currently registered user tasks
274  * \note This value does not include the number of child tasks
275  * (tasks of the type \ref ESOS_CHILD_TASK ), just the tasks
276  * of the type \ref ESOS_USER_TASK
277  * \hideinitializer
278  */
279 #define esos_GetNumberRegisteredTasks() (__esos_u8UserTasksRegistered)
280 
281 /**
282  * Returns the system tick value of a future time
283  * \param deltaT the number of ticks in the future you'd like the
284  * system tick value for
285  * \return The \ref uint32 number corresponding to the system tick
286  * value of that future time
287  * \sa esos_GetSystemTick
288  * \hideinitializer
289  */
290 #define esos_GetFutureSystemTick(deltaT) ((uint32)(deltaT) + __esos_hw_GetSystemTickCount());
291 
292 /**
293  * Sets bits in the global user flags provided by ESOS
294  * \param mask An \ref uint16 value composed of the OR-ed user
295  * mask flag masks, where each flag in the OR will be set
296  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
297  * to create their own readable constants
298  * \code
299  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
300  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
301  * esos_SetUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
302  * \endcode
303  * \sa esos_ClearUserFlag
304  * \sa esos_IsUserFlagSet
305  * \sa esos_IsUserFlagClear
306  * \hideinitializer
307  */
308 #define esos_SetUserFlag(mask) BIT_SET_MASK(__esos_u16UserFlags, (mask))
309 
310 /**
311  * Clears bits in the global user flags provided by ESOS
312  * \param mask An \ref uint16 value composed of the OR-ed user
313  * mask flag masks, where each flag in the OR will be cleared
314  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
315  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
316  * to create their own readable constants
317  * \code
318  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
319  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
320  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
321  * \endcode
322  * \sa esos_SetUserFlag
323  * \sa esos_IsUserFlagSet
324  * \sa esos_IsUserFlagClear
325  * \hideinitializer
326  */
327 
328 #define esos_ClearUserFlag(mask) BIT_CLEAR_MASK(__esos_u16UserFlags, (mask))
329 
330 /**
331  * Queries whether the global user flags provided by ESOS are set
332  * \param mask An \ref uint16 value composed of the OR-ed user
333  * mask flag masks, where each flag in the OR will be checked for being set
334  * \retval TRUE if <em>at least</em> one of the flags is set
335  * \retval FALSE if none of the flags are set
336  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
337  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
338  * to create their own readable constants
339  * \code
340  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
341  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
342  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
343  * while(esos_IsUserFlagSet( HEADLIGHTS_ARE_ON)); // falls through
344  * \endcode
345  * \sa esos_SetUserFlag
346  * \sa esos_ClearUserFlag
347  * \sa esos_IsUserFlagClear
348  * \hideinitializer
349  */
350 #define esos_IsUserFlagSet(mask) IS_BIT_SET_MASK(__esos_u16UserFlags, (mask))
351 
352 /**
353  * Queries whether the global user flags provided by ESOS are clear
354  * \param mask An \ref uint16 value composed of the OR-ed user
355  * mask flag masks, where each flag in the OR will be checked for being clear
356  * \retval TRUE if <em>at least</em> one of the flags is clear
357  * \retval FALSE if none of the flags are clear
358  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
359  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
360  * to create their own readable constants
361  * \code
362  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
363  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
364  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
365  * while(esos_IsUserFlagClear( HEADLIGHTS_ARE_ON)); // infinite loop
366  * \endcode
367  * \sa esos_SetUserFlag
368  * \sa esos_ClearUserFlag
369  * \sa esos_IsUserFlagSet
370  * \hideinitializer
371  */
372 #define esos_IsUserFlagClear(mask) IS_BIT_CLEAR_MASK(__esos_u16UserFlags, (mask))
373 
374 // define macros for ESOS system flags
375 // these flags are NOT to be manipulated directly by the user!
376 #define __esos_SetSystemFlag(mask) BIT_SET_MASK(__esos_u16SystemFlags, (mask))
377 #define __esos_ClearSystemFlag(mask) BIT_CLEAR_MASK(__esos_u16SystemFlags, (mask))
378 #define __esos_IsSystemFlagSet(mask) IS_BIT_SET_MASK(__esos_u16SystemFlags, (mask))
379 #define __esos_IsSystemFlagClear(mask) IS_BIT_CLEAR_MASK(__esos_u16SystemFlags, (mask))
380 
381 // Defines for ESOS timer services
382 #define ESOS_TMR_FAILURE 0xFF
383 #define MAX_NUM_TMRS 16
384 
385 /**
386  * Get the current number of user software timers registers (running)
387  * in the ESOS timer services
388  * \return The \ref uint8 number of currently registered user tasks
389  * \hideinitializer
390  */
391 #define esos_GetNumberRunningTimers() (__esos_u8TmrSvcsRegistered)
392 
393 /**
394  * Determines if the software timer represented by the handle is currently running
395  * \param hndl The \ref ESOS_TMR_HANDLE of a software timer
396  * \retval TRUE if the timer is currently running
397  * \retval FALSE if the timer is not currently running
398  * \sa ESOS_USER_TIMER
399  * \sa esos_UnregisterTimer
400  * \sa esos_GetTimerHandle
401  * \sa esos_ChangeTimerPeriod
402  * \hideinitializer
403  */
404 #define esos_IsTimerRunning(hndl) IS_BIT_SET_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
405 #define __esos_MarkTimerRunning(hndl) BIT_SET_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
406 #define __esos_MarkTimerStopped(hndl) BIT_CLEAR_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
407 
408 
409 // System flag definitions... only ESOS needs to use these
410 #define __ESOS_SYS_FLAG_PACK_TASKS BIT0
411 #define __ESOS_SYS_FLAG_NULL_LAST_TASK BIT1
412 #define __ESOS_SYS_COMM_TX_IS_BUSY BIT2
413 #define __ESOS_SYS_COMM_RX_IS_BUSY BIT3
414 
415 // Other useful macros for the user
416 #define __abs(x) (((x) < 0) ? -(x) : (x))
417 
418 #endif // ESOS_H