diff options
Diffstat (limited to 'lib/chibios/os/hal/osal')
-rw-r--r-- | lib/chibios/os/hal/osal/lib/osal_vt.c | 168 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/lib/osal_vt.h | 123 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c | 467 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h | 754 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk | 11 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/AVR/osal.c | 467 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/AVR/osal.h | 677 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/os-less/AVR/osal.mk | 9 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/rt-nil/osal.c | 51 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/rt-nil/osal.h | 1092 | ||||
-rw-r--r-- | lib/chibios/os/hal/osal/rt-nil/osal.mk | 9 |
11 files changed, 3828 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/osal/lib/osal_vt.c b/lib/chibios/os/hal/osal/lib/osal_vt.c new file mode 100644 index 000000000..29f60dfb5 --- /dev/null +++ b/lib/chibios/os/hal/osal/lib/osal_vt.c | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal_vt.c | ||
19 | * @brief OSAL Virtual Timers module code. | ||
20 | * @details This module can be used in an OSAL implementation whenever an | ||
21 | * underlying RTOS is unable to provide timeout services or there | ||
22 | * is no underlying RTOS. | ||
23 | * | ||
24 | * @addtogroup OSAL_VT | ||
25 | * @{ | ||
26 | */ | ||
27 | |||
28 | #include "osal.h" | ||
29 | #include "osal_vt.h" | ||
30 | |||
31 | /*===========================================================================*/ | ||
32 | /* Module local definitions. */ | ||
33 | /*===========================================================================*/ | ||
34 | |||
35 | /*===========================================================================*/ | ||
36 | /* Module exported variables. */ | ||
37 | /*===========================================================================*/ | ||
38 | |||
39 | /** | ||
40 | * @brief Virtual timers delta list header. | ||
41 | */ | ||
42 | virtual_timers_list_t vtlist; | ||
43 | |||
44 | /*===========================================================================*/ | ||
45 | /* Module local types. */ | ||
46 | /*===========================================================================*/ | ||
47 | |||
48 | /*===========================================================================*/ | ||
49 | /* Module local variables. */ | ||
50 | /*===========================================================================*/ | ||
51 | |||
52 | /*===========================================================================*/ | ||
53 | /* Module local functions. */ | ||
54 | /*===========================================================================*/ | ||
55 | |||
56 | /*===========================================================================*/ | ||
57 | /* Module exported functions. */ | ||
58 | /*===========================================================================*/ | ||
59 | |||
60 | /** | ||
61 | * @brief Timers initialization. | ||
62 | * | ||
63 | * @init | ||
64 | */ | ||
65 | void vtInit(void) { | ||
66 | |||
67 | /* Virtual Timers initialization.*/ | ||
68 | vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; | ||
69 | vtlist.vt_delta = (sysinterval_t)-1; | ||
70 | vtlist.vt_systime = 0; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * @brief Returns @p TRUE if the specified timer is armed. | ||
75 | * | ||
76 | * @param[out] vtp the @p virtual_timer_t structure pointer | ||
77 | * | ||
78 | * @iclass | ||
79 | */ | ||
80 | bool vtIsArmedI(virtual_timer_t *vtp) { | ||
81 | |||
82 | return vtp->vt_func != NULL; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * @brief Virtual timers ticker. | ||
87 | * @note The system lock is released before entering the callback and | ||
88 | * re-acquired immediately after. It is callback's responsibility | ||
89 | * to acquire the lock if needed. This is done in order to reduce | ||
90 | * interrupts jitter when many timers are in use. | ||
91 | * | ||
92 | * @iclass | ||
93 | */ | ||
94 | void vtDoTickI(void) { | ||
95 | |||
96 | vtlist.vt_systime++; | ||
97 | if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) { | ||
98 | virtual_timer_t *vtp; | ||
99 | |||
100 | --vtlist.vt_next->vt_delta; | ||
101 | while (!(vtp = vtlist.vt_next)->vt_delta) { | ||
102 | vtfunc_t fn = vtp->vt_func; | ||
103 | vtp->vt_func = (vtfunc_t)NULL; | ||
104 | vtp->vt_next->vt_prev = (void *)&vtlist; | ||
105 | (&vtlist)->vt_next = vtp->vt_next; | ||
106 | osalSysUnlockFromISR(); | ||
107 | fn(vtp->vt_par); | ||
108 | osalSysLockFromISR(); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * @brief Enables a virtual timer. | ||
115 | * @note The associated function is invoked from interrupt context. | ||
116 | * | ||
117 | * @param[out] vtp the @p virtual_timer_t structure pointer | ||
118 | * @param[in] timeout the number of ticks before the operation timeouts, the | ||
119 | * special values are handled as follow: | ||
120 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
121 | * normal time specification. | ||
122 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
123 | * . | ||
124 | * @param[in] vtfunc the timer callback function. After invoking the | ||
125 | * callback the timer is disabled and the structure can | ||
126 | * be disposed or reused. | ||
127 | * @param[in] par a parameter that will be passed to the callback | ||
128 | * function | ||
129 | * | ||
130 | * @iclass | ||
131 | */ | ||
132 | void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout, | ||
133 | vtfunc_t vtfunc, void *par) { | ||
134 | virtual_timer_t *p; | ||
135 | |||
136 | vtp->vt_par = par; | ||
137 | vtp->vt_func = vtfunc; | ||
138 | p = vtlist.vt_next; | ||
139 | while (p->vt_delta < timeout) { | ||
140 | timeout -= p->vt_delta; | ||
141 | p = p->vt_next; | ||
142 | } | ||
143 | |||
144 | vtp->vt_prev = (vtp->vt_next = p)->vt_prev; | ||
145 | vtp->vt_prev->vt_next = p->vt_prev = vtp; | ||
146 | vtp->vt_delta = timeout; | ||
147 | if (p != (void *)&vtlist) | ||
148 | p->vt_delta -= timeout; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * @brief Disables a Virtual Timer. | ||
153 | * @note The timer MUST be active when this function is invoked. | ||
154 | * | ||
155 | * @param[in] vtp the @p virtual_timer_t structure pointer | ||
156 | * | ||
157 | * @iclass | ||
158 | */ | ||
159 | void vtResetI(virtual_timer_t *vtp) { | ||
160 | |||
161 | if (vtp->vt_next != (void *)&vtlist) | ||
162 | vtp->vt_next->vt_delta += vtp->vt_delta; | ||
163 | vtp->vt_prev->vt_next = vtp->vt_next; | ||
164 | vtp->vt_next->vt_prev = vtp->vt_prev; | ||
165 | vtp->vt_func = (vtfunc_t)NULL; | ||
166 | } | ||
167 | |||
168 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/lib/osal_vt.h b/lib/chibios/os/hal/osal/lib/osal_vt.h new file mode 100644 index 000000000..41373418b --- /dev/null +++ b/lib/chibios/os/hal/osal/lib/osal_vt.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal_vt.h | ||
19 | * @brief OSAL Virtual Timers module header. | ||
20 | * | ||
21 | * @addtogroup OSAL_VT | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #ifndef _OSAL_VT_H_ | ||
26 | #define _OSAL_VT_H_ | ||
27 | |||
28 | /*===========================================================================*/ | ||
29 | /* Module constants. */ | ||
30 | /*===========================================================================*/ | ||
31 | |||
32 | /*===========================================================================*/ | ||
33 | /* Module pre-compile time settings. */ | ||
34 | /*===========================================================================*/ | ||
35 | |||
36 | /*===========================================================================*/ | ||
37 | /* Derived constants and error checks. */ | ||
38 | /*===========================================================================*/ | ||
39 | |||
40 | /*===========================================================================*/ | ||
41 | /* Module data structures and types. */ | ||
42 | /*===========================================================================*/ | ||
43 | |||
44 | /** | ||
45 | * @brief Type of a Virtual Timer callback function. | ||
46 | */ | ||
47 | typedef void (*vtfunc_t)(void *); | ||
48 | |||
49 | /** | ||
50 | * @brief Type of a Virtual Timer structure. | ||
51 | */ | ||
52 | typedef struct virtual_timer virtual_timer_t; | ||
53 | |||
54 | /** | ||
55 | * @brief Virtual timers list header. | ||
56 | * @note The content of this structure is not part of the API and should | ||
57 | * not be relied upon. Implementers may define this structure in | ||
58 | * an entirely different way. | ||
59 | * @note The delta list is implemented as a double link bidirectional list | ||
60 | * in order to make the unlink time constant, the reset of a virtual | ||
61 | * timer is often used in the code. | ||
62 | */ | ||
63 | typedef struct { | ||
64 | virtual_timer_t *vt_next; /**< @brief Next timer in the timers | ||
65 | list. */ | ||
66 | virtual_timer_t *vt_prev; /**< @brief Last timer in the timers | ||
67 | list. */ | ||
68 | sysinterval_t vt_delta; /**< @brief Must be initialized to -1. */ | ||
69 | volatile systime_t vt_systime; /**< @brief System Time counter. */ | ||
70 | } virtual_timers_list_t; | ||
71 | |||
72 | /** | ||
73 | * @extends virtual_timers_list_t | ||
74 | * | ||
75 | * @brief Virtual Timer descriptor structure. | ||
76 | * @note The content of this structure is not part of the API and should | ||
77 | * not be relied upon. Implementers may define this structure in | ||
78 | * an entirely different way. | ||
79 | */ | ||
80 | struct virtual_timer { | ||
81 | virtual_timer_t *vt_next; /**< @brief Next timer in the timers | ||
82 | list. */ | ||
83 | virtual_timer_t *vt_prev; /**< @brief Previous timer in the timers | ||
84 | list. */ | ||
85 | sysinterval_t vt_delta; /**< @brief Time delta before timeout. */ | ||
86 | vtfunc_t vt_func; /**< @brief Timer callback function | ||
87 | pointer. */ | ||
88 | void *vt_par; /**< @brief Timer callback function | ||
89 | parameter. */ | ||
90 | }; | ||
91 | |||
92 | /*===========================================================================*/ | ||
93 | /* Module macros. */ | ||
94 | /*===========================================================================*/ | ||
95 | |||
96 | /*===========================================================================*/ | ||
97 | /* External declarations. */ | ||
98 | /*===========================================================================*/ | ||
99 | |||
100 | #if !defined(__DOXYGEN__) | ||
101 | extern virtual_timers_list_t vtlist; | ||
102 | #endif | ||
103 | |||
104 | #ifdef __cplusplus | ||
105 | extern "C" { | ||
106 | #endif | ||
107 | void vtInit(void); | ||
108 | bool vtIsArmedI(virtual_timer_t *vtp); | ||
109 | void vtDoTickI(void); | ||
110 | void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout, | ||
111 | vtfunc_t vtfunc, void *par); | ||
112 | void vtResetI(virtual_timer_t *vtp); | ||
113 | #ifdef __cplusplus | ||
114 | } | ||
115 | #endif | ||
116 | |||
117 | /*===========================================================================*/ | ||
118 | /* Module inline functions. */ | ||
119 | /*===========================================================================*/ | ||
120 | |||
121 | #endif /* _OSAL_VT_H_ */ | ||
122 | |||
123 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c new file mode 100644 index 000000000..a4cb7aabf --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c | |||
@@ -0,0 +1,467 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.c | ||
19 | * @brief OSAL module code. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #include "osal.h" | ||
26 | #include "osal_vt.h" | ||
27 | |||
28 | /*===========================================================================*/ | ||
29 | /* Module local definitions. */ | ||
30 | /*===========================================================================*/ | ||
31 | |||
32 | /*===========================================================================*/ | ||
33 | /* Module exported variables. */ | ||
34 | /*===========================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @brief Pointer to a halt error message. | ||
38 | * @note The message is meant to be retrieved by the debugger after the | ||
39 | * system halt caused by an unexpected error. | ||
40 | */ | ||
41 | const char *osal_halt_msg; | ||
42 | |||
43 | /*===========================================================================*/ | ||
44 | /* Module local types. */ | ||
45 | /*===========================================================================*/ | ||
46 | |||
47 | /*===========================================================================*/ | ||
48 | /* Module local variables. */ | ||
49 | /*===========================================================================*/ | ||
50 | |||
51 | /*===========================================================================*/ | ||
52 | /* Module local functions. */ | ||
53 | /*===========================================================================*/ | ||
54 | |||
55 | static void callback_timeout(void *p) { | ||
56 | osalSysLockFromISR(); | ||
57 | osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT); | ||
58 | osalSysUnlockFromISR(); | ||
59 | } | ||
60 | |||
61 | /*===========================================================================*/ | ||
62 | /* Module exported functions. */ | ||
63 | /*===========================================================================*/ | ||
64 | |||
65 | /** | ||
66 | * @brief OSAL module initialization. | ||
67 | * | ||
68 | * @api | ||
69 | */ | ||
70 | void osalInit(void) { | ||
71 | |||
72 | vtInit(); | ||
73 | |||
74 | OSAL_INIT_HOOK(); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * @brief System halt with error message. | ||
79 | * | ||
80 | * @param[in] reason the halt message pointer | ||
81 | * | ||
82 | * @api | ||
83 | */ | ||
84 | #if !defined(__DOXYGEN__) | ||
85 | __attribute__((weak, noreturn)) | ||
86 | #endif | ||
87 | void osalSysHalt(const char *reason) { | ||
88 | |||
89 | osalSysDisable(); | ||
90 | osal_halt_msg = reason; | ||
91 | while (true) { | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * @brief Polled delay. | ||
97 | * @note The real delay is always few cycles in excess of the specified | ||
98 | * value. | ||
99 | * | ||
100 | * @param[in] cycles number of cycles | ||
101 | * | ||
102 | * @xclass | ||
103 | */ | ||
104 | void osalSysPolledDelayX(rtcnt_t cycles) { | ||
105 | |||
106 | (void)cycles; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * @brief System timer handler. | ||
111 | * @details The handler is used for scheduling and Virtual Timers management. | ||
112 | * | ||
113 | * @iclass | ||
114 | */ | ||
115 | void osalOsTimerHandlerI(void) { | ||
116 | |||
117 | osalDbgCheckClassI(); | ||
118 | |||
119 | vtDoTickI(); | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * @brief Checks if a reschedule is required and performs it. | ||
124 | * @note I-Class functions invoked from thread context must not reschedule | ||
125 | * by themselves, an explicit reschedule using this function is | ||
126 | * required in this scenario. | ||
127 | * @note Not implemented in this simplified OSAL. | ||
128 | * | ||
129 | * @sclass | ||
130 | */ | ||
131 | void osalOsRescheduleS(void) { | ||
132 | |||
133 | } | ||
134 | |||
135 | /** | ||
136 | * @brief Current system time. | ||
137 | * @details Returns the number of system ticks since the @p osalInit() | ||
138 | * invocation. | ||
139 | * @note The counter can reach its maximum and then restart from zero. | ||
140 | * @note This function can be called from any context but its atomicity | ||
141 | * is not guaranteed on architectures whose word size is less than | ||
142 | * @p systime_t size. | ||
143 | * | ||
144 | * @return The system time in ticks. | ||
145 | * | ||
146 | * @xclass | ||
147 | */ | ||
148 | systime_t osalOsGetSystemTimeX(void) { | ||
149 | |||
150 | return vtlist.vt_systime; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * @brief Suspends the invoking thread for the specified time. | ||
155 | * | ||
156 | * @param[in] time the delay in system ticks, the special values are | ||
157 | * handled as follow: | ||
158 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
159 | * normal time specification. | ||
160 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
161 | * . | ||
162 | * | ||
163 | * @sclass | ||
164 | */ | ||
165 | void osalThreadSleepS(sysinterval_t time) { | ||
166 | virtual_timer_t vt; | ||
167 | thread_reference_t tr; | ||
168 | |||
169 | tr = NULL; | ||
170 | vtSetI(&vt, time, callback_timeout, (void *)&tr); | ||
171 | osalThreadSuspendS(&tr); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * @brief Suspends the invoking thread for the specified time. | ||
176 | * | ||
177 | * @param[in] time the delay in system ticks, the special values are | ||
178 | * handled as follow: | ||
179 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
180 | * normal time specification. | ||
181 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
182 | * . | ||
183 | * | ||
184 | * @api | ||
185 | */ | ||
186 | void osalThreadSleep(sysinterval_t time) { | ||
187 | |||
188 | osalSysLock(); | ||
189 | osalThreadSleepS(time); | ||
190 | osalSysUnlock(); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
195 | * @note This function must reschedule, it can only be called from thread | ||
196 | * context. | ||
197 | * | ||
198 | * @param[in] trp a pointer to a thread reference object | ||
199 | * @return The wake up message. | ||
200 | * | ||
201 | * @sclass | ||
202 | */ | ||
203 | msg_t osalThreadSuspendS(thread_reference_t *trp) { | ||
204 | thread_t self = {MSG_WAIT}; | ||
205 | |||
206 | osalDbgCheck(trp != NULL); | ||
207 | |||
208 | *trp = &self; | ||
209 | while (self.message == MSG_WAIT) { | ||
210 | osalSysUnlock(); | ||
211 | /* A state-changing interrupt could occur here and cause the loop to | ||
212 | terminate, an hook macro is executed while waiting.*/ | ||
213 | OSAL_IDLE_HOOK(); | ||
214 | osalSysLock(); | ||
215 | } | ||
216 | |||
217 | return self.message; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
222 | * @note This function must reschedule, it can only be called from thread | ||
223 | * context. | ||
224 | * | ||
225 | * @param[in] trp a pointer to a thread reference object | ||
226 | * @param[in] timeout the timeout in system ticks, the special values are | ||
227 | * handled as follow: | ||
228 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
229 | * state. | ||
230 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
231 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
232 | * occurred. | ||
233 | * . | ||
234 | * @return The wake up message. | ||
235 | * @retval MSG_TIMEOUT if the operation timed out. | ||
236 | * | ||
237 | * @sclass | ||
238 | */ | ||
239 | msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) { | ||
240 | msg_t msg; | ||
241 | virtual_timer_t vt; | ||
242 | |||
243 | osalDbgCheck(trp != NULL); | ||
244 | |||
245 | if (TIME_INFINITE == timeout) | ||
246 | return osalThreadSuspendS(trp); | ||
247 | |||
248 | vtSetI(&vt, timeout, callback_timeout, (void *)trp); | ||
249 | msg = osalThreadSuspendS(trp); | ||
250 | if (vtIsArmedI(&vt)) | ||
251 | vtResetI(&vt); | ||
252 | |||
253 | return msg; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * @brief Wakes up a thread waiting on a thread reference object. | ||
258 | * @note This function must not reschedule because it can be called from | ||
259 | * ISR context. | ||
260 | * | ||
261 | * @param[in] trp a pointer to a thread reference object | ||
262 | * @param[in] msg the message code | ||
263 | * | ||
264 | * @iclass | ||
265 | */ | ||
266 | void osalThreadResumeI(thread_reference_t *trp, msg_t msg) { | ||
267 | |||
268 | osalDbgCheck(trp != NULL); | ||
269 | |||
270 | if (*trp != NULL) { | ||
271 | (*trp)->message = msg; | ||
272 | *trp = NULL; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * @brief Wakes up a thread waiting on a thread reference object. | ||
278 | * @note This function must reschedule, it can only be called from thread | ||
279 | * context. | ||
280 | * | ||
281 | * @param[in] trp a pointer to a thread reference object | ||
282 | * @param[in] msg the message code | ||
283 | * | ||
284 | * @iclass | ||
285 | */ | ||
286 | void osalThreadResumeS(thread_reference_t *trp, msg_t msg) { | ||
287 | |||
288 | osalDbgCheck(trp != NULL); | ||
289 | |||
290 | if (*trp != NULL) { | ||
291 | (*trp)->message = msg; | ||
292 | *trp = NULL; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * @brief Enqueues the caller thread. | ||
298 | * @details The caller thread is enqueued and put to sleep until it is | ||
299 | * dequeued or the specified timeouts expires. | ||
300 | * | ||
301 | * @param[in] tqp pointer to the threads queue object | ||
302 | * @param[in] timeout the timeout in system ticks, the special values are | ||
303 | * handled as follow: | ||
304 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
305 | * state. | ||
306 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
307 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
308 | * occurred. | ||
309 | * . | ||
310 | * @return The message from @p osalQueueWakeupOneI() or | ||
311 | * @p osalQueueWakeupAllI() functions. | ||
312 | * @retval MSG_TIMEOUT if the thread has not been dequeued within the | ||
313 | * specified timeout or if the function has been | ||
314 | * invoked with @p TIME_IMMEDIATE as timeout | ||
315 | * specification. | ||
316 | * | ||
317 | * @sclass | ||
318 | */ | ||
319 | msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) { | ||
320 | msg_t msg; | ||
321 | virtual_timer_t vt; | ||
322 | |||
323 | osalDbgCheck(tqp != NULL); | ||
324 | |||
325 | if (TIME_IMMEDIATE == timeout) | ||
326 | return MSG_TIMEOUT; | ||
327 | |||
328 | tqp->tr = NULL; | ||
329 | |||
330 | if (TIME_INFINITE == timeout) | ||
331 | return osalThreadSuspendS(&tqp->tr); | ||
332 | |||
333 | vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr); | ||
334 | msg = osalThreadSuspendS(&tqp->tr); | ||
335 | if (vtIsArmedI(&vt)) | ||
336 | vtResetI(&vt); | ||
337 | |||
338 | return msg; | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * @brief Dequeues and wakes up one thread from the queue, if any. | ||
343 | * | ||
344 | * @param[in] tqp pointer to the threads queue object | ||
345 | * @param[in] msg the message code | ||
346 | * | ||
347 | * @iclass | ||
348 | */ | ||
349 | void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) { | ||
350 | |||
351 | osalDbgCheck(tqp != NULL); | ||
352 | |||
353 | osalThreadResumeI(&tqp->tr, msg); | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * @brief Dequeues and wakes up all threads from the queue. | ||
358 | * | ||
359 | * @param[in] tqp pointer to the threads queue object | ||
360 | * @param[in] msg the message code | ||
361 | * | ||
362 | * @iclass | ||
363 | */ | ||
364 | void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) { | ||
365 | |||
366 | osalDbgCheck(tqp != NULL); | ||
367 | |||
368 | osalThreadResumeI(&tqp->tr, msg); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * @brief Add flags to an event source object. | ||
373 | * | ||
374 | * @param[in] esp pointer to the event flags object | ||
375 | * @param[in] flags flags to be ORed to the flags mask | ||
376 | * | ||
377 | * @iclass | ||
378 | */ | ||
379 | void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) { | ||
380 | |||
381 | osalDbgCheck(esp != NULL); | ||
382 | |||
383 | esp->flags |= flags; | ||
384 | if (esp->cb != NULL) { | ||
385 | esp->cb(esp); | ||
386 | } | ||
387 | } | ||
388 | |||
389 | /** | ||
390 | * @brief Add flags to an event source object. | ||
391 | * | ||
392 | * @param[in] esp pointer to the event flags object | ||
393 | * @param[in] flags flags to be ORed to the flags mask | ||
394 | * | ||
395 | * @iclass | ||
396 | */ | ||
397 | void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) { | ||
398 | |||
399 | osalDbgCheck(esp != NULL); | ||
400 | |||
401 | osalSysLock(); | ||
402 | osalEventBroadcastFlagsI(esp, flags); | ||
403 | osalSysUnlock(); | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * @brief Event callback setup. | ||
408 | * @note The callback is invoked from ISR context and can | ||
409 | * only invoke I-Class functions. The callback is meant | ||
410 | * to wakeup the task that will handle the event by | ||
411 | * calling @p osalEventGetAndClearFlagsI(). | ||
412 | * @note This function is not part of the OSAL API and is provided | ||
413 | * exclusively as an example and for convenience. | ||
414 | * | ||
415 | * @param[in] esp pointer to the event flags object | ||
416 | * @param[in] cb pointer to the callback function | ||
417 | * @param[in] param parameter to be passed to the callback function | ||
418 | * | ||
419 | * @api | ||
420 | */ | ||
421 | void osalEventSetCallback(event_source_t *esp, | ||
422 | eventcallback_t cb, | ||
423 | void *param) { | ||
424 | |||
425 | osalDbgCheck(esp != NULL); | ||
426 | |||
427 | esp->cb = cb; | ||
428 | esp->param = param; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * @brief Locks the specified mutex. | ||
433 | * @post The mutex is locked and inserted in the per-thread stack of owned | ||
434 | * mutexes. | ||
435 | * | ||
436 | * @param[in,out] mp pointer to the @p mutex_t object | ||
437 | * | ||
438 | * @api | ||
439 | */ | ||
440 | void osalMutexLock(mutex_t *mp) { | ||
441 | |||
442 | osalDbgCheck(mp != NULL); | ||
443 | |||
444 | *mp = 1; | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * @brief Unlocks the specified mutex. | ||
449 | * @note The HAL guarantees to release mutex in reverse lock order. The | ||
450 | * mutex being unlocked is guaranteed to be the last locked mutex | ||
451 | * by the invoking thread. | ||
452 | * The implementation can rely on this behavior and eventually | ||
453 | * ignore the @p mp parameter which is supplied in order to support | ||
454 | * those OSes not supporting a stack of the owned mutexes. | ||
455 | * | ||
456 | * @param[in,out] mp pointer to the @p mutex_t object | ||
457 | * | ||
458 | * @api | ||
459 | */ | ||
460 | void osalMutexUnlock(mutex_t *mp) { | ||
461 | |||
462 | osalDbgCheck(mp != NULL); | ||
463 | |||
464 | *mp = 0; | ||
465 | } | ||
466 | |||
467 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h new file mode 100644 index 000000000..0ec4ee199 --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h | |||
@@ -0,0 +1,754 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.h | ||
19 | * @brief OSAL module header. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #ifndef OSAL_H | ||
26 | #define OSAL_H | ||
27 | |||
28 | #include <stddef.h> | ||
29 | #include <stdint.h> | ||
30 | #include <stdbool.h> | ||
31 | |||
32 | #include "cmparams.h" | ||
33 | |||
34 | #include "osalconf.h" | ||
35 | |||
36 | /*===========================================================================*/ | ||
37 | /* Module constants. */ | ||
38 | /*===========================================================================*/ | ||
39 | |||
40 | /** | ||
41 | * @name Common constants | ||
42 | * @{ | ||
43 | */ | ||
44 | #if !defined(FALSE) || defined(__DOXYGEN__) | ||
45 | #define FALSE 0 | ||
46 | #endif | ||
47 | |||
48 | #if !defined(TRUE) || defined(__DOXYGEN__) | ||
49 | #define TRUE 1 | ||
50 | #endif | ||
51 | |||
52 | #define OSAL_SUCCESS false | ||
53 | #define OSAL_FAILED true | ||
54 | /** @} */ | ||
55 | |||
56 | /** | ||
57 | * @name Messages | ||
58 | * @{ | ||
59 | */ | ||
60 | #define MSG_OK (msg_t)0 | ||
61 | #define MSG_RESET (msg_t)-1 | ||
62 | #define MSG_TIMEOUT (msg_t)-2 | ||
63 | #define MSG_WAIT (msg_t)-10 | ||
64 | /** @} */ | ||
65 | |||
66 | /** | ||
67 | * @name Special time constants | ||
68 | * @{ | ||
69 | */ | ||
70 | #define TIME_IMMEDIATE ((sysinterval_t)0) | ||
71 | #define TIME_INFINITE ((sysinterval_t)-1) | ||
72 | /** @} */ | ||
73 | |||
74 | /** | ||
75 | * @name Systick modes. | ||
76 | * @{ | ||
77 | */ | ||
78 | #define OSAL_ST_MODE_NONE 0 | ||
79 | #define OSAL_ST_MODE_PERIODIC 1 | ||
80 | #define OSAL_ST_MODE_FREERUNNING 2 | ||
81 | /** @} */ | ||
82 | |||
83 | /** | ||
84 | * @name Systick parameters. | ||
85 | * @{ | ||
86 | */ | ||
87 | /** | ||
88 | * @brief Size in bits of the @p systick_t type. | ||
89 | */ | ||
90 | #define OSAL_ST_RESOLUTION 32 | ||
91 | |||
92 | /** | ||
93 | * @brief Systick mode required by the underlying OS. | ||
94 | */ | ||
95 | #define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC | ||
96 | /** @} */ | ||
97 | |||
98 | /** | ||
99 | * @name IRQ-related constants | ||
100 | * @{ | ||
101 | */ | ||
102 | /** | ||
103 | * @brief Total priority levels. | ||
104 | */ | ||
105 | #define OSAL_IRQ_PRIORITY_LEVELS (1U << CORTEX_PRIORITY_BITS) | ||
106 | |||
107 | /** | ||
108 | * @brief Highest IRQ priority for HAL drivers. | ||
109 | */ | ||
110 | #if (CORTEX_MODEL == 0) || defined(__DOXYGEN__) | ||
111 | #define OSAL_IRQ_MAXIMUM_PRIORITY 0 | ||
112 | #else | ||
113 | #define OSAL_IRQ_MAXIMUM_PRIORITY 1 | ||
114 | #endif | ||
115 | |||
116 | /** | ||
117 | * @brief Converts from numeric priority to BASEPRI register value. | ||
118 | */ | ||
119 | #define OSAL_BASEPRI(priority) ((priority) << (8U - CORTEX_PRIORITY_BITS)) | ||
120 | /** @} */ | ||
121 | |||
122 | /*===========================================================================*/ | ||
123 | /* Module pre-compile time settings. */ | ||
124 | /*===========================================================================*/ | ||
125 | |||
126 | /** | ||
127 | * @brief Frequency in Hertz of the system tick. | ||
128 | */ | ||
129 | #if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__) | ||
130 | #define OSAL_ST_FREQUENCY 1000 | ||
131 | #endif | ||
132 | |||
133 | /** | ||
134 | * @brief Enables OSAL assertions. | ||
135 | */ | ||
136 | #if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) | ||
137 | #define OSAL_DBG_ENABLE_ASSERTS FALSE | ||
138 | #endif | ||
139 | |||
140 | /** | ||
141 | * @brief Enables OSAL functions parameters checks. | ||
142 | */ | ||
143 | #if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) | ||
144 | #define OSAL_DBG_ENABLE_CHECKS FALSE | ||
145 | #endif | ||
146 | |||
147 | /** | ||
148 | * @brief OSAL initialization hook. | ||
149 | */ | ||
150 | #if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__) | ||
151 | #define OSAL_INIT_HOOK() | ||
152 | #endif | ||
153 | |||
154 | /** | ||
155 | * @brief Idle loop hook macro. | ||
156 | */ | ||
157 | #if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__) | ||
158 | #define OSAL_IDLE_HOOK() | ||
159 | #endif | ||
160 | |||
161 | /*===========================================================================*/ | ||
162 | /* Derived constants and error checks. */ | ||
163 | /*===========================================================================*/ | ||
164 | |||
165 | /*===========================================================================*/ | ||
166 | /* Module data structures and types. */ | ||
167 | /*===========================================================================*/ | ||
168 | |||
169 | /** | ||
170 | * @brief Type of a system status word. | ||
171 | */ | ||
172 | typedef uint32_t syssts_t; | ||
173 | |||
174 | /** | ||
175 | * @brief Type of a message. | ||
176 | */ | ||
177 | typedef int32_t msg_t; | ||
178 | |||
179 | /** | ||
180 | * @brief Type of system time counter. | ||
181 | */ | ||
182 | typedef uint32_t systime_t; | ||
183 | |||
184 | /** | ||
185 | * @brief Type of system time interval. | ||
186 | */ | ||
187 | typedef uint32_t sysinterval_t; | ||
188 | |||
189 | /** | ||
190 | * @brief Type of realtime counter. | ||
191 | */ | ||
192 | typedef uint32_t rtcnt_t; | ||
193 | |||
194 | /** | ||
195 | * @brief Type of a thread. | ||
196 | * @note The content of this structure is not part of the API and should | ||
197 | * not be relied upon. Implementers may define this structure in | ||
198 | * an entirely different way. | ||
199 | */ | ||
200 | typedef struct { | ||
201 | volatile msg_t message; | ||
202 | } thread_t; | ||
203 | |||
204 | /** | ||
205 | * @brief Type of a thread reference. | ||
206 | */ | ||
207 | typedef thread_t * thread_reference_t; | ||
208 | |||
209 | /** | ||
210 | * @brief Type of an event flags mask. | ||
211 | */ | ||
212 | typedef uint32_t eventflags_t; | ||
213 | |||
214 | /** | ||
215 | * @brief Type of an event flags object. | ||
216 | * @note The content of this structure is not part of the API and should | ||
217 | * not be relied upon. Implementers may define this structure in | ||
218 | * an entirely different way. | ||
219 | * @note Retrieval and clearing of the flags are not defined in this | ||
220 | * API and are implementation-dependent. | ||
221 | */ | ||
222 | typedef struct event_source event_source_t; | ||
223 | |||
224 | /** | ||
225 | * @brief Type of an event source callback. | ||
226 | * @note This type is not part of the OSAL API and is provided | ||
227 | * exclusively as an example and for convenience. | ||
228 | */ | ||
229 | typedef void (*eventcallback_t)(event_source_t *esp); | ||
230 | |||
231 | /** | ||
232 | * @brief Events source object. | ||
233 | * @note The content of this structure is not part of the API and should | ||
234 | * not be relied upon. Implementers may define this structure in | ||
235 | * an entirely different way. | ||
236 | * @note Retrieval and clearing of the flags are not defined in this | ||
237 | * API and are implementation-dependent. | ||
238 | */ | ||
239 | struct event_source { | ||
240 | volatile eventflags_t flags; /**< @brief Stored event flags. */ | ||
241 | eventcallback_t cb; /**< @brief Event source callback. */ | ||
242 | void *param; /**< @brief User defined field. */ | ||
243 | }; | ||
244 | |||
245 | /** | ||
246 | * @brief Type of a mutex. | ||
247 | * @note If the OS does not support mutexes or there is no OS then them | ||
248 | * mechanism can be simulated. | ||
249 | */ | ||
250 | typedef uint32_t mutex_t; | ||
251 | |||
252 | /** | ||
253 | * @brief Type of a thread queue. | ||
254 | * @details A thread queue is a queue of sleeping threads, queued threads | ||
255 | * can be dequeued one at time or all together. | ||
256 | * @note If the OSAL is implemented on a bare metal machine without RTOS | ||
257 | * then the queue can be implemented as a single thread reference. | ||
258 | */ | ||
259 | typedef struct { | ||
260 | thread_reference_t tr; | ||
261 | } threads_queue_t; | ||
262 | |||
263 | /*===========================================================================*/ | ||
264 | /* Module macros. */ | ||
265 | /*===========================================================================*/ | ||
266 | |||
267 | /** | ||
268 | * @name Debug related macros | ||
269 | * @{ | ||
270 | */ | ||
271 | /** | ||
272 | * @brief Condition assertion. | ||
273 | * @details If the condition check fails then the OSAL panics with a | ||
274 | * message and halts. | ||
275 | * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS | ||
276 | * switch is enabled. | ||
277 | * @note The remark string is not currently used except for putting a | ||
278 | * comment in the code about the assertion. | ||
279 | * | ||
280 | * @param[in] c the condition to be verified to be true | ||
281 | * @param[in] remark a remark string | ||
282 | * | ||
283 | * @api | ||
284 | */ | ||
285 | #define osalDbgAssert(c, remark) do { \ | ||
286 | /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ | ||
287 | if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \ | ||
288 | if (!(c)) { \ | ||
289 | /*lint -restore*/ \ | ||
290 | osalSysHalt(__func__); \ | ||
291 | } \ | ||
292 | } \ | ||
293 | } while (false) | ||
294 | |||
295 | /** | ||
296 | * @brief Function parameters check. | ||
297 | * @details If the condition check fails then the OSAL panics and halts. | ||
298 | * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch | ||
299 | * is enabled. | ||
300 | * | ||
301 | * @param[in] c the condition to be verified to be true | ||
302 | * | ||
303 | * @api | ||
304 | */ | ||
305 | #define osalDbgCheck(c) do { \ | ||
306 | /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ | ||
307 | if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \ | ||
308 | if (!(c)) { \ | ||
309 | /*lint -restore*/ \ | ||
310 | osalSysHalt(__func__); \ | ||
311 | } \ | ||
312 | } \ | ||
313 | } while (false) | ||
314 | |||
315 | /** | ||
316 | * @brief I-Class state check. | ||
317 | * @note Implementation is optional. | ||
318 | */ | ||
319 | #define osalDbgCheckClassI() | ||
320 | |||
321 | /** | ||
322 | * @brief S-Class state check. | ||
323 | * @note Implementation is optional. | ||
324 | */ | ||
325 | #define osalDbgCheckClassS() | ||
326 | /** @} */ | ||
327 | |||
328 | /** | ||
329 | * @name IRQ service routines wrappers | ||
330 | * @{ | ||
331 | */ | ||
332 | /** | ||
333 | * @brief Priority level verification macro. | ||
334 | */ | ||
335 | #define OSAL_IRQ_IS_VALID_PRIORITY(n) \ | ||
336 | (((n) >= OSAL_IRQ_MAXIMUM_PRIORITY) && ((n) < OSAL_IRQ_PRIORITY_LEVELS)) | ||
337 | |||
338 | /** | ||
339 | * @brief IRQ prologue code. | ||
340 | * @details This macro must be inserted at the start of all IRQ handlers. | ||
341 | */ | ||
342 | #define OSAL_IRQ_PROLOGUE() | ||
343 | |||
344 | /** | ||
345 | * @brief IRQ epilogue code. | ||
346 | * @details This macro must be inserted at the end of all IRQ handlers. | ||
347 | */ | ||
348 | #define OSAL_IRQ_EPILOGUE() | ||
349 | |||
350 | /** | ||
351 | * @brief IRQ handler function declaration. | ||
352 | * @details This macro hides the details of an ISR function declaration. | ||
353 | * | ||
354 | * @param[in] id a vector name as defined in @p vectors.s | ||
355 | */ | ||
356 | #define OSAL_IRQ_HANDLER(id) void id(void) | ||
357 | /** @} */ | ||
358 | |||
359 | /** | ||
360 | * @name Time conversion utilities | ||
361 | * @{ | ||
362 | */ | ||
363 | /** | ||
364 | * @brief Seconds to system ticks. | ||
365 | * @details Converts from seconds to system ticks number. | ||
366 | * @note The result is rounded upward to the next tick boundary. | ||
367 | * | ||
368 | * @param[in] secs number of seconds | ||
369 | * @return The number of ticks. | ||
370 | * | ||
371 | * @api | ||
372 | */ | ||
373 | #define OSAL_S2I(secs) \ | ||
374 | ((sysinterval_t)((uint32_t)(secs) * (uint32_t)OSAL_ST_FREQUENCY)) | ||
375 | |||
376 | /** | ||
377 | * @brief Milliseconds to system ticks. | ||
378 | * @details Converts from milliseconds to system ticks number. | ||
379 | * @note The result is rounded upward to the next tick boundary. | ||
380 | * | ||
381 | * @param[in] msecs number of milliseconds | ||
382 | * @return The number of ticks. | ||
383 | * | ||
384 | * @api | ||
385 | */ | ||
386 | #define OSAL_MS2I(msecs) \ | ||
387 | ((sysinterval_t)((((((uint32_t)(msecs)) * \ | ||
388 | ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000UL) + 1UL)) | ||
389 | |||
390 | /** | ||
391 | * @brief Microseconds to system ticks. | ||
392 | * @details Converts from microseconds to system ticks number. | ||
393 | * @note The result is rounded upward to the next tick boundary. | ||
394 | * | ||
395 | * @param[in] usecs number of microseconds | ||
396 | * @return The number of ticks. | ||
397 | * | ||
398 | * @api | ||
399 | */ | ||
400 | #define OSAL_US2I(usecs) \ | ||
401 | ((sysinterval_t)((((((uint32_t)(usecs)) * \ | ||
402 | ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000000UL) + 1UL)) | ||
403 | /** @} */ | ||
404 | |||
405 | /** | ||
406 | * @name Time conversion utilities for the realtime counter | ||
407 | * @{ | ||
408 | */ | ||
409 | /** | ||
410 | * @brief Seconds to realtime counter. | ||
411 | * @details Converts from seconds to realtime counter cycles. | ||
412 | * @note The macro assumes that @p freq >= @p 1. | ||
413 | * | ||
414 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
415 | * @param[in] sec number of seconds | ||
416 | * @return The number of cycles. | ||
417 | * | ||
418 | * @api | ||
419 | */ | ||
420 | #define OSAL_S2RTC(freq, sec) ((freq) * (sec)) | ||
421 | |||
422 | /** | ||
423 | * @brief Milliseconds to realtime counter. | ||
424 | * @details Converts from milliseconds to realtime counter cycles. | ||
425 | * @note The result is rounded upward to the next millisecond boundary. | ||
426 | * @note The macro assumes that @p freq >= @p 1000. | ||
427 | * | ||
428 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
429 | * @param[in] msec number of milliseconds | ||
430 | * @return The number of cycles. | ||
431 | * | ||
432 | * @api | ||
433 | */ | ||
434 | #define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec)) | ||
435 | |||
436 | /** | ||
437 | * @brief Microseconds to realtime counter. | ||
438 | * @details Converts from microseconds to realtime counter cycles. | ||
439 | * @note The result is rounded upward to the next microsecond boundary. | ||
440 | * @note The macro assumes that @p freq >= @p 1000000. | ||
441 | * | ||
442 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
443 | * @param[in] usec number of microseconds | ||
444 | * @return The number of cycles. | ||
445 | * | ||
446 | * @api | ||
447 | */ | ||
448 | #define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec)) | ||
449 | /** @} */ | ||
450 | |||
451 | /** | ||
452 | * @name Sleep macros using absolute time | ||
453 | * @{ | ||
454 | */ | ||
455 | /** | ||
456 | * @brief Delays the invoking thread for the specified number of seconds. | ||
457 | * @note The specified time is rounded up to a value allowed by the real | ||
458 | * system tick clock. | ||
459 | * @note The maximum specifiable value is implementation dependent. | ||
460 | * | ||
461 | * @param[in] secs time in seconds, must be different from zero | ||
462 | * | ||
463 | * @api | ||
464 | */ | ||
465 | #define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs)) | ||
466 | |||
467 | /** | ||
468 | * @brief Delays the invoking thread for the specified number of | ||
469 | * milliseconds. | ||
470 | * @note The specified time is rounded up to a value allowed by the real | ||
471 | * system tick clock. | ||
472 | * @note The maximum specifiable value is implementation dependent. | ||
473 | * | ||
474 | * @param[in] msecs time in milliseconds, must be different from zero | ||
475 | * | ||
476 | * @api | ||
477 | */ | ||
478 | #define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs)) | ||
479 | |||
480 | /** | ||
481 | * @brief Delays the invoking thread for the specified number of | ||
482 | * microseconds. | ||
483 | * @note The specified time is rounded up to a value allowed by the real | ||
484 | * system tick clock. | ||
485 | * @note The maximum specifiable value is implementation dependent. | ||
486 | * | ||
487 | * @param[in] usecs time in microseconds, must be different from zero | ||
488 | * | ||
489 | * @api | ||
490 | */ | ||
491 | #define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs)) | ||
492 | /** @} */ | ||
493 | |||
494 | /*===========================================================================*/ | ||
495 | /* External declarations. */ | ||
496 | /*===========================================================================*/ | ||
497 | |||
498 | extern const char *osal_halt_msg; | ||
499 | |||
500 | #ifdef __cplusplus | ||
501 | extern "C" { | ||
502 | #endif | ||
503 | void osalInit(void); | ||
504 | void osalSysHalt(const char *reason); | ||
505 | void osalSysPolledDelayX(rtcnt_t cycles); | ||
506 | void osalOsTimerHandlerI(void); | ||
507 | void osalOsRescheduleS(void); | ||
508 | systime_t osalOsGetSystemTimeX(void); | ||
509 | void osalThreadSleepS(sysinterval_t time); | ||
510 | void osalThreadSleep(sysinterval_t time); | ||
511 | msg_t osalThreadSuspendS(thread_reference_t *trp); | ||
512 | msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout); | ||
513 | void osalThreadResumeI(thread_reference_t *trp, msg_t msg); | ||
514 | void osalThreadResumeS(thread_reference_t *trp, msg_t msg); | ||
515 | msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout); | ||
516 | void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg); | ||
517 | void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg); | ||
518 | void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags); | ||
519 | void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags); | ||
520 | void osalEventSetCallback(event_source_t *esp, | ||
521 | eventcallback_t cb, | ||
522 | void *param); | ||
523 | void osalMutexLock(mutex_t *mp); | ||
524 | void osalMutexUnlock(mutex_t *mp); | ||
525 | #ifdef __cplusplus | ||
526 | } | ||
527 | #endif | ||
528 | |||
529 | /*===========================================================================*/ | ||
530 | /* Module inline functions. */ | ||
531 | /*===========================================================================*/ | ||
532 | |||
533 | /** | ||
534 | * @brief Disables interrupts globally. | ||
535 | * | ||
536 | * @special | ||
537 | */ | ||
538 | static inline void osalSysDisable(void) { | ||
539 | |||
540 | __disable_irq(); | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | * @brief Enables interrupts globally. | ||
545 | * | ||
546 | * @special | ||
547 | */ | ||
548 | static inline void osalSysEnable(void) { | ||
549 | |||
550 | __enable_irq(); | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * @brief Enters a critical zone from thread context. | ||
555 | * @note This function cannot be used for reentrant critical zones. | ||
556 | * | ||
557 | * @special | ||
558 | */ | ||
559 | static inline void osalSysLock(void) { | ||
560 | |||
561 | #if CORTEX_MODEL == 0 | ||
562 | __disable_irq(); | ||
563 | #else | ||
564 | __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY)); | ||
565 | #endif | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * @brief Leaves a critical zone from thread context. | ||
570 | * @note This function cannot be used for reentrant critical zones. | ||
571 | * | ||
572 | * @special | ||
573 | */ | ||
574 | static inline void osalSysUnlock(void) { | ||
575 | |||
576 | #if CORTEX_MODEL == 0 | ||
577 | __enable_irq(); | ||
578 | #else | ||
579 | __set_BASEPRI(0); | ||
580 | #endif | ||
581 | } | ||
582 | |||
583 | /** | ||
584 | * @brief Enters a critical zone from ISR context. | ||
585 | * @note This function cannot be used for reentrant critical zones. | ||
586 | * | ||
587 | * @special | ||
588 | */ | ||
589 | static inline void osalSysLockFromISR(void) { | ||
590 | |||
591 | #if CORTEX_MODEL == 0 | ||
592 | __disable_irq(); | ||
593 | #else | ||
594 | __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY)); | ||
595 | #endif | ||
596 | } | ||
597 | |||
598 | /** | ||
599 | * @brief Leaves a critical zone from ISR context. | ||
600 | * @note This function cannot be used for reentrant critical zones. | ||
601 | * | ||
602 | * @special | ||
603 | */ | ||
604 | static inline void osalSysUnlockFromISR(void) { | ||
605 | |||
606 | #if CORTEX_MODEL == 0 | ||
607 | __enable_irq(); | ||
608 | #else | ||
609 | __set_BASEPRI(0); | ||
610 | #endif | ||
611 | } | ||
612 | |||
613 | /** | ||
614 | * @brief Returns the execution status and enters a critical zone. | ||
615 | * @details This functions enters into a critical zone and can be called | ||
616 | * from any context. Because its flexibility it is less efficient | ||
617 | * than @p chSysLock() which is preferable when the calling context | ||
618 | * is known. | ||
619 | * @post The system is in a critical zone. | ||
620 | * | ||
621 | * @return The previous system status, the encoding of this | ||
622 | * status word is architecture-dependent and opaque. | ||
623 | * | ||
624 | * @xclass | ||
625 | */ | ||
626 | static inline syssts_t osalSysGetStatusAndLockX(void) { | ||
627 | syssts_t sts; | ||
628 | |||
629 | #if CORTEX_MODEL == 0 | ||
630 | sts = (syssts_t)__get_PRIMASK(); | ||
631 | __disable_irq(); | ||
632 | #else | ||
633 | sts = (syssts_t)__get_BASEPRI(); | ||
634 | __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY)); | ||
635 | #endif | ||
636 | return sts; | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * @brief Restores the specified execution status and leaves a critical zone. | ||
641 | * @note A call to @p chSchRescheduleS() is automatically performed | ||
642 | * if exiting the critical zone and if not in ISR context. | ||
643 | * | ||
644 | * @param[in] sts the system status to be restored. | ||
645 | * | ||
646 | * @xclass | ||
647 | */ | ||
648 | static inline void osalSysRestoreStatusX(syssts_t sts) { | ||
649 | |||
650 | #if CORTEX_MODEL == 0 | ||
651 | if ((sts & (syssts_t)1) == (syssts_t)0) { | ||
652 | __enable_irq(); | ||
653 | } | ||
654 | #else | ||
655 | __set_BASEPRI(sts); | ||
656 | #endif | ||
657 | } | ||
658 | |||
659 | /** | ||
660 | * @brief Adds an interval to a system time returning a system time. | ||
661 | * | ||
662 | * @param[in] systime base system time | ||
663 | * @param[in] interval interval to be added | ||
664 | * @return The new system time. | ||
665 | * | ||
666 | * @xclass | ||
667 | */ | ||
668 | static inline systime_t osalTimeAddX(systime_t systime, | ||
669 | sysinterval_t interval) { | ||
670 | |||
671 | return systime + (systime_t)interval; | ||
672 | } | ||
673 | |||
674 | /** | ||
675 | * @brief Subtracts two system times returning an interval. | ||
676 | * | ||
677 | * @param[in] start first system time | ||
678 | * @param[in] end second system time | ||
679 | * @return The interval representing the time difference. | ||
680 | * | ||
681 | * @xclass | ||
682 | */ | ||
683 | static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) { | ||
684 | |||
685 | return (sysinterval_t)((systime_t)(end - start)); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * @brief Checks if the specified time is within the specified time window. | ||
690 | * @note When start==end then the function returns always false because the | ||
691 | * time window has zero size. | ||
692 | * @note This function can be called from any context. | ||
693 | * | ||
694 | * @param[in] time the time to be verified | ||
695 | * @param[in] start the start of the time window (inclusive) | ||
696 | * @param[in] end the end of the time window (non inclusive) | ||
697 | * @retval true current time within the specified time window. | ||
698 | * @retval false current time not within the specified time window. | ||
699 | * | ||
700 | * @xclass | ||
701 | */ | ||
702 | static inline bool osalTimeIsInRangeX(systime_t time, | ||
703 | systime_t start, | ||
704 | systime_t end) { | ||
705 | |||
706 | return (bool)((systime_t)((systime_t)time - (systime_t)start) < | ||
707 | (systime_t)((systime_t)end - (systime_t)start)); | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * @brief Initializes a threads queue object. | ||
712 | * | ||
713 | * @param[out] tqp pointer to the threads queue object | ||
714 | * | ||
715 | * @init | ||
716 | */ | ||
717 | static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) { | ||
718 | |||
719 | osalDbgCheck(tqp != NULL); | ||
720 | } | ||
721 | |||
722 | /** | ||
723 | * @brief Initializes an event source object. | ||
724 | * | ||
725 | * @param[out] esp pointer to the event source object | ||
726 | * | ||
727 | * @init | ||
728 | */ | ||
729 | static inline void osalEventObjectInit(event_source_t *esp) { | ||
730 | |||
731 | osalDbgCheck(esp != NULL); | ||
732 | |||
733 | esp->flags = (eventflags_t)0; | ||
734 | esp->cb = NULL; | ||
735 | esp->param = NULL; | ||
736 | } | ||
737 | |||
738 | /** | ||
739 | * @brief Initializes s @p mutex_t object. | ||
740 | * | ||
741 | * @param[out] mp pointer to the @p mutex_t object | ||
742 | * | ||
743 | * @init | ||
744 | */ | ||
745 | static inline void osalMutexObjectInit(mutex_t *mp) { | ||
746 | |||
747 | osalDbgCheck(mp != NULL); | ||
748 | |||
749 | *mp = 0; | ||
750 | } | ||
751 | |||
752 | #endif /* OSAL_H */ | ||
753 | |||
754 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk new file mode 100644 index 000000000..60285045b --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk | |||
@@ -0,0 +1,11 @@ | |||
1 | # OSAL files. | ||
2 | OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx/osal.c \ | ||
3 | ${CHIBIOS}/os/hal/osal/lib/osal_vt.c | ||
4 | |||
5 | # Required include directories | ||
6 | OSALINC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx \ | ||
7 | ${CHIBIOS}/os/hal/osal/lib | ||
8 | |||
9 | # Shared variables | ||
10 | ALLCSRC += $(OSALSRC) | ||
11 | ALLINC += $(OSALINC) | ||
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.c b/lib/chibios/os/hal/osal/os-less/AVR/osal.c new file mode 100644 index 000000000..4b7e0a9c1 --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.c | |||
@@ -0,0 +1,467 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.c | ||
19 | * @brief OSAL module code. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #include "osal.h" | ||
26 | #include "osal_vt.h" | ||
27 | |||
28 | /*===========================================================================*/ | ||
29 | /* Module local definitions. */ | ||
30 | /*===========================================================================*/ | ||
31 | |||
32 | /*===========================================================================*/ | ||
33 | /* Module exported variables. */ | ||
34 | /*===========================================================================*/ | ||
35 | |||
36 | /** | ||
37 | * @brief Pointer to a halt error message. | ||
38 | * @note The message is meant to be retrieved by the debugger after the | ||
39 | * system halt caused by an unexpected error. | ||
40 | */ | ||
41 | const char *osal_halt_msg; | ||
42 | |||
43 | /*===========================================================================*/ | ||
44 | /* Module local types. */ | ||
45 | /*===========================================================================*/ | ||
46 | |||
47 | /*===========================================================================*/ | ||
48 | /* Module local variables. */ | ||
49 | /*===========================================================================*/ | ||
50 | |||
51 | /*===========================================================================*/ | ||
52 | /* Module local functions. */ | ||
53 | /*===========================================================================*/ | ||
54 | |||
55 | static void callback_timeout(void *p) { | ||
56 | osalSysLockFromISR(); | ||
57 | osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT); | ||
58 | osalSysUnlockFromISR(); | ||
59 | } | ||
60 | |||
61 | /*===========================================================================*/ | ||
62 | /* Module exported functions. */ | ||
63 | /*===========================================================================*/ | ||
64 | |||
65 | /** | ||
66 | * @brief OSAL module initialization. | ||
67 | * | ||
68 | * @api | ||
69 | */ | ||
70 | void osalInit(void) { | ||
71 | |||
72 | vtInit(); | ||
73 | |||
74 | OSAL_INIT_HOOK(); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * @brief System halt with error message. | ||
79 | * | ||
80 | * @param[in] reason the halt message pointer | ||
81 | * | ||
82 | * @api | ||
83 | */ | ||
84 | #if !defined(__DOXYGEN__) | ||
85 | __attribute__((weak, noreturn)) | ||
86 | #endif | ||
87 | void osalSysHalt(const char *reason) { | ||
88 | |||
89 | osalSysDisable(); | ||
90 | osal_halt_msg = reason; | ||
91 | while (true) { | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /** | ||
96 | * @brief Polled delay. | ||
97 | * @note The real delay is always few cycles in excess of the specified | ||
98 | * value. | ||
99 | * | ||
100 | * @param[in] cycles number of cycles | ||
101 | * | ||
102 | * @xclass | ||
103 | */ | ||
104 | void osalSysPolledDelayX(rtcnt_t cycles) { | ||
105 | |||
106 | (void)cycles; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * @brief System timer handler. | ||
111 | * @details The handler is used for scheduling and Virtual Timers management. | ||
112 | * | ||
113 | * @iclass | ||
114 | */ | ||
115 | void osalOsTimerHandlerI(void) { | ||
116 | |||
117 | osalDbgCheckClassI(); | ||
118 | |||
119 | vtDoTickI(); | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * @brief Checks if a reschedule is required and performs it. | ||
124 | * @note I-Class functions invoked from thread context must not reschedule | ||
125 | * by themselves, an explicit reschedule using this function is | ||
126 | * required in this scenario. | ||
127 | * @note Not implemented in this simplified OSAL. | ||
128 | * | ||
129 | * @sclass | ||
130 | */ | ||
131 | void osalOsRescheduleS(void) { | ||
132 | |||
133 | } | ||
134 | |||
135 | /** | ||
136 | * @brief Current system time. | ||
137 | * @details Returns the number of system ticks since the @p osalInit() | ||
138 | * invocation. | ||
139 | * @note The counter can reach its maximum and then restart from zero. | ||
140 | * @note This function can be called from any context but its atomicity | ||
141 | * is not guaranteed on architectures whose word size is less than | ||
142 | * @p systime_t size. | ||
143 | * | ||
144 | * @return The system time in ticks. | ||
145 | * | ||
146 | * @xclass | ||
147 | */ | ||
148 | systime_t osalOsGetSystemTimeX(void) { | ||
149 | |||
150 | return vtlist.vt_systime; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * @brief Suspends the invoking thread for the specified time. | ||
155 | * | ||
156 | * @param[in] time the delay in system ticks, the special values are | ||
157 | * handled as follow: | ||
158 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
159 | * normal time specification. | ||
160 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
161 | * . | ||
162 | * | ||
163 | * @sclass | ||
164 | */ | ||
165 | void osalThreadSleepS(systime_t time) { | ||
166 | virtual_timer_t vt; | ||
167 | thread_reference_t tr; | ||
168 | |||
169 | tr = NULL; | ||
170 | vtSetI(&vt, time, callback_timeout, (void *)&tr); | ||
171 | osalThreadSuspendS(&tr); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * @brief Suspends the invoking thread for the specified time. | ||
176 | * | ||
177 | * @param[in] time the delay in system ticks, the special values are | ||
178 | * handled as follow: | ||
179 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
180 | * normal time specification. | ||
181 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
182 | * . | ||
183 | * | ||
184 | * @api | ||
185 | */ | ||
186 | void osalThreadSleep(systime_t time) { | ||
187 | |||
188 | osalSysLock(); | ||
189 | osalThreadSleepS(time); | ||
190 | osalSysUnlock(); | ||
191 | } | ||
192 | |||
193 | /** | ||
194 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
195 | * @note This function must reschedule, it can only be called from thread | ||
196 | * context. | ||
197 | * | ||
198 | * @param[in] trp a pointer to a thread reference object | ||
199 | * @return The wake up message. | ||
200 | * | ||
201 | * @sclass | ||
202 | */ | ||
203 | msg_t osalThreadSuspendS(thread_reference_t *trp) { | ||
204 | thread_t self = {MSG_WAIT}; | ||
205 | |||
206 | osalDbgCheck(trp != NULL); | ||
207 | |||
208 | *trp = &self; | ||
209 | while (self.message == MSG_WAIT) { | ||
210 | osalSysUnlock(); | ||
211 | /* A state-changing interrupt could occur here and cause the loop to | ||
212 | terminate, an hook macro is executed while waiting.*/ | ||
213 | OSAL_IDLE_HOOK(); | ||
214 | osalSysLock(); | ||
215 | } | ||
216 | |||
217 | return self.message; | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
222 | * @note This function must reschedule, it can only be called from thread | ||
223 | * context. | ||
224 | * | ||
225 | * @param[in] trp a pointer to a thread reference object | ||
226 | * @param[in] timeout the timeout in system ticks, the special values are | ||
227 | * handled as follow: | ||
228 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
229 | * state. | ||
230 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
231 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
232 | * occurred. | ||
233 | * . | ||
234 | * @return The wake up message. | ||
235 | * @retval MSG_TIMEOUT if the operation timed out. | ||
236 | * | ||
237 | * @sclass | ||
238 | */ | ||
239 | msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) { | ||
240 | msg_t msg; | ||
241 | virtual_timer_t vt; | ||
242 | |||
243 | osalDbgCheck(trp != NULL); | ||
244 | |||
245 | if (TIME_INFINITE == timeout) | ||
246 | return osalThreadSuspendS(trp); | ||
247 | |||
248 | vtSetI(&vt, timeout, callback_timeout, (void *)trp); | ||
249 | msg = osalThreadSuspendS(trp); | ||
250 | if (vtIsArmedI(&vt)) | ||
251 | vtResetI(&vt); | ||
252 | |||
253 | return msg; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * @brief Wakes up a thread waiting on a thread reference object. | ||
258 | * @note This function must not reschedule because it can be called from | ||
259 | * ISR context. | ||
260 | * | ||
261 | * @param[in] trp a pointer to a thread reference object | ||
262 | * @param[in] msg the message code | ||
263 | * | ||
264 | * @iclass | ||
265 | */ | ||
266 | void osalThreadResumeI(thread_reference_t *trp, msg_t msg) { | ||
267 | |||
268 | osalDbgCheck(trp != NULL); | ||
269 | |||
270 | if (*trp != NULL) { | ||
271 | (*trp)->message = msg; | ||
272 | *trp = NULL; | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * @brief Wakes up a thread waiting on a thread reference object. | ||
278 | * @note This function must reschedule, it can only be called from thread | ||
279 | * context. | ||
280 | * | ||
281 | * @param[in] trp a pointer to a thread reference object | ||
282 | * @param[in] msg the message code | ||
283 | * | ||
284 | * @iclass | ||
285 | */ | ||
286 | void osalThreadResumeS(thread_reference_t *trp, msg_t msg) { | ||
287 | |||
288 | osalDbgCheck(trp != NULL); | ||
289 | |||
290 | if (*trp != NULL) { | ||
291 | (*trp)->message = msg; | ||
292 | *trp = NULL; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * @brief Enqueues the caller thread. | ||
298 | * @details The caller thread is enqueued and put to sleep until it is | ||
299 | * dequeued or the specified timeouts expires. | ||
300 | * | ||
301 | * @param[in] tqp pointer to the threads queue object | ||
302 | * @param[in] timeout the timeout in system ticks, the special values are | ||
303 | * handled as follow: | ||
304 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
305 | * state. | ||
306 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
307 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
308 | * occurred. | ||
309 | * . | ||
310 | * @return The message from @p osalQueueWakeupOneI() or | ||
311 | * @p osalQueueWakeupAllI() functions. | ||
312 | * @retval MSG_TIMEOUT if the thread has not been dequeued within the | ||
313 | * specified timeout or if the function has been | ||
314 | * invoked with @p TIME_IMMEDIATE as timeout | ||
315 | * specification. | ||
316 | * | ||
317 | * @sclass | ||
318 | */ | ||
319 | msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout) { | ||
320 | msg_t msg; | ||
321 | virtual_timer_t vt; | ||
322 | |||
323 | osalDbgCheck(tqp != NULL); | ||
324 | |||
325 | if (TIME_IMMEDIATE == timeout) | ||
326 | return MSG_TIMEOUT; | ||
327 | |||
328 | tqp->tr = NULL; | ||
329 | |||
330 | if (TIME_INFINITE == timeout) | ||
331 | return osalThreadSuspendS(&tqp->tr); | ||
332 | |||
333 | vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr); | ||
334 | msg = osalThreadSuspendS(&tqp->tr); | ||
335 | if (vtIsArmedI(&vt)) | ||
336 | vtResetI(&vt); | ||
337 | |||
338 | return msg; | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * @brief Dequeues and wakes up one thread from the queue, if any. | ||
343 | * | ||
344 | * @param[in] tqp pointer to the threads queue object | ||
345 | * @param[in] msg the message code | ||
346 | * | ||
347 | * @iclass | ||
348 | */ | ||
349 | void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) { | ||
350 | |||
351 | osalDbgCheck(tqp != NULL); | ||
352 | |||
353 | osalThreadResumeI(&tqp->tr, msg); | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * @brief Dequeues and wakes up all threads from the queue. | ||
358 | * | ||
359 | * @param[in] tqp pointer to the threads queue object | ||
360 | * @param[in] msg the message code | ||
361 | * | ||
362 | * @iclass | ||
363 | */ | ||
364 | void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) { | ||
365 | |||
366 | osalDbgCheck(tqp != NULL); | ||
367 | |||
368 | osalThreadResumeI(&tqp->tr, msg); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * @brief Add flags to an event source object. | ||
373 | * | ||
374 | * @param[in] esp pointer to the event flags object | ||
375 | * @param[in] flags flags to be ORed to the flags mask | ||
376 | * | ||
377 | * @iclass | ||
378 | */ | ||
379 | void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) { | ||
380 | |||
381 | osalDbgCheck(esp != NULL); | ||
382 | |||
383 | esp->flags |= flags; | ||
384 | if (esp->cb != NULL) { | ||
385 | esp->cb(esp); | ||
386 | } | ||
387 | } | ||
388 | |||
389 | /** | ||
390 | * @brief Add flags to an event source object. | ||
391 | * | ||
392 | * @param[in] esp pointer to the event flags object | ||
393 | * @param[in] flags flags to be ORed to the flags mask | ||
394 | * | ||
395 | * @iclass | ||
396 | */ | ||
397 | void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) { | ||
398 | |||
399 | osalDbgCheck(esp != NULL); | ||
400 | |||
401 | osalSysLock(); | ||
402 | osalEventBroadcastFlagsI(esp, flags); | ||
403 | osalSysUnlock(); | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * @brief Event callback setup. | ||
408 | * @note The callback is invoked from ISR context and can | ||
409 | * only invoke I-Class functions. The callback is meant | ||
410 | * to wakeup the task that will handle the event by | ||
411 | * calling @p osalEventGetAndClearFlagsI(). | ||
412 | * @note This function is not part of the OSAL API and is provided | ||
413 | * exclusively as an example and for convenience. | ||
414 | * | ||
415 | * @param[in] esp pointer to the event flags object | ||
416 | * @param[in] cb pointer to the callback function | ||
417 | * @param[in] param parameter to be passed to the callback function | ||
418 | * | ||
419 | * @api | ||
420 | */ | ||
421 | void osalEventSetCallback(event_source_t *esp, | ||
422 | eventcallback_t cb, | ||
423 | void *param) { | ||
424 | |||
425 | osalDbgCheck(esp != NULL); | ||
426 | |||
427 | esp->cb = cb; | ||
428 | esp->param = param; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * @brief Locks the specified mutex. | ||
433 | * @post The mutex is locked and inserted in the per-thread stack of owned | ||
434 | * mutexes. | ||
435 | * | ||
436 | * @param[in,out] mp pointer to the @p mutex_t object | ||
437 | * | ||
438 | * @api | ||
439 | */ | ||
440 | void osalMutexLock(mutex_t *mp) { | ||
441 | |||
442 | osalDbgCheck(mp != NULL); | ||
443 | |||
444 | *mp = 1; | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * @brief Unlocks the specified mutex. | ||
449 | * @note The HAL guarantees to release mutex in reverse lock order. The | ||
450 | * mutex being unlocked is guaranteed to be the last locked mutex | ||
451 | * by the invoking thread. | ||
452 | * The implementation can rely on this behavior and eventually | ||
453 | * ignore the @p mp parameter which is supplied in order to support | ||
454 | * those OSes not supporting a stack of the owned mutexes. | ||
455 | * | ||
456 | * @param[in,out] mp pointer to the @p mutex_t object | ||
457 | * | ||
458 | * @api | ||
459 | */ | ||
460 | void osalMutexUnlock(mutex_t *mp) { | ||
461 | |||
462 | osalDbgCheck(mp != NULL); | ||
463 | |||
464 | *mp = 0; | ||
465 | } | ||
466 | |||
467 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.h b/lib/chibios/os/hal/osal/os-less/AVR/osal.h new file mode 100644 index 000000000..833ab9acb --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.h | |||
@@ -0,0 +1,677 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.h | ||
19 | * @brief OSAL module header. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #ifndef OSAL_H | ||
26 | #define OSAL_H | ||
27 | |||
28 | #include <stddef.h> | ||
29 | #include <stdint.h> | ||
30 | #include <stdbool.h> | ||
31 | |||
32 | #include <avr/io.h> | ||
33 | #include <avr/interrupt.h> | ||
34 | |||
35 | #include "osalconf.h" | ||
36 | |||
37 | /*===========================================================================*/ | ||
38 | /* Module constants. */ | ||
39 | /*===========================================================================*/ | ||
40 | |||
41 | /** | ||
42 | * @name Common constants | ||
43 | * @{ | ||
44 | */ | ||
45 | #if !defined(FALSE) || defined(__DOXYGEN__) | ||
46 | #define FALSE 0 | ||
47 | #endif | ||
48 | |||
49 | #if !defined(TRUE) || defined(__DOXYGEN__) | ||
50 | #define TRUE 1 | ||
51 | #endif | ||
52 | |||
53 | #define OSAL_SUCCESS false | ||
54 | #define OSAL_FAILED true | ||
55 | /** @} */ | ||
56 | |||
57 | /** | ||
58 | * @name Messages | ||
59 | * @{ | ||
60 | */ | ||
61 | #define MSG_OK (msg_t)0 | ||
62 | #define MSG_RESET (msg_t)-1 | ||
63 | #define MSG_TIMEOUT (msg_t)-2 | ||
64 | #define MSG_WAIT (msg_t)-10 | ||
65 | /** @} */ | ||
66 | |||
67 | /** | ||
68 | * @name Special time constants | ||
69 | * @{ | ||
70 | */ | ||
71 | #define TIME_IMMEDIATE ((systime_t)0) | ||
72 | #define TIME_INFINITE ((systime_t)-1) | ||
73 | /** @} */ | ||
74 | |||
75 | /** | ||
76 | * @name Systick modes. | ||
77 | * @{ | ||
78 | */ | ||
79 | #define OSAL_ST_MODE_NONE 0 | ||
80 | #define OSAL_ST_MODE_PERIODIC 1 | ||
81 | #define OSAL_ST_MODE_FREERUNNING 2 | ||
82 | /** @} */ | ||
83 | |||
84 | /** | ||
85 | * @name Systick parameters. | ||
86 | * @{ | ||
87 | */ | ||
88 | /** | ||
89 | * @brief Size in bits of the @p systick_t type. | ||
90 | */ | ||
91 | #define OSAL_ST_RESOLUTION 32 | ||
92 | |||
93 | /** | ||
94 | * @brief Systick mode required by the underlying OS. | ||
95 | */ | ||
96 | #define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC | ||
97 | /** @} */ | ||
98 | |||
99 | /** | ||
100 | * @brief ROM constant modifier. | ||
101 | * @note It is set to use the "const" keyword in this port. | ||
102 | */ | ||
103 | #define ROMCONST const | ||
104 | |||
105 | /*===========================================================================*/ | ||
106 | /* Module pre-compile time settings. */ | ||
107 | /*===========================================================================*/ | ||
108 | |||
109 | /** | ||
110 | * @brief Frequency in Hertz of the system tick. | ||
111 | */ | ||
112 | #if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__) | ||
113 | #define OSAL_ST_FREQUENCY 1000 | ||
114 | #endif | ||
115 | |||
116 | /** | ||
117 | * @brief Enables OSAL assertions. | ||
118 | */ | ||
119 | #if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) | ||
120 | #define OSAL_DBG_ENABLE_ASSERTS FALSE | ||
121 | #endif | ||
122 | |||
123 | /** | ||
124 | * @brief Enables OSAL functions parameters checks. | ||
125 | */ | ||
126 | #if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) | ||
127 | #define OSAL_DBG_ENABLE_CHECKS FALSE | ||
128 | #endif | ||
129 | |||
130 | /** | ||
131 | * @brief OSAL initialization hook. | ||
132 | */ | ||
133 | #if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__) | ||
134 | #define OSAL_INIT_HOOK() | ||
135 | #endif | ||
136 | |||
137 | /** | ||
138 | * @brief Idle loop hook macro. | ||
139 | */ | ||
140 | #if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__) | ||
141 | #define OSAL_IDLE_HOOK() | ||
142 | #endif | ||
143 | |||
144 | /*===========================================================================*/ | ||
145 | /* Derived constants and error checks. */ | ||
146 | /*===========================================================================*/ | ||
147 | |||
148 | /*===========================================================================*/ | ||
149 | /* Module data structures and types. */ | ||
150 | /*===========================================================================*/ | ||
151 | |||
152 | /** | ||
153 | * @brief Type of a system status word. | ||
154 | */ | ||
155 | typedef uint8_t syssts_t; | ||
156 | |||
157 | /** | ||
158 | * @brief Type of a message. | ||
159 | */ | ||
160 | typedef int16_t msg_t; | ||
161 | |||
162 | /** | ||
163 | * @brief Type of system time counter. | ||
164 | */ | ||
165 | typedef uint32_t systime_t; | ||
166 | |||
167 | /** | ||
168 | * @brief Type of realtime counter. | ||
169 | */ | ||
170 | typedef uint32_t rtcnt_t; | ||
171 | |||
172 | /** | ||
173 | * @brief Type of a thread. | ||
174 | * @note The content of this structure is not part of the API and should | ||
175 | * not be relied upon. Implementers may define this structure in | ||
176 | * an entirely different way. | ||
177 | */ | ||
178 | typedef struct { | ||
179 | volatile msg_t message; | ||
180 | } thread_t; | ||
181 | |||
182 | /** | ||
183 | * @brief Type of a thread reference. | ||
184 | */ | ||
185 | typedef thread_t * thread_reference_t; | ||
186 | |||
187 | /** | ||
188 | * @brief Type of an event flags object. | ||
189 | * @note The content of this structure is not part of the API and should | ||
190 | * not be relied upon. Implementers may define this structure in | ||
191 | * an entirely different way. | ||
192 | * @note Retrieval and clearing of the flags are not defined in this | ||
193 | * API and are implementation-dependent. | ||
194 | */ | ||
195 | typedef struct event_source event_source_t; | ||
196 | |||
197 | /** | ||
198 | * @brief Type of an event source callback. | ||
199 | * @note This type is not part of the OSAL API and is provided | ||
200 | * exclusively as an example and for convenience. | ||
201 | */ | ||
202 | typedef void (*eventcallback_t)(event_source_t *esp); | ||
203 | |||
204 | /** | ||
205 | * @brief Type of an event flags mask. | ||
206 | */ | ||
207 | typedef uint8_t eventflags_t; | ||
208 | |||
209 | /** | ||
210 | * @brief Events source object. | ||
211 | * @note The content of this structure is not part of the API and should | ||
212 | * not be relied upon. Implementers may define this structure in | ||
213 | * an entirely different way. | ||
214 | * @note Retrieval and clearing of the flags are not defined in this | ||
215 | * API and are implementation-dependent. | ||
216 | */ | ||
217 | struct event_source { | ||
218 | volatile eventflags_t flags; /**< @brief Stored event flags. */ | ||
219 | eventcallback_t cb; /**< @brief Event source callback. */ | ||
220 | void *param; /**< @brief User defined field. */ | ||
221 | }; | ||
222 | |||
223 | /** | ||
224 | * @brief Type of a mutex. | ||
225 | * @note If the OS does not support mutexes or there is no OS then them | ||
226 | * mechanism can be simulated. | ||
227 | */ | ||
228 | typedef uint8_t mutex_t; | ||
229 | |||
230 | /** | ||
231 | * @brief Type of a thread queue. | ||
232 | * @details A thread queue is a queue of sleeping threads, queued threads | ||
233 | * can be dequeued one at time or all together. | ||
234 | * @note If the OSAL is implemented on a bare metal machine without RTOS | ||
235 | * then the queue can be implemented as a single thread reference. | ||
236 | */ | ||
237 | typedef struct { | ||
238 | thread_reference_t tr; | ||
239 | } threads_queue_t; | ||
240 | |||
241 | /*===========================================================================*/ | ||
242 | /* Module macros. */ | ||
243 | /*===========================================================================*/ | ||
244 | |||
245 | /** | ||
246 | * @name Debug related macros | ||
247 | * @{ | ||
248 | */ | ||
249 | /** | ||
250 | * @brief Condition assertion. | ||
251 | * @details If the condition check fails then the OSAL panics with a | ||
252 | * message and halts. | ||
253 | * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS | ||
254 | * switch is enabled. | ||
255 | * @note The remark string is not currently used except for putting a | ||
256 | * comment in the code about the assertion. | ||
257 | * | ||
258 | * @param[in] c the condition to be verified to be true | ||
259 | * @param[in] remark a remark string | ||
260 | * | ||
261 | * @api | ||
262 | */ | ||
263 | #define osalDbgAssert(c, remark) do { \ | ||
264 | /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ | ||
265 | if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \ | ||
266 | if (!(c)) { \ | ||
267 | /*lint -restore*/ \ | ||
268 | osalSysHalt(__func__); \ | ||
269 | } \ | ||
270 | } \ | ||
271 | } while (false) | ||
272 | |||
273 | /** | ||
274 | * @brief Function parameters check. | ||
275 | * @details If the condition check fails then the OSAL panics and halts. | ||
276 | * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch | ||
277 | * is enabled. | ||
278 | * | ||
279 | * @param[in] c the condition to be verified to be true | ||
280 | * | ||
281 | * @api | ||
282 | */ | ||
283 | #define osalDbgCheck(c) do { \ | ||
284 | /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \ | ||
285 | if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \ | ||
286 | if (!(c)) { \ | ||
287 | /*lint -restore*/ \ | ||
288 | osalSysHalt(__func__); \ | ||
289 | } \ | ||
290 | } \ | ||
291 | } while (false) | ||
292 | |||
293 | /** | ||
294 | * @brief I-Class state check. | ||
295 | * @note Implementation is optional. | ||
296 | */ | ||
297 | #define osalDbgCheckClassI() | ||
298 | |||
299 | /** | ||
300 | * @brief S-Class state check. | ||
301 | * @note Implementation is optional. | ||
302 | */ | ||
303 | #define osalDbgCheckClassS() | ||
304 | /** @} */ | ||
305 | |||
306 | /** | ||
307 | * @name IRQ service routines wrappers | ||
308 | * @{ | ||
309 | */ | ||
310 | /** | ||
311 | * @brief IRQ prologue code. | ||
312 | * @details This macro must be inserted at the start of all IRQ handlers. | ||
313 | */ | ||
314 | #define OSAL_IRQ_PROLOGUE() | ||
315 | |||
316 | /** | ||
317 | * @brief IRQ epilogue code. | ||
318 | * @details This macro must be inserted at the end of all IRQ handlers. | ||
319 | */ | ||
320 | #define OSAL_IRQ_EPILOGUE() | ||
321 | |||
322 | /** | ||
323 | * @brief IRQ handler function declaration. | ||
324 | * @details This macro hides the details of an ISR function declaration. | ||
325 | * | ||
326 | * @param[in] id a vector name as defined in @p vectors.s | ||
327 | */ | ||
328 | #define OSAL_IRQ_HANDLER(id) ISR(id) | ||
329 | /** @} */ | ||
330 | |||
331 | /** | ||
332 | * @name Time conversion utilities | ||
333 | * @{ | ||
334 | */ | ||
335 | /** | ||
336 | * @brief Seconds to system ticks. | ||
337 | * @details Converts from seconds to system ticks number. | ||
338 | * @note The result is rounded upward to the next tick boundary. | ||
339 | * | ||
340 | * @param[in] sec number of seconds | ||
341 | * @return The number of ticks. | ||
342 | * | ||
343 | * @api | ||
344 | */ | ||
345 | #define OSAL_S2ST(sec) \ | ||
346 | ((systime_t)((uint32_t)(sec) * (uint32_t)OSAL_ST_FREQUENCY)) | ||
347 | |||
348 | /** | ||
349 | * @brief Milliseconds to system ticks. | ||
350 | * @details Converts from milliseconds to system ticks number. | ||
351 | * @note The result is rounded upward to the next tick boundary. | ||
352 | * | ||
353 | * @param[in] msec number of milliseconds | ||
354 | * @return The number of ticks. | ||
355 | * | ||
356 | * @api | ||
357 | */ | ||
358 | #define OSAL_MS2ST(msec) \ | ||
359 | ((systime_t)((((uint32_t)(msec)) * \ | ||
360 | ((uint32_t)OSAL_ST_FREQUENCY) + 999UL) / 1000UL)) | ||
361 | |||
362 | /** | ||
363 | * @brief Microseconds to system ticks. | ||
364 | * @details Converts from microseconds to system ticks number. | ||
365 | * @note The result is rounded upward to the next tick boundary. | ||
366 | * | ||
367 | * @param[in] usec number of microseconds | ||
368 | * @return The number of ticks. | ||
369 | * | ||
370 | * @api | ||
371 | */ | ||
372 | #define OSAL_US2ST(usec) \ | ||
373 | ((systime_t)((((uint32_t)(usec)) * \ | ||
374 | ((uint32_t)OSAL_ST_FREQUENCY) + 999999UL) / 1000000UL)) | ||
375 | /** @} */ | ||
376 | |||
377 | /** | ||
378 | * @name Time conversion utilities for the realtime counter | ||
379 | * @{ | ||
380 | */ | ||
381 | /** | ||
382 | * @brief Seconds to realtime counter. | ||
383 | * @details Converts from seconds to realtime counter cycles. | ||
384 | * @note The macro assumes that @p freq >= @p 1. | ||
385 | * | ||
386 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
387 | * @param[in] sec number of seconds | ||
388 | * @return The number of cycles. | ||
389 | * | ||
390 | * @api | ||
391 | */ | ||
392 | #define OSAL_S2RTC(freq, sec) ((freq) * (sec)) | ||
393 | |||
394 | /** | ||
395 | * @brief Milliseconds to realtime counter. | ||
396 | * @details Converts from milliseconds to realtime counter cycles. | ||
397 | * @note The result is rounded upward to the next millisecond boundary. | ||
398 | * @note The macro assumes that @p freq >= @p 1000. | ||
399 | * | ||
400 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
401 | * @param[in] msec number of milliseconds | ||
402 | * @return The number of cycles. | ||
403 | * | ||
404 | * @api | ||
405 | */ | ||
406 | #define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec)) | ||
407 | |||
408 | /** | ||
409 | * @brief Microseconds to realtime counter. | ||
410 | * @details Converts from microseconds to realtime counter cycles. | ||
411 | * @note The result is rounded upward to the next microsecond boundary. | ||
412 | * @note The macro assumes that @p freq >= @p 1000000. | ||
413 | * | ||
414 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
415 | * @param[in] usec number of microseconds | ||
416 | * @return The number of cycles. | ||
417 | * | ||
418 | * @api | ||
419 | */ | ||
420 | #define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec)) | ||
421 | /** @} */ | ||
422 | |||
423 | /** | ||
424 | * @name Sleep macros using absolute time | ||
425 | * @{ | ||
426 | */ | ||
427 | /** | ||
428 | * @brief Delays the invoking thread for the specified number of seconds. | ||
429 | * @note The specified time is rounded up to a value allowed by the real | ||
430 | * system tick clock. | ||
431 | * @note The maximum specifiable value is implementation dependent. | ||
432 | * | ||
433 | * @param[in] sec time in seconds, must be different from zero | ||
434 | * | ||
435 | * @api | ||
436 | */ | ||
437 | #define osalThreadSleepSeconds(sec) osalThreadSleep(OSAL_S2ST(sec)) | ||
438 | |||
439 | /** | ||
440 | * @brief Delays the invoking thread for the specified number of | ||
441 | * milliseconds. | ||
442 | * @note The specified time is rounded up to a value allowed by the real | ||
443 | * system tick clock. | ||
444 | * @note The maximum specifiable value is implementation dependent. | ||
445 | * | ||
446 | * @param[in] msec time in milliseconds, must be different from zero | ||
447 | * | ||
448 | * @api | ||
449 | */ | ||
450 | #define osalThreadSleepMilliseconds(msec) osalThreadSleep(OSAL_MS2ST(msec)) | ||
451 | |||
452 | /** | ||
453 | * @brief Delays the invoking thread for the specified number of | ||
454 | * microseconds. | ||
455 | * @note The specified time is rounded up to a value allowed by the real | ||
456 | * system tick clock. | ||
457 | * @note The maximum specifiable value is implementation dependent. | ||
458 | * | ||
459 | * @param[in] usec time in microseconds, must be different from zero | ||
460 | * | ||
461 | * @api | ||
462 | */ | ||
463 | #define osalThreadSleepMicroseconds(usec) osalThreadSleep(OSAL_US2ST(usec)) | ||
464 | /** @} */ | ||
465 | |||
466 | /*===========================================================================*/ | ||
467 | /* External declarations. */ | ||
468 | /*===========================================================================*/ | ||
469 | |||
470 | extern const char *osal_halt_msg; | ||
471 | |||
472 | #ifdef __cplusplus | ||
473 | extern "C" { | ||
474 | #endif | ||
475 | void osalInit(void); | ||
476 | void osalSysHalt(const char *reason); | ||
477 | void osalSysPolledDelayX(rtcnt_t cycles); | ||
478 | void osalOsTimerHandlerI(void); | ||
479 | void osalOsRescheduleS(void); | ||
480 | systime_t osalOsGetSystemTimeX(void); | ||
481 | void osalThreadSleepS(systime_t time); | ||
482 | void osalThreadSleep(systime_t time); | ||
483 | msg_t osalThreadSuspendS(thread_reference_t *trp); | ||
484 | msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout); | ||
485 | void osalThreadResumeI(thread_reference_t *trp, msg_t msg); | ||
486 | void osalThreadResumeS(thread_reference_t *trp, msg_t msg); | ||
487 | msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout); | ||
488 | void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg); | ||
489 | void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg); | ||
490 | void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags); | ||
491 | void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags); | ||
492 | void osalEventSetCallback(event_source_t *esp, | ||
493 | eventcallback_t cb, | ||
494 | void *param); | ||
495 | void osalMutexLock(mutex_t *mp); | ||
496 | void osalMutexUnlock(mutex_t *mp); | ||
497 | #ifdef __cplusplus | ||
498 | } | ||
499 | #endif | ||
500 | |||
501 | /*===========================================================================*/ | ||
502 | /* Module inline functions. */ | ||
503 | /*===========================================================================*/ | ||
504 | |||
505 | /** | ||
506 | * @brief Disables interrupts globally. | ||
507 | * | ||
508 | * @special | ||
509 | */ | ||
510 | static inline void osalSysDisable(void) { | ||
511 | |||
512 | asm volatile ("cli" : : : "memory"); | ||
513 | } | ||
514 | |||
515 | /** | ||
516 | * @brief Enables interrupts globally. | ||
517 | * | ||
518 | * @special | ||
519 | */ | ||
520 | static inline void osalSysEnable(void) { | ||
521 | |||
522 | asm volatile ("sei" : : : "memory"); | ||
523 | asm volatile ("nop"); | ||
524 | } | ||
525 | |||
526 | /** | ||
527 | * @brief Enters a critical zone from thread context. | ||
528 | * @note This function cannot be used for reentrant critical zones. | ||
529 | * | ||
530 | * @special | ||
531 | */ | ||
532 | static inline void osalSysLock(void) { | ||
533 | |||
534 | asm volatile ("cli" : : : "memory"); | ||
535 | } | ||
536 | |||
537 | /** | ||
538 | * @brief Leaves a critical zone from thread context. | ||
539 | * @note This function cannot be used for reentrant critical zones. | ||
540 | * | ||
541 | * @special | ||
542 | */ | ||
543 | static inline void osalSysUnlock(void) { | ||
544 | |||
545 | asm volatile ("sei" : : : "memory"); | ||
546 | asm volatile ("nop"); | ||
547 | } | ||
548 | |||
549 | /** | ||
550 | * @brief Enters a critical zone from ISR context. | ||
551 | * @note This function cannot be used for reentrant critical zones. | ||
552 | * @note This function is empty in this port. | ||
553 | * | ||
554 | * @special | ||
555 | */ | ||
556 | static inline void osalSysLockFromISR(void) { | ||
557 | |||
558 | } | ||
559 | |||
560 | /** | ||
561 | * @brief Leaves a critical zone from ISR context. | ||
562 | * @note This function cannot be used for reentrant critical zones. | ||
563 | * @note This function is empty in this port. | ||
564 | * | ||
565 | * @special | ||
566 | */ | ||
567 | static inline void osalSysUnlockFromISR(void) { | ||
568 | |||
569 | } | ||
570 | |||
571 | /** | ||
572 | * @brief Returns the execution status and enters a critical zone. | ||
573 | * @details This functions enters into a critical zone and can be called | ||
574 | * from any context. Because its flexibility it is less efficient | ||
575 | * than @p chSysLock() which is preferable when the calling context | ||
576 | * is known. | ||
577 | * @post The system is in a critical zone. | ||
578 | * | ||
579 | * @return The previous system status, the encoding of this | ||
580 | * status word is architecture-dependent and opaque. | ||
581 | * | ||
582 | * @xclass | ||
583 | */ | ||
584 | static inline syssts_t osalSysGetStatusAndLockX(void) { | ||
585 | syssts_t sts; | ||
586 | |||
587 | sts = SREG; | ||
588 | asm volatile ("cli" : : : "memory"); | ||
589 | |||
590 | return sts; | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * @brief Restores the specified execution status and leaves a critical zone. | ||
595 | * @note A call to @p chSchRescheduleS() is automatically performed | ||
596 | * if exiting the critical zone and if not in ISR context. | ||
597 | * | ||
598 | * @param[in] sts the system status to be restored. | ||
599 | * | ||
600 | * @xclass | ||
601 | */ | ||
602 | static inline void osalSysRestoreStatusX(syssts_t sts) { | ||
603 | |||
604 | if ((sts & 0x80) != 0) { | ||
605 | asm volatile ("sei" : : : "memory"); | ||
606 | asm volatile ("nop"); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | /** | ||
611 | * @brief Checks if the specified time is within the specified time window. | ||
612 | * @note When start==end then the function returns always false because the | ||
613 | * time window has zero size. | ||
614 | * @note This function can be called from any context. | ||
615 | * | ||
616 | * @param[in] time the time to be verified | ||
617 | * @param[in] start the start of the time window (inclusive) | ||
618 | * @param[in] end the end of the time window (non inclusive) | ||
619 | * @retval true current time within the specified time window. | ||
620 | * @retval false current time not within the specified time window. | ||
621 | * | ||
622 | * @xclass | ||
623 | */ | ||
624 | static inline bool osalOsIsTimeWithinX(systime_t time, | ||
625 | systime_t start, | ||
626 | systime_t end) { | ||
627 | |||
628 | return (bool)((time - start) < (end - start)); | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * @brief Initializes a threads queue object. | ||
633 | * | ||
634 | * @param[out] tqp pointer to the threads queue object | ||
635 | * | ||
636 | * @init | ||
637 | */ | ||
638 | static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) { | ||
639 | |||
640 | osalDbgCheck(tqp != NULL); | ||
641 | |||
642 | (void)tqp; | ||
643 | } | ||
644 | |||
645 | /** | ||
646 | * @brief Initializes an event flags object. | ||
647 | * | ||
648 | * @param[out] esp pointer to the event flags object | ||
649 | * | ||
650 | * @init | ||
651 | */ | ||
652 | static inline void osalEventObjectInit(event_source_t *esp) { | ||
653 | |||
654 | osalDbgCheck(esp != NULL); | ||
655 | |||
656 | esp->flags = (eventflags_t)0; | ||
657 | esp->cb = NULL; | ||
658 | esp->param = NULL; | ||
659 | } | ||
660 | |||
661 | /** | ||
662 | * @brief Initializes s @p mutex_t object. | ||
663 | * | ||
664 | * @param[out] mp pointer to the @p mutex_t object | ||
665 | * | ||
666 | * @init | ||
667 | */ | ||
668 | static inline void osalMutexObjectInit(mutex_t *mp) { | ||
669 | |||
670 | osalDbgCheck(mp != NULL); | ||
671 | |||
672 | *mp = 0; | ||
673 | } | ||
674 | |||
675 | #endif /* OSAL_H */ | ||
676 | |||
677 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.mk b/lib/chibios/os/hal/osal/os-less/AVR/osal.mk new file mode 100644 index 000000000..6295bd54a --- /dev/null +++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.mk | |||
@@ -0,0 +1,9 @@ | |||
1 | # OSAL files. | ||
2 | OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/AVR/osal.c | ||
3 | |||
4 | # Required include directories | ||
5 | OSALINC += ${CHIBIOS}/os/hal/osal/os-less/AVR | ||
6 | |||
7 | # Shared variables | ||
8 | ALLCSRC += $(OSALSRC) | ||
9 | ALLINC += $(OSALINC) | ||
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.c b/lib/chibios/os/hal/osal/rt-nil/osal.c new file mode 100644 index 000000000..853abe694 --- /dev/null +++ b/lib/chibios/os/hal/osal/rt-nil/osal.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.c | ||
19 | * @brief OSAL module code. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #include "osal.h" | ||
26 | |||
27 | /*===========================================================================*/ | ||
28 | /* Module local definitions. */ | ||
29 | /*===========================================================================*/ | ||
30 | |||
31 | /*===========================================================================*/ | ||
32 | /* Module exported variables. */ | ||
33 | /*===========================================================================*/ | ||
34 | |||
35 | /*===========================================================================*/ | ||
36 | /* Module local types. */ | ||
37 | /*===========================================================================*/ | ||
38 | |||
39 | /*===========================================================================*/ | ||
40 | /* Module local variables. */ | ||
41 | /*===========================================================================*/ | ||
42 | |||
43 | /*===========================================================================*/ | ||
44 | /* Module local functions. */ | ||
45 | /*===========================================================================*/ | ||
46 | |||
47 | /*===========================================================================*/ | ||
48 | /* Module exported functions. */ | ||
49 | /*===========================================================================*/ | ||
50 | |||
51 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.h b/lib/chibios/os/hal/osal/rt-nil/osal.h new file mode 100644 index 000000000..25ac4de9b --- /dev/null +++ b/lib/chibios/os/hal/osal/rt-nil/osal.h | |||
@@ -0,0 +1,1092 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file osal.h | ||
19 | * @brief OSAL module header. | ||
20 | * | ||
21 | * @addtogroup OSAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #ifndef OSAL_H | ||
26 | #define OSAL_H | ||
27 | |||
28 | #include <stddef.h> | ||
29 | #include <stdint.h> | ||
30 | #include <stdbool.h> | ||
31 | |||
32 | #include "ch.h" | ||
33 | |||
34 | /*===========================================================================*/ | ||
35 | /* Module constants. */ | ||
36 | /*===========================================================================*/ | ||
37 | |||
38 | /** | ||
39 | * @name Common constants | ||
40 | * @{ | ||
41 | */ | ||
42 | #if !defined(FALSE) || defined(__DOXYGEN__) | ||
43 | #define FALSE 0 | ||
44 | #endif | ||
45 | |||
46 | #if !defined(TRUE) || defined(__DOXYGEN__) | ||
47 | #define TRUE 1 | ||
48 | #endif | ||
49 | |||
50 | #define OSAL_SUCCESS false | ||
51 | #define OSAL_FAILED true | ||
52 | /** @} */ | ||
53 | |||
54 | #if 0 | ||
55 | /** | ||
56 | * @name Messages | ||
57 | * @{ | ||
58 | */ | ||
59 | #define MSG_OK (msg_t)0 | ||
60 | #define MSG_TIMEOUT (msg_t)-1 | ||
61 | #define MSG_RESET (msg_t)-2 | ||
62 | /** @} */ | ||
63 | #endif | ||
64 | |||
65 | #if 0 | ||
66 | /** | ||
67 | * @name Special time constants | ||
68 | * @{ | ||
69 | */ | ||
70 | #define TIME_IMMEDIATE ((sysinterval_t)0) | ||
71 | #define TIME_INFINITE ((sysinterval_t)-1) | ||
72 | /** @} */ | ||
73 | #endif | ||
74 | |||
75 | /** | ||
76 | * @name Systick modes. | ||
77 | * @{ | ||
78 | */ | ||
79 | #define OSAL_ST_MODE_NONE 0 | ||
80 | #define OSAL_ST_MODE_PERIODIC 1 | ||
81 | #define OSAL_ST_MODE_FREERUNNING 2 | ||
82 | /** @} */ | ||
83 | |||
84 | /** | ||
85 | * @name Systick parameters. | ||
86 | * @{ | ||
87 | */ | ||
88 | /** | ||
89 | * @brief Size in bits of the @p systick_t type. | ||
90 | */ | ||
91 | #define OSAL_ST_RESOLUTION CH_CFG_ST_RESOLUTION | ||
92 | |||
93 | /** | ||
94 | * @brief Required systick frequency or resolution. | ||
95 | */ | ||
96 | #define OSAL_ST_FREQUENCY CH_CFG_ST_FREQUENCY | ||
97 | |||
98 | /** | ||
99 | * @brief Systick mode required by the underlying OS. | ||
100 | */ | ||
101 | #if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__) | ||
102 | #define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC | ||
103 | #else | ||
104 | #define OSAL_ST_MODE OSAL_ST_MODE_FREERUNNING | ||
105 | #endif | ||
106 | /** @} */ | ||
107 | |||
108 | /*===========================================================================*/ | ||
109 | /* Module pre-compile time settings. */ | ||
110 | /*===========================================================================*/ | ||
111 | |||
112 | /*===========================================================================*/ | ||
113 | /* Derived constants and error checks. */ | ||
114 | /*===========================================================================*/ | ||
115 | |||
116 | #if !(OSAL_ST_MODE == OSAL_ST_MODE_NONE) && \ | ||
117 | !(OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) && \ | ||
118 | !(OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) | ||
119 | #error "invalid OSAL_ST_MODE setting in osal.h" | ||
120 | #endif | ||
121 | |||
122 | #if (OSAL_ST_RESOLUTION != 16) && (OSAL_ST_RESOLUTION != 32) && \ | ||
123 | (OSAL_ST_RESOLUTION != 64) | ||
124 | #error "invalid OSAL_ST_RESOLUTION, must be 16, 32 or 64" | ||
125 | #endif | ||
126 | |||
127 | /*===========================================================================*/ | ||
128 | /* Module data structures and types. */ | ||
129 | /*===========================================================================*/ | ||
130 | |||
131 | #if 0 | ||
132 | /** | ||
133 | * @brief Type of a system status word. | ||
134 | */ | ||
135 | typedef uint32_t syssts_t; | ||
136 | #endif | ||
137 | |||
138 | #if 0 | ||
139 | /** | ||
140 | * @brief Type of a message. | ||
141 | */ | ||
142 | typedef int32_t msg_t; | ||
143 | #endif | ||
144 | |||
145 | #if 0 | ||
146 | /** | ||
147 | * @brief Type of system time counter. | ||
148 | */ | ||
149 | typedef uint32_t systime_t; | ||
150 | #endif | ||
151 | |||
152 | #if 0 | ||
153 | /** | ||
154 | * @brief Type of system time interval. | ||
155 | */ | ||
156 | typedef uint32_t sysinterval_t; | ||
157 | #endif | ||
158 | |||
159 | #if 0 | ||
160 | /** | ||
161 | * @brief Type of time conversion variable. | ||
162 | * @note This type must have double width than other time types, it is | ||
163 | * only used internally for conversions. | ||
164 | */ | ||
165 | typedef uint64_t time_conv_t; | ||
166 | #endif | ||
167 | |||
168 | #if 0 | ||
169 | /** | ||
170 | * @brief Type of realtime counter. | ||
171 | */ | ||
172 | typedef uint32_t rtcnt_t; | ||
173 | #endif | ||
174 | |||
175 | #if 0 | ||
176 | /** | ||
177 | * @brief Type of a thread reference. | ||
178 | */ | ||
179 | typedef thread_t * thread_reference_t; | ||
180 | #endif | ||
181 | |||
182 | #if 0 | ||
183 | /** | ||
184 | * @brief Type of an event flags mask. | ||
185 | */ | ||
186 | typedef uint32_t eventflags_t; | ||
187 | #endif | ||
188 | |||
189 | #if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__) | ||
190 | /** | ||
191 | * @brief Type of an event flags object. | ||
192 | * @note The content of this structure is not part of the API and should | ||
193 | * not be relied upon. Implementers may define this structure in | ||
194 | * an entirely different way. | ||
195 | * @note Retrieval and clearing of the flags are not defined in this | ||
196 | * API and are implementation-dependent. | ||
197 | */ | ||
198 | typedef struct event_source event_source_t; | ||
199 | |||
200 | /** | ||
201 | * @brief Type of an event source callback. | ||
202 | * @note This type is not part of the OSAL API and is provided | ||
203 | * exclusively as an example and for convenience. | ||
204 | */ | ||
205 | typedef void (*eventcallback_t)(event_source_t *esp); | ||
206 | |||
207 | /** | ||
208 | * @brief Events source object. | ||
209 | * @note The content of this structure is not part of the API and should | ||
210 | * not be relied upon. Implementers may define this structure in | ||
211 | * an entirely different way. | ||
212 | * @note Retrieval and clearing of the flags are not defined in this | ||
213 | * API and are implementation-dependent. | ||
214 | */ | ||
215 | struct event_source { | ||
216 | volatile eventflags_t flags; /**< @brief Stored event flags. */ | ||
217 | eventcallback_t cb; /**< @brief Event source callback. */ | ||
218 | void *param; /**< @brief User defined field. */ | ||
219 | }; | ||
220 | #endif /* CH_CFG_USE_EVENTS == FALSE */ | ||
221 | |||
222 | /** | ||
223 | * @brief Type of a mutex. | ||
224 | * @note If the OS does not support mutexes or there is no OS then the | ||
225 | * mechanism can be simulated. | ||
226 | */ | ||
227 | #if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__) | ||
228 | #elif CH_CFG_USE_SEMAPHORES | ||
229 | typedef semaphore_t mutex_t; | ||
230 | #else | ||
231 | typedef uint32_t mutex_t; | ||
232 | #endif | ||
233 | |||
234 | #if 0 | ||
235 | /** | ||
236 | * @brief Type of a thread queue. | ||
237 | * @details A thread queue is a queue of sleeping threads, queued threads | ||
238 | * can be dequeued one at time or all together. | ||
239 | * @note In this implementation it is implemented as a single reference | ||
240 | * because there are no real threads. | ||
241 | */ | ||
242 | typedef struct { | ||
243 | thread_reference_t tr; | ||
244 | } threads_queue_t; | ||
245 | #endif | ||
246 | |||
247 | /*===========================================================================*/ | ||
248 | /* Module macros. */ | ||
249 | /*===========================================================================*/ | ||
250 | |||
251 | /** | ||
252 | * @name Debug related macros | ||
253 | * @{ | ||
254 | */ | ||
255 | /** | ||
256 | * @brief Condition assertion. | ||
257 | * @details If the condition check fails then the OSAL panics with a | ||
258 | * message and halts. | ||
259 | * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS | ||
260 | * switch is enabled. | ||
261 | * @note The remark string is not currently used except for putting a | ||
262 | * comment in the code about the assertion. | ||
263 | * | ||
264 | * @param[in] c the condition to be verified to be true | ||
265 | * @param[in] remark a remark string | ||
266 | * | ||
267 | * @api | ||
268 | */ | ||
269 | #define osalDbgAssert(c, remark) chDbgAssert(c, remark) | ||
270 | |||
271 | /** | ||
272 | * @brief Function parameters check. | ||
273 | * @details If the condition check fails then the OSAL panics and halts. | ||
274 | * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch | ||
275 | * is enabled. | ||
276 | * | ||
277 | * @param[in] c the condition to be verified to be true | ||
278 | * | ||
279 | * @api | ||
280 | */ | ||
281 | #define osalDbgCheck(c) chDbgCheck(c) | ||
282 | |||
283 | /** | ||
284 | * @brief I-Class state check. | ||
285 | * @note Not implemented in this simplified OSAL. | ||
286 | */ | ||
287 | #define osalDbgCheckClassI() chDbgCheckClassI() | ||
288 | |||
289 | /** | ||
290 | * @brief S-Class state check. | ||
291 | * @note Not implemented in this simplified OSAL. | ||
292 | */ | ||
293 | #define osalDbgCheckClassS() chDbgCheckClassS() | ||
294 | /** @} */ | ||
295 | |||
296 | /** | ||
297 | * @name IRQ service routines wrappers | ||
298 | * @{ | ||
299 | */ | ||
300 | /** | ||
301 | * @brief Priority level verification macro. | ||
302 | */ | ||
303 | #define OSAL_IRQ_IS_VALID_PRIORITY(n) CH_IRQ_IS_VALID_KERNEL_PRIORITY(n) | ||
304 | |||
305 | /** | ||
306 | * @brief IRQ prologue code. | ||
307 | * @details This macro must be inserted at the start of all IRQ handlers. | ||
308 | */ | ||
309 | #define OSAL_IRQ_PROLOGUE() CH_IRQ_PROLOGUE() | ||
310 | |||
311 | /** | ||
312 | * @brief IRQ epilogue code. | ||
313 | * @details This macro must be inserted at the end of all IRQ handlers. | ||
314 | */ | ||
315 | #define OSAL_IRQ_EPILOGUE() CH_IRQ_EPILOGUE() | ||
316 | |||
317 | /** | ||
318 | * @brief IRQ handler function declaration. | ||
319 | * @details This macro hides the details of an ISR function declaration. | ||
320 | * | ||
321 | * @param[in] id a vector name as defined in @p vectors.s | ||
322 | */ | ||
323 | #define OSAL_IRQ_HANDLER(id) CH_IRQ_HANDLER(id) | ||
324 | /** @} */ | ||
325 | |||
326 | /** | ||
327 | * @name Time conversion utilities | ||
328 | * @{ | ||
329 | */ | ||
330 | /** | ||
331 | * @brief Seconds to time interval. | ||
332 | * @details Converts from seconds to system ticks number. | ||
333 | * @note The result is rounded upward to the next tick boundary. | ||
334 | * @note Use of this macro for large values is not secure because | ||
335 | * integer overflows, make sure your value can be correctly | ||
336 | * converted. | ||
337 | * | ||
338 | * @param[in] secs number of seconds | ||
339 | * @return The number of ticks. | ||
340 | * | ||
341 | * @api | ||
342 | */ | ||
343 | #define OSAL_S2I(secs) TIME_S2I(secs) | ||
344 | |||
345 | /** | ||
346 | * @brief Milliseconds to time interval. | ||
347 | * @details Converts from milliseconds to system ticks number. | ||
348 | * @note The result is rounded upward to the next tick boundary. | ||
349 | * @note Use of this macro for large values is not secure because | ||
350 | * integer overflows, make sure your value can be correctly | ||
351 | * converted. | ||
352 | * | ||
353 | * @param[in] msecs number of milliseconds | ||
354 | * @return The number of ticks. | ||
355 | * | ||
356 | * @api | ||
357 | */ | ||
358 | #define OSAL_MS2I(msecs) TIME_MS2I(msecs) | ||
359 | |||
360 | /** | ||
361 | * @brief Microseconds to time interval. | ||
362 | * @details Converts from microseconds to system ticks number. | ||
363 | * @note The result is rounded upward to the next tick boundary. | ||
364 | * @note Use of this macro for large values is not secure because | ||
365 | * integer overflows, make sure your value can be correctly | ||
366 | * converted. | ||
367 | * | ||
368 | * @param[in] usecs number of microseconds | ||
369 | * @return The number of ticks. | ||
370 | * | ||
371 | * @api | ||
372 | */ | ||
373 | #define OSAL_US2I(usecs) TIME_US2I(usecs) | ||
374 | |||
375 | /** | ||
376 | * @brief Time interval to seconds. | ||
377 | * @details Converts from system ticks number to seconds. | ||
378 | * @note The result is rounded up to the next second boundary. | ||
379 | * @note Use of this macro for large values is not secure because | ||
380 | * integer overflows, make sure your value can be correctly | ||
381 | * converted. | ||
382 | * | ||
383 | * @param[in] interval interval in ticks | ||
384 | * @return The number of seconds. | ||
385 | * | ||
386 | * @api | ||
387 | */ | ||
388 | #define OSAL_I2S(interval) TIME_I2S(interval) | ||
389 | |||
390 | /** | ||
391 | * @brief Time interval to milliseconds. | ||
392 | * @details Converts from system ticks number to milliseconds. | ||
393 | * @note The result is rounded up to the next millisecond boundary. | ||
394 | * @note Use of this macro for large values is not secure because | ||
395 | * integer overflows, make sure your value can be correctly | ||
396 | * converted. | ||
397 | * | ||
398 | * @param[in] interval interval in ticks | ||
399 | * @return The number of milliseconds. | ||
400 | * | ||
401 | * @api | ||
402 | */ | ||
403 | #define OSAL_I2MS(interval) TIME_I2MS(interval) | ||
404 | |||
405 | /** | ||
406 | * @brief Time interval to microseconds. | ||
407 | * @details Converts from system ticks number to microseconds. | ||
408 | * @note The result is rounded up to the next microsecond boundary. | ||
409 | * @note Use of this macro for large values is not secure because | ||
410 | * integer overflows, make sure your value can be correctly | ||
411 | * converted. | ||
412 | * | ||
413 | * @param[in] interval interval in ticks | ||
414 | * @return The number of microseconds. | ||
415 | * | ||
416 | * @api | ||
417 | */ | ||
418 | #define OSAL_I2US(interval) TIME_I2US(interval) | ||
419 | /** @} */ | ||
420 | |||
421 | /** | ||
422 | * @name Time conversion utilities for the realtime counter | ||
423 | * @{ | ||
424 | */ | ||
425 | /** | ||
426 | * @brief Seconds to realtime counter. | ||
427 | * @details Converts from seconds to realtime counter cycles. | ||
428 | * @note The macro assumes that @p freq >= @p 1. | ||
429 | * | ||
430 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
431 | * @param[in] sec number of seconds | ||
432 | * @return The number of cycles. | ||
433 | * | ||
434 | * @api | ||
435 | */ | ||
436 | #define OSAL_S2RTC(freq, sec) S2RTC(freq, sec) | ||
437 | |||
438 | /** | ||
439 | * @brief Milliseconds to realtime counter. | ||
440 | * @details Converts from milliseconds to realtime counter cycles. | ||
441 | * @note The result is rounded upward to the next millisecond boundary. | ||
442 | * @note The macro assumes that @p freq >= @p 1000. | ||
443 | * | ||
444 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
445 | * @param[in] msec number of milliseconds | ||
446 | * @return The number of cycles. | ||
447 | * | ||
448 | * @api | ||
449 | */ | ||
450 | #define OSAL_MS2RTC(freq, msec) MS2RTC(freq, msec) | ||
451 | |||
452 | /** | ||
453 | * @brief Microseconds to realtime counter. | ||
454 | * @details Converts from microseconds to realtime counter cycles. | ||
455 | * @note The result is rounded upward to the next microsecond boundary. | ||
456 | * @note The macro assumes that @p freq >= @p 1000000. | ||
457 | * | ||
458 | * @param[in] freq clock frequency, in Hz, of the realtime counter | ||
459 | * @param[in] usec number of microseconds | ||
460 | * @return The number of cycles. | ||
461 | * | ||
462 | * @api | ||
463 | */ | ||
464 | #define OSAL_US2RTC(freq, usec) US2RTC(freq, usec) | ||
465 | /** @} */ | ||
466 | |||
467 | /** | ||
468 | * @name Sleep macros using absolute time | ||
469 | * @{ | ||
470 | */ | ||
471 | /** | ||
472 | * @brief Delays the invoking thread for the specified number of seconds. | ||
473 | * @note The specified time is rounded up to a value allowed by the real | ||
474 | * system tick clock. | ||
475 | * @note The maximum specifiable value is implementation dependent. | ||
476 | * | ||
477 | * @param[in] secs time in seconds, must be different from zero | ||
478 | * | ||
479 | * @api | ||
480 | */ | ||
481 | #define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs)) | ||
482 | |||
483 | /** | ||
484 | * @brief Delays the invoking thread for the specified number of | ||
485 | * milliseconds. | ||
486 | * @note The specified time is rounded up to a value allowed by the real | ||
487 | * system tick clock. | ||
488 | * @note The maximum specifiable value is implementation dependent. | ||
489 | * | ||
490 | * @param[in] msecs time in milliseconds, must be different from zero | ||
491 | * | ||
492 | * @api | ||
493 | */ | ||
494 | #define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs)) | ||
495 | |||
496 | /** | ||
497 | * @brief Delays the invoking thread for the specified number of | ||
498 | * microseconds. | ||
499 | * @note The specified time is rounded up to a value allowed by the real | ||
500 | * system tick clock. | ||
501 | * @note The maximum specifiable value is implementation dependent. | ||
502 | * | ||
503 | * @param[in] usecs time in microseconds, must be different from zero | ||
504 | * | ||
505 | * @api | ||
506 | */ | ||
507 | #define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs)) | ||
508 | /** @} */ | ||
509 | |||
510 | /*===========================================================================*/ | ||
511 | /* External declarations. */ | ||
512 | /*===========================================================================*/ | ||
513 | |||
514 | #ifdef __cplusplus | ||
515 | extern "C" { | ||
516 | #endif | ||
517 | |||
518 | #ifdef __cplusplus | ||
519 | } | ||
520 | #endif | ||
521 | |||
522 | /*===========================================================================*/ | ||
523 | /* Module inline functions. */ | ||
524 | /*===========================================================================*/ | ||
525 | |||
526 | /** | ||
527 | * @brief OSAL module initialization. | ||
528 | * | ||
529 | * @api | ||
530 | */ | ||
531 | static inline void osalInit(void) { | ||
532 | |||
533 | } | ||
534 | |||
535 | /** | ||
536 | * @brief System halt with error message. | ||
537 | * | ||
538 | * @param[in] reason the halt message pointer | ||
539 | * | ||
540 | * @api | ||
541 | */ | ||
542 | static inline void osalSysHalt(const char *reason) { | ||
543 | |||
544 | chSysHalt(reason); | ||
545 | } | ||
546 | |||
547 | /** | ||
548 | * @brief Disables interrupts globally. | ||
549 | * | ||
550 | * @special | ||
551 | */ | ||
552 | static inline void osalSysDisable(void) { | ||
553 | |||
554 | chSysDisable(); | ||
555 | } | ||
556 | |||
557 | /** | ||
558 | * @brief Enables interrupts globally. | ||
559 | * | ||
560 | * @special | ||
561 | */ | ||
562 | static inline void osalSysEnable(void) { | ||
563 | |||
564 | chSysEnable(); | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * @brief Enters a critical zone from thread context. | ||
569 | * @note This function cannot be used for reentrant critical zones. | ||
570 | * | ||
571 | * @special | ||
572 | */ | ||
573 | static inline void osalSysLock(void) { | ||
574 | |||
575 | chSysLock(); | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * @brief Leaves a critical zone from thread context. | ||
580 | * @note This function cannot be used for reentrant critical zones. | ||
581 | * | ||
582 | * @special | ||
583 | */ | ||
584 | static inline void osalSysUnlock(void) { | ||
585 | |||
586 | chSysUnlock(); | ||
587 | } | ||
588 | |||
589 | /** | ||
590 | * @brief Enters a critical zone from ISR context. | ||
591 | * @note This function cannot be used for reentrant critical zones. | ||
592 | * | ||
593 | * @special | ||
594 | */ | ||
595 | static inline void osalSysLockFromISR(void) { | ||
596 | |||
597 | chSysLockFromISR(); | ||
598 | } | ||
599 | |||
600 | /** | ||
601 | * @brief Leaves a critical zone from ISR context. | ||
602 | * @note This function cannot be used for reentrant critical zones. | ||
603 | * | ||
604 | * @special | ||
605 | */ | ||
606 | static inline void osalSysUnlockFromISR(void) { | ||
607 | |||
608 | chSysUnlockFromISR(); | ||
609 | } | ||
610 | |||
611 | /** | ||
612 | * @brief Returns the execution status and enters a critical zone. | ||
613 | * @details This functions enters into a critical zone and can be called | ||
614 | * from any context. Because its flexibility it is less efficient | ||
615 | * than @p chSysLock() which is preferable when the calling context | ||
616 | * is known. | ||
617 | * @post The system is in a critical zone. | ||
618 | * | ||
619 | * @return The previous system status, the encoding of this | ||
620 | * status word is architecture-dependent and opaque. | ||
621 | * | ||
622 | * @xclass | ||
623 | */ | ||
624 | static inline syssts_t osalSysGetStatusAndLockX(void) { | ||
625 | |||
626 | return chSysGetStatusAndLockX(); | ||
627 | } | ||
628 | |||
629 | /** | ||
630 | * @brief Restores the specified execution status and leaves a critical zone. | ||
631 | * @note A call to @p chSchRescheduleS() is automatically performed | ||
632 | * if exiting the critical zone and if not in ISR context. | ||
633 | * | ||
634 | * @param[in] sts the system status to be restored. | ||
635 | * | ||
636 | * @xclass | ||
637 | */ | ||
638 | static inline void osalSysRestoreStatusX(syssts_t sts) { | ||
639 | |||
640 | chSysRestoreStatusX(sts); | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * @brief Polled delay. | ||
645 | * @note The real delay is always few cycles in excess of the specified | ||
646 | * value. | ||
647 | * | ||
648 | * @param[in] cycles number of cycles | ||
649 | * | ||
650 | * @xclass | ||
651 | */ | ||
652 | #if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__) | ||
653 | static inline void osalSysPolledDelayX(rtcnt_t cycles) { | ||
654 | |||
655 | chSysPolledDelayX(cycles); | ||
656 | } | ||
657 | #endif | ||
658 | |||
659 | /** | ||
660 | * @brief Systick callback for the underlying OS. | ||
661 | * @note This callback is only defined if the OSAL requires such a | ||
662 | * service from the HAL. | ||
663 | */ | ||
664 | #if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__) | ||
665 | static inline void osalOsTimerHandlerI(void) { | ||
666 | |||
667 | chSysTimerHandlerI(); | ||
668 | } | ||
669 | #endif | ||
670 | |||
671 | /** | ||
672 | * @brief Checks if a reschedule is required and performs it. | ||
673 | * @note I-Class functions invoked from thread context must not reschedule | ||
674 | * by themselves, an explicit reschedule using this function is | ||
675 | * required in this scenario. | ||
676 | * @note Not implemented in this simplified OSAL. | ||
677 | * | ||
678 | * @sclass | ||
679 | */ | ||
680 | static inline void osalOsRescheduleS(void) { | ||
681 | |||
682 | chSchRescheduleS(); | ||
683 | } | ||
684 | |||
685 | /** | ||
686 | * @brief Current system time. | ||
687 | * @details Returns the number of system ticks since the @p osalInit() | ||
688 | * invocation. | ||
689 | * @note The counter can reach its maximum and then restart from zero. | ||
690 | * @note This function can be called from any context but its atomicity | ||
691 | * is not guaranteed on architectures whose word size is less than | ||
692 | * @p systime_t size. | ||
693 | * | ||
694 | * @return The system time in ticks. | ||
695 | * | ||
696 | * @xclass | ||
697 | */ | ||
698 | static inline systime_t osalOsGetSystemTimeX(void) { | ||
699 | |||
700 | return chVTGetSystemTimeX(); | ||
701 | } | ||
702 | |||
703 | /** | ||
704 | * @brief Adds an interval to a system time returning a system time. | ||
705 | * | ||
706 | * @param[in] systime base system time | ||
707 | * @param[in] interval interval to be added | ||
708 | * @return The new system time. | ||
709 | * | ||
710 | * @xclass | ||
711 | */ | ||
712 | static inline systime_t osalTimeAddX(systime_t systime, | ||
713 | sysinterval_t interval) { | ||
714 | |||
715 | return chTimeAddX(systime, interval); | ||
716 | } | ||
717 | |||
718 | /** | ||
719 | * @brief Subtracts two system times returning an interval. | ||
720 | * | ||
721 | * @param[in] start first system time | ||
722 | * @param[in] end second system time | ||
723 | * @return The interval representing the time difference. | ||
724 | * | ||
725 | * @xclass | ||
726 | */ | ||
727 | static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) { | ||
728 | |||
729 | return chTimeDiffX(start, end); | ||
730 | } | ||
731 | |||
732 | /** | ||
733 | * @brief Checks if the specified time is within the specified time window. | ||
734 | * @note When start==end then the function returns always true because the | ||
735 | * whole time range is specified. | ||
736 | * @note This function can be called from any context. | ||
737 | * | ||
738 | * @param[in] time the time to be verified | ||
739 | * @param[in] start the start of the time window (inclusive) | ||
740 | * @param[in] end the end of the time window (non inclusive) | ||
741 | * @retval true current time within the specified time window. | ||
742 | * @retval false current time not within the specified time window. | ||
743 | * | ||
744 | * @xclass | ||
745 | */ | ||
746 | static inline bool osalTimeIsInRangeX(systime_t time, | ||
747 | systime_t start, | ||
748 | systime_t end) { | ||
749 | |||
750 | return chTimeIsInRangeX(time, start, end); | ||
751 | } | ||
752 | |||
753 | /** | ||
754 | * @brief Suspends the invoking thread for the specified time. | ||
755 | * | ||
756 | * @param[in] delay the delay in system ticks, the special values are | ||
757 | * handled as follow: | ||
758 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
759 | * normal time specification. | ||
760 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
761 | * . | ||
762 | * | ||
763 | * @sclass | ||
764 | */ | ||
765 | static inline void osalThreadSleepS(sysinterval_t delay) { | ||
766 | |||
767 | chThdSleepS(delay); | ||
768 | } | ||
769 | |||
770 | /** | ||
771 | * @brief Suspends the invoking thread for the specified time. | ||
772 | * | ||
773 | * @param[in] delay the delay in system ticks, the special values are | ||
774 | * handled as follow: | ||
775 | * - @a TIME_INFINITE is allowed but interpreted as a | ||
776 | * normal time specification. | ||
777 | * - @a TIME_IMMEDIATE this value is not allowed. | ||
778 | * . | ||
779 | * | ||
780 | * @api | ||
781 | */ | ||
782 | static inline void osalThreadSleep(sysinterval_t delay) { | ||
783 | |||
784 | chThdSleep(delay); | ||
785 | } | ||
786 | |||
787 | /** | ||
788 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
789 | * @note This function must reschedule, it can only be called from thread | ||
790 | * context. | ||
791 | * | ||
792 | * @param[in] trp a pointer to a thread reference object | ||
793 | * @return The wake up message. | ||
794 | * | ||
795 | * @sclass | ||
796 | */ | ||
797 | static inline msg_t osalThreadSuspendS(thread_reference_t *trp) { | ||
798 | |||
799 | return chThdSuspendTimeoutS(trp, TIME_INFINITE); | ||
800 | } | ||
801 | |||
802 | /** | ||
803 | * @brief Sends the current thread sleeping and sets a reference variable. | ||
804 | * @note This function must reschedule, it can only be called from thread | ||
805 | * context. | ||
806 | * | ||
807 | * @param[in] trp a pointer to a thread reference object | ||
808 | * @param[in] timeout the timeout in system ticks, the special values are | ||
809 | * handled as follow: | ||
810 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
811 | * state. | ||
812 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
813 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
814 | * occurred. | ||
815 | * . | ||
816 | * @return The wake up message. | ||
817 | * @retval MSG_TIMEOUT if the operation timed out. | ||
818 | * | ||
819 | * @sclass | ||
820 | */ | ||
821 | static inline msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, | ||
822 | sysinterval_t timeout) { | ||
823 | |||
824 | return chThdSuspendTimeoutS(trp, timeout); | ||
825 | } | ||
826 | |||
827 | /** | ||
828 | * @brief Wakes up a thread waiting on a thread reference object. | ||
829 | * @note This function must not reschedule because it can be called from | ||
830 | * ISR context. | ||
831 | * | ||
832 | * @param[in] trp a pointer to a thread reference object | ||
833 | * @param[in] msg the message code | ||
834 | * | ||
835 | * @iclass | ||
836 | */ | ||
837 | static inline void osalThreadResumeI(thread_reference_t *trp, msg_t msg) { | ||
838 | |||
839 | chThdResumeI(trp, msg); | ||
840 | } | ||
841 | |||
842 | /** | ||
843 | * @brief Wakes up a thread waiting on a thread reference object. | ||
844 | * @note This function must reschedule, it can only be called from thread | ||
845 | * context. | ||
846 | * | ||
847 | * @param[in] trp a pointer to a thread reference object | ||
848 | * @param[in] msg the message code | ||
849 | * | ||
850 | * @iclass | ||
851 | */ | ||
852 | static inline void osalThreadResumeS(thread_reference_t *trp, msg_t msg) { | ||
853 | |||
854 | chThdResumeS(trp, msg); | ||
855 | } | ||
856 | |||
857 | /** | ||
858 | * @brief Initializes a threads queue object. | ||
859 | * | ||
860 | * @param[out] tqp pointer to the threads queue object | ||
861 | * | ||
862 | * @init | ||
863 | */ | ||
864 | static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) { | ||
865 | |||
866 | chThdQueueObjectInit(tqp); | ||
867 | } | ||
868 | |||
869 | /** | ||
870 | * @brief Enqueues the caller thread. | ||
871 | * @details The caller thread is enqueued and put to sleep until it is | ||
872 | * dequeued or the specified timeouts expires. | ||
873 | * | ||
874 | * @param[in] tqp pointer to the threads queue object | ||
875 | * @param[in] timeout the timeout in system ticks, the special values are | ||
876 | * handled as follow: | ||
877 | * - @a TIME_INFINITE the thread enters an infinite sleep | ||
878 | * state. | ||
879 | * - @a TIME_IMMEDIATE the thread is not enqueued and | ||
880 | * the function returns @p MSG_TIMEOUT as if a timeout | ||
881 | * occurred. | ||
882 | * . | ||
883 | * @return The message from @p osalQueueWakeupOneI() or | ||
884 | * @p osalQueueWakeupAllI() functions. | ||
885 | * @retval MSG_TIMEOUT if the thread has not been dequeued within the | ||
886 | * specified timeout or if the function has been | ||
887 | * invoked with @p TIME_IMMEDIATE as timeout | ||
888 | * specification. | ||
889 | * | ||
890 | * @sclass | ||
891 | */ | ||
892 | static inline msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, | ||
893 | sysinterval_t timeout) { | ||
894 | |||
895 | return chThdEnqueueTimeoutS(tqp, timeout); | ||
896 | } | ||
897 | |||
898 | /** | ||
899 | * @brief Dequeues and wakes up one thread from the queue, if any. | ||
900 | * | ||
901 | * @param[in] tqp pointer to the threads queue object | ||
902 | * @param[in] msg the message code | ||
903 | * | ||
904 | * @iclass | ||
905 | */ | ||
906 | static inline void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) { | ||
907 | |||
908 | chThdDequeueNextI(tqp, msg); | ||
909 | } | ||
910 | |||
911 | /** | ||
912 | * @brief Dequeues and wakes up all threads from the queue. | ||
913 | * | ||
914 | * @param[in] tqp pointer to the threads queue object | ||
915 | * @param[in] msg the message code | ||
916 | * | ||
917 | * @iclass | ||
918 | */ | ||
919 | static inline void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) { | ||
920 | |||
921 | chThdDequeueAllI(tqp, msg); | ||
922 | } | ||
923 | |||
924 | #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) | ||
925 | /** | ||
926 | * @brief Initializes an event source object. | ||
927 | * | ||
928 | * @param[out] esp pointer to the event source object | ||
929 | * | ||
930 | * @init | ||
931 | */ | ||
932 | static inline void osalEventObjectInit(event_source_t *esp) { | ||
933 | |||
934 | chEvtObjectInit(esp); | ||
935 | } | ||
936 | #else | ||
937 | static inline void osalEventObjectInit(event_source_t *esp) { | ||
938 | |||
939 | osalDbgCheck(esp != NULL); | ||
940 | |||
941 | esp->flags = (eventflags_t)0; | ||
942 | esp->cb = NULL; | ||
943 | esp->param = NULL; | ||
944 | } | ||
945 | #endif | ||
946 | |||
947 | #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) | ||
948 | /** | ||
949 | * @brief Add flags to an event source object. | ||
950 | * | ||
951 | * @param[in] esp pointer to the event flags object | ||
952 | * @param[in] flags flags to be ORed to the flags mask | ||
953 | * | ||
954 | * @iclass | ||
955 | */ | ||
956 | static inline void osalEventBroadcastFlagsI(event_source_t *esp, | ||
957 | eventflags_t flags) { | ||
958 | |||
959 | chEvtBroadcastFlagsI(esp, flags); | ||
960 | } | ||
961 | #else | ||
962 | static inline void osalEventBroadcastFlagsI(event_source_t *esp, | ||
963 | eventflags_t flags) { | ||
964 | |||
965 | osalDbgCheck(esp != NULL); | ||
966 | |||
967 | esp->flags |= flags; | ||
968 | if (esp->cb != NULL) { | ||
969 | esp->cb(esp); | ||
970 | } | ||
971 | } | ||
972 | #endif | ||
973 | |||
974 | #if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__) | ||
975 | /** | ||
976 | * @brief Add flags to an event source object. | ||
977 | * | ||
978 | * @param[in] esp pointer to the event flags object | ||
979 | * @param[in] flags flags to be ORed to the flags mask | ||
980 | * | ||
981 | * @iclass | ||
982 | */ | ||
983 | static inline void osalEventBroadcastFlags(event_source_t *esp, | ||
984 | eventflags_t flags) { | ||
985 | |||
986 | chEvtBroadcastFlags(esp, flags); | ||
987 | } | ||
988 | #else | ||
989 | static inline void osalEventBroadcastFlags(event_source_t *esp, | ||
990 | eventflags_t flags) { | ||
991 | |||
992 | osalDbgCheck(esp != NULL); | ||
993 | |||
994 | osalSysLock(); | ||
995 | esp->flags |= flags; | ||
996 | if (esp->cb != NULL) { | ||
997 | esp->cb(esp); | ||
998 | } | ||
999 | osalSysUnlock(); | ||
1000 | } | ||
1001 | #endif | ||
1002 | |||
1003 | #if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__) | ||
1004 | /** | ||
1005 | * @brief Event callback setup. | ||
1006 | * @note The callback is invoked from ISR context and can | ||
1007 | * only invoke I-Class functions. The callback is meant | ||
1008 | * to wakeup the task that will handle the event by | ||
1009 | * calling @p osalEventGetAndClearFlagsI(). | ||
1010 | * | ||
1011 | * @param[in] esp pointer to the event flags object | ||
1012 | * @param[in] cb pointer to the callback function | ||
1013 | * @param[in] param parameter to be passed to the callback function | ||
1014 | * | ||
1015 | * @api | ||
1016 | */ | ||
1017 | static inline void osalEventSetCallback(event_source_t *esp, | ||
1018 | eventcallback_t cb, | ||
1019 | void *param) { | ||
1020 | |||
1021 | osalDbgCheck(esp != NULL); | ||
1022 | |||
1023 | esp->cb = cb; | ||
1024 | esp->param = param; | ||
1025 | } | ||
1026 | #endif | ||
1027 | |||
1028 | /** | ||
1029 | * @brief Initializes s @p mutex_t object. | ||
1030 | * | ||
1031 | * @param[out] mp pointer to the @p mutex_t object | ||
1032 | * | ||
1033 | * @init | ||
1034 | */ | ||
1035 | static inline void osalMutexObjectInit(mutex_t *mp) { | ||
1036 | |||
1037 | #if CH_CFG_USE_MUTEXES | ||
1038 | chMtxObjectInit(mp); | ||
1039 | #elif CH_CFG_USE_SEMAPHORES | ||
1040 | chSemObjectInit((semaphore_t *)mp, 1); | ||
1041 | #else | ||
1042 | *mp = 0; | ||
1043 | #endif | ||
1044 | } | ||
1045 | |||
1046 | /** | ||
1047 | * @brief Locks the specified mutex. | ||
1048 | * @post The mutex is locked and inserted in the per-thread stack of owned | ||
1049 | * mutexes. | ||
1050 | * | ||
1051 | * @param[in,out] mp pointer to the @p mutex_t object | ||
1052 | * | ||
1053 | * @api | ||
1054 | */ | ||
1055 | static inline void osalMutexLock(mutex_t *mp) { | ||
1056 | |||
1057 | #if CH_CFG_USE_MUTEXES | ||
1058 | chMtxLock(mp); | ||
1059 | #elif CH_CFG_USE_SEMAPHORES | ||
1060 | chSemWait((semaphore_t *)mp); | ||
1061 | #else | ||
1062 | *mp = 1; | ||
1063 | #endif | ||
1064 | } | ||
1065 | |||
1066 | /** | ||
1067 | * @brief Unlocks the specified mutex. | ||
1068 | * @note The HAL guarantees to release mutex in reverse lock order. The | ||
1069 | * mutex being unlocked is guaranteed to be the last locked mutex | ||
1070 | * by the invoking thread. | ||
1071 | * The implementation can rely on this behavior and eventually | ||
1072 | * ignore the @p mp parameter which is supplied in order to support | ||
1073 | * those OSes not supporting a stack of the owned mutexes. | ||
1074 | * | ||
1075 | * @param[in,out] mp pointer to the @p mutex_t object | ||
1076 | * | ||
1077 | * @api | ||
1078 | */ | ||
1079 | static inline void osalMutexUnlock(mutex_t *mp) { | ||
1080 | |||
1081 | #if CH_CFG_USE_MUTEXES | ||
1082 | chMtxUnlock(mp); | ||
1083 | #elif CH_CFG_USE_SEMAPHORES | ||
1084 | chSemSignal((semaphore_t *)mp); | ||
1085 | #else | ||
1086 | *mp = 0; | ||
1087 | #endif | ||
1088 | } | ||
1089 | |||
1090 | #endif /* OSAL_H */ | ||
1091 | |||
1092 | /** @} */ | ||
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.mk b/lib/chibios/os/hal/osal/rt-nil/osal.mk new file mode 100644 index 000000000..98f162f83 --- /dev/null +++ b/lib/chibios/os/hal/osal/rt-nil/osal.mk | |||
@@ -0,0 +1,9 @@ | |||
1 | # OSAL files. | ||
2 | OSALSRC += ${CHIBIOS}/os/hal/osal/rt-nil/osal.c | ||
3 | |||
4 | # Required include directories | ||
5 | OSALINC += ${CHIBIOS}/os/hal/osal/rt-nil | ||
6 | |||
7 | # Shared variables | ||
8 | ALLCSRC += $(OSALSRC) | ||
9 | ALLINC += $(OSALINC) | ||