µGFX  2.9
version 2.9
gos_freertos.c
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 #include "../../gfx.h"
9 #include <string.h>
10 
11 #if GFX_USE_OS_FREERTOS
12 
13 #if INCLUDE_vTaskDelay != 1
14  #error "GOS: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h"
15 #endif
16 
17 #if configUSE_MUTEXES != 1
18  #error "GOS: configUSE_MUTEXES must be defined in FreeRTOSConfig.h"
19 #endif
20 
21 #if configUSE_COUNTING_SEMAPHORES != 1
22  #error "GOS: configUSE_COUNTING_SEMAPHORES must be defined in FreeRTOSConfig.h"
23 #endif
24 
25 #if !GFX_OS_NO_INIT && INCLUDE_xTaskGetSchedulerState != 1 && configUSE_TIMERS != 1
26  #error "GOS: Either INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be defined in FreeRTOSConfig.h"
27 #endif
28 
29 #if !GFX_OS_NO_INIT && !GFX_OS_CALL_UGFXMAIN
30  #error "GOS: Either GFX_OS_NO_INIT or GFX_OS_CALL_UGFXMAIN must be defined for FreeRTOS"
31 #endif
32 
33 void _gosInit(void)
34 {
35  #if GFX_OS_NO_INIT && !GFX_OS_INIT_NO_WARNING
36  #if GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_DIRECT
37  #warning "GOS: Operating System initialization has been turned off. Make sure you call vTaskStartScheduler()."
38  #elif GFX_COMPILER_WARNING_TYPE == GFX_COMPILER_WARNING_MACRO
39  COMPILER_WARNING("GOS: Operating System initialization has been turned off. Make sure you call vTaskStartScheduler().")
40  #endif
41  #endif
42 }
43 
44 #if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN
45  static GFX_THREAD_FUNCTION(startUGFX_FreeRTOS, p) {
46  (void) p;
47  uGFXMain();
48  }
49 #endif
50 
51 void _gosPostInit(void)
52 {
53  #if !GFX_OS_NO_INIT && GFX_OS_CALL_UGFXMAIN
54  if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
55  gfxThreadCreate(0, GFX_OS_UGFXMAIN_STACKSIZE, gThreadpriorityNormal, startUGFX_FreeRTOS, 0);
56  vTaskStartScheduler();
57  gfxHalt("Unable to start FreeRTOS scheduler. Out of memory?");
58  }
59  #endif
60 }
61 
62 void _gosDeinit(void)
63 {
64  #if !GFX_OS_NO_INIT
65  vTaskDelete(0);
66  #endif
67 }
68 
69 void* gfxRealloc(void *ptr, gMemSize oldsz, gMemSize newsz)
70 {
71  void *np;
72 
73  if (newsz <= oldsz)
74  return ptr;
75 
76  np = gfxAlloc(newsz);
77  if (!np)
78  return 0;
79 
80  if (oldsz) {
81  memcpy(np, ptr, oldsz);
82  gfxFree(ptr);
83  }
84 
85  return np;
86 }
87 
88 void gfxSleepMilliseconds(gDelay ms)
89 {
90  vTaskDelay(gfxMillisecondsToTicks(ms));
91 }
92 
93 void gfxSleepMicroseconds(gDelay ms)
94 {
95 
96  // delay milli seconds - microsecond resolution delay is not supported in FreeRTOS
97  vTaskDelay(gfxMillisecondsToTicks(ms/1000));
98  // vUsDelay(ms%1000);
99 }
100 
101 void gfxMutexInit(gMutex *pmutex)
102 {
103  *pmutex = xSemaphoreCreateMutex();
104  #if GFX_FREERTOS_USE_TRACE
105  vTraceSetMutexName(*pmutex,"uGFXMutex");
106  #endif
107 }
108 
109 void gfxSemInit(gSem* psem, gSemcount val, gSemcount limit)
110 {
111  if (val > limit)
112  val = limit;
113 
114  *psem = xSemaphoreCreateCounting(limit,val);
115  #if GFX_FREERTOS_USE_TRACE
116  vTraceSetSemaphoreName(*psem, "uGFXSema");
117  #endif
118 }
119 
120 gBool gfxSemWait(gSem* psem, gDelay ms)
121 {
122  if (xSemaphoreTake(*psem, gfxMillisecondsToTicks(ms)) == pdPASS)
123  return gTrue;
124  return gFalse;
125 }
126 
127 gBool gfxSemWaitI(gSem* psem)
128 {
129  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
130 
131  if (xSemaphoreTakeFromISR(*psem, &xHigherPriorityTaskWoken) == pdTRUE)
132  return gTrue;
133  return gFalse;
134 }
135 
136 void gfxSemSignal(gSem* psem)
137 {
138  xSemaphoreGive(*psem);
139  taskYIELD();
140 }
141 
142 void gfxSemSignalI(gSem* psem)
143 {
144  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
145 
146  xSemaphoreGiveFromISR(*psem,&xHigherPriorityTaskWoken);
147 }
148 
149 gThread gfxThreadCreate(void *stackarea, gMemSize stacksz, gThreadpriority prio, GFX_THREAD_FUNCTION((*fn),p), void *param)
150 {
151  gThread task;
152  (void) stackarea;
153 
154  // uGFX expresses stack size in bytes - FreeRTOS in "Stack Words"
155  stacksz /= sizeof(StackType_t);
156 
157  if (stacksz < configMINIMAL_STACK_SIZE)
158  stacksz = configMINIMAL_STACK_SIZE;
159 
160  task = 0;
161  if (xTaskCreate(fn, "uGFX_TASK", stacksz, param, prio, &task) != pdPASS)
162  return 0;
163 
164  return task;
165 }
166 
167 #if INCLUDE_eTaskGetState == 1
168  gThreadreturn gfxThreadWait(gThread thread) {
169  while (eTaskGetState(thread) != eDeleted)
170  gfxYield();
171  }
172 #endif
173 
174 #endif /* GFX_USE_OS_FREERTOS */
void GFXUSERFN uGFXMain(void)
The user supplied function containing all the user uGFX application code.
gThreadreturn gfxThreadWait(gThread thread)
Wait for a thread to finish.
#define GFX_OS_UGFXMAIN_STACKSIZE
When uGFXMain() is started as a thread, what stack size should be used.
Definition: gos_options.h:227
void gfxSemSignal(gSem *psem)
Signal a semaphore.
void * gThread
A thread handle.
Definition: gos.h:116
void gfxYield(void)
Yield the current thread.
#define GFX_THREAD_FUNCTION(fnName, param)
Declare a thread function.
Definition: gos.h:73
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 gfxSleepMicroseconds(gDelay us)
Put the current thread to sleep for the specified period in microseconds.
void * gfxAlloc(gMemSize sz)
Allocate memory.
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 gfxSemInit(gSem *psem, gSemcount val, gSemcount limit)
Initialise a Counted Semaphore.
void * gfxRealloc(void *ptr, gMemSize oldsz, gMemSize newsz)
Re-allocate memory.
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.
A mutex.
Definition: gos.h:110
A semaphore.
Definition: gos.h:104