µGFX  2.9
version 2.9
gos.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.io/license.html
6  */
7 
8 /**
9  * @file src/gos/gos.h
10  * @brief GOS - Operating System Support header file
11  *
12  * @addtogroup GOS
13  *
14  * @brief Module to build a uniform abstraction layer between uGFX and the underlying system
15  *
16  * @note Some of the routines specified below may be implemented simply as
17  * a macro to the real operating system call.
18  * @{
19  */
20 
21 #ifndef _GOS_H
22 #define _GOS_H
23 
24 #if defined(__DOXYGEN__)
25  /*===========================================================================*/
26  /* Type definitions */
27  /*===========================================================================*/
28 
29  /**
30  * @name Various integer sizes
31  * @note Your platform may define these differently to these.
32  * @note These sizes are guaranteed minimum sizes for the type. It might actually be larger.
33  * eg gI8 may actually be 9 bits.
34  * @{
35  */
36  typedef unsigned char gBool;
37  typedef signed char gI8;
38  typedef unsigned char gU8;
39  typedef short gI16;
40  typedef unsigned short gU16;
41  typedef long gI32;
42  typedef unsigned long gU32;
43  /** @} */
44 
45  /**
46  * @name More integer sizes
47  * @pre These are only available if GFX_TYPE_64 is GFXON as not all compilers support 64 bit.
48  * @note GFX_TYPE_64 is set to GFXON or GFXOFF by the compiler detector. It is not a user configuration macro.
49  * @{
50  */
51  typedef long long gI64;
52  typedef unsigned long long gU64;
53  /** @} */
54 
55  /**
56  * @name Various platform (and operating system) dependent types
57  * @note Your platform may use slightly different definitions to these
58  * @{
59  */
60  typedef unsigned long gDelay;
61  typedef unsigned long gTicks;
62  typedef short gSemcount;
63  typedef int gThreadreturn;
64  typedef int gThreadpriority;
65  /** @} */
66 
67  /**
68  * @brief Declare a thread function
69  *
70  * @param[in] fnName The name of the function
71  * @param[in] param A custom parameter that is passed to the function
72  */
73  #define GFX_THREAD_FUNCTION(fnName, param) gThreadreturn fnName(void *param)
74 
75  /**
76  * @brief Declare a thread stack
77  *
78  * @param[in] name The name of the stack
79  * @param[in] sz The size of the stack in bytes
80  *
81  * @note The size provided is just a suggestion to the required stack size.
82  * Many platforms will round the size to ensure correct stack alignment.
83  * Other platforms may entirely ignore the suggested size.
84  */
85  #define GFX_THREAD_STACK(name, sz) gU8 name[sz];
86 
87  /**
88  * @name Various platform (and operating system) constants
89  * @note Your platform may use slightly different definitions to these
90  * @{
91  */
92  #define gDelayNone 0
93  #define gDelayForever ((gDelay)-1)
94  #define gSemMaxCount ((gSemcount)(((unsigned long)((gSemcount)(-1))) >> 1))
95  #define gThreadpriorityLow 0
96  #define gThreadpriorityNormal 1
97  #define gThreadpriorityHigh 2
98  /** @} */
99 
100  /**
101  * @brief A semaphore
102  * @note Your operating system will have a proper definition for this structure
103  */
104  typedef struct {} gSem;
105 
106  /**
107  * @brief A mutex
108  * @note Your operating system will have a proper definition for this structure
109  */
110  typedef struct {} gMutex;
111 
112  /**
113  * @brief A thread handle
114  * @note Your operating system will have a proper definition for this.
115  */
116  typedef void * gThread;
117 
118  /*===========================================================================*/
119  /* Function declarations. */
120  /*===========================================================================*/
121 
122  /**
123  * @brief Halt the GFX application due to an error.
124  *
125  * @param[in] msg An optional debug message to show (Can be NULL)
126  *
127  * @api
128  */
129  void gfxHalt(const char *msg);
130 
131  /**
132  * @brief Exit the GFX application.
133  *
134  * @api
135  */
136  void gfxExit(void);
137 
138  /**
139  * @brief Allocate memory
140  * @return A pointer to the memory allocated or NULL if there is no more memory available
141  *
142  * @param[in] sz The size in bytes of the area to allocate
143  *
144  * @api
145  */
146  void *gfxAlloc(gMemSize sz);
147 
148  /**
149  * @brief Re-allocate memory
150  * @return A pointer to the new memory area or NULL if there is no more memory available
151  *
152  * @param[in] ptr The old memory area to be increased/decreased in size
153  * @param[in] oldsz The size in bytes of the old memory area
154  * @param[in] newsz The size in bytes of the new memory area
155  *
156  * @note Some operating systems don't use the oldsz parameter as they implicitly know the size of
157  * old memory area. The parameter must always be supplied however for API compatibility.
158  * @note gfxRealloc() can make the area smaller or larger but may have to return a different pointer.
159  * If this occurs the new area contains a copy of the data from the old area. The old memory
160  * pointer should not be used after this routine as the original area may have been freed.
161  * @note If there is insufficient memory to create the new memory region, NULL is returned and the
162  * old memory area is left unchanged.
163  *
164  * @api
165  */
166  void *gfxRealloc(void *ptr, gMemSize oldsz, gMemSize newsz);
167 
168  /**
169  * @brief Free memory
170  *
171  * @param[in] ptr The memory to free
172  *
173  * @api
174  */
175  void gfxFree(void *ptr);
176 
177  /**
178  * @brief Use gfxAlloc and gfxFree to implement malloc() and free()
179  *
180  * @note Sometimes your application will include functions that
181  * want to internally use malloc() and free(). As the default
182  * implementations of these in your C library are almost
183  * invariably incorrect for an embedded platform, this option
184  * allows you to emulate those calls with gfxAlloc() and gfxFree().
185  * An example is the C library routine rand() which on many
186  * implementations internally uses malloc().
187  *
188  * @api
189  */
190  #ifndef GFX_EMULATE_MALLOC
191  #define GFX_EMULATE_MALLOC GFXOFF
192  #endif
193 
194  /**
195  * @brief Yield the current thread
196  * @details Give up the rest of the current time slice for this thread in order to give other threads
197  * a chance to run.
198  *
199  * @api
200  */
201  void gfxYield(void);
202 
203  /**
204  * @brief Put the current thread to sleep for the specified period in milliseconds
205  *
206  * @param[in] ms The number milliseconds to sleep
207  *
208  * @note Specifying gDelayNone will yield the current thread but return
209  * on the next time slice.
210  * @note Specifying gDelayForever will sleep forever.
211  *
212  * @api
213  */
214  void gfxSleepMilliseconds(gDelay ms);
215 
216  /**
217  * @brief Put the current thread to sleep for the specified period in microseconds
218  *
219  * @param[in] us The number microseconds to sleep
220  *
221  * @note Specifying gDelayNone will return immediately (no sleeping)
222  * @note Specifying gDelayForever will sleep forever.
223  *
224  * @api
225  */
226  void gfxSleepMicroseconds(gDelay us);
227 
228  /**
229  * @brief Get the current operating system tick time
230  * @return The current tick time
231  *
232  * @note A "tick" is an arbitrary period of time that the operating
233  * system uses to mark time.
234  * @note The absolute value of this call is relatively meaningless. Its usefulness
235  * is in calculating periods between two calls to this function.
236  * @note As the value from this function can wrap it is important that any periods are calculated
237  * as t2 - t1 and then compared to the desired period rather than comparing
238  * t1 + period to t2
239  *
240  * @api
241  */
242  gTicks gfxSystemTicks(void);
243 
244  /**
245  * @brief Convert a given number of millseconds to a number of operating system ticks
246  * @return The period in system ticks.
247  *
248  * @note A "tick" is an arbitrary period of time that the operating
249  * system uses to mark time.
250  *
251  * @param[in] ms The number of millseconds
252  *
253  * @api
254  */
255  gTicks gfxMillisecondsToTicks(gDelay ms);
256 
257  /**
258  * @brief Lock the operating system to protect a sequence of code
259  *
260  * @note Calling this will lock out all other threads from executing even at interrupt level
261  * within the GFX system. On hardware this may be implemented as a disabling of interrupts,
262  * however in an operating system which hides real interrupt level code it may simply use a
263  * mutex lock.
264  * @note The thread MUST NOT block whilst the system is locked. It must execute in this state for
265  * as short a period as possible as this can seriously affect interrupt latency on some
266  * platforms.
267  * @note While locked only interrupt level (iclass) GFX routines may be called.
268  *
269  * @api
270  */
271  void gfxSystemLock(void);
272 
273  /**
274  * @brief Unlock the operating system previous locked by gfxSystemLock()
275  *
276  * @api
277  */
278  void gfxSystemUnlock(void);
279 
280  /**
281  * @brief Initialise a mutex to protect a region of code from other threads.
282  *
283  * @param[in] pmutex A pointer to the mutex
284  *
285  * @note Whilst a counting semaphore with a limit of 1 can be used for similiar purposes
286  * on many operating systems using a seperate mutex structure is more efficient.
287  *
288  * @api
289  */
290  void gfxMutexInit(gMutex *pmutex);
291 
292  /**
293  * @brief Destroy a Mutex.
294  *
295  * @param[in] pmutex A pointer to the mutex
296  *
297  * @api
298  */
299  void gfxMutexDestroy(gMutex *pmutex);
300 
301  /**
302  * @brief Enter the critical code region protected by the mutex.
303  * @details Blocks until there is no other thread in the critical region.
304  *
305  * @param[in] pmutex A pointer to the mutex
306  *
307  * @api
308  */
309  void gfxMutexEnter(gMutex *pmutex);
310 
311  /**
312  * @brief Exit the critical code region protected by the mutex.
313  * @details May cause another thread waiting on the mutex to now be placed into the run queue.
314  *
315  * @param[in] pmutex A pointer to the mutex
316  *
317  * @api
318  */
319  void gfxMutexExit(gMutex *pmutex);
320 
321  /**
322  * @brief Initialise a Counted Semaphore
323  *
324  * @param[in] psem A pointer to the semaphore
325  * @param[in] val The initial value of the semaphore
326  * @param[in] limit The maxmimum value of the semaphore
327  *
328  * @note Operations defined for counted semaphores:
329  * Signal: The semaphore counter is increased and if the result is non-positive then a waiting thread
330  * is queued for execution. Note that once the thread reaches "limit", further signals are
331  * ignored.
332  * Wait: The semaphore counter is decreased and if the result becomes negative the thread is queued
333  * in the semaphore and suspended.
334  *
335  * @api
336  */
337  void gfxSemInit(gSem *psem, gSemcount val, gSemcount limit);
338 
339  /**
340  * @brief Destroy a Counted Semaphore
341  *
342  * @param[in] psem A pointer to the semaphore
343  *
344  * @note Any threads waiting on the semaphore will be released
345  *
346  * @api
347  */
348  void gfxSemDestroy(gSem *psem);
349 
350  /**
351  * @brief Wait on a semaphore
352  * @details The semaphore counter is decreased and if the result becomes negative the thread waits for it to become
353  * non-negative again
354  * @return gFalse if the wait timeout occurred otherwise gTrue
355  *
356  * @param[in] psem A pointer to the semaphore
357  * @param[in] ms The maximum time to wait for the semaphore
358  *
359  * @api
360  */
361  gBool gfxSemWait(gSem *psem, gDelay ms);
362 
363  /**
364  * @brief Test if a wait on a semaphore can be satisfied immediately
365  * @details Equivalent to @p gfxSemWait(psem, gDelayNone) except it can be called at interrupt level
366  * @return gFalse if the wait would occur occurred otherwise gTrue
367  *
368  * @param[in] psem A pointer to the semaphore
369  *
370  * @iclass
371  * @api
372  */
373  gBool gfxSemWaitI(gSem *psem);
374 
375  /**
376  * @brief Signal a semaphore
377  * @details The semaphore counter is increased and if the result is non-positive then a waiting thread
378  * is queued for execution. Note that once the thread reaches "limit", further signals are
379  * ignored.
380  *
381  * @param[in] psem A pointer to the semaphore
382  *
383  * @api
384  */
385  void gfxSemSignal(gSem *psem);
386 
387  /**
388  * @brief Signal a semaphore
389  * @details The semaphore counter is increased and if the result is non-positive then a waiting thread
390  * is queued for execution. Note that once the thread reaches "limit", further signals are
391  * ignored.
392  *
393  * @param[in] psem A pointer to the semaphore
394  *
395  * @iclass
396  * @api
397  */
398  void gfxSemSignalI(gSem *psem);
399 
400  /**
401  * @brief Start a new thread.
402  * @return Returns a thread handle if the thread was started, NULL on an error
403  *
404  * @param[in] stackarea A pointer to the area for the new threads stack or NULL to dynamically allocate it
405  * @param[in] stacksz The size of the thread stack. 0 means the default operating system size although this
406  * is only valid when stackarea is dynamically allocated.
407  * @param[in] prio The priority of the new thread
408  * @param[in] fn The function the new thread will run
409  * @param[in] param A parameter to pass the thread function.
410  *
411  * @api
412  */
413  gThread gfxThreadCreate(void *stackarea, gMemSize stacksz, gThreadpriority prio, GFX_THREAD_FUNCTION((*fn),p), void *param);
414 
415  /**
416  * @brief Wait for a thread to finish.
417  * @return Returns the thread exit code.
418  *
419  * @param[in] thread The Thread Handle
420  *
421  * @note This will also close the thread handle as it is no longer useful
422  * once the thread has ended.
423  * @api
424  */
425  gThreadreturn gfxThreadWait(gThread thread);
426 
427  /**
428  * @brief Get the current thread handle.
429  * @return A thread handle
430  *
431  * @api
432  */
434 
435  /**
436  * @brief Close the thread handle.
437  *
438  * @param[in] thread The Thread Handle
439  *
440  * @note This does not affect the thread, it just closes our handle to the thread.
441  *
442  * @api
443  */
444  void gfxThreadClose(gThread thread);
445 
446  /*
447  * @brief Return from a thread
448  *
449  * @details Some underlying operating systems allow to return a value from a thread while others don't.
450  * For systems that don't allow to return a value from a thread function this call is simply ignored.
451  * @pre This pseudo function can only be called within the main body of the thread function (not a sub-function)
452  *
453  * @param[in] reval The value which should be returned
454  */
455  #define gfxThreadReturn(retval) return retval
456 
457 /**
458  * All the above was just for the doxygen documentation. All the implementation of the above
459  * (without any of the documentation overheads) is in the files below.
460  */
461 #elif GFX_USE_OS_RAWRTOS
462  #include "gos_rawrtos.h"
463 #elif GFX_USE_OS_CHIBIOS
464  #include "gos_chibios.h"
465 #elif GFX_USE_OS_FREERTOS
466  #include "gos_freertos.h"
467 #elif GFX_USE_OS_WIN32
468  #include "gos_win32.h"
469 #elif GFX_USE_OS_LINUX
470  #include "gos_linux.h"
471 #elif GFX_USE_OS_OSX
472  #include "gos_osx.h"
473 #elif GFX_USE_OS_RAW32
474  #include "gos_raw32.h"
475 #elif GFX_USE_OS_ECOS
476  #include "gos_ecos.h"
477 #elif GFX_USE_OS_ARDUINO
478  #include "gos_arduino.h"
479 #elif GFX_USE_OS_CMSIS
480  #include "gos_cmsis.h"
481 #elif GFX_USE_OS_CMSIS2
482  #include "gos_cmsis2.h"
483 #elif GFX_USE_OS_KEIL
484  #include "gos_keil.h"
485 #elif GFX_USE_OS_RTX5
486  #include "gos_rtx5.h"
487 #elif GFX_USE_OS_NIOS
488  #include "gos_nios.h"
489 #elif GFX_USE_OS_ZEPHYR
490  #include "gos_zephyr.h"
491 #elif GFX_USE_OS_QT
492  #include "gos_qt.h"
493 #else
494  #error "Your operating system is not supported yet"
495 #endif
496 
497 #if GFX_COMPAT_V2
498  typedef gDelay delaytime_t;
499  #if !GFX_USE_OS_CHIBIOS
500  // These values are defined by ChibiOS itself
501  #define TIME_IMMEDIATE gDelayNone
502  #define TIME_INFINITE gDelayForever
503  #endif
504  typedef gTicks systemticks_t;
505  typedef gThread gfxThreadHandle;
506  #define DECLARE_THREAD_FUNCTION GFX_THREAD_FUNCTION
507  #define DECLARE_THREAD_STACK GFX_THREAD_STACK
508  typedef gThreadreturn threadreturn_t;
509  #define THREAD_RETURN gfxThreadReturn
510  typedef gThreadpriority threadpriority_t;
511  #define LOW_PRIORITY gThreadpriorityLow
512  #define NORMAL_PRIORITY gThreadpriorityNormal
513  #define HIGH_PRIORITY gThreadpriorityHigh
514  typedef gSem gfxSem;
515  #define MAX_SEMAPHORE_COUNT gSemMaxCount
516  typedef gMutex gfxMutex;
517 #endif
518 
519 #endif /* _GOS_H */
520 /** @} */
GOS - Operating System Support header file for CMSIS 2.0 RTOS.
GOS - Operating System Support header file for CMSIS RTOS.
GOS - Operating System Support header file for FreeRTOS.
GOS - Operating System Support header file for Keil RTX.
GOS - Operating System Support header file for Keil RTX.
GOS - Operating System Support header file for WIN32.
GOS - Operating System Support header file for Zephyr RTOS. Zephyr SDK 0.9.1.
gThreadreturn gfxThreadWait(gThread thread)
Wait for a thread to finish.
void gfxSemSignal(gSem *psem)
Signal a semaphore.
void * gThread
A thread handle.
Definition: gos.h:116
gTicks gfxSystemTicks(void)
Get the current operating system tick time.
void gfxYield(void)
Yield the current thread.
#define GFX_THREAD_FUNCTION(fnName, param)
Declare a thread function.
Definition: gos.h:73
void gfxMutexExit(gMutex *pmutex)
Exit the critical code region protected by the mutex.
gTicks gfxMillisecondsToTicks(gDelay ms)
Convert a given number of millseconds to a number of operating system ticks.
gBool gfxSemWait(gSem *psem, gDelay ms)
Wait on a semaphore.
void gfxExit(void)
Exit the GFX application.
void gfxSystemUnlock(void)
Unlock the operating system previous locked by gfxSystemLock()
void gfxSleepMicroseconds(gDelay us)
Put the current thread to sleep for the specified period in microseconds.
void gfxMutexEnter(gMutex *pmutex)
Enter the critical code region protected by the mutex.
gThread gfxThreadMe(void)
Get the current thread handle.
void * gfxAlloc(gMemSize sz)
Allocate memory.
void gfxSystemLock(void)
Lock the operating system to protect a sequence of code.
void gfxMutexInit(gMutex *pmutex)
Initialise a mutex to protect a region of code from other threads.
gThread gfxThreadCreate(void *stackarea, gMemSize stacksz, gThreadpriority prio, GFX_THREAD_FUNCTION((*fn), p), void *param)
Start a new thread.
gBool gfxSemWaitI(gSem *psem)
Test if a wait on a semaphore can be satisfied immediately.
void gfxHalt(const char *msg)
Halt the GFX application due to an error.
void gfxSemDestroy(gSem *psem)
Destroy a Counted Semaphore.
void gfxSemInit(gSem *psem, gSemcount val, gSemcount limit)
Initialise a Counted Semaphore.
void * gfxRealloc(void *ptr, gMemSize oldsz, gMemSize newsz)
Re-allocate memory.
void gfxMutexDestroy(gMutex *pmutex)
Destroy a Mutex.
void gfxFree(void *ptr)
Free memory.
void gfxSemSignalI(gSem *psem)
Signal a semaphore.
void gfxSleepMilliseconds(gDelay ms)
Put the current thread to sleep for the specified period in milliseconds.
void gfxThreadClose(gThread thread)
Close the thread handle.
A mutex.
Definition: gos.h:110
A semaphore.
Definition: gos.h:104