ChibiOS 21.11.5
hal_safety.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 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 hal_safety.h
19 * @brief Safety manager macros and structures.
20 *
21 * @addtogroup HAL_SAFETY
22 * @{
23 */
24
25#ifndef HAL_SAFETY_H
26#define HAL_SAFETY_H
27
28/*===========================================================================*/
29/* Driver constants. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Driver pre-compile time settings. */
34/*===========================================================================*/
35
36/**
37 * @brief Enables the safety-related features in HAL.
38 * @note Disabling this option saves both code and data space.
39 */
40#if !defined(HAL_USE_SAFETY) || defined(__DOXYGEN__)
41#define HAL_USE_SAFETY FALSE
42#endif
43
44/*===========================================================================*/
45/* Derived constants and error checks. */
46/*===========================================================================*/
47
48/*===========================================================================*/
49/* Driver data structures and types. */
50/*===========================================================================*/
51
52/*===========================================================================*/
53/* Driver macros. */
54/*===========================================================================*/
55
56/**
57 * @name Function variants
58 * @{
59 */
60/**
61 * @brief Sets bits into an 8 bits register.
62 * @note There is a strong assumption for memory-mapped I/O, this is not
63 * necessarily true on all architectures.
64 * @note Verification failure results in entering the fault handler.
65 *
66 * @param[in] p pointer to the register
67 * @param[in] s mask of bits to be set
68 * @param[in] v verification flag, register is read back if @p true,
69 * this flag only has effect if @p HAL_USE_SAFETY is
70 * set to @p TRUE
71 *
72 * @xclass
73 */
74#define halRegSet8X(p, s, v) halRegModify8X(p, s, (uint8_t)0, v)
75
76/**
77 * @brief Sets bits into a 16 bits register.
78 * @note There is a strong assumption for memory-mapped I/O, this is not
79 * necessarily true on all architectures.
80 * @note Verification failure results in entering the fault handler.
81 *
82 * @param[in] p pointer to the register
83 * @param[in] s mask of bits to be set
84 * @param[in] v verification flag, register is read back if @p true,
85 * this flag only has effect if @p HAL_USE_SAFETY is
86 * set to @p TRUE
87 *
88 * @xclass
89 */
90#define halRegSet16X(p, s, v) halRegModify16X(p, s, (uint16_t)0, v)
91
92/**
93 * @brief Sets bits into a 32 bits register.
94 * @note There is a strong assumption for memory-mapped I/O, this is not
95 * necessarily true on all architectures.
96 * @note Verification failure results in entering the fault handler.
97 *
98 * @param[in] p pointer to the register
99 * @param[in] s mask of bits to be set
100 * @param[in] v verification flag, register is read back if @p true,
101 * this flag only has effect if @p HAL_USE_SAFETY is
102 * set to @p TRUE
103 *
104 * @xclass
105 */
106#define halRegSet32X(p, s, v) halRegModify32X(p, s, (uint32_t)0, v)
107
108/**
109 * @brief Clears bits into an 8 bits register.
110 * @note There is a strong assumption for memory-mapped I/O, this is not
111 * necessarily true on all architectures.
112 * @note Verification failure results in entering the fault handler.
113 *
114 * @param[in] p pointer to the register
115 * @param[in] c mask of bits to be cleared
116 * @param[in] v verification flag, register is read back if @p true,
117 * this flag only has effect if @p HAL_USE_SAFETY is
118 * set to @p TRUE
119 *
120 * @xclass
121 */
122#define halRegClear8X(p, c, v) halRegModify8X(p, (uint8_t)0, c, v)
123
124/**
125 * @brief Clears bits into a 16 bits register.
126 * @note There is a strong assumption for memory-mapped I/O, this is not
127 * necessarily true on all architectures.
128 * @note Verification failure results in entering the fault handler.
129 *
130 * @param[in] p pointer to the register
131 * @param[in] c mask of bits to be cleared
132 * @param[in] v verification flag, register is read back if @p true,
133 * this flag only has effect if @p HAL_USE_SAFETY is
134 * set to @p TRUE
135 *
136 * @xclass
137 */
138#define halRegClear16X(p, c, v) halRegModify16X(p, (uint16_t)0, c, v)
139
140/**
141 * @brief Clears bits into a 32 bits register.
142 * @note There is a strong assumption for memory-mapped I/O, this is not
143 * necessarily true on all architectures.
144 * @note Verification failure results in entering the fault handler.
145 *
146 * @param[in] p pointer to the register
147 * @param[in] c mask of bits to be cleared
148 * @param[in] v verification flag, register is read back if @p true,
149 * this flag only has effect if @p HAL_USE_SAFETY is
150 * set to @p TRUE
151 *
152 * @xclass
153 */
154#define halRegClear32X(p, c, v) halRegModify32X(p, (uint32_t)0, c, v)
155/** @} */
156
157/*===========================================================================*/
158/* External declarations. */
159/*===========================================================================*/
160
161#ifdef __cplusplus
162extern "C" {
163#endif
164 void halSftFail(const char *message);
165 bool halRegWaitMatch8X(volatile uint8_t *p, uint8_t mask,
166 uint8_t match, uint32_t tmo, uint8_t *valp);
167 bool halRegWaitMatch16X(volatile uint16_t *p, uint16_t mask,
168 uint16_t match, uint32_t tmo, uint16_t *valp);
169 bool halRegWaitMatch32X(volatile uint32_t *p, uint32_t mask,
170 uint32_t match, uint32_t tmo, uint32_t *valp);
171 bool halRegWaitAllSet8X(volatile uint8_t *p, uint8_t mask,
172 uint32_t tmo, uint8_t *valp);
173 bool halRegWaitAllSet16X(volatile uint16_t *p, uint16_t mask,
174 uint32_t tmo, uint16_t *valp);
175 bool halRegWaitAllSet32X(volatile uint32_t *p, uint32_t mask,
176 uint32_t tmo, uint32_t *valp);
177 bool halRegWaitAnySet8X(volatile uint8_t *p, uint8_t mask,
178 uint32_t tmo, uint8_t *valp);
179 bool halRegWaitAnySet16X(volatile uint16_t *p, uint16_t mask,
180 uint32_t tmo, uint16_t *valp);
181 bool halRegWaitAnySet32X(volatile uint32_t *p, uint32_t mask,
182 uint32_t tmo, uint32_t *valp);
183 bool halRegWaitAllClear8X(volatile uint8_t *p, uint8_t mask,
184 uint32_t tmo, uint8_t *valp);
185 bool halRegWaitAllClear16X(volatile uint16_t *p, uint16_t mask,
186 uint32_t tmo, uint16_t *valp);
187 bool halRegWaitAllClear32X(volatile uint32_t *p, uint32_t mask,
188 uint32_t tmo, uint32_t *valp);
189 bool halRegWaitAnyClear8X(volatile uint8_t *p, uint8_t mask,
190 uint32_t tmo, uint8_t *valp);
191 bool halRegWaitAnyClear16X(volatile uint16_t *p, uint16_t mask,
192 uint32_t tmo, uint16_t *valp);
193 bool halRegWaitAnyClear32X(volatile uint32_t *p, uint32_t mask,
194 uint32_t tmo, uint32_t *valp);
195#ifdef __cplusplus
196}
197#endif
198
199/*===========================================================================*/
200/* Inline functions. */
201/*===========================================================================*/
202
203/**
204 * @brief Enters a common safety fault handler on error.
205 * @note IF a custom handler is not defined then the default action is to
206 * call @p osalSysHalt().
207 * @note This function can potentially not return.
208 *
209 * @param[in] result the error status, @p true if an error occurred
210 * @param[in] message an optional descriptive message
211 *
212 * @api
213 */
214static inline void halSftFailOnError(bool result, const char *message) {
215
216 if (result) {
217 halSftFail(message);
218 }
219}
220
221/**
222 * @brief Writes an 8 bits register.
223 * @note This code relies on compiler optimizations, the constant
224 * operations that cause no change to the final value are
225 * optimized out.
226 * @note There is a strong assumption for memory-mapped I/O, this is not
227 * necessarily true on all architectures.
228 * @note Verification failure results in entering the fault handler.
229 *
230 * @param[in] p pointer to the register
231 * @param[in] value value to be written
232 * @param[in] verify verification flag, register is read back if @p true,
233 * this flag only has effect if @p HAL_USE_SAFETY is
234 * set to @p TRUE
235 *
236 * @xclass
237 */
238static inline void halRegWrite8X(volatile uint8_t *p,
239 uint8_t value,
240 bool verify) {
241
242 *p = value;
243
244#if HAL_USE_SAFETY == FALSE
245 (void)verify;
246#else
247 if (verify) {
248 if (*p != value) {
249 halSftFail("w8");
250 }
251 }
252#endif
253}
254
255/**
256 * @brief Writes a 16 bits register.
257 * @note This code relies on compiler optimizations, the constant
258 * operations that cause no change to the final value are
259 * optimized out.
260 * @note There is a strong assumption for memory-mapped I/O, this is not
261 * necessarily true on all architectures.
262 * @note Verification failure results in entering the fault handler.
263 *
264 * @param[in] p pointer to the register
265 * @param[in] value value to be written
266 * @param[in] verify verification flag, register is read back if @p true,
267 * this flag only has effect if @p HAL_USE_SAFETY is
268 * set to @p TRUE
269 *
270 * @xclass
271 */
272static inline void halRegWrite16X(volatile uint16_t *p,
273 uint16_t value,
274 bool verify) {
275
276 *p = value;
277
278#if HAL_USE_SAFETY == FALSE
279 (void)verify;
280#else
281 if (verify) {
282 if (*p != value) {
283 halSftFail("w16");
284 }
285 }
286#endif
287}
288
289/**
290 * @brief Writes a 32 bits register.
291 * @note This code relies on compiler optimizations, the constant
292 * operations that cause no change to the final value are
293 * optimized out.
294 * @note There is a strong assumption for memory-mapped I/O, this is not
295 * necessarily true on all architectures.
296 * @note Verification failure results in entering the fault handler.
297 *
298 * @param[in] p pointer to the register
299 * @param[in] value value to be written
300 * @param[in] verify verification flag, register is read back if @p true,
301 * this flag only has effect if @p HAL_USE_SAFETY is
302 * set to @p TRUE
303 *
304 * @xclass
305 */
306static inline void halRegWrite32X(volatile uint32_t *p,
307 uint32_t value,
308 bool verify) {
309
310 *p = value;
311
312#if HAL_USE_SAFETY == FALSE
313 (void)verify;
314#else
315 if (verify) {
316 if (*p != value) {
317 halSftFail("w32");
318 }
319 }
320#endif
321}
322
323/**
324 * @brief Modifies a 8 bits register.
325 * @note This code relies on compiler optimizations, the constant
326 * operations that cause no change to the final value are
327 * optimized out.
328 * @note There is a strong assumption for memory-mapped I/O, this is not
329 * necessarily true on all architectures.
330 * @note Verification failure results in entering the fault handler.
331 *
332 * @param[in] p pointer to the register
333 * @param[in] setmask mask of bits to be set
334 * @param[in] clrmask mask of bits to be cleared
335 * @param[in] verify verification flag, register is read back if @p true,
336 * this flag only has effect if @p HAL_USE_SAFETY is
337 * set to @p TRUE
338 *
339 * @xclass
340 */
341static inline void halRegModify8X(volatile uint8_t *p,
342 uint8_t setmask,
343 uint8_t clrmask,
344 bool verify) {
345 uint8_t v = *p;
346 v |= setmask;
347 v &= ~clrmask;
348 *p = v;
349
350#if HAL_USE_SAFETY == FALSE
351 (void)verify;
352#else
353 if (verify) {
354 uint8_t check = *p;
355
356 if (((check & setmask) != setmask) || ((check & clrmask) != (uint8_t)0)) {
357 halSftFail("m8");
358 }
359 }
360#endif
361}
362
363/**
364 * @brief Modifies a 16 bits register.
365 * @note This code relies on compiler optimizations, the constant
366 * operations that cause no change to the final value are
367 * optimized out.
368 * @note There is a strong assumption for memory-mapped I/O, this is not
369 * necessarily true on all architectures.
370 * @note Verification failure results in entering the fault handler.
371 *
372 * @param[in] p pointer to the register
373 * @param[in] setmask mask of bits to be set
374 * @param[in] clrmask mask of bits to be cleared
375 * @param[in] verify verification flag, register is read back if @p true,
376 * this flag only has effect if @p HAL_USE_SAFETY is
377 * set to @p TRUE
378 *
379 * @xclass
380 */
381static inline void halRegModify16X(volatile uint16_t *p,
382 uint16_t setmask,
383 uint16_t clrmask,
384 bool verify) {
385 uint16_t v = *p;
386 v |= setmask;
387 v &= ~clrmask;
388 *p = v;
389
390#if HAL_USE_SAFETY == FALSE
391 (void)verify;
392#else
393 if (verify) {
394 uint16_t check = *p;
395
396 if (((check & setmask) != setmask) || ((check & clrmask) != (uint16_t)0)) {
397 halSftFail("m16");
398 }
399 }
400#endif
401}
402
403/**
404 * @brief Modifies a 32 bits register.
405 * @note This code relies on compiler optimizations, the constant
406 * operations that cause no change to the final value are
407 * optimized out.
408 * @note There is a strong assumption for memory-mapped I/O, this is not
409 * necessarily true on all architectures.
410 * @note Verification failure results in entering the fault handler.
411 *
412 * @param[in] p pointer to the register
413 * @param[in] setmask mask of bits to be set
414 * @param[in] clrmask mask of bits to be cleared
415 * @param[in] verify verification flag, register is read back if @p true,
416 * this flag only has effect if @p HAL_USE_SAFETY is
417 * set to @p TRUE
418 *
419 * @xclass
420 */
421static inline void halRegModify32X(volatile uint32_t *p,
422 uint32_t setmask,
423 uint32_t clrmask,
424 bool verify) {
425 uint32_t v = *p;
426 v |= setmask;
427 v &= ~clrmask;
428 *p = v;
429
430#if HAL_USE_SAFETY == FALSE
431 (void)verify;
432#else
433 if (verify) {
434 uint32_t check = *p;
435
436 if (((check & setmask) != setmask) || ((check & clrmask) != (uint32_t)0)) {
437 halSftFail("m32");
438 }
439 }
440#endif
441}
442
443/**
444 * @brief Writes a field into an 8 bits register.
445 * @note This code relies on compiler optimizations, the constant
446 * operations that cause no change to the final value are
447 * optimized out.
448 * @note There is a strong assumption for memory-mapped I/O, this is not
449 * necessarily true on all architectures.
450 * @note Verification failure results in entering the fault handler.
451 *
452 * @param[in] p pointer to the register
453 * @param[in] mask mask of bits field to be written
454 * @param[in] value value to be written, must be pre-shifted to match the
455 * mask
456 * @param[in] verify verification flag, register is read back if @p true,
457 * this flag only has effect if @p HAL_USE_SAFETY is
458 * set to @p TRUE
459 *
460 * @xclass
461 */
462static inline void halRegMaskedWrite8X(volatile uint8_t *p,
463 uint8_t mask,
464 uint8_t value,
465 bool verify) {
466 uint8_t v;
467
468 osalDbgCheck((value & ~mask) == 0U);
469
470 v = *p;
471 v &= ~mask;
472 v |= value;
473 *p = v;
474
475#if HAL_USE_SAFETY == FALSE
476 (void)verify;
477#else
478 if (verify) {
479 uint8_t check = *p;
480
481 if ((check & mask) != value) {
482 halSftFail("mw8");
483 }
484 }
485#endif
486}
487
488/**
489 * @brief Writes a field into a 16 bits register.
490 * @note This code relies on compiler optimizations, the constant
491 * operations that cause no change to the final value are
492 * optimized out.
493 * @note There is a strong assumption for memory-mapped I/O, this is not
494 * necessarily true on all architectures.
495 * @note Verification failure results in entering the fault handler.
496 *
497 * @param[in] p pointer to the register
498 * @param[in] mask mask of bits field to be written
499 * @param[in] value value to be written, must be pre-shifted to match the
500 * mask
501 * @param[in] verify verification flag, register is read back if @p true,
502 * this flag only has effect if @p HAL_USE_SAFETY is
503 * set to @p TRUE
504 *
505 * @xclass
506 */
507static inline void halRegMaskedWrite16X(volatile uint16_t *p,
508 uint16_t mask,
509 uint16_t value,
510 bool verify) {
511 uint16_t v;
512
513 osalDbgCheck((value & ~mask) == 0U);
514
515 v= *p;
516 v &= ~mask;
517 v |= value;
518 *p = v;
519
520#if HAL_USE_SAFETY == FALSE
521 (void)verify;
522#else
523 if (verify) {
524 uint16_t check = *p;
525
526 if ((check & mask) != value) {
527 halSftFail("mw16");
528 }
529 }
530#endif
531}
532
533/**
534 * @brief Writes a field into a 32 bits register.
535 * @note This code relies on compiler optimizations, the constant
536 * operations that cause no change to the final value are
537 * optimized out.
538 * @note There is a strong assumption for memory-mapped I/O, this is not
539 * necessarily true on all architectures.
540 * @note Verification failure results in entering the fault handler.
541 *
542 * @param[in] p pointer to the register
543 * @param[in] mask mask of bits field to be written
544 * @param[in] value value to be written, must be pre-shifted to match the
545 * mask
546 * @param[in] verify verification flag, register is read back if @p true,
547 * this flag only has effect if @p HAL_USE_SAFETY is
548 * set to @p TRUE
549 *
550 * @xclass
551 */
552static inline void halRegMaskedWrite32X(volatile uint32_t *p,
553 uint32_t mask,
554 uint32_t value,
555 bool verify) {
556 uint32_t v;
557
558 osalDbgCheck((value & ~mask) == 0U);
559
560 v = *p;
561 v &= ~mask;
562 v |= value;
563 *p = v;
564
565#if HAL_USE_SAFETY == FALSE
566 (void)verify;
567#else
568 if (verify) {
569 uint32_t check = *p;
570
571 if ((check & mask) != value) {
572 halSftFail("mw32");
573 }
574 }
575#endif
576}
577
578#endif /* HAL_SAFETY_H */
579
580/** @} */
bool halRegWaitAnyClear32X(volatile uint32_t *p, uint32_t mask, uint32_t tmo, uint32_t *valp)
Waits for any of specified bits to be cleared or a timeout.
Definition hal_safety.c:706
bool halRegWaitAnyClear8X(volatile uint8_t *p, uint8_t mask, uint32_t tmo, uint8_t *valp)
Waits for any of specified bits to be cleared or a timeout.
Definition hal_safety.c:622
bool halRegWaitMatch8X(volatile uint8_t *p, uint8_t mask, uint8_t match, uint32_t tmo, uint8_t *valp)
Waits for masked bits to match or a timeout.
Definition hal_safety.c:116
bool halRegWaitMatch32X(volatile uint32_t *p, uint32_t mask, uint32_t match, uint32_t tmo, uint32_t *valp)
Waits for masked bits to match or a timeout.
Definition hal_safety.c:202
bool halRegWaitAllClear32X(volatile uint32_t *p, uint32_t mask, uint32_t tmo, uint32_t *valp)
Waits for all specified bits to be cleared or a timeout.
Definition hal_safety.c:580
bool halRegWaitAnyClear16X(volatile uint16_t *p, uint16_t mask, uint32_t tmo, uint16_t *valp)
Waits for any of specified bits to be cleared or a timeout.
Definition hal_safety.c:664
static void halRegWrite32X(volatile uint32_t *p, uint32_t value, bool verify)
Writes a 32 bits register.
Definition hal_safety.h:306
bool halRegWaitAllSet32X(volatile uint32_t *p, uint32_t mask, uint32_t tmo, uint32_t *valp)
Waits for all specified bits to be set or a timeout.
Definition hal_safety.c:328
static void halRegModify32X(volatile uint32_t *p, uint32_t setmask, uint32_t clrmask, bool verify)
Modifies a 32 bits register.
Definition hal_safety.h:421
bool halRegWaitAllClear8X(volatile uint8_t *p, uint8_t mask, uint32_t tmo, uint8_t *valp)
Waits for all specified bits to be cleared or a timeout.
Definition hal_safety.c:496
static void halRegMaskedWrite32X(volatile uint32_t *p, uint32_t mask, uint32_t value, bool verify)
Writes a field into a 32 bits register.
Definition hal_safety.h:552
bool halRegWaitAllSet16X(volatile uint16_t *p, uint16_t mask, uint32_t tmo, uint16_t *valp)
Waits for all specified bits to be set or a timeout.
Definition hal_safety.c:286
bool halRegWaitAnySet16X(volatile uint16_t *p, uint16_t mask, uint32_t tmo, uint16_t *valp)
Waits for any of specified bits to be set or a timeout.
Definition hal_safety.c:412
bool halRegWaitAllClear16X(volatile uint16_t *p, uint16_t mask, uint32_t tmo, uint16_t *valp)
Waits for all specified bits to be cleared or a timeout.
Definition hal_safety.c:538
static void halSftFailOnError(bool result, const char *message)
Enters a common safety fault handler on error.
Definition hal_safety.h:214
bool halRegWaitMatch16X(volatile uint16_t *p, uint16_t mask, uint16_t match, uint32_t tmo, uint16_t *valp)
Waits for masked bits to match or a timeout.
Definition hal_safety.c:159
static void halRegMaskedWrite8X(volatile uint8_t *p, uint8_t mask, uint8_t value, bool verify)
Writes a field into an 8 bits register.
Definition hal_safety.h:462
static void halRegModify16X(volatile uint16_t *p, uint16_t setmask, uint16_t clrmask, bool verify)
Modifies a 16 bits register.
Definition hal_safety.h:381
bool halRegWaitAnySet32X(volatile uint32_t *p, uint32_t mask, uint32_t tmo, uint32_t *valp)
Waits for any of specified bits to be set or a timeout.
Definition hal_safety.c:454
static void halRegModify8X(volatile uint8_t *p, uint8_t setmask, uint8_t clrmask, bool verify)
Modifies a 8 bits register.
Definition hal_safety.h:341
bool halRegWaitAnySet8X(volatile uint8_t *p, uint8_t mask, uint32_t tmo, uint8_t *valp)
Waits for any of specified bits to be set or a timeout.
Definition hal_safety.c:370
CC_NO_RETURN void halSftFail(const char *message)
Common safety fault handler.
Definition hal_safety.c:89
static void halRegWrite16X(volatile uint16_t *p, uint16_t value, bool verify)
Writes a 16 bits register.
Definition hal_safety.h:272
static void halRegWrite8X(volatile uint8_t *p, uint8_t value, bool verify)
Writes an 8 bits register.
Definition hal_safety.h:238
bool halRegWaitAllSet8X(volatile uint8_t *p, uint8_t mask, uint32_t tmo, uint8_t *valp)
Waits for all specified bits to be set or a timeout.
Definition hal_safety.c:244
static void halRegMaskedWrite16X(volatile uint16_t *p, uint16_t mask, uint16_t value, bool verify)
Writes a field into a 16 bits register.
Definition hal_safety.h:507
#define osalDbgCheck(c)
Function parameters check.
Definition osal.h:284