ChibiOS  0.0.0
chcore.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 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; either version 3 of the License, or
9  (at your option) any later version.
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 alignement 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 an alternative timer implementation.
125  * @details Usually the port uses a timer interface defined in the file
126  * @p chcore_timer.h, if this option is enabled then the file
127  * @p chcore_timer_alt.h is included instead.
128  */
129 #if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__)
130 #define PORT_USE_ALT_TIMER FALSE
131 #endif
132 
133 /**
134  * @brief Enables a "wait for interrupt" instruction in the idle loop.
135  */
136 #if !defined(PORT_XXX_WFI_SLEEP_IDLE) || defined(__DOXYGEN__)
137 #define PORT_XXX_ENABLE_WFI_IDLE FALSE
138 #endif
139 
140 /*===========================================================================*/
141 /* Derived constants and error checks. */
142 /*===========================================================================*/
143 
144 /*===========================================================================*/
145 /* Module data structures and types. */
146 /*===========================================================================*/
147 
148 /* The following code is not processed when the file is included from an
149  asm module.*/
150 #if !defined(_FROM_ASM_)
151 
152 /**
153  * @brief Type of stack and memory alignment enforcement.
154  * @note In this architecture the stack alignment is enforced to 64 bits.
155  */
156 typedef uint64_t stkalign_t;
157 
158 /**
159  * @brief Interrupt saved context.
160  * @details This structure represents the stack frame saved during a
161  * preemption-capable interrupt handler.
162  * @note R2 and R13 are not saved because those are assumed to be immutable
163  * during the system life cycle.
164  */
165 struct port_extctx {
166 };
167 
168 /**
169  * @brief System saved context.
170  * @details This structure represents the inner stack frame during a context
171  * switching.
172  * @note R2 and R13 are not saved because those are assumed to be immutable
173  * during the system life cycle.
174  * @note LR is stored in the caller context so it is not present in this
175  * structure.
176  */
177 struct port_intctx {
178 };
179 
180 /**
181  * @brief Platform dependent part of the @p thread_t structure.
182  * @details This structure usually contains just the saved stack pointer
183  * defined as a pointer to a @p port_intctx structure.
184  */
185 struct port_context {
186  struct port_intctx *sp;
187 };
188 
189 #endif /* !defined(_FROM_ASM_) */
190 
191 /*===========================================================================*/
192 /* Module macros. */
193 /*===========================================================================*/
194 
195 /**
196  * @brief Platform dependent part of the @p chThdCreateI() API.
197  * @details This code usually setup the context switching frame represented
198  * by an @p port_intctx structure.
199  */
200 #define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
201 }
202 
203 /**
204  * @brief Computes the thread working area global size.
205  * @note There is no need to perform alignments in this macro.
206  */
207 #define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
208  sizeof(struct port_extctx) + \
209  ((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
210 
211 /**
212  * @brief Static working area allocation.
213  * @details This macro is used to allocate a static thread working area
214  * aligned as both position and size.
215  *
216  * @param[in] s the name to be assigned to the stack array
217  * @param[in] n the stack size to be assigned to the thread
218  */
219 #define PORT_WORKING_AREA(s, n) \
220  stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
221 
222 /**
223  * @brief Priority level verification macro.
224  */
225 #define PORT_IRQ_IS_VALID_PRIORITY(n) false
226 
227 /**
228  * @brief Priority level verification macro.
229  */
230 #define PORT_IRQ_IS_VALID_KERNEL_PRIORITY(n) false
231 
232 /**
233  * @brief IRQ prologue code.
234  * @details This macro must be inserted at the start of all IRQ handlers
235  * enabled to invoke system APIs.
236  */
237 #define PORT_IRQ_PROLOGUE()
238 
239 /**
240  * @brief IRQ epilogue code.
241  * @details This macro must be inserted at the end of all IRQ handlers
242  * enabled to invoke system APIs.
243  */
244 #define PORT_IRQ_EPILOGUE()
245 
246 /**
247  * @brief 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 #define PORT_IRQ_HANDLER(id) void id(void)
252 
253 /**
254  * @brief Fast IRQ handler function declaration.
255  * @note @p id can be a function name or a vector number depending on the
256  * port implementation.
257  */
258 #define PORT_FAST_IRQ_HANDLER(id) void id(void)
259 
260 /**
261  * @brief Performs a context switch between two threads.
262  * @details This is the most critical code in any port, this function
263  * is responsible for the context switch between 2 threads.
264  * @note The implementation of this code affects <b>directly</b> the context
265  * switch performance so optimize here as much as you can.
266  *
267  * @param[in] ntp the thread to be switched in
268  * @param[in] otp the thread to be switched out
269  */
270 #if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
271 #define port_switch(ntp, otp) _port_switch(ntp, otp)
272 #else
273 #define port_switch(ntp, otp) { \
274  register struct port_intctx *sp asm ("%r1"); \
275  if ((stkalign_t *)(sp - 1) < otp->wabase) \
276  chSysHalt("stack overflow"); \
277  _port_switch(ntp, otp); \
278 }
279 #endif
280 
281 /*===========================================================================*/
282 /* External declarations. */
283 /*===========================================================================*/
284 
285 /* The following code is not processed when the file is included from an
286  asm module.*/
287 #if !defined(_FROM_ASM_)
288 
289 #ifdef __cplusplus
290 extern "C" {
291 #endif
292  void _port_init(void);
293  void _port_switch(thread_t *ntp, thread_t *otp);
294 #ifdef __cplusplus
295 }
296 #endif
297 
298 #endif /* !defined(_FROM_ASM_) */
299 
300 /*===========================================================================*/
301 /* Module inline functions. */
302 /*===========================================================================*/
303 
304 /* The following code is not processed when the file is included from an
305  asm module.*/
306 #if !defined(_FROM_ASM_)
307 
308 /**
309  * @brief Returns a word encoding the current interrupts status.
310  *
311  * @return The interrupts status.
312  */
313 static inline syssts_t port_get_irq_status(void) {
314 
315  return 0;
316 }
317 
318 /**
319  * @brief Checks the interrupt status.
320  *
321  * @param[in] sts the interrupt status word
322  *
323  * @return The interrupt status.
324  * @retval false the word specified a disabled interrupts status.
325  * @retval true the word specified an enabled interrupts status.
326  */
327 static inline bool port_irq_enabled(syssts_t sts) {
328 
329  (void)sts;
330 
331  return false;
332 }
333 
334 /**
335  * @brief Determines the current execution context.
336  *
337  * @return The execution context.
338  * @retval false not running in ISR mode.
339  * @retval true running in ISR mode.
340  */
341 static inline bool port_is_isr_context(void) {
342 
343  return false;
344 }
345 
346 /**
347  * @brief Kernel-lock action.
348  * @details Usually this function just disables interrupts but may perform more
349  * actions.
350  */
351 static inline void port_lock(void) {
352 
353 }
354 
355 /**
356  * @brief Kernel-unlock action.
357  * @details Usually this function just enables interrupts but may perform more
358  * actions.
359  */
360 static inline void port_unlock(void) {
361 
362 }
363 
364 /**
365  * @brief Kernel-lock action from an interrupt handler.
366  * @details This function is invoked before invoking I-class APIs from
367  * interrupt handlers. The implementation is architecture dependent,
368  * in its simplest form it is void.
369  */
370 static inline void port_lock_from_isr(void) {
371 
372 }
373 
374 /**
375  * @brief Kernel-unlock action from an interrupt handler.
376  * @details This function is invoked after invoking I-class APIs from interrupt
377  * handlers. The implementation is architecture dependent, in its
378  * simplest form it is void.
379  */
380 static inline void port_unlock_from_isr(void) {
381 
382 }
383 
384 /**
385  * @brief Disables all the interrupt sources.
386  * @note Of course non-maskable interrupt sources are not included.
387  */
388 static inline void port_disable(void) {
389 
390 }
391 
392 /**
393  * @brief Disables the interrupt sources below kernel-level priority.
394  * @note Interrupt sources above kernel level remains enabled.
395  */
396 static inline void port_suspend(void) {
397 
398 }
399 
400 /**
401  * @brief Enables all the interrupt sources.
402  */
403 static inline void port_enable(void) {
404 
405 }
406 
407 /**
408  * @brief Enters an architecture-dependent IRQ-waiting mode.
409  * @details The function is meant to return when an interrupt becomes pending.
410  * The simplest implementation is an empty function or macro but this
411  * would not take advantage of architecture-specific power saving
412  * modes.
413  */
414 static inline void port_wait_for_interrupt(void) {
415 
416 #if PORT_XXX_ENABLE_WFI_IDLE
417 #endif
418 }
419 
420 /**
421  * @brief Returns the current value of the realtime counter.
422  *
423  * @return The realtime counter value.
424  */
425 static inline rtcnt_t port_rt_get_counter_value(void) {
426 
427  return 0;
428 }
429 
430 #endif /* !defined(_FROM_ASM_) */
431 
432 /*===========================================================================*/
433 /* Module late inclusions. */
434 /*===========================================================================*/
435 
436 /* The following code is not processed when the file is included from an
437  asm module.*/
438 #if !defined(_FROM_ASM_)
439 
440 #if CH_CFG_ST_TIMEDELTA > 0
441 #if !PORT_USE_ALT_TIMER
442 #include "chcore_timer.h"
443 #else /* PORT_USE_ALT_TIMER */
444 #include "chcore_timer_alt.h"
445 #endif /* PORT_USE_ALT_TIMER */
446 #endif /* CH_CFG_ST_TIMEDELTA > 0 */
447 
448 #endif /* !defined(_FROM_ASM_) */
449 
450 #endif /* CHCORE_H */
451 
452 /** @} */
static void port_wait_for_interrupt(void)
Enters an architecture-dependent IRQ-waiting mode.
Definition: chcore.h:414
static void port_enable(void)
Enables all the interrupt sources.
Definition: chcore.h:403
void _port_init(void)
Port-related initialization code.
Definition: chcore.c:59
static rtcnt_t port_rt_get_counter_value(void)
Returns the current value of the realtime counter.
Definition: chcore.h:425
Platform dependent part of the thread_t structure.
Definition: chcore.h:185
static void port_disable(void)
Disables all the interrupt sources.
Definition: chcore.h:388
static void port_unlock(void)
Kernel-unlock action.
Definition: chcore.h:360
System saved context.
Definition: chcore.h:177
static void port_lock_from_isr(void)
Kernel-lock action from an interrupt handler.
Definition: chcore.h:370
uint32_t rtcnt_t
Definition: chtypes.h:43
void _port_switch(thread_t *ntp, thread_t *otp)
Performs a context switch between two threads.
Definition: chcore.c:72
static bool port_is_isr_context(void)
Determines the current execution context.
Definition: chcore.h:341
static void port_lock(void)
Kernel-lock action.
Definition: chcore.h:351
uint32_t syssts_t
Definition: chtypes.h:45
Interrupt saved context.
Definition: chcore.h:165
uint64_t stkalign_t
Type of stack and memory alignment enforcement.
Definition: chcore.h:156
static void port_unlock_from_isr(void)
Kernel-unlock action from an interrupt handler.
Definition: chcore.h:380
static syssts_t port_get_irq_status(void)
Returns a word encoding the current interrupts status.
Definition: chcore.h:313
static void port_suspend(void)
Disables the interrupt sources below kernel-level priority.
Definition: chcore.h:396
static bool port_irq_enabled(syssts_t sts)
Checks the interrupt status.
Definition: chcore.h:327
Structure representing a thread.
Definition: chschd.h:153