Skip to content

Commit 7444a6c

Browse files
swoiszclaude
andcommitted
refactor: split toolchain.h and sys/__assert.h out of util.h
util.h was accreting symbols whose upstream homes are <zephyr/toolchain.h> (likely/unlikely, __weak, ALWAYS_INLINE, __noinit) and <zephyr/sys/__assert.h> (__ASSERT, __ASSERT_NO_MSG), while the repo otherwise mirrors upstream include paths exactly -- the devlog TODO already records a downstream smf port hand-editing upstream #includes because of this. Thin headers at the upstream paths fix that now, while they have 1-2 consumers; util.h re-includes both so existing ports keep working. Also two correctness fixes folded in: - __noinit now maps to __NOINIT_ATTR (real .noinit on hardware, no-op on the linux target via esp_attr.h's CONFIG_IDF_TARGET_LINUX gate in both IDF v5.4 and v5.5). The old empty shim silently gave zero-init BSS semantics to any future warm-reset-retention user, and its stated Mach-O blocker was false -- the macOS host build of the linux target compiles clean. - likely/unlikely now document the divergence from esp_compiler.h (ESP-IDF's are CONFIG_COMPILER_OPTIMIZATION_PERF-gated; Boreas matches upstream Zephyr's unconditional __builtin_expect; both are #ifndef-guarded so the include-order race is codegen-only). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 74af6dc commit 7444a6c

3 files changed

Lines changed: 89 additions & 56 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright 2026 Intercreate
4+
*
5+
* Zephyr-compatible runtime assertions (upstream <zephyr/sys/__assert.h>
6+
* spellings).
7+
*
8+
* Divergence: upstream compiles these out unless CONFIG_ASSERT=y
9+
* (default n); Boreas keeps them always on -- they log and abort.
10+
* NOT safe from IRAM ISR context (ESP_LOGE + abort are flash-resident).
11+
* Use k_panic() (sys/util.h) for unrecoverable errors in ISR/IRAM
12+
* context.
13+
*/
14+
15+
#pragma once
16+
17+
#ifndef __ASSERT
18+
#include <stdlib.h> /* abort() */
19+
20+
#include "esp_log.h"
21+
#define __ASSERT(cond, msg) \
22+
do { \
23+
if (!(cond)) { \
24+
ESP_LOGE("ASSERT", "%s at %s:%d", (msg), __FILE__, __LINE__); \
25+
abort(); \
26+
} \
27+
} while (0)
28+
#endif
29+
30+
/* Assertion with no message (upstream spelling). */
31+
#ifndef __ASSERT_NO_MSG
32+
#define __ASSERT_NO_MSG(cond) __ASSERT((cond), "")
33+
#endif

components/zkernel/include/boreas/zephyr/sys/util.h

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313

1414
#include "esp_attr.h"
1515

