ChibiOS  21.6.0
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  */
149 struct port_extctx {
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  */
161 struct port_intctx {
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  */
169 struct port_context {
170  struct port_intctx *sp;
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 /* External declarations. */
280 /*===========================================================================*/
281 
282 /* The following code is not processed when the file is included from an
283  asm module.*/
284 #if !defined(_FROM_ASM_)
285 
286 #ifdef __cplusplus
287 extern "C" {
288 #endif
289  void _port_init(void);
290  void _port_switch(thread_t *ntp, thread_t *otp);
291 #ifdef __cplusplus
292 }
293 #endif
294 
295 #endif /* !defined(_FROM_ASM_) */
296 
297 /*===========================================================================*/
298 /* Module inline functions. */
299 /*===========================================================================*/
300 
301 /* The following code is not processed when the file is included from an
302  asm module.*/
303 #if !defined(_FROM_ASM_)
304 
305 /**
306  * @brief Returns a word encoding the current interrupts status.
307  *
308  * @return The interrupts status.
309  */
310 static inline syssts_t port_get_irq_status(void) {
311 
312  return 0;
313 }
314 
315 /**
316  * @brief Checks the interrupt status.
317  *
318  * @param[in] sts the interrupt status word
319  *
320  * @return The interrupt status.
321  * @retval false the word specified a disabled interrupts status.
322  * @retval true the word specified an enabled interrupts status.
323  */
324 static inline bool port_irq_enabled(syssts_t sts) {
325 
326  (void)sts;
327 
328  return false;
329 }
330 
331 /**
332  * @brief Determines the current execution context.
333  *
334  * @return The execution context.
335  * @retval false not running in ISR mode.
336  * @retval true running in ISR mode.
337  */
338 static inline bool port_is_isr_context(void) {
339 
340  return false;
341 }
342 
343 /**
344  * @brief Kernel-lock action.
345  * @details Usually this function just disables interrupts but may perform more
346  * actions.
347  */
348 static inline void port_lock(void) {
349 
350 }
351 
352 /**
353  * @brief Kernel-unlock action.
354  * @details Usually this function just enables interrupts but may perform more
355  * actions.
356  */
357 static inline void port_unlock(void) {
358 
359 }
360 
361 /**
362  * @brief Kernel-lock action from an interrupt handler.
363  * @details This function is invoked before invoking I-class APIs from
364  * interrupt handlers. The implementation is architecture dependent,
365  * in its simplest form it is void.
366  */
367 static inline void port_lock_from_isr(void) {
368 
369 }
370 
371 /**
372  * @brief Kernel-unlock action from an interrupt handler.
373  * @details This function is invoked after invoking I-class APIs from interrupt
374  * handlers. The implementation is architecture dependent, in its
375  * simplest form it is void.
376  */
377 static inline void port_unlock_from_isr(void) {
378 
379 }
380 
381 /**
382  * @brief Disables all the interrupt sources.
383  * @note Of course non-maskable interrupt sources are not included.
384  */
385 static inline void port_disable(void) {
386 
387 }
388 
389 /**
390  * @brief Disables the interrupt sources below kernel-level priority.
391  * @note Interrupt sources above kernel level remains enabled.
392  */
393 static inline void port_suspend(void) {
394 
395 }
396 
397 /**
398  * @brief Enables all the interrupt sources.
399  */
400 static inline void port_enable(void) {
401 
402 }
403 
404 /**
405  * @brief Enters an architecture-dependent IRQ-waiting mode.
406  * @details The function is meant to return when an interrupt becomes pending.
407  * The simplest implementation is an empty function or macro but this
408  * would not take advantage of architecture-specific power saving
409  * modes.
410  */
411 static inline void port_wait_for_interrupt(void) {
412 
413 #if PORT_XXX_ENABLE_WFI_IDLE
414 #endif
415 }
416 
417 /**
418  * @brief Returns the current value of the realtime counter.
419  *
420  * @return The realtime counter value.
421  */
422 static inline rtcnt_t port_rt_get_counter_value(void) {
423 
424  return 0;
425 }
426 
427 #endif /* !defined(_FROM_ASM_) */
428 
429 /*===========================================================================*/
430 /* Module late inclusions. */
431 /*===========================================================================*/
432 
433 #if !defined(_FROM_ASM_)
434 
435 #if CH_CFG_ST_TIMEDELTA > 0
436 #include "chcore_timer.h"
437 #endif /* CH_CFG_ST_TIMEDELTA > 0 */
438 
439 #endif /* !defined(_FROM_ASM_) */
440 
441 #endif /* CHCORE_H */
442 
443 /** @} */
port_irq_enabled
static bool port_irq_enabled(syssts_t sts)
Checks the interrupt status.
Definition: chcore.h:324
port_extctx
Interrupt saved context.
Definition: chcore.h:149
port_unlock_from_isr
static void port_unlock_from_isr(void)
Kernel-unlock action from an interrupt handler.
Definition: chcore.h:377
port_is_isr_context
static bool port_is_isr_context(void)
Determines the current execution context.
Definition: chcore.h:338
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
syssts_t
port_syssts_t syssts_t
Definition: chearly.h:79
port_suspend
static void port_suspend(void)
Disables the interrupt sources below kernel-level priority.
Definition: chcore.h:393
rtcnt_t
port_rtcnt_t rtcnt_t
Definition: chearly.h:77
port_unlock
static void port_unlock(void)
Kernel-unlock action.
Definition: chcore.h:357
port_get_irq_status
static syssts_t port_get_irq_status(void)
Returns a word encoding the current interrupts status.
Definition: chcore.h:310
port_lock
static void port_lock(void)
Kernel-lock action.
Definition: chcore.h:348
port_enable
static void port_enable(void)
Enables all the interrupt sources.
Definition: chcore.h:400
port_lock_from_isr
static void port_lock_from_isr(void)
Kernel-lock action from an interrupt handler.
Definition: chcore.h:367
port_disable
static void port_disable(void)
Disables all the interrupt sources.
Definition: chcore.h:385
port_intctx
System saved context.
Definition: chcore.h:161
_port_init
void _port_init(void)
Port-related initialization code.
Definition: chcore.c:59
port_wait_for_interrupt
static void port_wait_for_interrupt(void)
Enters an architecture-dependent IRQ-waiting mode.
Definition: chcore.h:411
port_rt_get_counter_value
static rtcnt_t port_rt_get_counter_value(void)
Returns the current value of the realtime counter.
Definition: chcore.h:422
port_context
Platform dependent part of the thread_t structure.
Definition: chcore.h:169
_port_switch
void _port_switch(thread_t *ntp, thread_t *otp)
Performs a context switch between two threads.
Definition: chcore.c:72