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