16+
/* Compatibility re-exports: upstream code reaches these symbols through
17+
* <zephyr/toolchain.h> and <zephyr/sys/__assert.h>, but historical
18+
* Boreas ports include only this header -- keep both paths working. */
19+
#include "zephyr/sys/__assert.h"
20+
#include "zephyr/toolchain.h"
21+
1622
#ifdef __cplusplus
1723
extern "C" {
1824
#endif
@@ -97,62 +103,6 @@ extern "C" {
97103
#define ALIGNED(x) __attribute__((__aligned__(x)))
98104
#endif
99105

100-
/* Weak symbol */
101-
#ifndef __weak
102-
#define __weak __attribute__((__weak__))
103-
#endif
104-
105-
/* Always inline — undef any prior definition to guarantee `inline` is present
106-
* (RISC-V GCC errors without it under -Werror=attributes). */
107-
#undef ALWAYS_INLINE
108-
#define ALWAYS_INLINE __attribute__((always_inline)) inline
109-
110-
/* Runtime assertion -- logs and aborts.
111-
* NOT safe from IRAM ISR context (ESP_LOGE + abort are flash-resident).
112-
* Use k_panic() for unrecoverable errors in ISR/IRAM context. */
113-
#ifndef __ASSERT
114-
#include <stdlib.h> /* abort() */
115-
116-
#include "esp_log.h"
117-
#define __ASSERT(cond, msg) \
118-
do { \
119-
if (!(cond)) { \
120-
ESP_LOGE("ASSERT", "%s at %s:%d", (msg), __FILE__, __LINE__); \
121-
abort(); \
122-
} \
123-
} while (0)
124-
#endif
125-
126-
/* Assertion with no message (upstream spelling). */
127-
#ifndef __ASSERT_NO_MSG
128-
#define __ASSERT_NO_MSG(cond) __ASSERT((cond), "")
129-
#endif
130-
131-
/* Branch-prediction hints (upstream toolchain.h). */
132-
#ifndef likely
133-
#define likely(x) __builtin_expect(!!(x), 1)
134-
#endif
135-
#ifndef unlikely
136-
#define unlikely(x) __builtin_expect(!!(x), 0)
137-
#endif
138-
139-
/* Upstream places __noinit data in a section the loader does not zero,
140-
* to save startup cost. Boreas maps it to ordinary zero-initialized BSS
141-
* rather than ESP-IDF's __NOINIT_ATTR (which is a `.noinit` section
142-
* attribute): for the only user, ring_buf, a RING_BUF_DECLARE'd buffer
143-
* has its indices zero-initialized by the struct's static initializer
144-
* and never reads buffer bytes it has not written, so no-init vs
145-
* zero-init is behaviorally invisible. Plain BSS also keeps the shim
146-
* free of a section attribute (which does not port cleanly to the
147-
* Mach-O host toolchain used for the linux test target).
148-
*
149-
* Known limitation: genuine no-init semantics are NOT provided -- code
150-
* that needs data left uninitialized (or retained across a warm reset)
151-
* must use ESP-IDF's __NOINIT_ATTR / RTC_NOINIT_ATTR directly. */
152-
#ifndef __noinit
153-
#define __noinit
154-
#endif
155-
156106
/* IRAM-safe panic -- triggers an illegal-instruction exception caught by
157107
* the ESP-IDF panic handler (which is IRAM-resident). Produces a full
158108
* backtrace on UART and reboots. Safe to call from IRAM_ATTR ISR context.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright 2026 Intercreate
4+
*
5+
* Zephyr-compatible toolchain shims (upstream <zephyr/toolchain.h>
6+
* spellings), kept thin so near-verbatim ports can keep their upstream
7+
* #include shape. All definitions are #ifndef-guarded: a TU that
8+
* already got a definition elsewhere keeps the first one it saw.
9+
*/
10+
11+
#pragma once
12+
13+
#include "esp_attr.h"
14+
15+
/* Branch-prediction hints.
16+
* Divergence from ESP-IDF: esp_compiler.h defines likely/unlikely as
17+
* plain (x) unless CONFIG_COMPILER_OPTIMIZATION_PERF is set; Boreas
18+
* matches upstream Zephyr's unconditional __builtin_expect instead.
19+
* Both definitions are #ifndef-guarded, so include order picks the
20+
* winner per TU -- the difference is codegen-only (identical
21+
* semantics either way). */
22+
#ifndef likely
23+
#define likely(x) __builtin_expect(!!(x), 1)
24+
#endif
25+
#ifndef unlikely
26+
#define unlikely(x) __builtin_expect(!!(x), 0)
27+
#endif
28+
29+
/* Weak symbol */
30+
#ifndef __weak
31+
#define __weak __attribute__((__weak__))
32+
#endif
33+
34+
/* Always inline -- undef any prior definition to guarantee `inline` is
35+
* present (RISC-V GCC errors without it under -Werror=attributes). */
36+
#undef ALWAYS_INLINE
37+
#define ALWAYS_INLINE __attribute__((always_inline)) inline
38+
39+
/* Upstream places __noinit data in a section the loader does not zero
40+
* (so it also survives a warm reset). Mapped to ESP-IDF's
41+
* __NOINIT_ATTR: a genuine .noinit section on hardware targets, and a
42+
* no-op on the linux/host test target (esp_attr.h's _SECTION_ATTR_IMPL
43+
* expands to nothing under CONFIG_IDF_TARGET_LINUX), where __noinit
44+
* data is ordinary zero-initialized BSS instead. Code that must retain
45+
* data across a warm reset therefore cannot rely on this shim on the
46+
* host target; on hardware, prefer RTC_NOINIT_ATTR when the data must
47+
* also survive deep sleep. */
48+
#ifndef __noinit
49+
#define __noinit __NOINIT_ATTR
50+
#endif

0 commit comments

Comments
 (0)