ChibiOS 21.11.4
chcore.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file templates/chcore.h
22 * @brief Port related template macros and structures.
23 * @details This file is a template of the system driver macros provided by
24 * a port.
25 *
26 * @addtogroup port_core
27 * @{
28 */
29
30#ifndef CHCORE_H
31#define CHCORE_H
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/**
38 * @name Port Capabilities and Constants
39 * @{
40 */
41/**
42 * @brief This port supports a realtime counter.
43 */
44#define PORT_SUPPORTS_RT FALSE
45
46/**
47 * @brief Natural alignment constant.
48 * @note It is the minimum alignment for pointer-size variables.
49 */
50#define PORT_NATURAL_ALIGN sizeof (void *)
51
52/**
53 * @brief Stack alignment constant.
54 * @note It is the alignment required for the stack pointer.
55 */
56#define PORT_STACK_ALIGN sizeof (stkalign_t)
57
58/**
59 * @brief Working Areas alignment constant.
60 * @note It is the alignment to be enforced for thread working areas.
61 */
62#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t)
63/** @} */
64
65/**
66 * @name Architecture and Compiler
67 * @{
68 */
69/**
70 * @brief Macro defining an XXX architecture.
71 */
72#define PORT_ARCHITECTURE_XXX
73
74/**
75 * @brief Macro defining the specific XXX architecture.
76 */
77#define PORT_ARCHITECTURE_XXX_YYY
78
79/**
80 * @brief Name of the implemented architecture.
81 */
82#define PORT_ARCHITECTURE_NAME "XXX Architecture"
83
84/**
85 * @brief Compiler name and version.
86 */
87#if defined(__GNUC__) || defined(__DOXYGEN__)
88#define PORT_COMPILER_NAME "GCC " __VERSION__
89
90#else
91#error "unsupported compiler"
92#endif
93
94/**
95 * @brief Port-specific information string.
96 */
97#define PORT_INFO "no info"
98/** @} */
99
100/*===========================================================================*/
101/* Module pre-compile time settings. */
102/*===========================================================================*/
103
104/**
105 * @brief Stack size for the system idle thread.
106 * @details This size depends on the idle thread implementation, usually
107 * the idle thread should take no more space than those reserved
108 * by @p PORT_INT_REQUIRED_STACK.
109 */
110#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
111#define PORT_IDLE_THREAD_STACK_SIZE 32
112#endif
113
114/**
115 * @brief Per-thread stack overhead for interrupts servicing.
116 * @details This constant is used in the calculation of the correct working
117 * area size.
118 */
119#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
120#define PORT_INT_REQUIRED_STACK 256
121#endif
122
123/**
124 * @brief Enables a "wait for interrupt" instruction in the idle loop.
125 */
126#if !defined(PORT_XXX_WFI_SLEEP_IDLE) || defined(__DOXYGEN__)
127#define PORT_XXX_ENABLE_WFI_IDLE FALSE
128#endif
129
130/*===========================================================================*/
131/* Derived constants and error checks. */
132/*===========================================================================*/
133
134/*===========================================================================*/
135/* Module data structures and types. */
136/*===========================================================================*/
137
138/* The following code is not processed when the file is included from an
139 asm module.*/
140#if !defined(_FROM_ASM_)
141
142/**
143 * @brief Interrupt saved context.
144 * @details This structure represents the stack frame saved during a
145 * preemption-capable interrupt handler.
146 * @note R2 and R13 are not saved because those are assumed to be immutable
147 * during the system life cycle.
148 */
150};
151
152/**
153 * @brief System saved context.
154 * @details This structure represents the inner stack frame during a context
155 * switching.
156 * @note R2 and R13 are not saved because those are assumed to be immutable
157 * during the system life cycle.
158 * @note LR is stored in the caller context so it is not present in this
159 * structure.
160 */
162};
163
164/**
165 * @brief Platform dependent part of the @p thread_t structure.
166 * @details This structure usually contains just the saved stack pointer
167 * defined as a pointer to a @p port_intctx structure.
168 */
171};
172
173#endif /* !defined(_FROM_ASM_) */
174
175/*===========================================================================*/
176/* Module macros. */
177/*===========================================================================*/
178
179/**
180 * @brief Optimized thread function declaration macro.
181 */
182#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
183
184/**
185 * @brief Platform dependent part of the @p chThdCreateI() API.
186 * @details This code usually setup the context switching frame represented
187 * by an @p port_intctx structure.
188 */
189#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
190}
191
192/**
193 * @brief Computes the thread working area global size.
194 * @note There is no need to perform alignments in this macro.
195 */
196#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
197 sizeof(struct port_extctx) + \
198 ((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
199
200/**
201 * @brief Static working area allocation.
202 * @details This macro is used to allocate a static thread working area
203 * aligned as both position and size.
204 *
205 * @param[in] s the name to be assigned to the stack array
206 * @param[in] n the stack size to be assigned to the thread
207 */
208#define PORT_WORKING_AREA(s, n) \
209 stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
210
211/**
212 * @brief Priority level verification macro.
213 */
214#define PORT_IRQ_IS_VALID_PRIORITY(n) false
215
216/**
217 * @brief Priority level verification macro.
218 */
219#define PORT_IRQ_IS_VALID_KERNEL_PRIORITY(n) false
220
221/**
222 * @brief IRQ prologue code.
223 * @details This macro must be inserted at the start of all IRQ handlers
224 * enabled to invoke system APIs.
225 */
226#define PORT_IRQ_PROLOGUE()
227
228/**
229 * @brief IRQ epilogue code.
230 * @details This macro must be inserted at the end of all IRQ handlers
231 * enabled to invoke system APIs.
232 */
233#define PORT_IRQ_EPILOGUE()
234
235/**
236 * @brief IRQ handler function declaration.
237 * @note @p id can be a function name or a vector number depending on the
238 * port implementation.
239 */
240#ifdef __cplusplus
241#define PORT_IRQ_HANDLER(id) extern "C" void id(void)
242#else
243#define PORT_IRQ_HANDLER(id) void id(void)
244#endif
245
246/**
247 * @brief Fast IRQ handler function declaration.
248 * @note @p id can be a function name or a vector number depending on the
249 * port implementation.
250 */
251#ifdef __cplusplus
252#define PORT_FAST_IRQ_HANDLER(id) extern "C" void id(void)
253#else
254#define PORT_FAST_IRQ_HANDLER(id) void id(void)
255#endif
256
257/**
258 * @brief Performs a context switch between two threads.
259 * @details This is the most critical code in any port, this function
260 * is responsible for the context switch between 2 threads.
261 * @note The implementation of this code affects <b>directly</b> the context
262 * switch performance so optimize here as much as you can.
263 *
264 * @param[in] ntp the thread to be switched in
265 * @param[in] otp the thread to be switched out
266 */
267#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
268#define port_switch(ntp, otp) _port_switch(ntp, otp)
269#else
270#define port_switch(ntp, otp) { \
271 register struct port_intctx *sp asm ("%r1"); \
272 if ((stkalign_t *)(sp - 1) < otp->wabase) \
273 chSysHalt("stack overflow"); \
274 _port_switch(ntp, otp); \
275}
276#endif
277
278/**
279 * @brief Returns a word representing a critical section status.
280 *
281 * @return The critical section status.
282 */
283#define port_get_lock_status() 0U
284
285/**
286 * @brief Determines if in a critical section.
287 *
288 * @param[in] sts status word returned by @p port_get_lock_status()
289 * @return The current status.
290 * @retval false if running outside a critical section.
291 * @retval true if running within a critical section.
292 */
293#define port_is_locked(sts) ((sts) != 0U)
294
295/*===========================================================================*/
296/* External declarations. */
297/*===========================================================================*/
298
299/* The following code is not processed when the file is included from an
300 asm module.*/
301#if !defined(_FROM_ASM_)
302
303#ifdef __cplusplus
304extern "C" {
305#endif
306 void _port_init(void);
307 void _port_switch(thread_t *ntp, thread_t *otp);
308#ifdef __cplusplus
309}
310#endif
311
312#endif /* !defined(_FROM_ASM_) */
313
314/*===========================================================================*/
315/* Module inline functions. */
316/*===========================================================================*/
317
318/* The following code is not processed when the file is included from an
319 asm module.*/
320#if !defined(_FROM_ASM_)
321
322/**
323 * @brief Determines the current execution context.
324 *
325 * @return The execution context.
326 * @retval false not running in ISR mode.
327 * @retval true running in ISR mode.
328 */
329static inline bool port_is_isr_context(void) {
330
331 return false;
332}
333
334/**
335 * @brief Kernel-lock action.
336 * @details Usually this function just disables interrupts but may perform more
337 * actions.
338 */
339static inline void port_lock(void) {
340
341}
342
343/**
344 * @brief Kernel-unlock action.
345 * @details Usually this function just enables interrupts but may perform more
346 * actions.
347 */
348static inline void port_unlock(void) {
349
350}
351
352/**
353 * @brief Kernel-lock action from an interrupt handler.
354 * @details This function is invoked before invoking I-class APIs from
355 * interrupt handlers. The implementation is architecture dependent,
356 * in its simplest form it is void.
357 */
358static inline void port_lock_from_isr(void) {
359
360}
361
362/**
363 * @brief Kernel-unlock action from an interrupt handler.
364 * @details This function is invoked after invoking I-class APIs from interrupt
365 * handlers. The implementation is architecture dependent, in its
366 * simplest form it is void.
367 */
368static inline void port_unlock_from_isr(void) {
369
370}
371
372/**
373 * @brief Disables all the interrupt sources.
374 * @note Of course non-maskable interrupt sources are not included.
375 */
376static inline void port_disable(void) {
377
378}
379
380/**
381 * @brief Disables the interrupt sources below kernel-level priority.
382 * @note Interrupt sources above kernel level remains enabled.
383 */
384static inline void port_suspend(void) {
385
386}
387
388/**
389 * @brief Enables all the interrupt sources.
390 */
391static inline void port_enable(void) {
392
393}
394
395/**
396 * @brief Enters an architecture-dependent IRQ-waiting mode.
397 * @details The function is meant to return when an interrupt becomes pending.
398 * The simplest implementation is an empty function or macro but this
399 * would not take advantage of architecture-specific power saving
400 * modes.
401 */
402static inline void port_wait_for_interrupt(void) {
403
404#if PORT_XXX_ENABLE_WFI_IDLE
405#endif
406}
407
408/**
409 * @brief Returns the current value of the realtime counter.
410 *
411 * @return The realtime counter value.
412 */
414
415 return 0;
416}
417
418#endif /* !defined(_FROM_ASM_) */
419
420/*===========================================================================*/
421/* Module late inclusions. */
422/*===========================================================================*/
423
424#if !defined(_FROM_ASM_)
425
426#if CH_CFG_ST_TIMEDELTA > 0
427#include "chcore_timer.h"
428#endif /* CH_CFG_ST_TIMEDELTA > 0 */
429
430#endif /* !defined(_FROM_ASM_) */
431
432#endif /* CHCORE_H */
433
434/** @} */
port_rtcnt_t rtcnt_t
Definition chearly.h:77
struct ch_thread thread_t
Type of a thread structure.
Definition chearly.h:133
static void port_unlock_from_isr(void)
Kernel-unlock action from an interrupt handler.
Definition chcore.h:368
void _port_init(void)
Port-related initialization code.
Definition chcore.c:59
static void port_wait_for_interrupt(void)
Enters an architecture-dependent IRQ-waiting mode.
Definition chcore.h:402
static void port_disable(void)
Disables all the interrupt sources.
Definition chcore.h:376
static rtcnt_t port_rt_get_counter_value(void)
Returns the current value of the realtime counter.
Definition chcore.h:413
static void port_lock_from_isr(void)
Kernel-lock action from an interrupt handler.
Definition chcore.h:358
static void port_enable(void)
Enables all the interrupt sources.
Definition chcore.h:391
static void port_lock(void)
Kernel-lock action.
Definition chcore.h:339
static bool port_is_isr_context(void)
Determines the current execution context.
Definition chcore.h:329
static void port_suspend(void)
Disables the interrupt sources below kernel-level priority.
Definition chcore.h:384
void _port_switch(thread_t *ntp, thread_t *otp)
Performs a context switch between two threads.
Definition chcore.c:72
static void port_unlock(void)
Kernel-unlock action.
Definition chcore.h:348
Platform dependent part of the thread_t structure.
Definition chcore.h:169
struct port_intctx * sp
Definition chcore.h:170
Interrupt saved context.
Definition chcore.h:149
System saved context.
Definition chcore.h:161