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