# Changelog / 变更记录
> 记录中间件 shelf 用户可见的变化。更细的设计动机见 [docs/design_decisions.md](docs/cn/design_decisions.md)。
> User-visible changes to the middleware shelf. Deeper design rationale: [docs/design_decisions.md](docs/cn/design_decisions.md).
---
## [Unreleased] / 未发布
### 三个子体系的私有错误码落片 / Private error codes for mini-os / log / ota
- **mini-ota → ota 片(`-128..-159`)**:`bootutil/inc/err.h` 的 `ERR_*` 原先占 `-1..-15`,与 `MINI_ERR_*` 通用段(`-1..-27`)**同值异义**(`-2` 既是 `ERR_TOO_SMALL` 又是 `MINI_ERR_ISR`),现整体迁入 ota 片;`ERR_UNSUPPORTED` 收敛为 `ERR_NOT_SUPPORTED` 的同义别名,零使用的 `ERR_INVAL` 删除;`err_str()` 补齐原先缺失的 `ERR_OTA_OPEN` / `ERR_TRANSMIT` 两个 case;`arch/arm/cortex-m/cortex_m.S` 里硬编码的 `-4` 同步为 `-131`。
- **mini-log → log 片(`-160..-191`)**:`inc/log_err.h` 的 7 个码由 `-1..-7` 迁入。
- **mini-os → 新增第 6 片(`-256..-287`)**:`inc/err.h` 新增 8 个内核私有码 `DEAD` / `NOTREADY` / `RANGE` / `DESTROYED` / `OVERFLOW` / `CORRUPT` / `PERM` / `NOT_STARTED`,承接现有 13 个通用别名表达不了的内核语义(任务已终止、调度器未启动、优先级越界、对象已销毁、递归溢出、堆块损坏、非所有者解锁、定时器未启动)。内核 `.c` 的现有返回点未动。
- **vendor 一律自包含**:三个头文件都**不 include `status.h`**,数值直接写死、注释标明对应片;`core/src/status.c` 加两条 `_Static_assert` 把 mini-log 的数值钉在 log 片基准上,任一侧漂移即编译失败。
- **顺带修掉头保护宏撞车**:`lib/mini-ota/bootutil/inc/err.h` 与 `lib/mini-os/inc/err.h` 都用 `ERR_H`,同一 TU 内先被包含者会把后者整份屏蔽;mini-ota 侧改为 `MINI_OTA_ERR_H`。
**Private error codes for mini-os / log / ota**: mini-ota's `ERR_*` (`bootutil/inc/err.h`) used to occupy `-1..-15`, **same values but different meanings** as the `MINI_ERR_*` common sector (`-1..-27`) — `-2` was both `ERR_TOO_SMALL` and `MINI_ERR_ISR`; they now live on the ota slot (`-128..-159`), with `ERR_UNSUPPORTED` folded into `ERR_NOT_SUPPORTED` as an alias, the unused `ERR_INVAL` dropped, the two missing `err_str()` cases (`ERR_OTA_OPEN`, `ERR_TRANSMIT`) added, and the hard-coded `-4` in `arch/arm/cortex-m/cortex_m.S` updated to `-131`. mini-log's seven codes (`inc/log_err.h`) moved from `-1..-7` onto the log slot (`-160..-191`). mini-os gained a new slot 6 (`-256..-287`) with eight kernel-private codes — `DEAD` / `NOTREADY` / `RANGE` / `DESTROYED` / `OVERFLOW` / `CORRUPT` / `PERM` / `NOT_STARTED` — covering meanings the 13 shared aliases cannot express (thread terminated, scheduler not started, priority out of range, object destroyed, recursion overflow, heap corrupt, not the owner, timer not started); existing return sites in the kernel `.c` files were left untouched. All three headers stay **self-contained vendors**: they do **not** include `status.h`, they hard-code the values and name the slot in comments, and `core/src/status.c` now pins mini-log's values to the log-slot base with two `_Static_assert`s so any drift fails the build. Also fixed: `lib/mini-ota/bootutil/inc/err.h` and `lib/mini-os/inc/err.h` both used the `ERR_H` include guard, so whichever came first silently blanked the other — the mini-ota header is now `MINI_OTA_ERR_H`.
### 错误码改为「通用段 + 子体系配额」/ Error codes: common sector plus per-subsystem quota
- **通用段 `-1..-63` 不变**,其后改为**每片固定 32 码**的子体系配额:新增 `MINI_ERR_SUBSYS_SLOT_SIZE 32` / `MINI_ERR_SUBSYS_SLOT_COUNT 14`(幅度 64..511)与 `MINI_ERR_SUBSYS_SLOT_BASE(slot)` / `MINI_ERR_SUBSYS_SLOT_LAST(slot)`;已分配片为 0 net / 1 fs / 2 ota / 3 log / 4 system / 5 driver,6..13 预留。`MINI_ERR_SUBSYS(base, idx)` 的 `idx` 由 0..15 放宽到 **0..31**(越片即侵占下一片)。旧名 `MINI_ERR_SUBSYS_NET_BASE` 等保留,数值随配额上移。
- **`MINI_ERR_MAX` 255 → 511**:即 `0` 成功 + 511 个错误码 = 512 个码位。`ERR_PTR` 仍是 `ERR_SECTION_BASE + 幅度`,511 个码位(`0xFFFFF000 + 0x1FF`)仍落在 `error_symbols.ld` 保留的那段地址内,**链接脚本无需改动**。
- **新增两条 `_Static_assert` 锁布局**(子体系段必须恰好容纳整数个 32 码片、驱动片基准须按片大小对齐)。它们当场抓出了一个算错:幅度取 `512` 时子体系段 `[64..512]` 是 **449** 个码位,并非 32 的整数倍,故上限定为 `511`(`[64..511]` = 448 = 14 × 32)。
- **驱动/板级不再独占一段**:原 `-128..-255` 段取消,驱动改为子体系段第 5 片(`-224..-255`);`MINI_ERR_SECTOR_DRIVER` / `MINI_ERR_IS_DRIVER()` 保留且语义延续(判该片),与 `MINI_ERR_IS_SUBSYS()` 仍互斥。新增 `MINI_ERR_SUBSYS_SLOT_OF()` 取片号(非子体系段返回 `MINI_ERR_SUBSYS_SLOT_COUNT`)。
- **影响面为零**:`core/src/status.c` 只 switch 通用码、`lib/mini-os/inc/err.h` 只别名 `-1..-13`,两者都无段边界依赖,均未修改;全仓亦无 `MINI_ERR_SUBSYS_*_BASE` / `MINI_ERR_IS_DRIVER` 的调用点。
**Error codes: common sector plus per-subsystem quota**: the common range `-1..-63` is unchanged; everything after it is now a fixed **32-code slot per subsystem** — new `MINI_ERR_SUBSYS_SLOT_SIZE 32` / `MINI_ERR_SUBSYS_SLOT_COUNT 14` (magnitudes 64..511) plus `MINI_ERR_SUBSYS_SLOT_BASE(slot)` / `MINI_ERR_SUBSYS_SLOT_LAST(slot)`, with slot 0 net, 1 fs, 2 ota, 3 log, 4 system, 5 driver and 6..13 reserved. `MINI_ERR_SUBSYS(base, idx)` now takes `idx` 0..**31** (a larger index spills into the next slot). The old `MINI_ERR_SUBSYS_NET_BASE`-style names are kept with shifted values. `MINI_ERR_MAX` went **255 → 512**: `ERR_PTR` still encodes `ERR_SECTION_BASE + magnitude`, and 512 codes (`0xFFFFF000 + 0x200`) still fit the address range reserved by `error_symbols.ld`, so **the linker script needs no change**. Driver/board no longer owns a dedicated range — it is slot 5 (`-224..-255`) of the subsystem sector; `MINI_ERR_SECTOR_DRIVER` / `MINI_ERR_IS_DRIVER()` keep working (they detect that slot) and remain mutually exclusive with `MINI_ERR_IS_SUBSYS()`. New `MINI_ERR_SUBSYS_SLOT_OF()` returns the slot number (`MINI_ERR_SUBSYS_SLOT_COUNT` when the code is outside the sector). Nothing else had to move: `core/src/status.c` only switches on common codes and `lib/mini-os/inc/err.h` only aliases `-1..-13`, and no call site in the tree uses `MINI_ERR_SUBSYS_*_BASE` or `MINI_ERR_IS_DRIVER`.
### 启用 USB 必须显式配置目标芯片 / Enabling USB requires an explicit MCU target
- **`USB_TUSB_MCU` 默认 `901` → `0`(`OPT_MCU_NONE`)**:启用 `CONFIG_USB` 时必须显式填目标芯片的 `OPT_MCU_*` 值(`304` STM32F4 / `306` STM32H7 / `901` ESP32-S3 / `1100` RP2040,完整表见 `lib/tinyusb/src/tusb_option.h` 与 Kconfig help),否则 `board/include/tusb_config.h:32` 直接 `#error` 中止编译;不用 USB 请关闭 `CONFIG_USB`。已用 `304` 验证:填对值即可正常编过。
- **起因是原默认值配错芯片**:`901` 是 ESP32-S3,而当前平台为 ARM_CM4F(STM32F4)。配错时 TinyUSB 走 ESP32 分支 —— `CFG_TUSB_OS_INC_PATH_DEFAULT` 被设成 `freertos/`(IDF 的头文件布局),而仓内 `lib/freeRTOS` 的头平铺在 `include/` 下,于是 RTOS 端口(`osal_freertos.h`)报 `freertos/FreeRTOS.h: No such file`;更隐蔽的是该分支下 CMake 不加入 DCD 源,USB 只有协议栈核心却能"构建通过",属静默错配。此前(`USB_TUSB_OS_*` 恒为 NONE)这条路径从未被触发,给各后端补上 `select USB_TUSB_OS_*` 后才暴露。`.config` 里残留的 `901` 已一并清零。
- **补上设备控制器驱动 (DCD) 的接线**:TinyUSB 核心源**不含** DCD/HCD(官方 `src/CMakeLists.txt` 顶部注释 "DCD and HCD drivers are not included"),而本仓此前只内联了核心源列表,于是 `dcd_dwc2.c` 在任何 MCU 值下都从未编入 —— 只编出协议栈核心,链接 ELF 时才缺 `dcd_init` / `dcd_edpt_open`。现新增 `CONFIG_USB_TUSB_DCD_SRC`(相对 `lib/tinyusb/src` 的驱动源路径),`cmake/tinyusb.cmake` 按它追加并校验:路径不存在 `FATAL_ERROR`,留空则配置期 `WARNING`。已用 `portable/synopsys/dwc2/dcd_dwc2.c` 验证接线生效(源确实进入编译),随后停在 `dwc2_stm32.h:50` 的 `stm32f4xx.h` —— 芯片头属板级 BSP / CMSIS,本仓不含,需板级提供。
**Enabling USB requires an explicit MCU target**: `USB_TUSB_MCU` now defaults to `0` (`OPT_MCU_NONE`) instead of `901`. With `CONFIG_USB` enabled you must set it to the target's `OPT_MCU_*` value (`304` STM32F4 / `306` STM32H7 / `901` ESP32-S3 / `1100` RP2040; see `lib/tinyusb/src/tusb_option.h` and the Kconfig help), otherwise `board/include/tusb_config.h:32` aborts the build with `#error`; disable `CONFIG_USB` if you do not need USB. Verified with `304`: a correct value builds cleanly. Reason: `901` is ESP32-S3 while the platform here is ARM_CM4F (STM32F4). With the wrong MCU, TinyUSB took the ESP32 branch — `CFG_TUSB_OS_INC_PATH_DEFAULT` became `freertos/` (the IDF header layout), but the bundled `lib/freeRTOS` keeps its headers flat under `include/`, so the RTOS port failed on `freertos/FreeRTOS.h`; worse, that branch adds no DCD sources, so USB compiled "fine" with the stack core only — a silent misconfiguration. It never showed up before because `USB_TUSB_OS_*` was always NONE; adding the per-backend `select USB_TUSB_OS_*` brought it out. The stale `901` in `.config` was cleared as well.
### Flash 位翻转检测收敛到 mini-ota 的纯数据校验 / Bit-rot detection folded into mini-ota's pure data check
- **mini-ota 新增纯数据校验**:`bootutil/inc/verify.h` 的 `image_verify_raw(read_fn, ctx, len, expected_crc)` 与便利版 `image_verify_area(area_id, off, len, expected_crc)` —— **不解析镜像头 / 尾部 meta**,不用密钥,不区分打包模式,只回答"这段数据/这段 flash 是否仍是当初写入的那一段"。内部走 `crc_stream_*` 增量 CRC,模型取 `boot_config.h` 的 `CRC_MODEL_*`(默认标准 CRC-32),无动态内存、无静态状态,bootloader 与 app 均可调用。
- **`system_scrubber` 改用它,第三份 CRC 消失**:删掉 `system_scrubber.c` 自带的 256 项 CRC 表(`crc32_update`),改为 `image_verify_area(FLASH_AREA_ID_IMAGE_0 + ota_current_partition_get(), 0, len, baseline)`,校验原语与模型统一到 mini-ota。巡检任务、`CONFIG_SYSTEM_SCRUBBER` 开关、失配即 `enter_safe_state()` 的行为均保留。
- **修掉基线口径错配(既有 bug)**:`post_build_crc.py` 的基线是 `firmware.bin` 的 CRC(**二进制长度**),而旧 scrubber 扫的是 `hal_flash_get_app_size()`(**整个分区**)—— 长度口径不一致时基线永远对不上。现工具**同时输出长度宏** `SYSTEM_SCRUBBER_IMAGE_LEN`(新增 `--len-define`,就地刷新 / 不存在则追加),scrubber 用"CRC + 长度"同源的基线比对;两项任一未配置则巡检自行退出而不空转。
- **编入门控修正**:`system_scrubber.c` 此前被**无条件**编入 3 处构建清单(根 `CMakeLists.txt`、`cmake/esp_idf.cmake`、`system_cpp/CMakeLists.txt`),即使 `CONFIG_SYSTEM_SCRUBBER=n` 也编(死代码)。现改为按 `CONFIG_SYSTEM_SCRUBBER` 门控;Kconfig 该选项新增 `depends on MINI_OTA`(校验原语来自 mini-ota,ESP/Xtensa 下 `CONFIG_MINI_OTA` 恒关故不会编入)。
- **删掉空函数 `system_scrubber_init()`**(实现恒 `return MINI_OK`,调用点还 `MINI_IGNORE_RESULT` 忽略);`system_scrubber_is_running()` 保留为对外查询口。
- **删除 flash HAL(已无调用者)**:`hal/storage/hal_flash.{c,h}` 整体删除 —— 其"只读巡检 + 应用区地址/大小查询"职责已由 mini-ota 的 `flash_area` 区域表(`fa_offset` / `fa_size` + `ota_current_partition_get()`)承担,上层 flash 访问也一律走 SPI / I2C,故 `hal_flash_read` / `hal_flash_get_app_addr` / `hal_flash_get_app_size` 三条 weak 桩一并消失。同步去掉 `CMakeLists.txt` 与 `cmake/esp_idf.cmake` HAL 清单中的引用 2 处;`hal/storage/hal_storage.{c,h}`(双槽 A/B 持久化)不受影响。
**Bit-rot detection folded into mini-ota's pure data check**: mini-ota gains a pure data check — `image_verify_raw(read_fn, ctx, len, expected_crc)` plus the `image_verify_area(area_id, off, len, expected_crc)` convenience wrapper (`bootutil/inc/verify.h`) — which **parses no image header or trailing meta**, uses no key and no packing mode, and just answers "is this data / this flash region still what was written". It streams through `crc_stream_*` with the `CRC_MODEL_*` model (standard CRC-32 by default), with no dynamic memory and no static state, usable from both bootloader and app. `system_scrubber` now calls it and its own 256-entry CRC table is gone, so the third CRC implementation in the tree disappears; the scrubber task, the `CONFIG_SYSTEM_SCRUBBER` switch and the "mismatch → `enter_safe_state()`" behaviour all stay. A pre-existing baseline mismatch was fixed: `post_build_crc.py` computed the CRC over `firmware.bin` (binary length) while the old scrubber scanned `hal_flash_get_app_size()` (the whole partition), so the two could never agree; the tool now also emits the length macro `SYSTEM_SCRUBBER_IMAGE_LEN` (new `--len-define`, refreshed in place or appended) and the scrubber compares a baseline whose CRC and length come from the same artifact, exiting quietly when either is unset. Compilation gating was corrected too: `system_scrubber.c` used to be compiled unconditionally in three build lists (root `CMakeLists.txt`, `cmake/esp_idf.cmake`, `system_cpp/CMakeLists.txt`) even with `CONFIG_SYSTEM_SCRUBBER=n`; it is now gated by that switch, which in turn gained `depends on MINI_OTA` since the check primitive comes from mini-ota (ESP/Xtensa can never enable `CONFIG_MINI_OTA`). The no-op `system_scrubber_init()` was dropped along with its call site, while `system_scrubber_is_running()` remains as a public query. The flash HAL is gone as well: `hal/storage/hal_flash.{c,h}` had no callers left — "read-only inspection + app-region address/size query" is now owned by mini-ota's `flash_area` table (`fa_offset` / `fa_size` plus `ota_current_partition_get()`), and upper layers reach flash through SPI / I2C — so `hal_flash_read` / `hal_flash_get_app_addr` / `hal_flash_get_app_size` (all weak stubs) disappeared with it. The two HAL source lists (`CMakeLists.txt`, `cmake/esp_idf.cmake`) dropped their entries; `hal/storage/hal_storage.{c,h}` (dual-slot A/B persistence) is unaffected.
### 错误码改为自持分段编号 / Error codes moved to self-owned sector numbering
- **`status.h` 自持编号**:`MINI_OK` / `MINI_ERR_*` 由 `-EINVAL` 等 **errno 别名改为自持 enum**(`0` 成功 / 负数失败),不再 `#include <errno.h>` —— 数值跨工具链稳定,不再随 libc(newlib / newlib-nano)漂移。
- **分段可扩容**:`-1..-63` 通用/栈层(原 12 码 + 新增 `STATE` / `RANGE` / `NOENT` / `EXIST` / `NOTINIT` / `NODATA` / `CORRUPT` / `CRC` / `PARITY` / `OVERFLOW` / `NOTREADY` / `CANCELED` / `PERM` / `PROTO` / `AUTH`,共 27 码;`-28..-63` 预留)、`-64..-127` 子系统私有、`-128..-255` 驱动/板级私有;幅度上限 `MINI_ERR_MAX`(255) 与 `ERR_PTR` 编码上限一致,链接脚本无需改动。
- **新增辅助**:`MINI_ERR_BUILD(mag)` 构造私有码、`MINI_ERR_SECTOR_OF()` / `MINI_ERR_IS_SUBSYS()` / `MINI_ERR_IS_DRIVER()` 判归属、`MINI_ERR_TO_STR()` 日志字符串(新 `core/src/status.c`,未被引用时由链接器整体丢弃)。
- **修复 `lib/mini-os/inc/err.h` 两分支不等价**:别名分支缺 `MINI_OS_ERR_STATE`(仅后备分支有),一旦 in-tree 使用即编译失败;现已补齐,且两分支**逐位数值一致**,`MINI_OS_ERR_*` ↔ `MINI_ERR_*` 零转换。
- **清扫 80 文件 / 210 处**:61 个文件 191 处 `@return ... VFS_ERR_*` 幽灵文档名(`VFS_ERR_*` 全仓无任何定义,为 OSAL 拆除后的文档残留)→ `MINI_ERR_*`;约 20 处 HAL / ESP 注释中的 `-ENOSYS` 与 `board_driver.c` 的 `EPROBE_DEFER` 措辞改为 `MINI_ERR_NOTSUPP` / `MINI_ERR_DEFER`。
- **类型化返回 `mt_err_t`**:错误码 enum 命名改为 `mt_err_t`,并把"返回错误码"的函数其返回类型由 `int` 统一改为 `mt_err_t`(**142 个文件,声明 + 定义共约 1180 处**);参数类型保持 `int`(C++ 侧 enum → int 隐式可行,int → enum 需显式转换)。同步改写 **65 处错误码回调的函数指针类型**(`file_operations` 的 init/open/close/ioctl/suspend/resume、bus host ops、HAL ops、各 VFS/驱动的 `*_ioctl_fn_t`、`probe_fn_t`/`remove_fn_t` 及其生成器 `tools/dtc_lite/generator.py` 与 `ide/stubs/board_devtable.h`)。**刻意保持 `int`**:`file_operations.write/read`("字节数或错误码"混合契约)、`interrupt_top_half_t`(返回 `MINI_IRQ_ENTRY_*` 标志)、bus host ops 的 `.role`、以及 `NET_*` / `BUFF_*` / `MINI_LOG_ERR_*` 与 coreMQTT/lwIP 等第三方回调。
- **文档同步**:`api_compatibility` 新增「错误码编号与命名空间边界」章节(明确 `MINI_ERR_*` / `MINI_OS_ERR_*` / `NET_ERR_*` / `BUFF_*` / `MINI_LOG_ERR_*` 的边界与翻译点,禁止跨命名空间按数值比较);`net.md`、`mini-os.md`、`design_decisions.md` 同步(并修正 `mini-os.md` 中 `(已移除)()` 的文档残留为 `mini_sched_freeze()`);6 篇 HAL 头文件的"返回值必须使用 int"约定更新为"错误码用 `mt_err_t`"。
**Error codes moved to self-owned sector numbering**: `status.h` no longer aliases `-EINVAL` and friends — `MINI_OK` / `MINI_ERR_*` are now a self-owned enum (`0` = success, negative = error) with no `<errno.h>` dependency, so values no longer drift with the libc (newlib vs newlib-nano). Sectors: `-1..-63` common/stack (the original 12 codes plus `STATE` / `RANGE` / `NOENT` / `EXIST` / `NOTINIT` / `NODATA` / `CORRUPT` / `CRC` / `PARITY` / `OVERFLOW` / `NOTREADY` / `CANCELED` / `PERM` / `PROTO` / `AUTH`, 27 in total, with `-28..-63` reserved), `-64..-127` subsystem-private, and `-128..-255` driver/board-private. The magnitude cap `MINI_ERR_MAX` (255) still matches the `ERR_PTR` encoding limit, so the linker script is untouched. New helpers: `MINI_ERR_BUILD(mag)`, `MINI_ERR_SECTOR_OF()` / `MINI_ERR_IS_SUBSYS()` / `MINI_ERR_IS_DRIVER()`, and `MINI_ERR_TO_STR()` (new `core/src/status.c`, dropped by the linker unless referenced). `lib/mini-os/inc/err.h` was fixed: the alias branch was missing `MINI_OS_ERR_STATE` (present only in the fallback branch), which would have failed to compile as soon as it was used in-tree; both branches now carry identical values, so `MINI_OS_ERR_*` ↔ `MINI_ERR_*` needs no conversion. 80 files / 210 occurrences were swept: 191 stale `VFS_ERR_*` doc-comment references across 61 files (the name had no definition anywhere) became `MINI_ERR_*`, and the `-ENOSYS` / `EPROBE_DEFER` wording in ~20 HAL/ESP comments plus `board_driver.c` became `MINI_ERR_NOTSUPP` / `MINI_ERR_DEFER`. Docs were synced: `api_compatibility` gained an "Error Code Numbering & Namespace Boundaries" section covering the `MINI_ERR_*` / `MINI_OS_ERR_*` / `NET_ERR_*` / `BUFF_*` / `MINI_LOG_ERR_*` boundaries and translation points (cross-namespace numeric comparison is forbidden), and `net.md`, `mini-os.md` (its `(已移除)()` remnant now reads `mini_sched_freeze()`) and `design_decisions.md` were updated. In addition, the error-code enum is now named `mt_err_t` and every error-returning function declares its return type as `mt_err_t` instead of `int` (roughly 1180 declarator sites across 142 files), while parameter types stay `int` (enum → int is implicit in C++, the reverse needs an explicit cast). The 65 error-code callback pointer types were converted with them (`file_operations` init/open/close/ioctl/suspend/resume, bus host ops, HAL ops, every VFS/driver `*_ioctl_fn_t`, and `probe_fn_t` / `remove_fn_t` including the `tools/dtc_lite/generator.py` generator and the `ide/stubs/board_devtable.h` stub). Deliberately left as `int`: `file_operations.write/read` (the "bytes or error" mixed contract), `interrupt_top_half_t` (returns the `MINI_IRQ_ENTRY_*` flag), bus host ops `.role`, and the `NET_*` / `BUFF_*` / `MINI_LOG_ERR_*` and coreMQTT/lwIP third-party callbacks. The six HAL headers' "must use int" convention note now says to use `mt_err_t` for error codes.
### 日志后端切换为随仓库 mini-log / Log backend switched to the bundled mini-log library
- **由独立仓库并入本仓(不留子模块)**:`mini-log/` 原本是自带 `.git` 的独立仓库、被父仓库记成无 `.gitmodules` 的裸 gitlink(160000)。现改为与 `lib/mini-os` 同款的**随仓源码**:摘除索引中的 gitlink、移出嵌套 `.git`,17 个文件以普通文件纳入(`git ls-files` 全为 `100644`,仓库内不再有任何 160000 条目)。理由:本仓的既有惯例就是"并入"而非子模块(`mini-log/.gitignore` 里那条 `.buffer-git-backup/` 即是 buffer 目录当年被并入时留下的同类处理)。
- **接入 `mini-log/` 随仓库**:删除仓内 `core/include/mini_log.h` + `core/src/mini_log.c`(基于 printf_output 的旧日志 shim);`core/include/system_log.h` 的 `SYS_LOG*` / `DRV_LOG*` 宏改为直接展开到 mini-log 的 `MINI_LOG_E/W/I/D`(`tag` 作为前缀并入格式串,全仓调用点签名不变);`core/include/mini_panic.h` 的 `MINI_PANIC` / `MINI_CRITICAL_ASSERT` 改用 mini-log 的 `mini_log_default_output()`。
- **Kconfig 改名**:日志后端选项 `CONFIG_SYS_LOG_USE_PRINTF` → `CONFIG_SYS_LOG_USE_MINI_LOG`(默认项,help 更新为 mini-log);`CONFIG_SYS_LOG_USE_ESP` 不变。`.config` / `ide/stubs/config.h` / `compile_flags.txt` 同步。
- **缓冲复用(避免重复符号)**:mini-log 自带的 `mini-log/buffer/` 与本仓 `algorithm/buffer/` 是同源但不兼容的两份实现(同名符号、不同签名),故不编入 `mini-log/buffer/`;`mini-log/src/log.c` 的环形缓冲调用改为复用仓内 `algorithm/buffer` API(`int` 返回 + `p_actual` 出参)。
- **构建接入**:根 `CMakeLists.txt` 与 `cmake/esp_idf.cmake` 编入 `mini-log/src/log.c` + `crc.c` 并公开 `mini-log/inc`;`net` / `board` / `bus` 等独立 target 同步 include。
- **文档同步**:`docs/{cn,en}` 的 `SYS_LOG_USE_PRINTF` 引用改为 `SYS_LOG_USE_MINI_LOG`(`getting_started` / `faq` / `debug_monitor` / `memory_footprint`)。
- **退役旧 printf sink**:`my_printf_output` 的最后调用点(`mini_backend_freertos.c` 的 AMP 回退告警)改用 `SYS_LOGW`;删除 `core/include/printf_output.h` + `core/src/printf_output.c` 及其在根/ESP 构建、poison 豁免名单中的引用(`ALLOW_STDIO_OUTPUT` 仅保留对 `vprintf` 的毒化)。
- **删除 production_log 黑匣子**:移除 `core/include/production_log.h` + `core/src/production_log.c`、`CONFIG_PRODUCTION_LOG` / `CONFIG_PRODUCTION_LOG_SLOT_COUNT`、`DRV_LOGE/W` 中的 push、`board_driver.c` 的 init 及构建/文档引用。该模块默认关且全仓无读取方,持久化日志改由 mini-log 的 flash 链路承担。
- **接入 mini-log Kconfig**:新增 `menu "mini-log"`(`MINI_LOG_MAX_LEN` / `RING_SIZE` / `AUTO_FLUSH` / `COLOR_ENABLE` / `USE_FLASH` / `FLASH_RING_SIZE` / `FLASH_AUTO_FLUSH` / `DEFAULT_ALIGIN` / `MAGIC`),生成的 `CONFIG_MINI_LOG_*` 由 `mini-log/inc/log_config.h` 消费;该头在 include 路径存在 `config.h` 时自动读入(独立构建回退默认值),并以 `CONFIG_SYS_LOG_USE_MINI_LOG` 为标记把"未定义的 bool"判为关闭。
- **日志宏加 `MT_LOG_` 前缀**:接入层宏 `SYS_LOGI/W/E` → `MT_LOG_ERROR/WARN/INFO`,`DRV_LOGE/W/I/D/V` → `MT_DRV_LOG_ERROR/WARN/INFO/DEBUG/VERBOSE`(`DRV_LOGV` 原与 `DRV_LOGD` 同映射 DEBUG,改名时拆出 `VERBOSE` 以便区分)。全仓 **80 文件 / 309 处**源码 + **16 篇文档**同步改名;mini-log 引擎、ESP 后端切换、tag 折入约定均不变。
**Log backend switched to the bundled mini-log library**: removed the in-tree `core/include/mini_log.h` + `core/src/mini_log.c` (the old printf_output-based shim); `SYS_LOG*` / `DRV_LOG*` in `core/include/system_log.h` now expand directly to mini-log's `MINI_LOG_E/W/I/D` (the `tag` is folded into the format string, so all call sites keep their signature), and `mini_panic.h`'s `MINI_PANIC` / `MINI_CRITICAL_ASSERT` use mini-log's `mini_log_default_output()`. The Kconfig backend option `CONFIG_SYS_LOG_USE_PRINTF` was renamed to `CONFIG_SYS_LOG_USE_MINI_LOG` (default, updated help); `.config` / `ide/stubs/config.h` / `compile_flags.txt` synced. `mini-log/buffer/` is not compiled because it is an incompatible same-name variant of `algorithm/buffer`; `mini-log/src/log.c` reuses the in-tree `algorithm/buffer` API instead. The root `CMakeLists.txt` and `cmake/esp_idf.cmake` build `mini-log/src/log.c` + `crc.c` and expose `mini-log/inc`; independent targets (`net` / `board` / `bus`) include it too. Docs referencing `SYS_LOG_USE_PRINTF` were updated. The old printf sink was retired: the last `my_printf_output` call (the AMP fallback warning in `mini_backend_freertos.c`) now uses `SYS_LOGW`, and `core/include/printf_output.h` + `core/src/printf_output.c` were deleted along with their root/ESP build and poison-exemption references (`ALLOW_STDIO_OUTPUT` now only poisons `vprintf`). The `production_log` black box was removed: `core/include/production_log.h` + `core/src/production_log.c`, `CONFIG_PRODUCTION_LOG` / `CONFIG_PRODUCTION_LOG_SLOT_COUNT`, the `DRV_LOGE/W` push, the `board_driver.c` init, and all build/doc references were dropped — it was off by default with no in-tree reader, and persistent logs are now served by mini-log's flash chain. mini-log's options are now exposed through a new `menu "mini-log"` (`MINI_LOG_MAX_LEN` / `RING_SIZE` / `AUTO_FLUSH` / `COLOR_ENABLE` / `USE_FLASH` / `FLASH_RING_SIZE` / `FLASH_AUTO_FLUSH` / `DEFAULT_ALIGIN` / `MAGIC`); the generated `CONFIG_MINI_LOG_*` are consumed by `mini-log/inc/log_config.h`, which auto-includes `config.h` when present (falling back to defaults for standalone builds) and treats an undefined bool as "off" via the `CONFIG_SYS_LOG_USE_MINI_LOG` marker. The facade macros were prefixed with `MT_LOG_`: `SYS_LOGI/W/E` → `MT_LOG_ERROR/WARN/INFO` and `DRV_LOGE/W/I/D/V` → `MT_DRV_LOG_ERROR/WARN/INFO/DEBUG/VERBOSE` (the old `DRV_LOGV` shared the DEBUG mapping with `DRV_LOGD`; it now gets a distinct `VERBOSE` name). 80 source files / 309 call sites plus 16 docs were renamed; the mini-log engine, the ESP backend switch and the tag-folding convention are unchanged.
### 接入 mini-ota OTA / 引导体系 / Integrate the mini-ota OTA/bootloader
- **Kconfig 新增 OTA 菜单**:`Bootloader / OTA (mini-ota)`,含总开关 `CONFIG_MINI_OTA`(仅 Cortex-M)、双分区 `CONFIG_OTA_DUAL_PARTITION`、镜像加密 `CONFIG_IMAGE_CRYPTO`(0/1,决定是否链接 mbedtls)、FLASH/SRAM 布局(`CONFIG_FLASH_START_ADDR` / `CONFIG_SRAM_START_ADDR` / `CONFIG_SRAM_SIZE`)、下载块大小 `CONFIG_MINI_BOOT_LOAD_MAX`、CRC 模型(`CONFIG_CRC_INIT` / `CRC_REFIN` / `CRC_REFOUT` / `CRC_XOR_OUT` / `CRC_POLY`)。所有 `CONFIG_*` 经 `config.h` 直供 mini-ota 的 `boot_config.h`。
- **CMake 合并**:`.config` 的 `CONFIG_MINI_OTA` 桥接 `add_subdirectory(lib/mini-ota)`;把生成的 `config.h` 与 `core/include` 注入 `mini_ota` 目标并加 `mini_tree_gen` 依赖(与 `lib/mini-os` 同范式);按 `CONFIG_PLATFORM_*` 派生 `MINI_BOOT_Mx` 供给 `arch/arm/cortex-m/cortex_m.S`;`CONFIG_IMAGE_CRYPTO=0` 时不编入 mbedtls 与 aes/sha/hmac。
- **mini-ota(嵌套仓库)**:加密源码与 mbedcrypto 按 `IMAGE_CRYPTO` 门控;编入 mini_tree 时复用工程级 `mini_tree_link_mbedtls()`(新增 `configs/mbedtls_config.h` 端口垫片),否则回退自带 mbedtls;工具链探测与 `-DCONFIG_SRAM_*` 仅在独立构建生效。
- **CMake 4.x 修复**:`cmake/mbedtls.cmake` 在 CMake ≥ 4.0 下放宽 `CMAKE_POLICY_VERSION_MINIMUM`,修复 mbedtls 2.28 因子工程 `cmake_minimum_required(<3.5)` 导致的配置失败。
- `.config` 中 `CONFIG_MINI_OTA` 默认关(按需开启)。
**Integrate the mini-ota OTA/bootloader**: a new Kconfig menu `Bootloader / OTA (mini-ota)` exposes the full `boot_config.h` surface (`CONFIG_MINI_OTA` master switch, dual-partition, `CONFIG_IMAGE_CRYPTO`, FLASH/SRAM layout, `MINI_BOOT_LOAD_MAX`, CRC model), all delivered to mini-ota through the shared `config.h`. CMake bridges `CONFIG_MINI_OTA` to `add_subdirectory(lib/mini-ota)`, injects `config.h` / `core/include` into `mini_ota` (plus a `mini_tree_gen` dependency), derives `MINI_BOOT_Mx` from `CONFIG_PLATFORM_*`, and skips mbedtls/aes/sha/hmac when `CONFIG_IMAGE_CRYPTO=0`. In-tree builds of mini-ota reuse the project-level `mini_tree_link_mbedtls()` (new `configs/mbedtls_config.h` port shim). `cmake/mbedtls.cmake` now relaxes `CMAKE_POLICY_VERSION_MINIMUM` under CMake >= 4.0 to fix mbedtls 2.28 configuration failures. `CONFIG_MINI_OTA` defaults to off.
### 系统层移除 C++ 后端 / Remove the C++ system-layer backend
- **系统层改为纯 C(命令模块除外)**:删除 `system_cpp/` 下与 `system_c/` 等价的 C++ 实现(`system_init` / `system_wdt` / `system_scrubber` / `task_manager` 的 `.cpp` + `.hpp`)及 `mini_tree::` 命名空间 API;系统层统一走 `system_c/` 的 C API(`mini_tree_pre_os_init()` / `mini_tree_start_tasks()` / `system_init_complete()` / `mini_tree_system_loop()` / `task_manager_create()`)。理由:C/C++ 两套等价 API 的维护成本高于收益。
- **`SystemCmd` 保留为 C++**:命令派发基础设施 `system_cpp/src/system_cmd.cpp`(`CONFIG_SYSTEM_CMD`,默认关,依赖 ETL)是系统层唯一的 C++ 例外,未改动。
- **Kconfig 简化**:移除「System backend」choice(`SYSTEM_C` / `SYSTEM_CPP`);`CONFIG_SYSTEM` 成为系统层唯一总开关,`CONFIG_SYSTEM_CMD` 依赖由 `SYSTEM_CPP` 改为 `SYSTEM`。
- **`safe_state` 归位 `system_c/`**:`safe_state.c/.h` 从 `system_cpp/` 移入 `system_c/`,删除 `core/include/safe_state.h` 的重复头。
- **删除死代码 `event_bus` C++ 副本**:`core/src/event_bus.cpp` + `core/include/event_bus.hpp`(未编译、无引用)删除;EventBus 统一为 `core/src/event_bus.c` + `event_bus.h`。
- **`system_c` 头自包含**:`system_wdt.h` / `system_scrubber.h` 内联 `extern "C"` 声明(不再转发包含已删除的 `.hpp`);修复 `task_manager.h` 缺 `mini_backend.h`(`mini_task_handle_t` 定义处)导致的编译错误(旧 `SYSTEM_CPP=y` 下 `task_manager.c` 从不参与编译,故未暴露)。
- **构建/配置同步**:根 `CMakeLists.txt` 与 `cmake/esp_idf.cmake` 的 SYSTEM 源恒为 C,`system_cmd.cpp` 按 `CONFIG_SYSTEM_CMD` 条件编入,C++ 编译选项(`-fno-rtti` / `-fno-exceptions`)门控改为 `SYSTEM_CMD`;`.config` / `compile_flags.txt` / `ide/stubs/config.h` 移除 `CONFIG_SYSTEM_CPP`。
- **文档同步**:`docs/{cn,en}` 全量更新(`runtime_services` / `getting_started` / `architecture` / `patterns` / `design_decisions` / `file_index` / `coding_style` / `driver_guide` / `service_spec` / `app_cpp_guide` / `ecosystem` / `keil_integration` / `usage` / `backend_switching` / `README` / `SUMMARY`);`memory_footprint` / `mini-os` 的 C/C++ 基准标注为历史数据。
**The system layer is now pure C (except the command module)**: removed the C++ implementations under `system_cpp/` that duplicated `system_c/` (`system_init` / `system_wdt` / `system_scrubber` / `task_manager` `.cpp` + `.hpp`) and the `mini_tree::` namespace API; the system layer now uses the C API in `system_c/` (`mini_tree_pre_os_init()` / `mini_tree_start_tasks()` / `system_init_complete()` / `mini_tree_system_loop()` / `task_manager_create()`). Rationale: maintaining two equivalent C/C++ API sets cost more than it returned.
**`SystemCmd` stays C++**: the command dispatch infra `system_cpp/src/system_cmd.cpp` (`CONFIG_SYSTEM_CMD`, off by default, ETL-based) is the only C++ exception in the system layer and is unchanged.
**Kconfig simplified**: removed the "System backend" choice (`SYSTEM_C` / `SYSTEM_CPP`); `CONFIG_SYSTEM` is now the sole master switch, and `CONFIG_SYSTEM_CMD`'s dependency changed from `SYSTEM_CPP` to `SYSTEM`.
**`safe_state` relocated to `system_c/`**: `safe_state.c/.h` moved from `system_cpp/`; the duplicate `core/include/safe_state.h` was deleted.
**Dead `event_bus` C++ copy removed**: `core/src/event_bus.cpp` + `core/include/event_bus.hpp` (never compiled, unreferenced) deleted; EventBus is now `core/src/event_bus.c` + `event_bus.h`.
**`system_c` headers self-contained**: `system_wdt.h` / `system_scrubber.h` inline their `extern "C"` declarations (no longer forwarding to deleted `.hpp`); fixed a compile error where `task_manager.h` lacked `mini_backend.h` (where `mini_task_handle_t` is defined) — it never surfaced before because `task_manager.c` was not compiled under the old `SYSTEM_CPP=y`.
**Build/config synced**: the root `CMakeLists.txt` and `cmake/esp_idf.cmake` always use C SYSTEM sources, compile `system_cmd.cpp` conditionally on `CONFIG_SYSTEM_CMD`, and gate the C++ options (`-fno-rtti` / `-fno-exceptions`) on `SYSTEM_CMD`; `.config` / `compile_flags.txt` / `ide/stubs/config.h` dropped `CONFIG_SYSTEM_CPP`.
**Docs synced**: `docs/{cn,en}` fully updated (`runtime_services` / `getting_started` / `architecture` / `patterns` / `design_decisions` / `file_index` / `coding_style` / `driver_guide` / `service_spec` / `app_cpp_guide` / `ecosystem` / `keil_integration` / `usage` / `backend_switching` / `README` / `SUMMARY`); the C/C++ benchmarks in `memory_footprint` / `mini-os` are marked historical.
### 移除 OSAL 抽象层 / Remove the OSAL abstraction layer
- **删除 OSAL 抽象层**:整目录 `osal/` 删除;仓库内代码(board / VFS / bus / core / system / net)改走极薄统一接口 `core/include/mini_backend.h`(互斥锁 / 二值信号量 / 定长队列 / 任务族 + 可嵌套临界区 + 内存三函数),每后端一份实现(`core/src/mini_backend_{bare,mini_os,freertos,rtthread}.c`),编译期分发,不用运行时函数指针表。
- **后端可选性不变**:Kconfig 保留四后端 choice(`OS_BARE` / `OS_MINI_OS` / `OS_FREERTOS` / `OS_RTTHREAD`,由 `OSAL_*` 改名),`lib/mini-os` / `lib/freeRTOS` / `lib/rtthread` 源码随仓保留,ESP 仍走 IDF freertos 绑定。
- **连带清理**:删除无人使用缓冲池模块、裸机内存走 mini-os 的开关、事件组 / 自旋锁抽象、裸机 C++ 任务封装。
- **缺陷修复**:`net/sys/sys_arch.c` 三处把布尔返回值与成功码(`MINI_OK`=0)比较导致逻辑反转的缺陷(`sys_mbox_trypost` 返回值反转、`sys_arch_mbox_fetch` 永返超时、`sys_arch_mbox_tryfetch` 永返空)。
- **文档纠错(既有缺陷,单独留痕)**:删除「mini-os 堆空闲链表无锁、ISR 内禁止调用」的错误描述(`docs/{cn,en}/mini-os.md` 内存模块段)—— 与 `lib/mini-os/inc/memory.h:178-179`("the ISR path is identical to the thread path")及 `lib/mini-os/src/memory.c` 的 `mini_os_irq_save/restore` 可嵌套关中断事实矛盾。同一措辞原本也写在 Kconfig 的 `OS_BARE_MINI_OS_MEM` 条目里;该开关本次恢复时,help 已按真实语义重写(分配/释放走可嵌套关中断临界区,只有惰性接管不是 ISR 安全)。
**Remove the OSAL abstraction layer**: the whole `osal/` directory is deleted; in-tree code (board / VFS / bus / core / system / net) now uses the thin unified interface `core/include/mini_backend.h` (mutex / binary semaphore / fixed queue / task family + nestable critical section + malloc family), with one implementation per backend (`core/src/mini_backend_{bare,mini_os,freertos,rtthread}.c`) dispatched at compile time — no runtime function-pointer table.
**Backend choice unchanged**: Kconfig keeps the four-backend choice (`OS_BARE` / `OS_MINI_OS` / `OS_FREERTOS` / `OS_RTTHREAD`, renamed from `OSAL_*`); `lib/mini-os` / `lib/freeRTOS` / `lib/rtthread` stay vendored, ESP still binds IDF freertos.
**Cleanups**: dropped the orphan buffer-pool module, the bare-metal memory-via-mini-os switch, the event-group / spinlock abstractions, and the bare-metal C++ task wrapper.
**Bug fixes**: three boolean-vs-status comparisons in `net/sys/sys_arch.c` (against `MINI_OK`=0) that inverted logic (`sys_mbox_trypost` inverted return, `sys_arch_mbox_fetch` always timing out, `sys_arch_mbox_tryfetch` always empty).
**Docs correction (pre-existing defect, recorded separately)**: the claim that the mini-os heap's free list is unlocked and must never be called from an ISR was dropped from `docs/{cn,en}/mini-os.md` (memory-module note) — it contradicted `lib/mini-os/inc/memory.h:178-179` ("the ISR path is identical to the thread path") and the `mini_os_irq_save/restore` nestable critical sections in `lib/mini-os/src/memory.c`. The same wording also sat in the Kconfig `OS_BARE_MINI_OS_MEM` entry, whose help text was rewritten to the real semantics when the switch was restored here (alloc/free run inside a nestable interrupt-masked critical section; only the lazy takeover is not ISR-safe).
### 工具与文档清理 / Tools & docs cleanup
- **删除孤儿头 `tools/system_scrubber_crc_gen.h`**:同名头共有三份,CMake 只用两份 —— 目标 `${SCRUBBER_GEN_DIR}/system_scrubber_crc_gen.h` 由 `tools/system_scrubber_crc_stub.h` 拷贝生成(根 `CMakeLists.txt` / `cmake/esp_idf.cmake` 各一处 `copy_if_different`),IDE 用 `ide/stubs/system_scrubber_crc_gen.h`;`tools/` 下这份全仓零引用。
- **修掉 4 组指向不存在脚本的文档 / 注释**:`docs/{cn,en}/tools_guide.md` 的 `tools/guiconfig.py` 与 `guiconfig_canvas.py`(只存在于 `cb2b652 "updata esp-branch"` 那条分支;本仓只有随仓的 `tools/_vendor/guiconfig.py`,也无 GUI 启动器,现改为直接运行上游脚本并说明 `.config` 落点)、`docs/{cn,en}/problem_summary.md` 与 `docs/{cn,en}/todolist.md` 里的 `tools/build_size.py` 行、以及 6 处把脚本写成 `tools/crc/image_crc.py` 的注释(真实路径 `lib/mini-ota/tools/m_crc/image_crc.py`,涉及 `mini-log` 与 `lib/mini-ota` 的 crc / verify 头)。
- **核对结论**:`tools/` 下 6 个顶层 `.py`(`genconfig` / `menuconfig` / `_vendor_loader` / `dtc-lite` / `gen_compile_db` / `post_build_crc`)与 `dtc_lite/` 包全部有活引用(CMake 目标与构建依赖、文档入口),无删减;`__pycache__/*.pyc` 属运行产物,`.gitignore` 已忽略。
**Tools & docs cleanup**: the orphan `tools/system_scrubber_crc_gen.h` was deleted — three same-named headers exist, and CMake only uses the one generated from `tools/system_scrubber_crc_stub.h` (a `copy_if_different` in both the root `CMakeLists.txt` and `cmake/esp_idf.cmake`) plus the IDE stub `ide/stubs/system_scrubber_crc_gen.h`. Four groups of references to non-existent scripts were fixed: `tools/guiconfig.py` / `guiconfig_canvas.py` in `docs/{cn,en}/tools_guide.md` (they only ever existed on the `cb2b652 "updata esp-branch"` branch — this branch ships only the vendored `tools/_vendor/guiconfig.py` and no GUI launcher, so the docs now run the upstream script directly and document where `.config` lands), the `tools/build_size.py` rows in `docs/{cn,en}/problem_summary.md` and `docs/{cn,en}/todolist.md`, and six comments naming `tools/crc/image_crc.py` (real path `lib/mini-ota/tools/m_crc/image_crc.py`, in the `mini-log` and `lib/mini-ota` crc / verify headers). Audit result: all six top-level `tools/*.py` (`genconfig` / `menuconfig` / `_vendor_loader` / `dtc-lite` / `gen_compile_db` / `post_build_crc`) and the `dtc_lite/` package have live references (CMake targets and build dependencies, documented entry points) — none were removed; `__pycache__/*.pyc` are run artifacts already covered by `.gitignore`.
### OSAL 与文档 / OSAL & Docs
- **新增 mini-os 后端(第四后端)**:`CONFIG_OS_MINI_OS`(仅 Cortex-M,`depends on !PLATFORM_RISCV && !PLATFORM_ESP32`)接入随仓自研内核 `lib/mini-os`——freestanding 无 libc 依赖,32 级抢占调度(就绪位图 O(1))+ 线程/定时器双时间轮 + 互斥锁优先级继承,堆为链接脚本区不计 bss;四后端中 text/bss 最小。板级接线:`SysTick_Handler` → `mini_os_systick_handler()`、`PendSV_Handler` → `pendsv_handler()`(小写)、链接脚本含 `mini-os-heap.ld`、启动遍历 `.init_array`。专题文档 `docs/cn/mini-os.md` / `docs/en/mini-os.md`。
**New mini-os backend (OSAL's fourth)**: `CONFIG_OS_MINI_OS` (Cortex-M only) wires in the in-tree kernel `lib/mini-os` — freestanding, 32-level preemptive scheduling (O(1) ready bitmap) + thread/timer dual time wheels + mutex priority inheritance; the heap is a linker region and not counted in bss. Smallest text/bss of the four backends. Board wiring: `SysTick_Handler` → `mini_os_systick_handler()`, `PendSV_Handler` → `pendsv_handler()` (lowercase), linker script includes `mini-os-heap.ld`, startup iterates `.init_array`. Deep-dive: `docs/cn/mini-os.md` / `docs/en/mini-os.md`.
- **修复 rtthread 后端 `context_gcc.S` 被静默丢弃**:只选 RTTHREAD 后端时无人启用 ASM,静态库阶段不报错、链接真实固件才缺 `rt_hw_context_switch*` / `rt_hw_interrupt_disable` 等 port 符号;`lib/rtthread/CMakeLists.txt` 现自启用 `enable_language(ASM)`,构建方式无关。
**Fixed rtthread backend silently dropping `context_gcc.S`**: with only the RTTHREAD backend nobody enabled ASM — the static library built fine but linking a real firmware missed the port symbols; `lib/rtthread/CMakeLists.txt` now enables `enable_language(ASM)` itself.
- **`memory_footprint.md` §4 基准重写(11 配置 × newlib-nano/完整 newlib 双口径,arm-none-eabi-gcc 13.3.1/Windows)**:裸机三态 / mini-os / FreeRTOS / RT-Thread × C/C++;旧表(uC/OS-II/III、ThreadX)退役。mini-os 为最省 RTOS 后端(nano ~14.2–14.4 KB text);完整 newlib 比 nano 约 +24.6 KB text(RT-Thread 例外 +6.4 KB,`RT_KLIBC_USING_LIBC_VSNPRINTF`);各后端堆口径不同,bss 需剔除可配堆后再比。
**`memory_footprint.md` §4 rewritten (11 configs × nano/full-newlib accounting)**: bare-metal tri-state / mini-os / FreeRTOS / RT-Thread × C/C++; the old table (uC/OS-II/III, ThreadX) is retired. mini-os is the leanest RTOS backend (nano ~14.2–14.4 KB text); full newlib costs ~+24.6 KB text over nano (RT-Thread +6.4 KB extra via `RT_KLIBC_USING_LIBC_VSNPRINTF`); exclude configurable heaps before comparing bss.
- **文档全面同步四后端**:根 `README`(概述/OSAL 表/Ecosystem vendor 清单/Targets)、`NOTICE`(vendor 清单加 mini-os)、`ecosystem` / `getting_started`(含启动示例代码补 `mini_os_schedule_start()` 分支)/ `architecture` / `usage` / `SUMMARY` / `README` 索引 / `osal_switching`(后端对照、优先级、启动、堆口径、板级接线)/ `file_index` / `references` / `api_compatibility` / `design_decisions` / `CHANGELOG`;措辞统一为四后端(mini-os 仅 Cortex-M)。
**Docs fully synced to four backends**: root `README` (overview / OSAL table / vendor list / targets), `NOTICE`, `ecosystem` / `getting_started` (startup example now includes the `mini_os_schedule_start()` branch) / `architecture` / `usage` / `SUMMARY` / index `README` / `osal_switching` (backend table, priorities, startup, heap accounting, board wiring) / `file_index` / `references` / `api_compatibility` / `design_decisions` / `CHANGELOG`; wording unified as four backends (mini-os is Cortex-M only).
- **裸机内存三函数可切到 mini-os 内存模块**:`mini_malloc/mini_calloc/mini_free`(四后端同步提供)默认走 libc `malloc/calloc/free`;裸机开启 `CONFIG_OS_BARE_MINI_OS_MEM` 后转发到 `lib/mini-os` 的内存模块 —— 只编 `memory.c` 单文件(无调度器/port 依赖,不链整个内核),first-fit + 相邻合并 + magic 防 double-free,堆区由链接脚本 `__mini_os_heap_start/__mini_os_heap_end` 提供(可 `INCLUDE lib/mini-os/mini-os-heap.ld`),首次分配惰性接管(`mini_os_heap_ensure_init()` 幂等),无需启动遍历 `.init_array`。(该开关在 OSAL 拆除中一度被删,本版恢复并按真实并发语义重写说明:分配/释放本身在可嵌套关中断临界区内,ISR 内并发调用不会破坏空闲链表;惰性接管不是 ISR 安全的,首次分配须在启动/线程上下文完成。)
**Bare-metal memory can switch to the mini-os memory module**: `mini_malloc/mini_calloc/mini_free` (provided by all four backends) default to libc `malloc/calloc/free`; with `CONFIG_OS_BARE_MINI_OS_MEM` on, bare metal forwards them to `lib/mini-os`'s memory module — only `memory.c` is compiled in (no scheduler/port dependency, the whole kernel is not linked), first-fit + adjacent coalescing + magic double-free guard, heap zone from `__mini_os_heap_start/__mini_os_heap_end` (`INCLUDE lib/mini-os/mini-os-heap.ld`), taken over lazily on the first allocation (idempotent `mini_os_heap_ensure_init()`), no `.init_array` traversal needed. (The switch had been dropped during the OSAL teardown and is restored here with a description rewritten to match the real concurrency semantics: alloc/free themselves run inside a nestable interrupt-masked critical section, so an ISR allocating concurrently cannot corrupt the free list; the lazy takeover is not ISR-safe, so the first allocation must happen in startup/thread context.)
### 配置系统 / Configuration
- **`CONFIG_SYSTEM`(默认自开)/ `CONFIG_EVENT_BUS` / `CONFIG_SYSTEM_CMD`(默认关闭)总开关**:System 模块、EventBus、命令系统均可整体裁剪,CMake 按 `.config` 裁剪源文件;另有 `CONFIG_BOTTOM_HALF_QUEUE_DEPTH`、`CONFIG_PRODUCTION_LOG_SLOT_COUNT`、`CONFIG_BOARD_MAX_SAFETY_PINS`、`CONFIG_BOARD_SAFETY_MAX_CALLBACKS`、`CONFIG_FREERTOS_USE_TIMERS`、`CONFIG_FREERTOS_HEAP_SIZE`、`CONFIG_RTT_HEAP_SIZE` 入库。
**Master switches**: `CONFIG_SYSTEM` (default on) / `CONFIG_EVENT_BUS` / `CONFIG_SYSTEM_CMD` (off by default): System, EventBus and the command infra are fully trimmable; CMake trims sources per `.config`; more knobs moved into Kconfig (`CONFIG_BOTTOM_HALF_QUEUE_DEPTH`, `CONFIG_PRODUCTION_LOG_SLOT_COUNT`, `CONFIG_BOARD_MAX_SAFETY_PINS`, `CONFIG_BOARD_SAFETY_MAX_CALLBACKS`, `CONFIG_FREERTOS_USE_TIMERS`, `CONFIG_FREERTOS_HEAP_SIZE`, `CONFIG_RTT_HEAP_SIZE`).
### 内存与 DTS / Memory & DTS
- **静态内存多轮压缩**(arm-none-eabi / Cortex-M4F 实测):`vfs-adc` 池 27.5→4.7 KB;VFS 池改由 `DTC_GEN_COUNT_*` 驱动;EventBus / SystemCmd / Flash-Scrubber 默认关闭;队列池 1×2048、config_store 8 项、mutex 24、下半部 16。全库 85.3 → **28.0 KB**;**默认最小(无外设)≈ 2.8 KB**,仍可再压(见 [memory_footprint.md](docs/cn/memory_footprint.md) §2.2)。
**Multi-round static-RAM cuts** (measured, Cortex-M4F): `vfs-adc` pool 27.5→4.7 KB; VFS pools `DTC_GEN_COUNT_*` driven; EventBus / SystemCmd / Flash-Scrubber off by default; queue pool 1×2048, config_store 8, mutex 24, bottom-half 16. Whole library 85.3 → **28.0 KB**; **default minimum (no peripherals) ≈ 2.8 KB**, still trimmable (see [memory_footprint.md](docs/cn/memory_footprint.md) §2.2).
- **裸机队列池改为"基础数 + EventBus 自动 +1"**:`CONFIG_OS_BARE_MAX_QUEUES` 为基础数(默认 0,不占内存),开启 `CONFIG_EVENT_BUS` 时自动 +1;FreeRTOS/RTT 堆也 Kconfig 化(`CONFIG_FREERTOS_HEAP_SIZE` / `CONFIG_RTT_HEAP_SIZE`)。
**Bare-metal queue pool is now "base + auto-1 for EventBus"**: `CONFIG_OS_BARE_MAX_QUEUES` is the base (default 0, no RAM); enabling `CONFIG_EVENT_BUS` auto-adds 1; FreeRTOS/RTT heaps are Kconfig-gated too (`CONFIG_FREERTOS_HEAP_SIZE` / `CONFIG_RTT_HEAP_SIZE`).
- **字段宽度/池宏移入 `board/define/` 配置头体系**:每 VFS 一个 `board/define/vfs/board_define_<name>.h`(普通 C 宏,板级改头或 `-D` 覆盖);池数量仍由 DTS 节点数自动生成(`DTC_GEN_COUNT_*`);不再走 DTS `#define` 透传。
**Field-width & pool macros moved into `board/define/` config headers**: one `board/define/vfs/board_define_<name>.h` per VFS (plain C macros, board override via header or `-D`); pool counts still auto-generated from DTS node counts (`DTC_GEN_COUNT_*`); the DTS `#define` pass-through was removed.
- **DTS 节点模板库**:`board/dtsi/vfs/`(11)+ `board/dtsi/drivers/`(37),参数全 0 占位 + 用法注释,板级拷走填值。
**DTS node templates**: `board/dtsi/vfs/` (11) + `board/dtsi/drivers/` (37), all-0 placeholders with usage comments.
- **调度方案内存对比基准(最小固件实测)**:`memory_footprint.md` 新增 §4,用最小链接固件(startup + system 层 + 全库,仿 STM32F4 链接脚本)实测全裸 `while` / 协调式 / 抢占式 / 5 个 RTOS 后端 × C/C++ system 后端的 `text`/`data`/`bss`。结论:全裸最省(86 B text,零 RAM);裸机 xtask 比最小 RTOS 内核(uC/OS-II ~33 KB)省 ~1.7 KB 且无独立任务栈;RTOS 内核开销 uC/OS-II < uC/OS-III < ThreadX < FreeRTOS < RT-Thread;C system 后端比 C++ 省。裸机调度三态(`XTASK_NONE`/`XTASK_COOP`/`XTASK_PREEMPT`)由 `Kconfig.mini_tree` choice 选择,CMake 注入 `MINI_TREE_XTASK_*` 宏。
**Scheduler memory comparison baseline (minimal-firmware measured)**: `memory_footprint.md` §4 now measures, via a minimal linked firmware (startup + system layer + whole library, STM32F4-like script), the `text`/`data`/`bss` of bare `while` / cooperative / preemptive / 5 RTOS backends × C/C++ system backends. Takeaways: bare `while` is smallest (86 B text, zero RAM); bare-metal xtask beats the smallest RTOS kernel (uC/OS-II ~33 KB) by ~1.7 KB with no per-task stack; RTOS kernel cost ordering uC/OS-II < uC/OS-III < ThreadX < FreeRTOS < RT-Thread; C system backend is smaller than C++. The bare-metal scheduler tri-state (`XTASK_NONE`/`XTASK_COOP`/`XTASK_PREEMPT`) is a `Kconfig.mini_tree` choice; CMake injects `MINI_TREE_XTASK_*` macros.
### 调度器与 API / Scheduler & API
- **裸机调度器三态落地(choice + CMake 双重门控)**:`Kconfig.mini_tree` 新增「裸机调度器」choice(`XTASK_NONE` / `XTASK_COOP` / `XTASK_PREEMPT`,默认 `XTASK_COOP`),取代旧的单开关 `CONFIG_XTASK` + `CONFIG_XTASK_PREEMPT` 软编码;CMake 据 `.config` 注入 `MINI_TREE_XTASK_*` 宏决定编译 `xtask_coop.c` 或 `xtask_preempt.c`。`CONFIG_XTASK_PREEMPT` 门控改为 `depends on OS_BARE && SYSTEM_CPP && !XTASK_NONE`(无调度时强制关闭 C++ 封装)。
**Bare-metal scheduler tri-state (choice + CMake dual gate)**: `Kconfig.mini_tree` gains a "bare-metal scheduler" choice (`XTASK_NONE` / `XTASK_COOP` / `XTASK_PREEMPT`, default `XTASK_COOP`), replacing the old `CONFIG_XTASK` + `CONFIG_XTASK_PREEMPT` soft switches; CMake injects `MINI_TREE_XTASK_*` macros to pick `xtask_coop.c` or `xtask_preempt.c`. `CONFIG_XTASK_PREEMPT` now gates on `!XTASK_NONE`.
- **抢占式调度器 `xtask_preempt.c` 完工可编译**:N+1 链表多优先级(分组优先级 + CLZ 定位最高,O(1)),支持可延迟/可休眠/可抢占,无就绪任务时精确 WFI 到最早到期时刻;补齐 `CHOSEN_SCHEDULER_TIM` fallback(无 chosen 板时 `xscheduler_start()` 直接返回,与协调式对称)。原 Kconfig help 的"实验性/可能编不过"已不适用。
**Preemptive scheduler `xtask_preempt.c` completed & compilable**: N+1 linked-list multi-priority (grouped priorities + CLZ for O(1) highest pick), delayable / sleepable / preemptive, precise WFI to the earliest deadline when idle; added `CHOSEN_SCHEDULER_TIM` fallback (returns early from `xscheduler_start()` on boards without a chosen tick device, symmetric with the cooperative version). The old "experimental / may not compile" Kconfig note no longer applies.
- **`xtask.h` 对外 API 调整**:新增 `x_scheduler_poll(void)`(无参全局轮询)、`x_task_run_preempt`、`x_scheduler_task_create(name, period_ms, priority, cb, param)`(抢占式带优先级);协调式 `xscheduler_task_create` 签名简化为 `(task, name, cb, period_ms)`。两套实现对外 API 完全一致,调用方无感切换。
**`xtask.h` public API adjusted**: added `x_scheduler_poll(void)` (parameterless global poll), `x_task_run_preempt`, and `x_scheduler_task_create(name, period_ms, priority, cb, param)` (preemptive, priority-aware); the cooperative `xscheduler_task_create` signature is simplified to `(task, name, cb, period_ms)`. Both implementations keep an identical external API — caller code switches transparently.
- **裸机 C++ 任务封装 `(C++ 封装已移除)` 双分支**:`mini_task_create` 按 `CONFIG_XTASK_PREEMPT` 分两分支——协调式 `period` 为周期 ms;抢占式同签名新增 `priority`(数值越大越优先),`stack_size` 在裸机下复用为周期。不再"抢占式整段关闭 C++ 重载"。
**Bare-metal C++ wrapper `(C++ 封装已移除)` dual-branch**: `mini_task_create` now branches on `CONFIG_XTASK_PREEMPT` — cooperative uses `period` as cycle ms; preemptive adds a `priority` arg (higher = more urgent) and reuses `stack_size` as the cycle on bare metal. The C++ wrapper is no longer "fully disabled under preemptive".
- **VFS TIM 新增命令与 inline**:`vfs-tim.h` 新增 `TIM_CMD_CLEAR_UPDATE_FLAG`(第 24 条命令)与 `vfs_tim_fast_clear_update_flag()` inline(ISR 上半部非阻塞清更新标志,无生命周期依赖)。
**VFS TIM new command & inline**: `vfs-tim.h` adds `TIM_CMD_CLEAR_UPDATE_FLAG` (24th command) and `vfs_tim_fast_clear_update_flag()` inline (non-blocking update-flag clear for ISR top halves, no lifetime dependency).
- **`compiler_compat.h` 新增 `MINI_WFI()`**:平台无关低功耗等待封装(Cortex-M `__WFI()` / RISC-V `wfi` / 其他空操作),供调度器空闲精确休眠使用。
**`compiler_compat.h` adds `MINI_WFI()`**: a platform-agnostic wait-for-interrupt wrapper (`__WFI()` on Cortex-M, `wfi` on RISC-V, no-op elsewhere), used by the scheduler's precise idle sleep.
### 工具链 / Toolchain
- **Keil Studio 单独列为支持项**:作者实测确认与经典 µVision 本质不同(VS Code 内核 + CMake 一等公民 + clangd + 官方调试/云编译),推荐作调试(与构建)环境;经典 µVision 维持不推荐、不支持立场。详见 [keil_integration.md](docs/cn/keil_integration.md) §2.1 与 [design_decisions.md](docs/cn/design_decisions.md) 工具链表。
**Keil Studio is now a supported entry on its own**: hands-on verified as fundamentally different from classic µVision (VS Code core + first-class CMake + clangd + official debug/cloud build); recommended as a debug (and build) environment. Classic µVision stays not recommended / unsupported. See [keil_integration.md](docs/cn/keil_integration.md) §2.1 and the toolchain table in [design_decisions.md](docs/cn/design_decisions.md).
### 目标平台 / Targets
- **新增 `PLATFORM_ARM_CM0`(ARM Cortex-M0 / M0+)**:Kconfig 平台选项,三个 OS 后端均可选。FreeRTOS 从官方仓库拉取最新 `ARM_CM0` port(`port.c` + `portasm.c`);RT-Thread 拉取 `cortex-m0` port(`context_gcc.S` + `cpuport.c`)。裸机 / FreeRTOS / RT-Thread 三后端 M0 全量构建实测通过(`-mcpu=cortex-m0 -mthumb`)。
**New `PLATFORM_ARM_CM0` (ARM Cortex-M0 / M0+)**: Kconfig target option, selectable for all three OS backends. FreeRTOS gains the upstream `ARM_CM0` port (`port.c` + `portasm.c`); RT-Thread gains the `cortex-m0` port (`context_gcc.S` + `cpuport.c`). Full-library builds verified on M0 for bare-metal / FreeRTOS / RT-Thread (`-mcpu=cortex-m0 -mthumb`).
- **FreeRTOSConfig.h 按 `__ARM_ARCH_6M__` 自动适配 M0**:无 MPU(`configENABLE_MPU 0`)、禁用 CLZ 优化任务选择(`configUSE_PORT_OPTIMISED_TASK_SELECTION 0`)、NVIC 仅 4 级优先级(`configMAX_SYSCALL_INTERRUPT_PRIORITY 3`);M3/M4F/M7 行为不变。
**FreeRTOSConfig.h auto-adapts to M0 via `__ARM_ARCH_6M__`**: no MPU (`configENABLE_MPU 0`), CLZ-optimised task selection off (`configUSE_PORT_OPTIMISED_TASK_SELECTION 0`), NVIC 4-level priority (`configMAX_SYSCALL_INTERRUPT_PRIORITY 3`); M3/M4F/M7 behavior unchanged.
- **RT-Thread M0 原子操作退回软件实现**:M0/M0+ 无 `LDREX/STREX` 指令,`rtconfig.h` 按 `__ARM_ARCH_6M__` 关闭 `RT_USING_HW_ATOMIC`,由 `rtatomic.h` 内联的 `rt_soft_atomic_*`(关中断)提供,`atomic_arm.c` 不编入。
**RT-Thread M0 falls back to software atomics**: M0/M0+ lacks `LDREX/STREX`; `rtconfig.h` disables `RT_USING_HW_ATOMIC` on `__ARM_ARCH_6M__`, using the inline `rt_soft_atomic_*` (IRQ-lock) implementations and excluding `atomic_arm.c`.
- **修复 `FREERTOS_PORT` 默认值遮蔽 Kconfig 派生**:`lib/CMakeLists.txt` 原写死 `GCC_ARM_CM4F`,导致 `lib/freeRTOS/CMakeLists.txt` 的 Kconfig 平台自动选 port 逻辑永远不执行;现在未通过 `-D` 指定时完全按 `CONFIG_PLATFORM_*` 自动选择。
**Fixed `FREERTOS_PORT` default shadowing Kconfig derivation**: `lib/CMakeLists.txt` hardcoded `GCC_ARM_CM4F`, which made the Kconfig-driven port selection in `lib/freeRTOS/CMakeLists.txt` dead code; the port is now always derived from `CONFIG_PLATFORM_*` unless overridden via `-D`.
---
## [v1.0.0] / 正式版 / Official Release
> **正式版 / Official Release**:平台无关的稳定基线——风格统一、构建可验证、文档双语、生态按需。
> A stable, platform-agnostic baseline: unified coding style, verified builds, bilingual docs, on-demand ecosystem.
>
> 本版核心亮点 / Release highlights:代码风格体系(`.clang-format` + 分层 `.clang-tidy`,app 以下强规定)、全库命名统一(`kTag`→`k_tag`、`struct Event`→`event`、`namespace mini_tree`、`xTask`→`x_task`、`dev`→`pdev` 指针显式化)、通用 CMake 芯片无关路径最小构建实测通过、安全类模块与异构多核 AMP 作为可选积木、全部文档中英双语。
> Coding-style enforcement (`.clang-format` + layered `.clang-tidy`, mandatory below `app/`); repo-wide naming unification (`kTag`→`k_tag`, `struct Event`→`event`, `namespace mini_tree`, `xTask`→`x_task`, `dev`→`pdev` explicit pointers); verified chip-agnostic CMake build; safety modules & heterogeneous AMP as optional bricks; fully bilingual docs.
### 产品驱动与布局 / Product Drivers & Layout
- 37 个产品驱动迁入 `drivers/<chip>/{include,src}`,统一 `DRIVER_REGISTER` + dtc-lite 编译期 probe;不再使用独立 `components/driver_*`(ws2812 为唯一厂商例外)。
The 37 product drivers moved to `drivers/<chip>/{include,src}`, all via `DRIVER_REGISTER` + compile-time probe by dtc-lite; standalone `components/driver_*` is gone (ws2812 is the only vendor exception).
- 板级 DTS/DTSI 外置(`board_port.cmake` 注入);中间件保持纯架构占位——一份 mini 配多 MCU,不硬编码 `board_*` / `IDF_TARGET`。
Board DTS/DTSI externalized (injected via `board_port.cmake`); the middleware stays pure-architecture — one mini tree, many MCUs, no hardcoded `board_*` / `IDF_TARGET`.
### 架构与代码 / Architecture & Code
- HAL 全面 weak 空实现;Bus/VFS 覆盖 gpio/spi/uart/i2c/i2s/can/usb/adc/dac/tim/rtc/iwdg/wwdg;USB 经 TinyUSB + 板级 `usb_tusb_port` 约定。
HAL is fully weak empty implementations; Bus/VFS covers gpio/spi/uart/i2c/i2s/can/usb/adc/dac/tim/rtc/iwdg/wwdg; USB goes through TinyUSB plus the board-level `usb_tusb_port` convention.
- ETL 作为上层 C++ 基础默认链入;`lib/` 仅 vendor FreeRTOS / RT-Thread / ETL,其余积木(TinyUSB / lwIP / cJSON 等)按需 FetchContent。
ETL is the default-linked C++ foundation; `lib/` vendors only FreeRTOS / RT-Thread / ETL, everything else (TinyUSB / lwIP / cJSON…) is FetchContent'd on demand.
- clangd 体系:`compile_flags.txt` + `ide/stubs`,禁止子目录覆盖。
clangd setup: `compile_flags.txt` + `ide/stubs`; per-directory overrides are forbidden.
### 代码风格与命名 / Code Style & Naming
- 新增 `.clang-format`(Allman 大括号、单语句 if/for/while 去大括号、4 空格、100 列、指针靠左)与分层 `.clang-tidy`:根 = 内核区(app 以下非 cpp 全小写无前缀);`app/` 与 `system_cpp/` = Google 区(PascalCase + s_/g_/k_ 前缀);宏全大写(container_of 等少数例外);格式化排除 `lib/`。
New `.clang-format` (Allman braces, no braces for single-statement if/for/while, 4-space, 100 cols, pointer-on-left) and layered `.clang-tidy`: root = kernel zone (all-lowercase below `app/`); `app/` & `system_cpp/` = Google zone (PascalCase + s_/g_/k_ prefixes); macros all-uppercase (a few exceptions like `container_of`); formatting excludes `lib/`.
- 全库命名统一并 clang-tidy 全量扫描清零(`kTag`→`k_tag`、`struct Event/Subscriber`→`event/subscriber`、`namespace MiniTree`→`mini_tree`、`xTask`→`x_task`、`dev`→`pdev` 等)。
Repo-wide naming unification, full clang-tidy scan clean (`kTag`→`k_tag`, `struct Event/Subscriber`→`event/subscriber`, `namespace MiniTree`→`mini_tree`, `xTask`→`x_task`, `dev`→`pdev`, etc.).
### 构建与文档 / Build & Docs
- 通用 CMake 芯片无关路径最小构建实测通过;全部文档中英双语并统一收进 `docs/`(目录页 [docs/README.md](docs/cn/README.md))。
Verified chip-agnostic CMake minimal build; all docs are bilingual and consolidated under `docs/` (index: [docs/README.md](docs/cn/README.md)).
- 补 [LICENSE](LICENSE)(Apache-2.0);[NOTICE](NOTICE) 全面重写(组件版本 / 版权 / SPDX / 合规要点);[CONTRIBUTING.md](CONTRIBUTING.md) 新增 SPDX 头规范。
Added [LICENSE](LICENSE) (Apache-2.0); [NOTICE](NOTICE) fully rewritten (component versions / copyright / SPDX / compliance notes); [CONTRIBUTING.md](CONTRIBUTING.md) gained the SPDX header spec.
---
## [Historical] / 历史
多轮重构(设备树、硬件直投、OSAL、安全回路、文档迁徙等)详见 [docs/design_decisions.md](docs/cn/design_decisions.md)。
Multiple refactoring rounds (device tree, direct hardware mapping, OSAL, safety loops, doc migration, etc.) — see [docs/design_decisions.md](docs/cn/design_decisions.md).
平台验证历史以各 SoC 工程仓库为准。
Platform verification history lives in the per-SoC project repositories.
---
## 相关文档 / Related Documents
- [docs/roadmap.md](docs/cn/roadmap.md) · [docs/todolist.md](docs/cn/todolist.md) · [docs/api_compatibility.md](docs/cn/api_compatibility.md)