Companion: Russian UI (#7180)
[opentx.git] / radio / src / rtos.h
blob6e42ebf3061a0954033225bcba8002c71f38833b
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #ifndef _RTOS_H_
22 #define _RTOS_H_
24 #include "definitions.h"
26 #ifdef __cplusplus
27 extern "C++" {
28 #endif
30 #if defined(SIMU)
31 #include <pthread.h>
32 #include <semaphore.h>
34 #define SIMU_SLEEP_OR_EXIT_MS(x) simuSleep(x)
35 #define RTOS_MS_PER_TICK 1
37 typedef pthread_t RTOS_TASK_HANDLE;
38 typedef pthread_mutex_t RTOS_MUTEX_HANDLE;
39 typedef uint32_t RTOS_FLAG_HANDLE;
40 typedef sem_t * RTOS_EVENT_HANDLE;
42 extern uint64_t simuTimerMicros(void);
43 extern uint8_t simuSleep(uint32_t ms);
45 static inline void RTOS_INIT()
49 static inline void RTOS_START()
53 static inline void RTOS_WAIT_MS(uint32_t x)
55 simuSleep(x);
58 static inline void RTOS_WAIT_TICKS(uint32_t x)
60 RTOS_WAIT_MS(x * RTOS_MS_PER_TICK);
63 #ifdef __cplusplus
64 static inline void RTOS_CREATE_MUTEX(pthread_mutex_t &mutex)
66 mutex = PTHREAD_MUTEX_INITIALIZER;
69 static inline void RTOS_LOCK_MUTEX(pthread_mutex_t &mutex)
71 pthread_mutex_lock(&mutex);
74 static inline void RTOS_UNLOCK_MUTEX(pthread_mutex_t &mutex)
76 pthread_mutex_unlock(&mutex);
79 static inline void RTOS_CREATE_FLAG(uint32_t &flag)
81 flag = 0; // TODO: real flags (use semaphores?)
84 static inline void RTOS_SET_FLAG(uint32_t &flag)
86 flag = 1;
89 template<int SIZE>
90 class FakeTaskStack
92 public:
93 FakeTaskStack()
97 void paint()
101 uint32_t size()
103 return SIZE;
106 uint32_t available()
108 return SIZE / 2;
111 #define RTOS_DEFINE_STACK(name, size) FakeTaskStack<size> name
113 #define TASK_FUNCTION(task) void * task(void * pdata)
115 inline void RTOS_CREATE_TASK(pthread_t &taskId, void * task(void *), const char * name)
117 pthread_create(&taskId, nullptr, task, nullptr);
118 #ifdef __linux__
119 pthread_setname_np(taskId, name);
120 #endif
123 template<int SIZE>
124 inline void RTOS_CREATE_TASK(pthread_t &taskId, void * task(void *), const char * name, FakeTaskStack<SIZE> &, unsigned size = 0, unsigned priority = 0)
126 UNUSED(size);
127 UNUSED(priority);
128 RTOS_CREATE_TASK(taskId, task, name);
131 #define TASK_RETURN() return nullptr
133 constexpr uint32_t stackAvailable()
135 return 500;
137 #endif // __cplusplus
139 // return 2ms resolution to match CoOS settings
140 static inline uint32_t RTOS_GET_TIME(void)
142 return (uint32_t)(simuTimerMicros() / 2000);
145 static inline uint32_t RTOS_GET_MS(void)
147 return (uint32_t)(simuTimerMicros() / 1000);
149 #elif defined(RTOS_COOS)
150 #ifdef __cplusplus
151 extern "C" {
152 #endif
153 #include <CoOS.h>
154 #ifdef __cplusplus
156 #endif
158 #define RTOS_MS_PER_TICK ((CFG_CPU_FREQ / CFG_SYSTICK_FREQ) / (CFG_CPU_FREQ / 1000)) // RTOS timer tick length in ms (currently 2)
160 typedef OS_TID RTOS_TASK_HANDLE;
161 typedef OS_MutexID RTOS_MUTEX_HANDLE;
162 typedef OS_FlagID RTOS_FLAG_HANDLE;
163 typedef OS_EventID RTOS_EVENT_HANDLE;
165 static inline void RTOS_INIT()
167 CoInitOS();
170 static inline void RTOS_START()
172 CoStartOS();
175 static inline void RTOS_WAIT_MS(uint32_t x)
177 if (!x)
178 return;
179 if ((x = x / RTOS_MS_PER_TICK) < 1)
180 x = 1;
181 CoTickDelay(x);
184 static inline void RTOS_WAIT_TICKS(uint32_t x)
186 CoTickDelay(x);
189 #define RTOS_CREATE_TASK(taskId, task, name, stackStruct, stackSize, priority) \
190 taskId = CoCreateTask(task, NULL, priority, &stackStruct.stack[stackSize-1], stackSize)
192 #ifdef __cplusplus
193 static inline void RTOS_CREATE_MUTEX(OS_MutexID &mutex)
195 mutex = CoCreateMutex();
198 static inline void RTOS_LOCK_MUTEX(OS_MutexID &mutex)
200 CoEnterMutexSection(mutex);
203 static inline void RTOS_UNLOCK_MUTEX(OS_MutexID &mutex)
205 CoLeaveMutexSection(mutex);
207 #endif // __cplusplus
209 static inline uint32_t getStackAvailable(void * address, uint32_t size)
211 uint32_t * array = (uint32_t *)address;
212 uint32_t i = 0;
213 while (i < size && array[i] == 0x55555555) {
214 i++;
216 return i;
219 extern int _estack;
220 extern int _main_stack_start;
221 static inline uint32_t stackSize()
223 return ((unsigned char *)&_estack - (unsigned char *)&_main_stack_start) / 4;
226 static inline uint32_t stackAvailable()
228 return getStackAvailable(&_main_stack_start, stackSize());
231 #define RTOS_CREATE_FLAG(flag) flag = CoCreateFlag(false, false)
232 #define RTOS_SET_FLAG(flag) (void)CoSetFlag(flag)
234 #ifdef __cplusplus
235 template<int SIZE>
236 class TaskStack
238 public:
239 TaskStack()
243 void paint()
245 for (uint32_t i=0; i<SIZE; i++) {
246 stack[i] = 0x55555555;
250 uint32_t size()
252 return SIZE * 4;
255 uint32_t available()
257 return getStackAvailable(stack, SIZE);
260 OS_STK stack[SIZE];
262 #endif // __cplusplus
264 static inline uint32_t RTOS_GET_TIME(void)
266 return (uint32_t)CoGetOSTime();
269 static inline uint32_t RTOS_GET_MS(void)
271 return (RTOS_GET_TIME() * RTOS_MS_PER_TICK);
274 #define RTOS_DEFINE_STACK(name, size) TaskStack<size> __ALIGNED(8) name // stack must be aligned to 8 bytes otherwise printf for %f does not work!
276 #define TASK_FUNCTION(task) void task(void * pdata)
277 #define TASK_RETURN() return
279 #else // no RTOS
280 static inline void RTOS_START()
284 static inline void RTOS_WAIT_MS(unsigned x)
288 static inline void RTOS_WAIT_TICKS(unsigned x)
291 #endif // RTOS type
293 #ifdef __cplusplus
295 #endif
297 #endif // _RTOS_H_