PIC24 Support Libraries
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 // Place this define here because many of the the following INCLUDE files need this macro variable
45 #define MAX_NUM_USER_TASKS 16
46 
47 
48 // Include all the files we need
49 //#include "user_config.h" // get the user's configuration requests
50 #include "all_generic.h"
51 #include "esos_task.h" // defines ESOS tasks and semaphores
52 #include "esos_mail.h" // defines ESOS task mailboxes (eventually make MAILBOXes optional)
53 
54 // PUT THESE HERE FOR NOW. They belong somewhere else
55 // in the long-run.
56 //
57 // PC versions do NOT have IRQs (yet) so do NOT define the variables
58 #ifndef __linux
59 #define ESOS_USE_IRQS
60 #endif
61 #define ESOS_USE_SERIAL_PORT
62 
63 /**
64 * Define the constants and structures required for our little
65 * embedded systems operating system
66 */
67 #if defined(ESOS_USE_BULK_CDC_USB) || defined(ESOS_USE_SERIAL_PORT)
68 #include "esos_comm.h"
69 #endif // USE_USB or USE_SERIAL
70 
71 #ifdef ESOS_USE_IRQS
72 /*
73 * user wants IRQ support, so prototype the required IRQ functions
74 */
75 #include "esos_irq.h"
76 #endif //ESOS_USE_IRQS
77 
78 #ifdef ESOS_RUNS_ON_REAL_OS
79 // computers running a host OS (windoze/Linux/etc) expect
80 // their applications to return and return a value
81 // so define a return type for main and create a return statement
82 // also, multitasking OS-es will want some CPU time for other
83 // applications, so sleep some (10ms = 10000us) should be enough
84 typedef int main_t;
85 #define OS_END return(1)
86 #define OS_ITERATE usleep(10000)
87 #else
88 // hardware w/o a hosting OS will never return. So main_t
89 // must be void return type and hang-up when done!
90 // (Of course, real hardware apps should never be done.)
91 typedef int main_t;
92 #define OS_END while(1)
93 #define OS_ITERATE
94 #endif
95 
96 //*********************************************************************
97 // P R I V A T E D E F I N I T I O N S
98 //*********************************************************************
99 /**
100  * Define the maximum number of user tasks in the system
101  * \note Technically, this is actually the maximum number of
102  * tasks that will be running "concurrently". Usually,
103  * this number is the maximum number of tasks that the
104  * user has defined, UNLESS they are absolutely sure that
105  * two (or more) tasks are mutually exclusive in execution.
106  *
107  * \note BOTH "parent" and "child" tasks use this NUMBER to allocate
108  * their pool of tasks. So this number should be equal to or greater
109  * than the MAXIMUM number of concurrently running child --OR--
110  * parent tasks.
111  */
112 #define MAX_NUM_CHILD_TASKS MAX_NUM_USER_TASKS
113 #define REMOVE_IDX 0xFE
114 
115 
116 /* S T R U C T U R E S ******************************************************/
117 /**
118 * structure to contain a set of descriptors about the buffers used
119 * to implement ESOS task mailboxes
120 **/
122  volatile uint8_t* pau8_Data;
123  int16_t u16_Head;
124  int16_t u16_Tail;
125  uint16_t u16_Length;
126  struct stTask pst_Task;
127 };
128 
129 /**
130 * structure to contain a mail message "envelope" -- a set of descriptors
131 * about a mail message and the contents within
132 **/
134  uint16_t u16_Header;
135  uint32_t u32_Postmark;
136 };
137 
138 struct stTimer {
139  void (*pfn)(void);
140  uint32_t u32_period;
141  uint32_t u32_cntDown;
142 };
143 
144 // Define masks for the user to use for their flags
145 /** Mask for a global user flag provided by ESOS
146  * \hideinitializer
147  */
148 #define ESOS_USER_FLAG_0 BIT0
149 /** Mask for a global user flag provided by ESOS
150  * \hideinitializer
151  */
152 #define ESOS_USER_FLAG_1 BIT1
153 /** Mask for a global user flag provided by ESOS
154  * \hideinitializer
155  */
156 #define ESOS_USER_FLAG_2 BIT2
157 /** Mask for a global user flag provided by ESOS
158  * \hideinitializer
159  */
160 #define ESOS_USER_FLAG_3 BIT3
161 /** Mask for a global user flag provided by ESOS
162  * \hideinitializer
163  */
164 #define ESOS_USER_FLAG_4 BIT4
165 /** Mask for a global user flag provided by ESOS
166  * \hideinitializer
167  */
168 #define ESOS_USER_FLAG_5 BIT5
169 /** Mask for a global user flag provided by ESOS
170  * \hideinitializer
171  */
172 #define ESOS_USER_FLAG_6 BIT6
173 /** Mask for a global user flag provided by ESOS
174  * \hideinitializer
175  */
176 #define ESOS_USER_FLAG_7 BIT7
177 /** Mask for a global user flag provided by ESOS
178  * \hideinitializer
179  */
180 #define ESOS_USER_FLAG_8 BIT8
181 /** Mask for a global user flag provided by ESOS
182  * \hideinitializer
183  */
184 #define ESOS_USER_FLAG_9 BIT9
185 /** Mask for a global user flag provided by ESOS
186  * \hideinitializer
187  */
188 #define ESOS_USER_FLAG_A BIT10
189 /** Mask for a global user flag provided by ESOS
190  * \hideinitializer
191  */
192 #define ESOS_USER_FLAG_B BIT11
193 /** Mask for a global user flag provided by ESOS
194  * \hideinitializer
195  */
196 #define ESOS_USER_FLAG_C BIT12
197 /** Mask for a global user flag provided by ESOS
198  * \hideinitializer
199  */
200 #define ESOS_USER_FLAG_D BIT13
201 /** Mask for a global user flag provided by ESOS
202  * \hideinitializer
203  */
204 #define ESOS_USER_FLAG_E BIT14
205 /** Mask for a global user flag provided by ESOS
206  * \hideinitializer
207  */
208 #define ESOS_USER_FLAG_F BIT15
209 
210 
211 /**
212  * Declaration of an user-defined timer callback (for ESOS timer services)
213  *
214  * This macro is used to declare a user-timer. All timers using ESOS timer
215  * services must be declared with this macro.
216  *
217  * \param timername The name of the software timer to create.
218  * \note You are really creating a C function implementing the user timer callback.
219  * Since ESOS timer serivces calls this callback function at the appropriate time,
220  * this function cannot be passed arguments and cannot return values
221  * \hideinitializer
222  */
223 #define ESOS_USER_TIMER(timername) void timername(void)
224 
225 /**
226  * Handle to a software timer in the ESOS timer service.
227  *
228  * \sa ESOS_USER_TIMER
229  * \sa esos_RegisterTimer
230  * \sa esos_UnregisterTimer
231  * \sa esos_GetTimerHandle
232  * \sa esos_ChangeTimerPeriod
233  *
234  * \hideinitializer
235  */
237 
238 /*
239  * Now define the public user function prototypes that are
240  * always available regardless of the user_config settings
241  */
242 /**
243  * User-provided function to initialize user's hardware configuration
244  * register user tasks.
245  *
246  * \note All ESOS applications <em>MUST</em> provide this function.
247  * \note This function <em>MUST</em> register at least one ESOS task.
248  *
249  * \note user_init() is a centralized initialization routine where
250  * the user can setup their application. It is called
251  * automagically by ES_OS during the operating system
252  * initialization.
253  *
254  * \note User should set up any state machines and init
255  * all application variables. They can also turn on
256  * any needed peripherals here.
257  *
258  * \note User <em>shall not</em> mess with the interrupt hardware
259  * directly!!! The ESOS must be aware of the interrupts
260  * and provides esos_XXXXXXX functions for the user to use.
261  * Using these ESOS-provided functions, the user may
262  * (and probably should) initialize, register, and enable
263  * interrupts in this routine.
264  *
265  * \note Furthermore, the user should register AT LEAST one
266  * user application task here via \ref esos_RegisterTask
267  * or the ES_OS scheduler will have nothing to schedule
268  * to run when this function returns.
269  * \hideinitializer
270  */
271 
272 void user_init( void );
273 ESOS_TASK_HANDLE esos_RegisterTask( uint8_t (*pfn_TaskFcn)(struct stTask *pst_Task) );
274 uint8_t esos_UnregisterTask( uint8_t (*pfn_TaskFcn)(struct stTask *pst_Task) ) ;
276 uint32_t esos_GetRandomUint32();
278 ESOS_TASK_HANDLE esos_GetTaskHandleFromID( uint16_t u16_TaskID );
279 
280 // ESOS-provided hash functions
281 uint16_t esos_hash_u32_to_u16(uint32_t u32_hash);
282 uint32_t esos_string_hash_u32(char *psz_str);
283 uint32_t esos_buffer_hash_u32(void *buf, uint16_t len);
284 
285 
286 // prototypes for ESOS software timers
287 ESOS_TMR_HANDLE esos_RegisterTimer( void (*pfnTmrFcn)(void), uint32_t u32_period );
289 ESOS_TMR_HANDLE esos_GetTimerHandle( void (*pfnTmrFcn)(void) );
290 uint8_t esos_ChangeTimerPeriod( ESOS_TMR_HANDLE hnd_timer, uint32_t u32_period );
291 
292 // The user must provide the HW-specific way of getting a 32bit 1.0ms tick
293 void __esos_hw_InitSystemTick(void);
294 uint32_t __esos_hw_GetSystemTickCount(void);
295 
296 /**
297  * Get the current value of the ESOS system tick counter
298  * In the current implementation of ESOS, a tick equal 1.0ms.
299  * Therefore, the value returned by this function is approximately
300  * equal to the number of milliseconds since the since was last
301  * reset.
302  * \return The uint32 value of current value of the ESOS
303  * system tick counter
304  * \note This counter value will roll-over every 49.7 days.
305  * \hideinitializer
306  */
307 #define esos_GetSystemTick() __esos_hw_GetSystemTickCount()
308 
309 
310 uint16_t __esos_hasTickDurationPassed(uint32_t u32_startTick, uint32_t u32_period);
311 void __esos_tmrSvcsExecute(void);
312 
313 void __esos_InitCommSystem(void);
314 
315 
316 /*
317  * expose these ESOS system variables to allow macro access
318  * intead of fcn access
319  */
320 extern uint8_t __esos_u8UserTasksRegistered;
321 extern uint16_t __esos_u16UserFlags, __esos_u16SystemFlags;
322 extern uint32_t __esos_u32FNVHash;
323 
324 /**
325  * Get the current number of user task registered with the
326  * ESOS scheduler.
327  * \return The uint8_t number of currently registered user tasks
328  * \note This value does not include the number of child tasks
329  * (tasks of the type \ref ESOS_CHILD_TASK ), just the tasks
330  * of the type \ref ESOS_USER_TASK
331  * \hideinitializer
332  */
333 #define esos_GetNumberRegisteredTasks() (__esos_u8UserTasksRegistered)
334 
335 /**
336  * Returns the system tick value of a future time
337  * \param deltaT the number of ticks in the future you'd like the
338  * system tick value for
339  * \return The uint32 number corresponding to the system tick
340  * value of that future time
341  * \sa esos_GetSystemTick
342  * \hideinitializer
343  */
344 #define esos_GetFutureSystemTick(deltaT) ((uint32_t)(deltaT) + __esos_hw_GetSystemTickCount());
345 
346 /**
347  * Sets bits in the global user flags provided by ESOS
348  * \param mask An uint16 value composed of the OR-ed user
349  * mask flag masks, where each flag in the OR will be set
350  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
351  * to create their own readable constants
352  * \code
353  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
354  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
355  * esos_SetUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
356  * \endcode
357  * \sa esos_ClearUserFlag
358  * \sa esos_IsUserFlagSet
359  * \sa esos_IsUserFlagClear
360  * \hideinitializer
361  */
362 #define esos_SetUserFlag(mask) BIT_SET_MASK(__esos_u16UserFlags, (mask))
363 
364 /**
365  * Clears bits in the global user flags provided by ESOS
366  * \param mask An uint16 value composed of the OR-ed user
367  * mask flag masks, where each flag in the OR will be cleared
368  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
369  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
370  * to create their own readable constants
371  * \code
372  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
373  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
374  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
375  * \endcode
376  * \sa esos_SetUserFlag
377  * \sa esos_IsUserFlagSet
378  * \sa esos_IsUserFlagClear
379  * \hideinitializer
380  */
381 
382 #define esos_ClearUserFlag(mask) BIT_CLEAR_MASK(__esos_u16UserFlags, (mask))
383 
384 /**
385  * Queries whether the global user flags provided by ESOS are set
386  * \param mask An uint16 value composed of the OR-ed user
387  * mask flag masks, where each flag in the OR will be checked for being set
388  * \retval TRUE if <em>at least</em> one of the flags is set
389  * \retval FALSE if none of the flags are set
390  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
391  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
392  * to create their own readable constants
393  * \code
394  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
395  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
396  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
397  * while(esos_IsUserFlagSet( HEADLIGHTS_ARE_ON)); // falls through
398  * \endcode
399  * \sa esos_SetUserFlag
400  * \sa esos_ClearUserFlag
401  * \sa esos_IsUserFlagClear
402  * \hideinitializer
403  */
404 #define esos_IsUserFlagSet(mask) IS_BIT_SET_MASK(__esos_u16UserFlags, (mask))
405 
406 /**
407  * Queries whether the global user flags provided by ESOS are clear
408  * \param mask An uint16 value composed of the OR-ed user
409  * mask flag masks, where each flag in the OR will be checked for being clear
410  * \retval TRUE if <em>at least</em> one of the flags is clear
411  * \retval FALSE if none of the flags are clear
412  * \note User should use the provided bits masks like \ref ESOS_USER_FLAG_0
413  * and \ref ESOS_USER_FLAG_1 and ... \ref ESOS_USER_FLAG_F
414  * to create their own readable constants
415  * \code
416  * #define HEADLIGHTS_ARE_ON ESOS_USER_FLAG_3
417  * #define MY_USER_FRIENDLY_FLAG ESOS_USER_FLAG_7
418  * esos_ClearUserFlag( HEADLIGHTS_ARE_ON | MY_USER_FRIENDLY_FLAG);
419  * while(esos_IsUserFlagClear( HEADLIGHTS_ARE_ON)); // infinite loop
420  * \endcode
421  * \sa esos_SetUserFlag
422  * \sa esos_ClearUserFlag
423  * \sa esos_IsUserFlagSet
424  * \hideinitializer
425  */
426 #define esos_IsUserFlagClear(mask) IS_BIT_CLEAR_MASK(__esos_u16UserFlags, (mask))
427 
428 // define macros for ESOS system flags
429 // these flags are NOT to be manipulated directly by the user!
430 #define __esos_SetSystemFlag(mask) BIT_SET_MASK(__esos_u16SystemFlags, (mask))
431 #define __esos_ClearSystemFlag(mask) BIT_CLEAR_MASK(__esos_u16SystemFlags, (mask))
432 #define __esos_IsSystemFlagSet(mask) IS_BIT_SET_MASK(__esos_u16SystemFlags, (mask))
433 #define __esos_IsSystemFlagClear(mask) IS_BIT_CLEAR_MASK(__esos_u16SystemFlags, (mask))
434 
435 // Defines for ESOS timer services
436 #define ESOS_TMR_FAILURE 0xFF
437 #define MAX_NUM_TMRS 16
438 
439 /**
440  * Get the current number of user software timers registers (running)
441  * in the ESOS timer services
442  * \return The uint8_t number of currently registered user tasks
443  * \hideinitializer
444  */
445 #define esos_GetNumberRunningTimers() (__esos_u8TmrSvcsRegistered)
446 
447 /**
448  * Determines if the software timer represented by the handle is currently running
449  * \param hndl The \ref ESOS_TMR_HANDLE of a software timer
450  * \retval TRUE if the timer is currently running
451  * \retval FALSE if the timer is not currently running
452  * \sa ESOS_USER_TIMER
453  * \sa esos_UnregisterTimer
454  * \sa esos_GetTimerHandle
455  * \sa esos_ChangeTimerPeriod
456  * \hideinitializer
457  */
458 #define esos_IsTimerRunning(hndl) IS_BIT_SET_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
459 #define __esos_MarkTimerRunning(hndl) BIT_SET_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
460 #define __esos_MarkTimerStopped(hndl) BIT_CLEAR_MASK(__esos_u16TmrActiveFlags, (BIT0<<(hndl)))
461 
462 
463 // System flag definitions... only ESOS needs to use these
464 #define __ESOS_SYS_FLAG_PACK_TASKS BIT0
465 #define __ESOS_SYS_FLAG_NULL_LAST_TASK BIT1
466 #define __ESOS_SYS_COMM_TX_IS_BUSY BIT2
467 #define __ESOS_SYS_COMM_RX_IS_BUSY BIT3
468 #define __ESOS_SYS_I2C_IS_BUSY BIT4
469 #define __ESOS_SYS_SPI_IS_BUSY BIT5
470 #define __ESOS_SYS_ADC_IS_BUSY BIT6
471 
472 // Other useful macros for the user
473 #define __abs(x) (((x) < 0) ? -(x) : (x))
474 
475 #endif // ESOS_H
ESOS_TASK_HANDLE esos_GetFreeChildTaskStruct()
Definition: esos.c:298
ESOS_TASK_HANDLE esos_RegisterTask(uint8_t(*taskname)(ESOS_TASK_HANDLE pstTask))
Definition: esos.c:86
uint32_t esos_GetRandomUint32()
Definition: esos.c:332
ESOS_TASK_HANDLE esos_GetTaskHandleFromID(uint16_t u16_TaskID)
Definition: esos.c:255
uint8_t ESOS_TMR_HANDLE
Definition: esos.h:236
ESOS_TMR_HANDLE esos_RegisterTimer(void(*pfnTmrFcn)(void), uint32_t u32_period)
Definition: esos.c:514
uint8_t esos_UnregisterTimer(ESOS_TMR_HANDLE hnd_timer)
Definition: esos.c:543
void user_init(void)
ESOS_TASK_HANDLE esos_GetTaskHandle(uint8_t(*taskname)(ESOS_TASK_HANDLE pstTask))
Definition: esos.c:219
uint32_t esos_string_hash_u32(char *psz_str)
Definition: esos.c:415
int main_t
Definition: esos.h:91
ESOS_TMR_HANDLE esos_GetTimerHandle(void(*pfnTmrFcn)(void))
Definition: esos.c:564
uint8_t esos_UnregisterTask(uint8_t(*taskname)(ESOS_TASK_HANDLE pstTask))
Definition: esos.c:178
uint8_t esos_ChangeTimerPeriod(ESOS_TMR_HANDLE hnd_timer, uint32_t u32_period)
Definition: esos.c:591
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194
Embedded Systems Operating System (ESOS) Definitions to make ESOS code more generic and portable...
uint32_t esos_buffer_hash_u32(void *buf, uint16_t len)
Definition: esos.c:379