version 2.8
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.org/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 DECLARE_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, NORMAL_PRIORITY, 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, size_t oldsz, size_t 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(delaytime_t ms)
89 {
90  vTaskDelay(gfxMillisecondsToTicks(ms));
91 }
92 
93 void gfxSleepMicroseconds(delaytime_t 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(gfxMutex *pmutex)
102 {
103  *pmutex = xSemaphoreCreateMutex();
104  #if GFX_FREERTOS_USE_TRACE
105  vTraceSetMutexName(*pmutex,"uGFXMutex");
106  #endif
107 }
108 
109 void gfxSemInit(gfxSem* psem, semcount_t val, semcount_t 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 bool_t gfxSemWait(gfxSem* psem, delaytime_t ms)
121 {
122  if (xSemaphoreTake(*psem, gfxMillisecondsToTicks(ms)) == pdPASS)
123  return TRUE;
124  return FALSE;
125 }
126 
127 bool_t gfxSemWaitI(gfxSem* psem)
128 {
129  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
130 
131  if (xSemaphoreTakeFromISR(*psem, &xHigherPriorityTaskWoken) == pdTRUE)
132  return TRUE;
133  return FALSE;
134 }
135 
136 void gfxSemSignal(gfxSem* psem)
137 {
138  xSemaphoreGive(*psem);
139  taskYIELD();
140 }
141 
142 void gfxSemSignalI(gfxSem* psem)
143 {
144  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
145 
146  xSemaphoreGiveFromISR(*psem,&xHigherPriorityTaskWoken);
147 }
148 
149 gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param)
150 {
151  gfxThreadHandle 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  threadreturn_t gfxThreadWait(gfxThreadHandle thread) {
169  while (eTaskGetState(thread) != eDeleted)
170  gfxYield();
171  }
172 #endif
173 
174 #endif /* GFX_USE_OS_FREERTOS */
void * gfxThreadHandle
A thread handle.
Definition: gos.h:117
#define GFX_OS_UGFXMAIN_STACKSIZE
When uGFXMain() is started as a thread, what stack size should be used.
Definition: gos_options.h:227
void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit)
Initialise a Counted Semaphore.
#define FALSE
Generic &#39;false&#39; boolean constant.
Definition: gfx.h:31
systemticks_t gfxMillisecondsToTicks(delaytime_t ms)
Convert a given number of millseconds to a number of operating system ticks.
void * gfxAlloc(size_t sz)
Allocate memory.
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
void * gfxRealloc(void *ptr, size_t oldsz, size_t newsz)
Re-allocate memory.
#define DECLARE_THREAD_FUNCTION(fnName, param)
Declare a thread function.
Definition: gos.h:62
void gfxFree(void *ptr)
Free memory.
void gfxHalt(const char *msg)
Halt the GFX application due to an error.
void uGFXMain(void)
The function containing all the user uGFX application code.
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 gfxMutexInit(gfxMutex *pmutex)
Initialise a mutex to protect a region of code from other threads.
void gfxYield(void)
Yield the current thread.
#define TRUE
Generic &#39;true&#39; boolean constant.
Definition: gfx.h:38
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.