The official µGFX library repository.

gos.h 14KB

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