From fac9d1c4093a6e8c445c471a28fe131baa774441 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Fri, 2 Oct 2026 11:40:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9A=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20sys=5Fclock=20=E4=B8=BB=E6=9C=BA=E4=BE=A7=E5=8D=95=E6=B5=8B?= =?UTF-8?q?=E5=B9=B6=E4=BF=AE=E5=A4=8D=20Zeller=20=E6=98=9F=E6=9C=9F?= =?UTF-8?q?=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 14 + App/util/README.md | 12 +- App/util/crc.c | 120 - App/util/crc.h | 28 - App/util/ringbuf.c | 154 - App/util/ringbuf.h | 42 - App/util/sys_clock.c | 48 +- docs/README.md | 8 + docs/images/引用关系图.dot | 45 +- docs/images/引用关系图.json | 326 +- docs/images/引用关系图.svg | 5904 ++++++++++++------------ docs/images/引用关系图_模块.dot | 23 +- docs/images/引用关系图_模块.svg | 927 ++-- docs/内存管理/RAM使用分析与优化方案.md | 4 +- docs/审查记录/测试与架构改进建议.md | 674 +++ docs/架构设计/项目架构总览.md | 4 +- docs/测试说明/系统时钟单元测试说明.md | 264 ++ test/host/README.md | 17 +- test/host/sys_clock/run_unit_test.py | 59 + test/host/sys_clock/stub/FreeRTOS.h | 32 + test/host/sys_clock/stub/dbg_log.h | 33 + test/host/sys_clock/stub/main.h | 28 + test/host/sys_clock/stub/task.h | 18 + test/host/sys_clock/sys_clock_test.c | 592 +++ 24 files changed, 5584 insertions(+), 3792 deletions(-) delete mode 100644 App/util/crc.c delete mode 100644 App/util/crc.h delete mode 100644 App/util/ringbuf.c delete mode 100644 App/util/ringbuf.h create mode 100644 docs/审查记录/测试与架构改进建议.md create mode 100644 docs/测试说明/系统时钟单元测试说明.md create mode 100644 test/host/sys_clock/run_unit_test.py create mode 100644 test/host/sys_clock/stub/FreeRTOS.h create mode 100644 test/host/sys_clock/stub/dbg_log.h create mode 100644 test/host/sys_clock/stub/main.h create mode 100644 test/host/sys_clock/stub/task.h create mode 100644 test/host/sys_clock/sys_clock_test.c diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3c366b4b..b183e79f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -162,6 +162,20 @@ repos: files: ^(App/util/task_watchdog\.(c|h)|test/host/watchdog/.*|test/host/common/unit_test_harness\.py)$ pass_filenames: false + # 7b) 系统时钟时间换算主机侧单元测试(2026-10-02 加) + # 背景:sys_clock.c 的 Unix↔日历换算(闰年 / 月末 / 世纪 / 2038 上限)、 + # 星期(Zeller)、"30 天惰性再基准化"(防 49.7 天 tick 回绕)、RTC 故障 + # 降级路径均为纯逻辑;本钩子用 MSVC 离线编译真实源文件(#include 纳入) + # 并以可注入桩驱动(可控时钟 + 阴影 RTC)。首次落地即抓出 Zeller 公式 + # 缺陷(1970~2099 全部日期星期皆错,详见测试说明文档)。 + # files 含 sys_clock.c 依赖的 sd2506.h(时间结构/返回值定义)。 + - id: sys-clock-unit-test + name: 系统时钟换算单测(主机侧) + entry: python test/host/sys_clock/run_unit_test.py + language: system + files: ^(App/util/sys_clock\.(c|h)|Drivers/BSP/SD2506/sd2506\.h|test/host/sys_clock/.*|test/host/common/unit_test_harness\.py)$ + pass_filenames: false + # 8) 测试套件开关门禁(2026-10-01 加) # 背景:test_config.h 的 TEST_SUITE_* 决定固件里编入哪个测试套件, # 全部注释 = 产品构建。但此前**无任何门禁检查**——实测已提交的 HEAD 里 diff --git a/App/util/README.md b/App/util/README.md index 4f9051e3..27121d7c 100644 --- a/App/util/README.md +++ b/App/util/README.md @@ -6,11 +6,14 @@ | 文件 | 作用 | |---|---| -| `crc.c/h` | 校验算法(CRC16/CRC32 等,供 RS-485 协议与数据校验使用) | -| `ringbuf.c/h` | 环形缓冲(SPSC 无锁环形队列,用于串口/数据流收发) | | `sys_clock.c/h` | **墙钟时间管理**:RTC 基准、tick 回绕防护、每 30 天惰性再基准化 | | `task_watchdog.c/h` | **独立看门狗(IWDG)判定状态机**:任务心跳位图 + defaultTask 单一喂狗者 | +> **已删除(2026-10-02)**:`crc.c/h`(CRC-16 Modbus / CRC-8)与 `ringbuf.c/h`(SPSC 环形缓冲) +> 两模块**零调用者**且未编入任何构建——CRC 唯一使用点 `net_cfg_legacy.c` 自带静态 +> `s_crc16_modbus()`,环形缓冲由 `App/log/console_log.c` 内联实现(`s_con_ring`)。 +> 保留只会造成"有统一实现"的误导,故整体移除(详见 `docs/待处理内容.md` E-15 销项)。 + ## 设计要点 ### sys_clock @@ -20,11 +23,6 @@ - RTC 故障时降级到默认时间基准并返回 -1,触发"时钟芯片异常"自检上报 - 设计详见 `docs/子系统设计/系统墙钟时间维护说明.md` -### ringbuf - -- 单生产者单消费者(SPSC)无锁设计,配合 DMA/中断收发 -- 容量为 2 的幂,用掩码取模(避免除法开销) - ### task_watchdog - **任务心跳位图**:各任务只置位(`task_wd_beat`),校验者取走并清零(单字原子,无锁) diff --git a/App/util/crc.c b/App/util/crc.c deleted file mode 100644 index 0df237c6..00000000 --- a/App/util/crc.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 模块名称:CRC Utility - * 模块功能:CRC-16 Modbus (poly=0x8005, init=0xFFFF, refin=true, refout=true, xorout=0x0000) - * CRC-8 (poly=0x07, init=0x00, refin=false, refout=false, xorout=0x00) - * 适用平台:通用嵌入式平台 - * 作者:王建锋 - * 创建日期:2026-07-19 - * 修改记录: - * v1.0 2026-07-19 王建锋 创建初始版本 - */ - -#include "crc.h" - -static const uint16_t s_crc16_table[256] = { - 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, - 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, - 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, - 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, - 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, - 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, - 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, - 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, - 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, - 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, - 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, - 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, - 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, - 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, - 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, - 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, - 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, - 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, - 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, - 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, - 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, - 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, - 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, - 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, - 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, - 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, - 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, - 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, - 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, - 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, - 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, - 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, -}; - -static const uint8_t s_crc8_table[256] = { - 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, - 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, - 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, - 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, - 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, - 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, - 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, - 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, - 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, - 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, - 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, - 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, - 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, - 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, - 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, - 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, - 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, - 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, - 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, - 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, - 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, - 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, - 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, - 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, - 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, - 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, - 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, - 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, - 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, - 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, - 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, - 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3, -}; - -/* - * 函数功能:计算 CRC-16 Modbus - * 入口参数:data - 数据指针 - * len - 数据长度 - * 返 回 值:16 位 CRC 值 - * 限定条件:data 为非空指针 - * 函数说明:多项式 0x8005,初始值 0xFFFF,结果异或 0x0000 - */ -uint16_t crc16_modbus(const uint8_t *data, size_t len) { - uint16_t crc = 0xFFFF; - size_t i; - - for (i = 0; i < len; i++) { - crc = (crc >> 8) ^ s_crc16_table[(crc ^ data[i]) & 0xFF]; - } - - return crc; -} - -/* - * 函数功能:计算 CRC-8 - * 入口参数:data - 数据指针 - * len - 数据长度 - * 返 回 值:8 位 CRC 值 - * 限定条件:data 为非空指针 - * 函数说明:多项式 0x07,初始值 0x00 - */ -uint8_t crc8(const uint8_t *data, size_t len) { - uint8_t crc = 0; - size_t i; - - for (i = 0; i < len; i++) { - crc = s_crc8_table[crc ^ data[i]]; - } - - return crc; -} diff --git a/App/util/crc.h b/App/util/crc.h deleted file mode 100644 index bc3e6787..00000000 --- a/App/util/crc.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 模块名称:CRC Utility - * 模块功能:CRC-16 Modbus & CRC-8 查表计算 - * 适用平台:通用嵌入式平台 - * 作者:王建锋 - * 创建日期:2026-07-19 - * 修改记录: - * v1.0 2026-07-19 王建锋 创建初始版本 - */ - -#ifndef CRC_H -#define CRC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -uint16_t crc16_modbus(const uint8_t *data, size_t len); -uint8_t crc8(const uint8_t *data, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif /* CRC_H */ diff --git a/App/util/ringbuf.c b/App/util/ringbuf.c deleted file mode 100644 index 02d65ec2..00000000 --- a/App/util/ringbuf.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 模块名称:Ring Buffer - * 模块功能:字节环形缓冲区实现,head == tail 为空,head + 1 == tail 为满 - * 适用平台:通用嵌入式平台 - * 作者:王建锋 - * 创建日期:2026-07-19 - * 修改记录: - * v1.0 2026-07-19 王建锋 创建初始版本 - */ - -#include "ringbuf.h" - -/* - * 函数功能:初始化环形缓冲区 - * 入口参数:rb - 缓冲区控制块指针 - * pool - 存储池指针 - * size - 存储池大小(字节) - * 返 回 值:无 - * 限定条件:rb 和 pool 均为非空指针 - * 函数说明:size 保留一个空位用于区分空/满状态 - */ -void ringbuf_init(ringbuf_t *rb, uint8_t *pool, size_t size) { - rb->buf = pool; - rb->size = size; - rb->head = 0; - rb->tail = 0; -} - -/* - * 函数功能:写入数据到环形缓冲区 - * 入口参数:rb - 缓冲区控制块指针 - * data - 源数据指针 - * len - 待写入长度 - * 返 回 值:实际写入字节数 - * 限定条件:rb 和 data 均为非空指针 - * 函数说明:空间不足时写入能容纳的最大字节数 - */ -size_t ringbuf_put(ringbuf_t *rb, const uint8_t *data, size_t len) { - size_t cap = 0; - size_t n = 0; - size_t i = 0; - - cap = rb->size - 1 - ringbuf_avail(rb); - n = (len < cap) ? len : cap; - - for (i = 0; i < n; i++) { - rb->buf[rb->head] = data[i]; - rb->head = (rb->head + 1) % rb->size; - } - - return n; -} - -/* - * 函数功能:从环形缓冲区读取数据 - * 入口参数:rb - 缓冲区控制块指针 - * data - 目标数据指针 - * len - 期望读取长度 - * 返 回 值:实际读取字节数 - * 限定条件:rb 和 data 均为非空指针 - * 函数说明:读取后数据从缓冲区移除 - */ -size_t ringbuf_get(ringbuf_t *rb, uint8_t *data, size_t len) { - size_t n = 0; - size_t i = 0; - - n = ringbuf_avail(rb); - n = (n < len) ? n : len; - - for (i = 0; i < n; i++) { - data[i] = rb->buf[rb->tail]; - rb->tail = (rb->tail + 1) % rb->size; - } - - return n; -} - -/* - * 函数功能:预读取数据(不移除) - * 入口参数:rb - 缓冲区控制块指针 - * data - 目标数据指针 - * len - 期望读取长度 - * 返 回 值:实际可读取字节数 - * 限定条件:rb 和 data 均为非空指针 - * 函数说明:与 ringbuf_get 的区别是不移动 tail 指针 - */ -size_t ringbuf_peek(const ringbuf_t *rb, uint8_t *data, size_t len) { - size_t n = 0; - size_t i = 0; - - n = ringbuf_avail(rb); - n = (n < len) ? n : len; - - for (i = 0; i < n; i++) { - size_t idx = (rb->tail + i) % rb->size; - data[i] = rb->buf[idx]; - } - - return n; -} - -/* - * 函数功能:获取缓冲区中有效数据长度 - * 入口参数:rb - 缓冲区控制块指针 - * 返 回 值:有效数据字节数 - * 限定条件:rb 为非空指针 - */ -size_t ringbuf_avail(const ringbuf_t *rb) { - if (rb->head >= rb->tail) { - return rb->head - rb->tail; - } - return rb->size - rb->tail + rb->head; -} - -/* - * 函数功能:获取缓冲区剩余空间 - * 入口参数:rb - 缓冲区控制块指针 - * 返 回 值:剩余空间字节数(保留一个空位) - * 限定条件:rb 为非空指针 - */ -size_t ringbuf_space(const ringbuf_t *rb) { - return rb->size - 1 - ringbuf_avail(rb); -} - -/* - * 函数功能:判断缓冲区是否为空 - * 入口参数:rb - 缓冲区控制块指针 - * 返 回 值:1 - 空,0 - 非空 - * 限定条件:rb 为非空指针 - */ -int ringbuf_is_empty(const ringbuf_t *rb) { - return (rb->head == rb->tail) ? 1 : 0; -} - -/* - * 函数功能:判断缓冲区是否为满 - * 入口参数:rb - 缓冲区控制块指针 - * 返 回 值:1 - 满,0 - 非满 - * 限定条件:rb 为非空指针 - */ -int ringbuf_is_full(const ringbuf_t *rb) { - return (ringbuf_avail(rb) == rb->size - 1) ? 1 : 0; -} - -/* - * 函数功能:重置缓冲区 - * 入口参数:rb - 缓冲区控制块指针 - * 返 回 值:无 - * 限定条件:rb 为非空指针 - */ -void ringbuf_reset(ringbuf_t *rb) { - rb->head = 0; - rb->tail = 0; -} diff --git a/App/util/ringbuf.h b/App/util/ringbuf.h deleted file mode 100644 index 4b256c34..00000000 --- a/App/util/ringbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 模块名称:Ring Buffer - * 模块功能:线程安全的字节环形缓冲区(单生产者-单消费者模型) - * 适用平台:通用嵌入式平台 - * 作者:王建锋 - * 创建日期:2026-07-19 - * 修改记录: - * v1.0 2026-07-19 王建锋 创建初始版本 - */ - -#ifndef RINGBUF_H -#define RINGBUF_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -typedef struct { - uint8_t *buf; - size_t size; - size_t head; - size_t tail; -} ringbuf_t; - -void ringbuf_init(ringbuf_t *rb, uint8_t *pool, size_t size); -size_t ringbuf_put(ringbuf_t *rb, const uint8_t *data, size_t len); -size_t ringbuf_get(ringbuf_t *rb, uint8_t *data, size_t len); -size_t ringbuf_peek(const ringbuf_t *rb, uint8_t *data, size_t len); -size_t ringbuf_avail(const ringbuf_t *rb); -size_t ringbuf_space(const ringbuf_t *rb); -int ringbuf_is_empty(const ringbuf_t *rb); -int ringbuf_is_full(const ringbuf_t *rb); -void ringbuf_reset(ringbuf_t *rb); - -#ifdef __cplusplus -} -#endif - -#endif /* RINGBUF_H */ diff --git a/App/util/sys_clock.c b/App/util/sys_clock.c index dbe2eca2..afdfb570 100644 --- a/App/util/sys_clock.c +++ b/App/util/sys_clock.c @@ -62,24 +62,41 @@ static volatile uint32_t s_base_unix_secs = UINT32_MAX; /* * 函数功能:根据公历日期计算星期几 * 入口参数:y - 年份 uint16_t 1970~2099 - * m - 月份 uint8_t 1~12 + * m - 月份 uint8_t 1~12(**1-based**,与 sd2506_time_t.month 一致) * d - 日 uint8_t 1~31 * 返回值:星期编号 uint8_t 0=Sunday, 1=Monday, ... 6=Saturday * 限定条件:输入为公历合法日期 - * 函数说明:1. 采用 Zeller 公式(变种),结果 0 表示周日 - * 2. 与 unix_to_sd2506() 内星期算法保持一致 + * 函数说明:1. 采用 Zeller 同余式(Gregorian): + * h = (d + ⌊13(m+1)/5⌋ + K + ⌊K/4⌋ + ⌊J/4⌋ + 5J) mod 7 + * 其中 mm 为调整月(1/2 月按上年 13/14 月处理), + * K = wy % 100,J = wy / 100;h: 0=Saturday, 1=Sunday, ... + * 结果映射 (h+6) mod 7 → 0=Sunday(sd2506 约定)。 + * 注:5J ≡ -2J (mod 7),取 5J 以保证各项非负(无符号安全)。 + * 2. 与 unix_to_sd2506() 内星期算法保持一致(后者按 0-based 月 + * 调用本函数前 +1,切勿再传 0-based 月)。 + * 修改记录: + * 2026-10-02 修正:原式错用 (wy%100 + wy/100/4 - wy/100/15)(缺 K/4、 + * 5J/世纪项,且把 1-based 月当 2-based 用),实测 1970~2099 + * 全部日期星期皆错(主机侧单测 TC-CLK-014/019 发现)。 */ static uint8_t rtc_calc_week(uint16_t y, uint8_t m, uint8_t d) { uint32_t wy = y; - uint32_t wm = m; + uint32_t wm = m; /* wm: 1-based 月,1/2 月上调为 13/14 月 */ - if (wm <= 2) { + if (wm <= 2u) { wy--; wm += 12u; } - /* Zeller 公式:世纪项 + 月项 + 日项,模 7 得星期(0=周日) */ - return (uint8_t)(((uint32_t)(wy % 100u + wy / 100u / 4u - wy / 100u / 15u) + - (uint32_t)((26u * (wm + 1u)) / 10u) + (uint32_t)(d % 100u)) % 7u); + + { + uint32_t K = wy % 100u; + uint32_t J = wy / 100u; + uint32_t h; + /* 各项均非负:d + 月项 + K + K/4 + J/4 + 5J,模 7 得 0=Saturday */ + h = (uint32_t)(d + (13u * (wm + 1u)) / 5u + K + K / 4u + J / 4u + 5u * J) % 7u; + /* h:0=Sat,1=Sun,... → 0=Sun 约定 */ + return (uint8_t)((h + 6u) % 7u); + } } /* @@ -136,17 +153,10 @@ static void unix_to_sd2506(uint32_t unix_secs, sd2506_time_t *p_sd_time) { } d = (uint32_t)(day_count + 1uL); - /* 星期(Zeller's congruence,0=Sunday) */ - uint64_t wy = y; - uint64_t wm = m; - if (wm <= 2) { - wy--; - wm += 12uL; - } - /* Zeller 公式同 rtc_calc_week():世纪项 + 月项 + 日项,模 7 得星期(0=周日) */ - uint8_t week = ((uint32_t)(wy % 100uLL + wy / 100uLL / 4uLL - wy / 100uLL / 15uLL) + - (uint32_t)(((uint64_t)26 * (wm + 1uL)) / 10uLL) + - (uint32_t)(d % 100uLL)) % 7uLL; + /* 星期:复用 rtc_calc_week()(1-based 月;此处 m 为 0-based → 传 m+1) + * 2026-10-02 修正:原内联变种公式有误(与 rtc_calc_week 同缺陷), + * 统一收敛到 rtc_calc_week,避免两处算法再次发散。 */ + uint8_t week = rtc_calc_week((uint16_t)y, (uint8_t)(m + 1u), (uint8_t)d); /* sd2506_time_t.year 采用完整年份(如 2026),与 sd2506_set_time * 中 year-2000、sd2506_get_time 中 +2000 的约定保持一致; diff --git a/docs/README.md b/docs/README.md index 904e561e..7bd917ad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -93,6 +93,13 @@ docs/ | [`测试文档模板规范.md`](测试说明/测试文档模板规范.md) | 测试文档模板与命名规则(TM / TC / DP) | | [`链路延迟测试说明.md`](测试说明/链路延迟测试说明.md) | 网络链路时延分段定义、判定基线、执行流程 | +**主机侧单元测试(L0.5)** + +| 文档 | 内容 | +|---|---| +| [`看门狗单元测试说明.md`](测试说明/看门狗单元测试说明.md) | Task Watchdog 判定状态机(位图 / 掩码 / 节流 / tick 回绕),39 用例 | +| [`系统时钟单元测试说明.md`](测试说明/系统时钟单元测试说明.md) | sys_clock 时间换算 / 星期 Zeller / 30 天惰性再基准化 / RTC 故障降级,100 断言点 | + **模块测试指南**(动手写测试前先读) | 文档 | 内容 | @@ -177,6 +184,7 @@ docs/ | [`项目审查与优化建议报告.md`](审查记录/项目审查与优化建议报告.md) | 项目全景审查:文档/代码/架构/可靠性问题清单(D-1~D-7、N-xx、Px-xx) | | [`项目审计改进清单.md`](审查记录/项目审计改进清单.md) | 审计待办清单(P0~P3,带状态与日期) | | [`下一步任务规划.md`](审查记录/下一步任务规划.md) | **项目状态盘点 + 下一步任务排序(阶段 A/B/C/D)**——每轮迭代后更新盘点 | +| [`测试与架构改进建议.md`](审查记录/测试与架构改进建议.md) | **测试充分性 + 架构改进专项复审**(2026-10-02,纯建议不改码):L0.5 覆盖率缺口、孤儿源文件、错误通道不对称等 S1~S14 实施建议 | ### 8.2 环境与部署 diff --git a/docs/images/引用关系图.dot b/docs/images/引用关系图.dot index 15bf3122..309c92b6 100644 --- a/docs/images/引用关系图.dot +++ b/docs/images/引用关系图.dot @@ -26,12 +26,10 @@ digraph refgraph_full { "App/task/rs485_task.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "App/task/ui_task.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "App/task/ui_task.h" [fillcolor="#dbeafe", color="#1d4ed8"]; - "App/util/crc.c" [fillcolor="#dbeafe", color="#1d4ed8"]; - "App/util/crc.h" [fillcolor="#dbeafe", color="#1d4ed8"]; - "App/util/ringbuf.c" [fillcolor="#dbeafe", color="#1d4ed8"]; - "App/util/ringbuf.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "App/util/sys_clock.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "App/util/sys_clock.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "App/util/task_watchdog.c" [fillcolor="#dbeafe", color="#1d4ed8"]; + "App/util/task_watchdog.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/CH395F/ch395f.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/CH395F/ch395f.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c" [fillcolor="#dbeafe", color="#1d4ed8"]; @@ -99,6 +97,7 @@ digraph refgraph_full { "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h" [fillcolor="#f3f4f6", color="#9ca3af"]; "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h" [fillcolor="#f3f4f6", color="#9ca3af"]; "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h" [fillcolor="#f3f4f6", color="#9ca3af"]; + "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h" [fillcolor="#f3f4f6", color="#9ca3af"]; "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h" [fillcolor="#f3f4f6", color="#9ca3af"]; "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h" [fillcolor="#f3f4f6", color="#9ca3af"]; "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h" [fillcolor="#f3f4f6", color="#9ca3af"]; @@ -108,6 +107,7 @@ digraph refgraph_full { "Inc/dma.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Inc/gpio.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Inc/i2c.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "Inc/iwdg.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Inc/main.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Inc/spi.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Inc/stm32f4xx_hal_conf.h" [fillcolor="#dbeafe", color="#1d4ed8"]; @@ -126,6 +126,7 @@ digraph refgraph_full { "Src/freertos.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Src/gpio.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Src/i2c.c" [fillcolor="#dbeafe", color="#1d4ed8"]; + "Src/iwdg.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Src/main.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Src/spi.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Src/stm32f4xx_hal_msp.c" [fillcolor="#dbeafe", color="#1d4ed8"]; @@ -157,8 +158,13 @@ digraph refgraph_full { "test/board/sd2506_test_task.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "test/board/storage_test.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "test/board/storage_test_task.c" [fillcolor="#dbeafe", color="#1d4ed8"]; + "test/board/test_common.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "test/board/test_config.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "test/board/test_config.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "test/host/watchdog/stub/dbg_log.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "test/host/watchdog/stub/iwdg.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "test/host/watchdog/stub/main.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "test/host/watchdog/watchdog_test.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "外部/系统头文件" [shape=ellipse, fillcolor="#fef3c7", color="#d97706", fontsize=12]; "App/app/app_main.c" -> "App/app/app_cfg.h" [color="#2563eb", penwidth=1.0]; "App/app/app_main.c" -> "App/app/app_main.h" [color="#2563eb", penwidth=1.0]; @@ -170,6 +176,7 @@ digraph refgraph_full { "App/app/app_main.c" -> "Drivers/BSP/TPAFE5160/tpafe5160.h" [color="#2563eb", penwidth=1.0]; "App/app/app_main.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "App/app/app_main.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; + "App/app/app_main.c" -> "Inc/stm32f4xx_it.h" [color="#2563eb", penwidth=1.0]; "App/app/app_main.c" -> "Inc/usart.h" [color="#2563eb", penwidth=1.0]; "App/app/app_main.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "App/app/sys_events.h" -> "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h" [color="#94a3b8", penwidth=0.7]; @@ -202,6 +209,7 @@ digraph refgraph_full { "App/sync/time_sync.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0]; "App/sync/time_sync.c" -> "App/sync/time_sync.h" [color="#2563eb", penwidth=1.0]; "App/sync/time_sync.c" -> "App/util/sys_clock.h" [color="#2563eb", penwidth=1.0]; + "App/sync/time_sync.c" -> "App/util/task_watchdog.h" [color="#2563eb", penwidth=1.0]; "App/sync/time_sync.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0]; "App/sync/time_sync.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "App/sync/time_sync.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; @@ -214,6 +222,7 @@ digraph refgraph_full { "App/task/default_task.c" -> "App/cfg/cfg_file.h" [color="#2563eb", penwidth=1.0]; "App/task/default_task.c" -> "App/log/sys_log.h" [color="#2563eb", penwidth=1.0]; "App/task/default_task.c" -> "App/task/default_task.h" [color="#2563eb", penwidth=1.0]; + "App/task/default_task.c" -> "App/util/task_watchdog.h" [color="#2563eb", penwidth=1.0]; "App/task/default_task.c" -> "Drivers/BSP/GD5F2GQ5UE/nand_ftl.h" [color="#2563eb", penwidth=1.0]; "App/task/default_task.c" -> "Drivers/BSP/NETCFG/net_cfg.h" [color="#2563eb", penwidth=1.0]; "App/task/default_task.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; @@ -226,6 +235,7 @@ digraph refgraph_full { "App/task/net_task.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0]; "App/task/net_task.c" -> "App/log/sys_log.h" [color="#2563eb", penwidth=1.0]; "App/task/net_task.c" -> "App/task/net_task.h" [color="#2563eb", penwidth=1.0]; + "App/task/net_task.c" -> "App/util/task_watchdog.h" [color="#2563eb", penwidth=1.0]; "App/task/net_task.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; "App/task/net_task.c" -> "Drivers/BSP/NET/net_select.h" [color="#2563eb", penwidth=1.0]; "App/task/net_task.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0]; @@ -241,6 +251,7 @@ digraph refgraph_full { "App/task/ui_task.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "App/task/ui_task.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "App/util/sys_clock.h" [color="#2563eb", penwidth=1.0]; + "App/task/ui_task.c" -> "App/util/task_watchdog.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "Drivers/BSP/UI/ui_menu.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "Drivers/BSP/UI/ui_net_sink.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "Drivers/BSP/UI/ui_port.h" [color="#2563eb", penwidth=1.0]; @@ -250,10 +261,6 @@ digraph refgraph_full { "App/task/ui_task.c" -> "test/board/net_latency_test.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0]; "App/task/ui_task.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; - "App/util/crc.c" -> "App/util/crc.h" [color="#2563eb", penwidth=1.0]; - "App/util/crc.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; - "App/util/ringbuf.c" -> "App/util/ringbuf.h" [color="#2563eb", penwidth=1.0]; - "App/util/ringbuf.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "App/util/sys_clock.c" -> "App/util/sys_clock.h" [color="#2563eb", penwidth=1.0]; "App/util/sys_clock.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "App/util/sys_clock.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; @@ -262,6 +269,11 @@ digraph refgraph_full { "App/util/sys_clock.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "App/util/sys_clock.h" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0]; "App/util/sys_clock.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "App/util/task_watchdog.c" -> "App/util/task_watchdog.h" [color="#2563eb", penwidth=1.0]; + "App/util/task_watchdog.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; + "App/util/task_watchdog.c" -> "Inc/iwdg.h" [color="#2563eb", penwidth=1.0]; + "App/util/task_watchdog.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; + "App/util/task_watchdog.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "Drivers/BSP/CH395F/ch395f.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/CH395F/ch395f.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/CH395F/ch395f.c" -> "Inc/spi.h" [color="#2563eb", penwidth=1.0]; @@ -423,6 +435,7 @@ digraph refgraph_full { "Inc/dma.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; "Inc/gpio.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; "Inc/i2c.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; + "Inc/iwdg.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; "Inc/main.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h" [color="#94a3b8", penwidth=0.7]; "Inc/spi.h" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h" [color="#94a3b8", penwidth=0.7]; @@ -431,6 +444,7 @@ digraph refgraph_full { "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h" [color="#94a3b8", penwidth=0.7]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h" [color="#94a3b8", penwidth=0.7]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h" [color="#94a3b8", penwidth=0.7]; + "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h" [color="#94a3b8", penwidth=0.7]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h" [color="#94a3b8", penwidth=0.7]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h" [color="#94a3b8", penwidth=0.7]; "Inc/stm32f4xx_hal_conf.h" -> "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h" [color="#94a3b8", penwidth=0.7]; @@ -457,6 +471,7 @@ digraph refgraph_full { "Src/freertos.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "Src/gpio.c" -> "Inc/gpio.h" [color="#2563eb", penwidth=1.0]; "Src/i2c.c" -> "Inc/i2c.h" [color="#2563eb", penwidth=1.0]; + "Src/iwdg.c" -> "Inc/iwdg.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "App/app/app_main.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "App/util/sys_clock.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; @@ -470,6 +485,7 @@ digraph refgraph_full { "Src/main.c" -> "Inc/dma.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Inc/gpio.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Inc/i2c.h" [color="#2563eb", penwidth=1.0]; + "Src/main.c" -> "Inc/iwdg.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Inc/spi.h" [color="#2563eb", penwidth=1.0]; "Src/main.c" -> "Inc/usart.h" [color="#2563eb", penwidth=1.0]; @@ -511,6 +527,7 @@ digraph refgraph_full { "simulator/sim/ui_net_sink_backend_sim.c" -> "Drivers/BSP/UI/ui_port.h" [color="#2563eb", penwidth=1.0]; "simulator/sim/ui_net_sink_backend_sim.c" -> "Lib/lvgl/lvgl.h" [color="#94a3b8", penwidth=0.7]; "simulator/sim/ui_net_sink_backend_sim.c" -> "simulator/sim/sim_port.h" [color="#2563eb", penwidth=1.0]; + "test/board/ch395f_test.h" -> "test/board/test_common.h" [color="#2563eb", penwidth=1.0]; "test/board/ch395f_test.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/ch395f_test_task.c" -> "App/app/sys_events.h" [color="#2563eb", penwidth=1.0]; "test/board/ch395f_test_task.c" -> "App/task/net_task.h" [color="#2563eb", penwidth=1.0]; @@ -528,6 +545,7 @@ digraph refgraph_full { "test/board/ch395f_test_task.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0]; "test/board/ch395f_test_task.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/gd5f_test.h" -> "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h" [color="#2563eb", penwidth=1.0]; + "test/board/gd5f_test.h" -> "test/board/test_common.h" [color="#2563eb", penwidth=1.0]; "test/board/gd5f_test.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/gd5f_test_task.c" -> "Drivers/BSP/GD5F2GQ5UE/nand_ftl.h" [color="#2563eb", penwidth=1.0]; "test/board/gd5f_test_task.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; @@ -555,6 +573,7 @@ digraph refgraph_full { "test/board/net_test_task.c" -> "test/board/net_latency_test.h" [color="#2563eb", penwidth=1.0]; "test/board/net_test_task.c" -> "test/board/net_test_task.h" [color="#2563eb", penwidth=1.0]; "test/board/net_test_task.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/board/sd2506_test.h" -> "test/board/test_common.h" [color="#2563eb", penwidth=1.0]; "test/board/sd2506_test.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/sd2506_test_task.c" -> "Drivers/BSP/SD2506/sd2506.h" [color="#2563eb", penwidth=1.0]; "test/board/sd2506_test_task.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; @@ -562,6 +581,7 @@ digraph refgraph_full { "test/board/sd2506_test_task.c" -> "test/board/sd2506_test.h" [color="#2563eb", penwidth=1.0]; "test/board/sd2506_test_task.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0]; "test/board/sd2506_test_task.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/board/storage_test.h" -> "test/board/test_common.h" [color="#2563eb", penwidth=1.0]; "test/board/storage_test.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/storage_test_task.c" -> "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h" [color="#2563eb", penwidth=1.0]; "test/board/storage_test_task.c" -> "Drivers/BSP/GD5F2GQ5UE/nand_ftl.h" [color="#2563eb", penwidth=1.0]; @@ -572,6 +592,7 @@ digraph refgraph_full { "test/board/storage_test_task.c" -> "test/board/storage_test.h" [color="#2563eb", penwidth=1.0]; "test/board/storage_test_task.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0]; "test/board/storage_test_task.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/board/test_common.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "test/board/test_config.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "test/board/test_config.c" -> "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h" [color="#94a3b8", penwidth=0.7]; "test/board/test_config.c" -> "test/board/ch395f_test_task.h" [color="#2563eb", penwidth=1.0]; @@ -584,4 +605,12 @@ digraph refgraph_full { "test/board/test_config.h" -> "test/board/sd2506_test.h" [color="#2563eb", penwidth=1.0]; "test/board/test_config.h" -> "test/board/storage_test.h" [color="#2563eb", penwidth=1.0]; "test/board/test_config.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/host/watchdog/stub/dbg_log.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/host/watchdog/stub/iwdg.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/host/watchdog/stub/main.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "test/host/watchdog/watchdog_test.c" -> "App/util/task_watchdog.c" [color="#2563eb", penwidth=1.0]; + "test/host/watchdog/watchdog_test.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; + "test/host/watchdog/watchdog_test.c" -> "Inc/iwdg.h" [color="#2563eb", penwidth=1.0]; + "test/host/watchdog/watchdog_test.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; + "test/host/watchdog/watchdog_test.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; } diff --git a/docs/images/引用关系图.json b/docs/images/引用关系图.json index b9f6d052..fa779a52 100644 --- a/docs/images/引用关系图.json +++ b/docs/images/引用关系图.json @@ -97,22 +97,6 @@ "path": "App/task/ui_task.h", "class": "fp" }, - { - "path": "App/util/crc.c", - "class": "fp" - }, - { - "path": "App/util/crc.h", - "class": "fp" - }, - { - "path": "App/util/ringbuf.c", - "class": "fp" - }, - { - "path": "App/util/ringbuf.h", - "class": "fp" - }, { "path": "App/util/sys_clock.c", "class": "fp" @@ -121,6 +105,14 @@ "path": "App/util/sys_clock.h", "class": "fp" }, + { + "path": "App/util/task_watchdog.c", + "class": "fp" + }, + { + "path": "App/util/task_watchdog.h", + "class": "fp" + }, { "path": "Drivers/BSP/CH395F/ch395f.c", "class": "fp" @@ -585,6 +577,10 @@ "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h", "class": "tp" }, + { + "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h", + "class": "tp" + }, { "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h", "class": "tp" @@ -641,6 +637,10 @@ "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_i2c.h", "class": "tp" }, + { + "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h", + "class": "tp" + }, { "path": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h", "class": "tp" @@ -709,6 +709,10 @@ "path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c", "class": "tp" }, + { + "path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c", + "class": "tp" + }, { "path": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c", "class": "tp" @@ -757,6 +761,10 @@ "path": "Inc/i2c.h", "class": "fp" }, + { + "path": "Inc/iwdg.h", + "class": "fp" + }, { "path": "Inc/main.h", "class": "fp" @@ -4725,6 +4733,10 @@ "path": "Src/i2c.c", "class": "fp" }, + { + "path": "Src/iwdg.c", + "class": "fp" + }, { "path": "Src/main.c", "class": "fp" @@ -5549,6 +5561,10 @@ "path": "test/board/storage_test_task.c", "class": "fp" }, + { + "path": "test/board/test_common.h", + "class": "fp" + }, { "path": "test/board/test_config.c", "class": "fp" @@ -5557,6 +5573,22 @@ "path": "test/board/test_config.h", "class": "fp" }, + { + "path": "test/host/watchdog/stub/dbg_log.h", + "class": "fp" + }, + { + "path": "test/host/watchdog/stub/iwdg.h", + "class": "fp" + }, + { + "path": "test/host/watchdog/stub/main.h", + "class": "fp" + }, + { + "path": "test/host/watchdog/watchdog_test.c", + "class": "fp" + }, { "path": "外部/系统头文件", "class": "ext" @@ -5581,6 +5613,12 @@ "kind": "fp-fp", "include": "main.h" }, + { + "from": "App/app/app_main.c", + "to": "Inc/stm32f4xx_it.h", + "kind": "fp-fp", + "include": "stm32f4xx_it.h" + }, { "from": "App/app/app_main.c", "to": "Inc/usart.h", @@ -5875,6 +5913,12 @@ "kind": "fp-fp", "include": "sys_events.h" }, + { + "from": "App/sync/time_sync.c", + "to": "App/util/task_watchdog.h", + "kind": "fp-fp", + "include": "task_watchdog.h" + }, { "from": "App/sync/time_sync.c", "to": "Drivers/BSP/dbg_log.h", @@ -5989,6 +6033,12 @@ "kind": "fp-fp", "include": "dbg_log.h" }, + { + "from": "App/task/default_task.c", + "to": "App/util/task_watchdog.h", + "kind": "fp-fp", + "include": "task_watchdog.h" + }, { "from": "App/task/net_task.c", "to": "外部/系统头文件", @@ -6049,6 +6099,12 @@ "kind": "fp-fp", "include": "test_config.h" }, + { + "from": "App/task/net_task.c", + "to": "App/util/task_watchdog.h", + "kind": "fp-fp", + "include": "task_watchdog.h" + }, { "from": "App/task/net_task.c", "to": "Drivers/BSP/dbg_log.h", @@ -6145,48 +6201,18 @@ "kind": "fp-fp", "include": "net_latency_test.h" }, + { + "from": "App/task/ui_task.c", + "to": "App/util/task_watchdog.h", + "kind": "fp-fp", + "include": "task_watchdog.h" + }, { "from": "App/task/ui_task.c", "to": "Drivers/BSP/dbg_log.h", "kind": "fp-fp", "include": "dbg_log.h" }, - { - "from": "App/util/crc.c", - "to": "App/util/crc.h", - "kind": "fp-fp", - "include": "crc.h" - }, - { - "from": "App/util/crc.h", - "to": "外部/系统头文件", - "kind": "fp-ext", - "include": "stdint.h" - }, - { - "from": "App/util/crc.h", - "to": "外部/系统头文件", - "kind": "fp-ext", - "include": "stddef.h" - }, - { - "from": "App/util/ringbuf.c", - "to": "App/util/ringbuf.h", - "kind": "fp-fp", - "include": "ringbuf.h" - }, - { - "from": "App/util/ringbuf.h", - "to": "外部/系统头文件", - "kind": "fp-ext", - "include": "stdint.h" - }, - { - "from": "App/util/ringbuf.h", - "to": "外部/系统头文件", - "kind": "fp-ext", - "include": "stddef.h" - }, { "from": "App/util/sys_clock.c", "to": "App/util/sys_clock.h", @@ -6241,6 +6267,36 @@ "kind": "fp-fp", "include": "sd2506.h" }, + { + "from": "App/util/task_watchdog.c", + "to": "App/util/task_watchdog.h", + "kind": "fp-fp", + "include": "task_watchdog.h" + }, + { + "from": "App/util/task_watchdog.c", + "to": "Inc/main.h", + "kind": "fp-fp", + "include": "main.h" + }, + { + "from": "App/util/task_watchdog.c", + "to": "Inc/iwdg.h", + "kind": "fp-fp", + "include": "iwdg.h" + }, + { + "from": "App/util/task_watchdog.c", + "to": "Drivers/BSP/dbg_log.h", + "kind": "fp-fp", + "include": "dbg_log.h" + }, + { + "from": "App/util/task_watchdog.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" + }, { "from": "Drivers/BSP/dbg_log.h", "to": "外部/系统头文件", @@ -8317,6 +8373,12 @@ "kind": "tp-tp", "include": "stm32f4xx_hal_def.h" }, + { + "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h", + "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h", + "kind": "tp-tp", + "include": "stm32f4xx_hal_def.h" + }, { "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h", "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h", @@ -8419,6 +8481,12 @@ "kind": "tp-tp", "include": "stm32f4xx.h" }, + { + "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_iwdg.h", + "to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h", + "kind": "tp-tp", + "include": "stm32f4xx.h" + }, { "from": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_pwr.h", "to": "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h", @@ -8521,6 +8589,12 @@ "kind": "tp-tp", "include": "stm32f4xx_hal.h" }, + { + "from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_iwdg.c", + "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h", + "kind": "tp-tp", + "include": "stm32f4xx_hal.h" + }, { "from": "Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c", "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h", @@ -8593,6 +8667,12 @@ "kind": "fp-fp", "include": "main.h" }, + { + "from": "Inc/iwdg.h", + "to": "Inc/main.h", + "kind": "fp-fp", + "include": "main.h" + }, { "from": "Inc/main.h", "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h", @@ -8757,8 +8837,8 @@ }, { "from": "Inc/stm32f4xx_hal_conf.h", - "to": "外部/系统头文件", - "kind": "fp-ext", + "to": "Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h", + "kind": "fp-tp", "include": "stm32f4xx_hal_iwdg.h" }, { @@ -38749,6 +38829,12 @@ "kind": "fp-fp", "include": "i2c.h" }, + { + "from": "Src/iwdg.c", + "to": "Inc/iwdg.h", + "kind": "fp-fp", + "include": "iwdg.h" + }, { "from": "Src/main.c", "to": "Inc/main.h", @@ -38773,6 +38859,12 @@ "kind": "fp-fp", "include": "i2c.h" }, + { + "from": "Src/main.c", + "to": "Inc/iwdg.h", + "kind": "fp-fp", + "include": "iwdg.h" + }, { "from": "Src/main.c", "to": "Inc/spi.h", @@ -38923,6 +39015,12 @@ "kind": "fp-ext", "include": "stdint.h" }, + { + "from": "test/board/ch395f_test.h", + "to": "test/board/test_common.h", + "kind": "fp-fp", + "include": "test_common.h" + }, { "from": "test/board/ch395f_test_task.c", "to": "外部/系统头文件", @@ -39019,6 +39117,12 @@ "kind": "fp-ext", "include": "stdint.h" }, + { + "from": "test/board/gd5f_test.h", + "to": "test/board/test_common.h", + "kind": "fp-fp", + "include": "test_common.h" + }, { "from": "test/board/gd5f_test.h", "to": "Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h", @@ -39193,6 +39297,12 @@ "kind": "fp-ext", "include": "stdint.h" }, + { + "from": "test/board/sd2506_test.h", + "to": "test/board/test_common.h", + "kind": "fp-fp", + "include": "test_common.h" + }, { "from": "test/board/sd2506_test_task.c", "to": "外部/系统头文件", @@ -39241,6 +39351,12 @@ "kind": "fp-ext", "include": "stdint.h" }, + { + "from": "test/board/storage_test.h", + "to": "test/board/test_common.h", + "kind": "fp-fp", + "include": "test_common.h" + }, { "from": "test/board/storage_test_task.c", "to": "外部/系统头文件", @@ -39295,6 +39411,12 @@ "kind": "fp-fp", "include": "gd5f2gq5ue.h" }, + { + "from": "test/board/test_common.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" + }, { "from": "test/board/test_config.c", "to": "Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h", @@ -39366,6 +39488,60 @@ "to": "test/board/sd2506_test.h", "kind": "fp-fp", "include": "sd2506_test.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdio.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "Inc/main.h", + "kind": "fp-fp", + "include": "main.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "Inc/iwdg.h", + "kind": "fp-fp", + "include": "iwdg.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "Drivers/BSP/dbg_log.h", + "kind": "fp-fp", + "include": "dbg_log.h" + }, + { + "from": "test/host/watchdog/watchdog_test.c", + "to": "App/util/task_watchdog.c", + "kind": "fp-fp", + "include": "task_watchdog.c" + }, + { + "from": "test/host/watchdog/stub/dbg_log.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdio.h" + }, + { + "from": "test/host/watchdog/stub/iwdg.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" + }, + { + "from": "test/host/watchdog/stub/main.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" } ], "unresolved": { @@ -39416,14 +39592,6 @@ "App/task/ui_task.c": [ "string.h" ], - "App/util/crc.h": [ - "stddef.h", - "stdint.h" - ], - "App/util/ringbuf.h": [ - "stddef.h", - "stdint.h" - ], "App/util/sys_clock.c": [ "stdio.h", "string.h" @@ -39431,6 +39599,9 @@ "App/util/sys_clock.h": [ "stdint.h" ], + "App/util/task_watchdog.h": [ + "stdint.h" + ], "Drivers/BSP/CH395F/ch395f.c": [ "stdio.h", "string.h" @@ -39699,7 +39870,6 @@ "stm32f4xx_hal_hcd.h", "stm32f4xx_hal_i2s.h", "stm32f4xx_hal_irda.h", - "stm32f4xx_hal_iwdg.h", "stm32f4xx_hal_lptim.h", "stm32f4xx_hal_ltdc.h", "stm32f4xx_hal_mmc.h", @@ -41092,18 +41262,34 @@ "test/board/storage_test_task.c": [ "string.h" ], + "test/board/test_common.h": [ + "stdint.h" + ], "test/board/test_config.h": [ "stdint.h" + ], + "test/host/watchdog/stub/dbg_log.h": [ + "stdio.h" + ], + "test/host/watchdog/stub/iwdg.h": [ + "stdint.h" + ], + "test/host/watchdog/stub/main.h": [ + "stdint.h" + ], + "test/host/watchdog/watchdog_test.c": [ + "stdint.h", + "stdio.h" ] }, "stats": { - "files_indexed": 1403, - "includes_parsed": 5634, - "resolved": 4579, - "unresolved": 1055, - "nodes_fp": 133, - "nodes_tp": 1256, - "ext_names": 353 + "files_indexed": 1411, + "includes_parsed": 5658, + "resolved": 4601, + "unresolved": 1057, + "nodes_fp": 138, + "nodes_tp": 1259, + "ext_names": 352 }, "include_dirs": [ "Inc", diff --git a/docs/images/引用关系图.svg b/docs/images/引用关系图.svg index 7b964998..8f4adf52 100644 --- a/docs/images/引用关系图.svg +++ b/docs/images/引用关系图.svg @@ -4,3503 +4,3677 @@ - - + + refgraph_full - -STM32F4-Base 项目文件引用关系图(项目代码视图) + +STM32F4-Base 项目文件引用关系图(项目代码视图) App/app/app_cfg.h - -App/app/app_cfg.h + +App/app/app_cfg.h App/app/app_main.c - -App/app/app_main.c + +App/app/app_main.c App/app/app_main.c->App/app/app_cfg.h - - + + App/app/app_main.h - -App/app/app_main.h + +App/app/app_main.h App/app/app_main.c->App/app/app_main.h - - + + App/log/sys_log.h - -App/log/sys_log.h + +App/log/sys_log.h App/app/app_main.c->App/log/sys_log.h - - + + - + App/util/sys_clock.h - -App/util/sys_clock.h + +App/util/sys_clock.h App/app/app_main.c->App/util/sys_clock.h - - + + - + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h App/app/app_main.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + Drivers/BSP/RS485/rs485.h - -Drivers/BSP/RS485/rs485.h + +Drivers/BSP/RS485/rs485.h App/app/app_main.c->Drivers/BSP/RS485/rs485.h - - + + - + Drivers/BSP/SD2506/sd2506.h - -Drivers/BSP/SD2506/sd2506.h + +Drivers/BSP/SD2506/sd2506.h App/app/app_main.c->Drivers/BSP/SD2506/sd2506.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.h - -Drivers/BSP/TPAFE5160/tpafe5160.h + +Drivers/BSP/TPAFE5160/tpafe5160.h App/app/app_main.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Drivers/BSP/dbg_log.h - -Drivers/BSP/dbg_log.h + +Drivers/BSP/dbg_log.h App/app/app_main.c->Drivers/BSP/dbg_log.h - - + + Inc/main.h - -Inc/main.h + +Inc/main.h App/app/app_main.c->Inc/main.h - - - - - -Inc/usart.h - -Inc/usart.h - - - -App/app/app_main.c->Inc/usart.h - - - - - -外部/系统头文件 - -外部/系统头文件 - - - -App/app/app_main.h->外部/系统头文件 - - - - - -App/app/sys_events.h - -App/app/sys_events.h - - - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - - - -App/app/sys_events.h->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - - - - - -App/cfg/cfg_file.c - -App/cfg/cfg_file.c - - - -App/cfg/cfg_file.h - -App/cfg/cfg_file.h - - - -App/cfg/cfg_file.c->App/cfg/cfg_file.h - - - - - -App/cfg/cfg_file_store.h - -App/cfg/cfg_file_store.h - - - -App/cfg/cfg_file.c->App/cfg/cfg_file_store.h - - - - - -App/cfg/cfg_file.c->App/log/sys_log.h - - - - - -App/cfg/cfg_file.c->Drivers/BSP/dbg_log.h - - - - - -App/cfg/cfg_file.c->外部/系统头文件 - - - - - -App/cfg/cfg_file.h->外部/系统头文件 - - - - - -App/cfg/cfg_file_store.h->外部/系统头文件 - - - - - -App/cfg/cfg_file_store_mcu.c - -App/cfg/cfg_file_store_mcu.c - - - -App/cfg/cfg_file_store_mcu.c->App/cfg/cfg_file_store.h - - - - - -Lib/FatFs/ff.h - -Lib/FatFs/ff.h - - - -App/cfg/cfg_file_store_mcu.c->Lib/FatFs/ff.h - - - - - -Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - -Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - -App/cfg/cfg_file_store_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -App/cfg/cfg_file_store_mcu.c->外部/系统头文件 - - - - - -App/log/console_log.c - -App/log/console_log.c - - - -App/log/console_log.c->App/app/sys_events.h - - - - - -App/log/console_log.h - -App/log/console_log.h - - - -App/log/console_log.c->App/log/console_log.h - - - - - -App/log/console_log.c->Inc/usart.h - - - - - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - -App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -Middlewares/Third_Party/FreeRTOS/Source/include/task.h - -Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - -App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -App/log/console_log.c->外部/系统头文件 - - - - - -App/log/console_log.h->外部/系统头文件 - - - - - -App/log/sys_log.h->外部/系统头文件 - - - - - -App/log/sys_log_mcu.c - -App/log/sys_log_mcu.c - - - -App/log/sys_log_mcu.c->App/log/sys_log.h - - - - - -App/log/sys_log_mcu.c->App/util/sys_clock.h - - - - - -App/log/sys_log_mcu.c->Drivers/BSP/dbg_log.h - - - - - -App/log/sys_log_mcu.c->Lib/FatFs/ff.h - - - - - -App/log/sys_log_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/log/sys_log_mcu.c->外部/系统头文件 - - - - - -App/sync/time_sync.c - -App/sync/time_sync.c - - - -App/sync/time_sync.c->App/app/sys_events.h - - - - - -App/sync/time_sync.h - -App/sync/time_sync.h - - - -App/sync/time_sync.c->App/sync/time_sync.h - - - - - -App/sync/time_sync.c->App/util/sys_clock.h - - - - - -Drivers/BSP/NET/net_socket.h - -Drivers/BSP/NET/net_socket.h - - - -App/sync/time_sync.c->Drivers/BSP/NET/net_socket.h - - - - - -App/sync/time_sync.c->Drivers/BSP/dbg_log.h - - - - - -App/sync/time_sync.c->外部/系统头文件 - - - - - -App/sync/time_sync.h->外部/系统头文件 - - - - - -App/task/adc_task.c - -App/task/adc_task.c - - - -App/task/adc_task.h - -App/task/adc_task.h - - - -App/task/adc_task.c->App/task/adc_task.h - - - - - -App/task/adc_task.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - - - - -App/task/adc_task.c->Drivers/BSP/dbg_log.h - - - - - -App/task/adc_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/task/default_task.c - -App/task/default_task.c - - - -App/task/default_task.c->App/app/sys_events.h - - - - - -App/task/default_task.c->App/cfg/cfg_file.h - - - - - -App/task/default_task.c->App/log/sys_log.h - - - - - -App/task/default_task.h - -App/task/default_task.h - - - -App/task/default_task.c->App/task/default_task.h - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - - -App/task/default_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - - - - -Drivers/BSP/NETCFG/net_cfg.h - -Drivers/BSP/NETCFG/net_cfg.h - - - -App/task/default_task.c->Drivers/BSP/NETCFG/net_cfg.h - - - - - -App/task/default_task.c->Drivers/BSP/dbg_log.h - - - - - -App/task/default_task.c->Inc/main.h - - - - - -App/task/default_task.c->Lib/FatFs/ff.h - - - - - -App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -test/board/test_config.h - -test/board/test_config.h - - - -App/task/default_task.c->test/board/test_config.h - - - - - -App/task/net_task.c - -App/task/net_task.c - - - -App/task/net_task.c->App/app/sys_events.h - - - - - -App/task/net_task.c->App/log/sys_log.h - - - - - -App/task/net_task.h - -App/task/net_task.h - - - -App/task/net_task.c->App/task/net_task.h - - - - - -Drivers/BSP/CH395F/ch395f.h - -Drivers/BSP/CH395F/ch395f.h - - - -App/task/net_task.c->Drivers/BSP/CH395F/ch395f.h - - - - - -Drivers/BSP/NET/net_select.h - -Drivers/BSP/NET/net_select.h - - - -App/task/net_task.c->Drivers/BSP/NET/net_select.h - - - - - -App/task/net_task.c->Drivers/BSP/NET/net_socket.h - - - - - -App/task/net_task.c->Drivers/BSP/NETCFG/net_cfg.h - - - - - -App/task/net_task.c->Drivers/BSP/dbg_log.h - - - - - -App/task/net_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/task/net_task.c->test/board/test_config.h - - - - - -App/task/net_task.c->外部/系统头文件 - - - - - -App/task/rs485_task.c - -App/task/rs485_task.c - - - -App/task/rs485_task.h - -App/task/rs485_task.h - - - -App/task/rs485_task.c->App/task/rs485_task.h - - - - - -App/task/rs485_task.c->Drivers/BSP/RS485/rs485.h - - - - - -App/task/rs485_task.c->Drivers/BSP/dbg_log.h - - - - - -App/task/rs485_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -App/task/ui_task.c - -App/task/ui_task.c - - - -App/task/ui_task.c->App/app/sys_events.h - - - - - -App/task/ui_task.h - -App/task/ui_task.h - - - -App/task/ui_task.c->App/task/ui_task.h - - - - - -App/task/ui_task.c->App/util/sys_clock.h - - - - - -Drivers/BSP/UI/ui_menu.h - -Drivers/BSP/UI/ui_menu.h - - - -App/task/ui_task.c->Drivers/BSP/UI/ui_menu.h - - - - - -Drivers/BSP/UI/ui_net_sink.h - -Drivers/BSP/UI/ui_net_sink.h - - - -App/task/ui_task.c->Drivers/BSP/UI/ui_net_sink.h - - - - - -Drivers/BSP/UI/ui_port.h - -Drivers/BSP/UI/ui_port.h - - - -App/task/ui_task.c->Drivers/BSP/UI/ui_port.h - - - - - -Drivers/BSP/UI/ui_standby.h - -Drivers/BSP/UI/ui_standby.h - - - -App/task/ui_task.c->Drivers/BSP/UI/ui_standby.h - - - - - -App/task/ui_task.c->Drivers/BSP/dbg_log.h - - - - - -App/task/ui_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -test/board/net_latency_test.h - -test/board/net_latency_test.h - - - -App/task/ui_task.c->test/board/net_latency_test.h - - - - - -App/task/ui_task.c->test/board/test_config.h - - - - - -App/task/ui_task.c->外部/系统头文件 - - - - - -App/util/crc.c - -App/util/crc.c - - - -App/util/crc.h - -App/util/crc.h - - - -App/util/crc.c->App/util/crc.h - - - - - -App/util/crc.h->外部/系统头文件 - - - - - -App/util/ringbuf.c - -App/util/ringbuf.c - - - -App/util/ringbuf.h - -App/util/ringbuf.h - - - -App/util/ringbuf.c->App/util/ringbuf.h - - - - - -App/util/ringbuf.h->外部/系统头文件 - - - - - -App/util/sys_clock.c - -App/util/sys_clock.c - - - -App/util/sys_clock.c->App/util/sys_clock.h - - - - - -App/util/sys_clock.c->Drivers/BSP/dbg_log.h - - - - - -App/util/sys_clock.c->Inc/main.h - - - - - -App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -App/util/sys_clock.c->外部/系统头文件 - - - - - -App/util/sys_clock.h->Drivers/BSP/SD2506/sd2506.h - - - - - -App/util/sys_clock.h->外部/系统头文件 - - - - - -Drivers/BSP/CH395F/ch395f.c - -Drivers/BSP/CH395F/ch395f.c - - - -Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/CH395F/ch395f.h - - - - - -Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/dbg_log.h - - - - - -Inc/spi.h - -Inc/spi.h - - - -Drivers/BSP/CH395F/ch395f.c->Inc/spi.h - - - - - -Drivers/BSP/CH395F/ch395f.c->Inc/usart.h - - - - - -Drivers/BSP/CH395F/ch395f.c->外部/系统头文件 - - - - - -Drivers/BSP/CH395F/ch395f.h->Inc/main.h - - - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->外部/系统头文件 - - - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->Inc/main.h - - - - - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->外部/系统头文件 - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/dbg_log.h - - - - - -Lib/FatFs/diskio.h - -Lib/FatFs/diskio.h - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/diskio.h - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/ff.h - - - - - -Lib/dhara/map.h - -Lib/dhara/map.h - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/map.h - - - - - -Lib/dhara/nand.h - -Lib/dhara/nand.h - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/nand.h - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->外部/系统头文件 - - - - - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.h->外部/系统头文件 - - - - - -Drivers/BSP/NET/lftpd/lftpd.h - -Drivers/BSP/NET/lftpd/lftpd.h - - - -Drivers/BSP/NET/net_config.h - -Drivers/BSP/NET/net_config.h - - - -Drivers/BSP/NET/net_select.c - -Drivers/BSP/NET/net_select.c - - - -Drivers/BSP/NET/net_select.c->Drivers/BSP/CH395F/ch395f.h - - - - - -Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_select.h - - - - - -Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_socket.h - - - - - -Drivers/BSP/NET/net_select.c->Inc/main.h - - - - - -Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -Drivers/BSP/NET/net_select.c->外部/系统头文件 - - - - - -Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_config.h - - - - - -Drivers/BSP/NET/net_types.h - -Drivers/BSP/NET/net_types.h - - - -Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_types.h - - - - - -Drivers/BSP/NET/net_socket.c - -Drivers/BSP/NET/net_socket.c - - - -Drivers/BSP/NET/net_socket.c->Drivers/BSP/CH395F/ch395f.h - - - - - -Drivers/BSP/NET/net_socket.c->Drivers/BSP/NET/net_socket.h - - - - - -Drivers/BSP/NET/net_socket.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/NET/net_socket.c->Inc/main.h - - - - - -Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - - - - -Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -Drivers/BSP/NET/net_socket.c->test/board/net_latency_test.h - - - - - -Drivers/BSP/NET/net_socket.c->test/board/test_config.h - - - - - -Drivers/BSP/NET/net_socket.c->外部/系统头文件 - - - - - -Drivers/BSP/NET/net_socket.h->Drivers/BSP/NET/net_types.h - - - - - -Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - - - - -Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - - - - -Drivers/BSP/NET/net_types.h->Drivers/BSP/NET/net_config.h - - - - - -Drivers/BSP/NET/net_types.h->外部/系统头文件 - - - - - -Drivers/BSP/NETCFG/net_cfg.c - -Drivers/BSP/NETCFG/net_cfg.c - - - -Drivers/BSP/NETCFG/net_cfg.c->App/cfg/cfg_file.h - - - - - -Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.h - -Drivers/BSP/NETCFG/net_cfg_legacy.h - - - -Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/net_cfg_legacy.h - - - - - -Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/NETCFG/net_cfg.c->外部/系统头文件 - - - - - -Drivers/BSP/NETCFG/net_cfg.h->外部/系统头文件 - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c - -Drivers/BSP/NETCFG/net_cfg_legacy.c - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->App/cfg/cfg_file.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->App/cfg/cfg_file_store.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/NETCFG/net_cfg.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/NETCFG/net_cfg_legacy.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/NETCFG/net_cfg_legacy.c->外部/系统头文件 - - - - - -Drivers/BSP/RS485/rs485.c - -Drivers/BSP/RS485/rs485.c - - - -Drivers/BSP/RS485/rs485.c->Drivers/BSP/RS485/rs485.h - - - - - -Drivers/BSP/RS485/rs485.h->Inc/main.h - - - - - -Drivers/BSP/SD2506/sd2506.c - -Drivers/BSP/SD2506/sd2506.c - - - -Drivers/BSP/SD2506/sd2506.c->Drivers/BSP/SD2506/sd2506.h - - - - - -Inc/i2c.h - -Inc/i2c.h - - - -Drivers/BSP/SD2506/sd2506.c->Inc/i2c.h - - - - - -Drivers/BSP/SD2506/sd2506.c->外部/系统头文件 - - - - - -Drivers/BSP/SD2506/sd2506.h->Inc/main.h - - - - - -Drivers/BSP/TPAFE5160/tpafe5160.c - -Drivers/BSP/TPAFE5160/tpafe5160.c - - - -Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - - - - -Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/TPAFE5160/tpafe5160.c->Inc/main.h - - - - - -Drivers/BSP/TPAFE5160/tpafe5160.h->Inc/main.h - - - - - -Drivers/BSP/UI/ui_content_page.c - -Drivers/BSP/UI/ui_content_page.c - - - -Drivers/BSP/UI/ui_content_page.h - -Drivers/BSP/UI/ui_content_page.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_deco.h - -Drivers/BSP/UI/ui_deco.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_deco.h - - - - - -Drivers/BSP/UI/ui_menu_view.h - -Drivers/BSP/UI/ui_menu_view.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_menu_view.h - - - - - -Drivers/BSP/UI/ui_page_ac.h - -Drivers/BSP/UI/ui_page_ac.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_ac.h - - - - - -Drivers/BSP/UI/ui_page_dc.h - -Drivers/BSP/UI/ui_page_dc.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_dc.h - - - - - -Drivers/BSP/UI/ui_page_device_info.h - -Drivers/BSP/UI/ui_page_device_info.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_device_info.h - - - - - -Drivers/BSP/UI/ui_page_net_cfg.h - -Drivers/BSP/UI/ui_page_net_cfg.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_net_cfg.h - - - - - -Drivers/BSP/UI/ui_page_password.h - -Drivers/BSP/UI/ui_page_password.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_password.h - - - - - -Drivers/BSP/UI/ui_page_runlog.h - -Drivers/BSP/UI/ui_page_runlog.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_runlog.h - - - - - -Drivers/BSP/UI/ui_page_selftest.h - -Drivers/BSP/UI/ui_page_selftest.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_selftest.h - - - - - -Drivers/BSP/UI/ui_pwd_def.h - -Drivers/BSP/UI/ui_pwd_def.h - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_pwd_def.h - - - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_standby.h - - - - - -Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/dbg_log.h - - - - - -Lib/lvgl/lvgl.h - -Lib/lvgl/lvgl.h - - - -Drivers/BSP/UI/ui_content_page.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_content_page.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_content_page.h->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_content_page.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_deco.c - -Drivers/BSP/UI/ui_deco.c - - - -Drivers/BSP/UI/ui_deco.c->Drivers/BSP/UI/ui_deco.h - - - - - -Drivers/BSP/UI/ui_deco.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_deco.h->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_font_cn_12.c - -Drivers/BSP/UI/ui_font_cn_12.c - - - -Drivers/BSP/UI/ui_font_cn_12.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_menu.c - -Drivers/BSP/UI/ui_menu.c - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu.h - - - - - -Drivers/BSP/UI/ui_menu_tab.h - -Drivers/BSP/UI/ui_menu_tab.h - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_tab.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_view.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_page_password.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_pwd_def.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_standby.h - - - - - -Drivers/BSP/UI/ui_menu.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/UI/ui_menu.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_menu.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_menu_tab.c - -Drivers/BSP/UI/ui_menu_tab.c - - - -Drivers/BSP/UI/ui_menu_tab.c->Drivers/BSP/UI/ui_menu_tab.h - - - - - -Drivers/BSP/UI/ui_menu_tab.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_menu_view.c - -Drivers/BSP/UI/ui_menu_view.c - - - -Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_deco.h - - - - - -Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_tab.h - - - - - -Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_view.h - - - - - -Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/UI/ui_menu_view.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_menu_view.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_menu_view.h->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_menu_view.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_net_sink.c - -Drivers/BSP/UI/ui_net_sink.c - - - -Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_socket.h - - - - - -Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_types.h - - - - - -Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink.h - - - - - -Drivers/BSP/UI/ui_net_sink_backend.h - -Drivers/BSP/UI/ui_net_sink_backend.h - - - -Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink_backend.h - - - - - -Drivers/BSP/UI/ui_net_sink.c->test/board/net_latency_test.h - - - - - -Drivers/BSP/UI/ui_net_sink.c->test/board/test_config.h - - - - - -Drivers/BSP/UI/ui_net_sink.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_net_sink.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_net_sink_backend.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c - - - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_net_sink_backend.h - - - - - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_port.h - - - - - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_page_ac.c - -Drivers/BSP/UI/ui_page_ac.c - - - -Drivers/BSP/UI/ui_page_ac.c->Drivers/BSP/UI/ui_page_ac.h - - - - - -Drivers/BSP/UI/ui_page_ac.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_dc.c - -Drivers/BSP/UI/ui_page_dc.c - - - -Drivers/BSP/UI/ui_page_dc.c->Drivers/BSP/UI/ui_page_dc.h - - - - - -Drivers/BSP/UI/ui_page_dc.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_device_info.c - -Drivers/BSP/UI/ui_page_device_info.c - - - -Drivers/BSP/UI/ui_page_device_info.c->Drivers/BSP/UI/ui_page_device_info.h - - - - - -Drivers/BSP/UI/ui_page_device_info.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_net_cfg.c - -Drivers/BSP/UI/ui_page_net_cfg.c - - - -Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h - - - - - -Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/UI/ui_page_net_cfg.h - - - - - -Drivers/BSP/UI/ui_page_net_cfg.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_page_net_cfg.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_password.c - -Drivers/BSP/UI/ui_page_password.c - - - -Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_page_password.h - - - - - -Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_pwd_def.h - - - - - -Drivers/BSP/UI/ui_page_password.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_page_password.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_runlog.c - -Drivers/BSP/UI/ui_page_runlog.c - - - -Drivers/BSP/UI/ui_page_runlog.c->App/log/sys_log.h - - - - - -Drivers/BSP/UI/ui_page_runlog.c->Drivers/BSP/UI/ui_page_runlog.h - - - - - -Drivers/BSP/UI/ui_page_runlog.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_page_runlog.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_page_selftest.c - -Drivers/BSP/UI/ui_page_selftest.c - - - -Drivers/BSP/UI/ui_page_selftest.c->App/log/sys_log.h - - - - - -Drivers/BSP/UI/ui_page_selftest.c->Drivers/BSP/UI/ui_page_selftest.h - - - - - -Drivers/BSP/UI/ui_page_selftest.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_page_selftest.h->Drivers/BSP/UI/ui_content_page.h - - - - - -Drivers/BSP/UI/ui_port.c - -Drivers/BSP/UI/ui_port.c - - - -Drivers/BSP/UI/ui_port.c->Drivers/BSP/UI/ui_port.h - - - - - -Drivers/BSP/UI/ui_port.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/UI/ui_port.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_port.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_port.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_pwd_def.h->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_standby.c - -Drivers/BSP/UI/ui_standby.c - - - -Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_menu_view.h - - - - - -Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_standby.h - - - - - -Drivers/BSP/UI/ui_standby.c->Drivers/BSP/dbg_log.h - - - - - -Drivers/BSP/UI/ui_standby.c->Lib/lvgl/lvgl.h - - - - - -Drivers/BSP/UI/ui_standby.c->外部/系统头文件 - - - - - -Drivers/BSP/UI/ui_standby.h->外部/系统头文件 - - - - - -Drivers/BSP/dbg_cfg.h - -Drivers/BSP/dbg_cfg.h - - - -Drivers/BSP/dbg_log.h->App/log/console_log.h - - - - - -Drivers/BSP/dbg_log.h->App/util/sys_clock.h - - - - - -Drivers/BSP/dbg_log.h->Drivers/BSP/dbg_cfg.h - - - - - -Drivers/BSP/dbg_log.h->外部/系统头文件 - - - - - -Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - -Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - - - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - - - -Inc/FreeRTOSConfig.h - -Inc/FreeRTOSConfig.h - - - -Inc/FreeRTOSConfig.h->外部/系统头文件 - - - - - -Inc/dma.h - -Inc/dma.h - - - -Inc/dma.h->Inc/main.h - - - - - -Inc/gpio.h - -Inc/gpio.h - - - -Inc/gpio.h->Inc/main.h - - - - - -Inc/i2c.h->Inc/main.h - - - - - -Inc/main.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - - - - -Inc/spi.h->Inc/main.h - - - - - -Inc/stm32f4xx_hal_conf.h - -Inc/stm32f4xx_hal_conf.h - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - - - - - -Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - - - - - -Inc/stm32f4xx_hal_conf.h->外部/系统头文件 - - + + Inc/stm32f4xx_it.h - -Inc/stm32f4xx_it.h + +Inc/stm32f4xx_it.h + + + +App/app/app_main.c->Inc/stm32f4xx_it.h + + + + + +Inc/usart.h + +Inc/usart.h + + + +App/app/app_main.c->Inc/usart.h + + + + + +外部/系统头文件 + +外部/系统头文件 + + + +App/app/app_main.h->外部/系统头文件 + + + + + +App/app/sys_events.h + +App/app/sys_events.h + + + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h + + + +App/app/sys_events.h->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h + + + + + +App/cfg/cfg_file.c + +App/cfg/cfg_file.c + + + +App/cfg/cfg_file.h + +App/cfg/cfg_file.h + + + +App/cfg/cfg_file.c->App/cfg/cfg_file.h + + + + + +App/cfg/cfg_file_store.h + +App/cfg/cfg_file_store.h + + + +App/cfg/cfg_file.c->App/cfg/cfg_file_store.h + + + + + +App/cfg/cfg_file.c->App/log/sys_log.h + + + + + +App/cfg/cfg_file.c->Drivers/BSP/dbg_log.h + + + + + +App/cfg/cfg_file.c->外部/系统头文件 + + + + + +App/cfg/cfg_file.h->外部/系统头文件 + + + + + +App/cfg/cfg_file_store.h->外部/系统头文件 + + + + + +App/cfg/cfg_file_store_mcu.c + +App/cfg/cfg_file_store_mcu.c + + + +App/cfg/cfg_file_store_mcu.c->App/cfg/cfg_file_store.h + + + + + +Lib/FatFs/ff.h + +Lib/FatFs/ff.h + + + +App/cfg/cfg_file_store_mcu.c->Lib/FatFs/ff.h + + + + + +Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + +Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + +App/cfg/cfg_file_store_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +App/cfg/cfg_file_store_mcu.c->外部/系统头文件 + + + + + +App/log/console_log.c + +App/log/console_log.c + + + +App/log/console_log.c->App/app/sys_events.h + + + + + +App/log/console_log.h + +App/log/console_log.h + + + +App/log/console_log.c->App/log/console_log.h + + + + + +App/log/console_log.c->Inc/usart.h + + + + + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + +App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Middlewares/Third_Party/FreeRTOS/Source/include/task.h + +Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + +App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +App/log/console_log.c->外部/系统头文件 + + + + + +App/log/console_log.h->外部/系统头文件 + + + + + +App/log/sys_log.h->外部/系统头文件 + + + + + +App/log/sys_log_mcu.c + +App/log/sys_log_mcu.c + + + +App/log/sys_log_mcu.c->App/log/sys_log.h + + + + + +App/log/sys_log_mcu.c->App/util/sys_clock.h + + + + + +App/log/sys_log_mcu.c->Drivers/BSP/dbg_log.h + + + + + +App/log/sys_log_mcu.c->Lib/FatFs/ff.h + + + + + +App/log/sys_log_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/log/sys_log_mcu.c->外部/系统头文件 + + + + + +App/sync/time_sync.c + +App/sync/time_sync.c + + + +App/sync/time_sync.c->App/app/sys_events.h + + + + + +App/sync/time_sync.h + +App/sync/time_sync.h + + + +App/sync/time_sync.c->App/sync/time_sync.h + + + + + +App/sync/time_sync.c->App/util/sys_clock.h + + + + + +App/util/task_watchdog.h + +App/util/task_watchdog.h + + + +App/sync/time_sync.c->App/util/task_watchdog.h + + + + + +Drivers/BSP/NET/net_socket.h + +Drivers/BSP/NET/net_socket.h + + + +App/sync/time_sync.c->Drivers/BSP/NET/net_socket.h + + + + + +App/sync/time_sync.c->Drivers/BSP/dbg_log.h + + + + + +App/sync/time_sync.c->外部/系统头文件 + + + + + +App/sync/time_sync.h->外部/系统头文件 + + + + + +App/task/adc_task.c + +App/task/adc_task.c + + + +App/task/adc_task.h + +App/task/adc_task.h + + + +App/task/adc_task.c->App/task/adc_task.h + + + + + +App/task/adc_task.c->Drivers/BSP/TPAFE5160/tpafe5160.h + + + + + +App/task/adc_task.c->Drivers/BSP/dbg_log.h + + + + + +App/task/adc_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/task/default_task.c + +App/task/default_task.c + + + +App/task/default_task.c->App/app/sys_events.h + + + + + +App/task/default_task.c->App/cfg/cfg_file.h + + + + + +App/task/default_task.c->App/log/sys_log.h + + + + + +App/task/default_task.h + +App/task/default_task.h + + + +App/task/default_task.c->App/task/default_task.h + + + + + +App/task/default_task.c->App/util/task_watchdog.h + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.h + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.h + + + +App/task/default_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h + + + + + +Drivers/BSP/NETCFG/net_cfg.h + +Drivers/BSP/NETCFG/net_cfg.h + + + +App/task/default_task.c->Drivers/BSP/NETCFG/net_cfg.h + + + + + +App/task/default_task.c->Drivers/BSP/dbg_log.h + + + + + +App/task/default_task.c->Inc/main.h + + + + + +App/task/default_task.c->Lib/FatFs/ff.h + + + + + +App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +test/board/test_config.h + +test/board/test_config.h + + + +App/task/default_task.c->test/board/test_config.h + + + + + +App/task/net_task.c + +App/task/net_task.c + + + +App/task/net_task.c->App/app/sys_events.h + + + + + +App/task/net_task.c->App/log/sys_log.h + + + + + +App/task/net_task.h + +App/task/net_task.h + + + +App/task/net_task.c->App/task/net_task.h + + + + + +App/task/net_task.c->App/util/task_watchdog.h + + + + + +Drivers/BSP/CH395F/ch395f.h + +Drivers/BSP/CH395F/ch395f.h + + + +App/task/net_task.c->Drivers/BSP/CH395F/ch395f.h + + + + + +Drivers/BSP/NET/net_select.h + +Drivers/BSP/NET/net_select.h + + + +App/task/net_task.c->Drivers/BSP/NET/net_select.h + + + + + +App/task/net_task.c->Drivers/BSP/NET/net_socket.h + + + + + +App/task/net_task.c->Drivers/BSP/NETCFG/net_cfg.h + + + + + +App/task/net_task.c->Drivers/BSP/dbg_log.h + + + + + +App/task/net_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/task/net_task.c->test/board/test_config.h + + + + + +App/task/net_task.c->外部/系统头文件 + + + + + +App/task/rs485_task.c + +App/task/rs485_task.c + + + +App/task/rs485_task.h + +App/task/rs485_task.h + + + +App/task/rs485_task.c->App/task/rs485_task.h + + + + + +App/task/rs485_task.c->Drivers/BSP/RS485/rs485.h + + + + + +App/task/rs485_task.c->Drivers/BSP/dbg_log.h + + + + + +App/task/rs485_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +App/task/ui_task.c + +App/task/ui_task.c + + + +App/task/ui_task.c->App/app/sys_events.h + + + + + +App/task/ui_task.h + +App/task/ui_task.h + + + +App/task/ui_task.c->App/task/ui_task.h + + + + + +App/task/ui_task.c->App/util/sys_clock.h + + + + + +App/task/ui_task.c->App/util/task_watchdog.h + + + + + +Drivers/BSP/UI/ui_menu.h + +Drivers/BSP/UI/ui_menu.h + + + +App/task/ui_task.c->Drivers/BSP/UI/ui_menu.h + + + + + +Drivers/BSP/UI/ui_net_sink.h + +Drivers/BSP/UI/ui_net_sink.h + + + +App/task/ui_task.c->Drivers/BSP/UI/ui_net_sink.h + + + + + +Drivers/BSP/UI/ui_port.h + +Drivers/BSP/UI/ui_port.h + + + +App/task/ui_task.c->Drivers/BSP/UI/ui_port.h + + + + + +Drivers/BSP/UI/ui_standby.h + +Drivers/BSP/UI/ui_standby.h + + + +App/task/ui_task.c->Drivers/BSP/UI/ui_standby.h + + + + + +App/task/ui_task.c->Drivers/BSP/dbg_log.h + + + + + +App/task/ui_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +test/board/net_latency_test.h + +test/board/net_latency_test.h + + + +App/task/ui_task.c->test/board/net_latency_test.h + + + + + +App/task/ui_task.c->test/board/test_config.h + + + + + +App/task/ui_task.c->外部/系统头文件 + + + + + +App/util/sys_clock.c + +App/util/sys_clock.c + + + +App/util/sys_clock.c->App/util/sys_clock.h + + + + + +App/util/sys_clock.c->Drivers/BSP/dbg_log.h + + + + + +App/util/sys_clock.c->Inc/main.h + + + + + +App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +App/util/sys_clock.c->外部/系统头文件 + + + + + +App/util/sys_clock.h->Drivers/BSP/SD2506/sd2506.h + + + + + +App/util/sys_clock.h->外部/系统头文件 + + + + + +App/util/task_watchdog.c + +App/util/task_watchdog.c + + + +App/util/task_watchdog.c->App/util/task_watchdog.h + + + + + +App/util/task_watchdog.c->Drivers/BSP/dbg_log.h + + + + + +Inc/iwdg.h + +Inc/iwdg.h + + + +App/util/task_watchdog.c->Inc/iwdg.h + + + + + +App/util/task_watchdog.c->Inc/main.h + + + + + +App/util/task_watchdog.h->外部/系统头文件 + + + + + +Drivers/BSP/CH395F/ch395f.c + +Drivers/BSP/CH395F/ch395f.c + + + +Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/CH395F/ch395f.h + + + + + +Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/dbg_log.h + + + + + +Inc/spi.h + +Inc/spi.h + + + +Drivers/BSP/CH395F/ch395f.c->Inc/spi.h + + + + + +Drivers/BSP/CH395F/ch395f.c->Inc/usart.h + + + + + +Drivers/BSP/CH395F/ch395f.c->外部/系统头文件 + + + + + +Drivers/BSP/CH395F/ch395f.h->Inc/main.h + + + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h + + + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->外部/系统头文件 + + + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->Inc/main.h + + + + + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->外部/系统头文件 + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/dbg_log.h + + + + + +Lib/FatFs/diskio.h + +Lib/FatFs/diskio.h + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/diskio.h + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/ff.h + + + + + +Lib/dhara/map.h + +Lib/dhara/map.h + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/map.h + + + + + +Lib/dhara/nand.h + +Lib/dhara/nand.h + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/nand.h + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->外部/系统头文件 + + + + + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.h->外部/系统头文件 + + + + + +Drivers/BSP/NET/lftpd/lftpd.h + +Drivers/BSP/NET/lftpd/lftpd.h + + + +Drivers/BSP/NET/net_config.h + +Drivers/BSP/NET/net_config.h + + + +Drivers/BSP/NET/net_select.c + +Drivers/BSP/NET/net_select.c + + + +Drivers/BSP/NET/net_select.c->Drivers/BSP/CH395F/ch395f.h + + + + + +Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_select.h + + + + + +Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_socket.h + + + + + +Drivers/BSP/NET/net_select.c->Inc/main.h + + + + + +Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +Drivers/BSP/NET/net_select.c->外部/系统头文件 + + + + + +Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_config.h + + + + + +Drivers/BSP/NET/net_types.h + +Drivers/BSP/NET/net_types.h + + + +Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_types.h + + + + + +Drivers/BSP/NET/net_socket.c + +Drivers/BSP/NET/net_socket.c + + + +Drivers/BSP/NET/net_socket.c->Drivers/BSP/CH395F/ch395f.h + + + + + +Drivers/BSP/NET/net_socket.c->Drivers/BSP/NET/net_socket.h + + + + + +Drivers/BSP/NET/net_socket.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/NET/net_socket.c->Inc/main.h + + + + + +Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + + + + + +Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +Drivers/BSP/NET/net_socket.c->test/board/net_latency_test.h + + + + + +Drivers/BSP/NET/net_socket.c->test/board/test_config.h + + + + + +Drivers/BSP/NET/net_socket.c->外部/系统头文件 + + + + + +Drivers/BSP/NET/net_socket.h->Drivers/BSP/NET/net_types.h + + + + + +Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +Drivers/BSP/NET/net_types.h->Drivers/BSP/NET/net_config.h + + + + + +Drivers/BSP/NET/net_types.h->外部/系统头文件 + + + + + +Drivers/BSP/NETCFG/net_cfg.c + +Drivers/BSP/NETCFG/net_cfg.c + + + +Drivers/BSP/NETCFG/net_cfg.c->App/cfg/cfg_file.h + + + + + +Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.h + +Drivers/BSP/NETCFG/net_cfg_legacy.h + + + +Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/net_cfg_legacy.h + + + + + +Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/NETCFG/net_cfg.c->外部/系统头文件 + + + + + +Drivers/BSP/NETCFG/net_cfg.h->外部/系统头文件 + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c + +Drivers/BSP/NETCFG/net_cfg_legacy.c + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->App/cfg/cfg_file.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->App/cfg/cfg_file_store.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/NETCFG/net_cfg.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/NETCFG/net_cfg_legacy.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/NETCFG/net_cfg_legacy.c->外部/系统头文件 + + + + + +Drivers/BSP/RS485/rs485.c + +Drivers/BSP/RS485/rs485.c + + + +Drivers/BSP/RS485/rs485.c->Drivers/BSP/RS485/rs485.h + + + + + +Drivers/BSP/RS485/rs485.h->Inc/main.h + + + + + +Drivers/BSP/SD2506/sd2506.c + +Drivers/BSP/SD2506/sd2506.c + + + +Drivers/BSP/SD2506/sd2506.c->Drivers/BSP/SD2506/sd2506.h + + + + + +Inc/i2c.h + +Inc/i2c.h + + + +Drivers/BSP/SD2506/sd2506.c->Inc/i2c.h + + + + + +Drivers/BSP/SD2506/sd2506.c->外部/系统头文件 + + + + + +Drivers/BSP/SD2506/sd2506.h->Inc/main.h + + + + + +Drivers/BSP/TPAFE5160/tpafe5160.c + +Drivers/BSP/TPAFE5160/tpafe5160.c + + + +Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/TPAFE5160/tpafe5160.h + + + + + +Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/TPAFE5160/tpafe5160.c->Inc/main.h + + + + + +Drivers/BSP/TPAFE5160/tpafe5160.h->Inc/main.h + + + + + +Drivers/BSP/UI/ui_content_page.c + +Drivers/BSP/UI/ui_content_page.c + + + +Drivers/BSP/UI/ui_content_page.h + +Drivers/BSP/UI/ui_content_page.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_deco.h + +Drivers/BSP/UI/ui_deco.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_deco.h + + + + + +Drivers/BSP/UI/ui_menu_view.h + +Drivers/BSP/UI/ui_menu_view.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_menu_view.h + + + + + +Drivers/BSP/UI/ui_page_ac.h + +Drivers/BSP/UI/ui_page_ac.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_ac.h + + + + + +Drivers/BSP/UI/ui_page_dc.h + +Drivers/BSP/UI/ui_page_dc.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_dc.h + + + + + +Drivers/BSP/UI/ui_page_device_info.h + +Drivers/BSP/UI/ui_page_device_info.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_device_info.h + + + + + +Drivers/BSP/UI/ui_page_net_cfg.h + +Drivers/BSP/UI/ui_page_net_cfg.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_net_cfg.h + + + + + +Drivers/BSP/UI/ui_page_password.h + +Drivers/BSP/UI/ui_page_password.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_password.h + + + + + +Drivers/BSP/UI/ui_page_runlog.h + +Drivers/BSP/UI/ui_page_runlog.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_runlog.h + + + + + +Drivers/BSP/UI/ui_page_selftest.h + +Drivers/BSP/UI/ui_page_selftest.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_selftest.h + + + + + +Drivers/BSP/UI/ui_pwd_def.h + +Drivers/BSP/UI/ui_pwd_def.h + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_pwd_def.h + + + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_standby.h + + + + + +Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/dbg_log.h + + + + + +Lib/lvgl/lvgl.h + +Lib/lvgl/lvgl.h + + + +Drivers/BSP/UI/ui_content_page.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_content_page.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_content_page.h->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_content_page.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_deco.c + +Drivers/BSP/UI/ui_deco.c + + + +Drivers/BSP/UI/ui_deco.c->Drivers/BSP/UI/ui_deco.h + + + + + +Drivers/BSP/UI/ui_deco.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_deco.h->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_font_cn_12.c + +Drivers/BSP/UI/ui_font_cn_12.c + + + +Drivers/BSP/UI/ui_font_cn_12.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_menu.c + +Drivers/BSP/UI/ui_menu.c + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu.h + + + + + +Drivers/BSP/UI/ui_menu_tab.h + +Drivers/BSP/UI/ui_menu_tab.h + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_tab.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_view.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_page_password.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_pwd_def.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_standby.h + + + + + +Drivers/BSP/UI/ui_menu.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/UI/ui_menu.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_menu.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_menu_tab.c + +Drivers/BSP/UI/ui_menu_tab.c + + + +Drivers/BSP/UI/ui_menu_tab.c->Drivers/BSP/UI/ui_menu_tab.h + + + + + +Drivers/BSP/UI/ui_menu_tab.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_menu_view.c + +Drivers/BSP/UI/ui_menu_view.c + + + +Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_deco.h + + + + + +Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_tab.h + + + + + +Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_view.h + + + + + +Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/UI/ui_menu_view.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_menu_view.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_menu_view.h->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_menu_view.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_net_sink.c + +Drivers/BSP/UI/ui_net_sink.c + + + +Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_socket.h + + + + + +Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_types.h + + + + + +Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink.h + + + + + +Drivers/BSP/UI/ui_net_sink_backend.h + +Drivers/BSP/UI/ui_net_sink_backend.h + + + +Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink_backend.h + + + + + +Drivers/BSP/UI/ui_net_sink.c->test/board/net_latency_test.h + + + + + +Drivers/BSP/UI/ui_net_sink.c->test/board/test_config.h + + + + + +Drivers/BSP/UI/ui_net_sink.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_net_sink.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_net_sink_backend.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c + + + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_net_sink_backend.h + + + + + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_port.h + + + + + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_page_ac.c + +Drivers/BSP/UI/ui_page_ac.c + + + +Drivers/BSP/UI/ui_page_ac.c->Drivers/BSP/UI/ui_page_ac.h + + + + + +Drivers/BSP/UI/ui_page_ac.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_dc.c + +Drivers/BSP/UI/ui_page_dc.c + + + +Drivers/BSP/UI/ui_page_dc.c->Drivers/BSP/UI/ui_page_dc.h + + + + + +Drivers/BSP/UI/ui_page_dc.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_device_info.c + +Drivers/BSP/UI/ui_page_device_info.c + + + +Drivers/BSP/UI/ui_page_device_info.c->Drivers/BSP/UI/ui_page_device_info.h + + + + + +Drivers/BSP/UI/ui_page_device_info.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_net_cfg.c + +Drivers/BSP/UI/ui_page_net_cfg.c + + + +Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h + + + + + +Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/UI/ui_page_net_cfg.h + + + + + +Drivers/BSP/UI/ui_page_net_cfg.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_page_net_cfg.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_password.c + +Drivers/BSP/UI/ui_page_password.c + + + +Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_page_password.h + + + + + +Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_pwd_def.h + + + + + +Drivers/BSP/UI/ui_page_password.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_page_password.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_runlog.c + +Drivers/BSP/UI/ui_page_runlog.c + + + +Drivers/BSP/UI/ui_page_runlog.c->App/log/sys_log.h + + + + + +Drivers/BSP/UI/ui_page_runlog.c->Drivers/BSP/UI/ui_page_runlog.h + + + + + +Drivers/BSP/UI/ui_page_runlog.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_page_runlog.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_page_selftest.c + +Drivers/BSP/UI/ui_page_selftest.c + + + +Drivers/BSP/UI/ui_page_selftest.c->App/log/sys_log.h + + + + + +Drivers/BSP/UI/ui_page_selftest.c->Drivers/BSP/UI/ui_page_selftest.h + + + + + +Drivers/BSP/UI/ui_page_selftest.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_page_selftest.h->Drivers/BSP/UI/ui_content_page.h + + + + + +Drivers/BSP/UI/ui_port.c + +Drivers/BSP/UI/ui_port.c + + + +Drivers/BSP/UI/ui_port.c->Drivers/BSP/UI/ui_port.h + + + + + +Drivers/BSP/UI/ui_port.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/UI/ui_port.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_port.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_port.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_pwd_def.h->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_standby.c + +Drivers/BSP/UI/ui_standby.c + + + +Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_menu_view.h + + + + + +Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_standby.h + + + + + +Drivers/BSP/UI/ui_standby.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/UI/ui_standby.c->Lib/lvgl/lvgl.h + + + + + +Drivers/BSP/UI/ui_standby.c->外部/系统头文件 + + + + + +Drivers/BSP/UI/ui_standby.h->外部/系统头文件 + + + + + +Drivers/BSP/dbg_cfg.h + +Drivers/BSP/dbg_cfg.h + + + +Drivers/BSP/dbg_log.h->App/log/console_log.h + + + + + +Drivers/BSP/dbg_log.h->App/util/sys_clock.h + + + + + +Drivers/BSP/dbg_log.h->Drivers/BSP/dbg_cfg.h + + + + + +Drivers/BSP/dbg_log.h->外部/系统头文件 + + + + + +Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h + +Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h + + + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h + + + +Inc/FreeRTOSConfig.h + +Inc/FreeRTOSConfig.h + + + +Inc/FreeRTOSConfig.h->外部/系统头文件 + + + + + +Inc/dma.h + +Inc/dma.h + + + +Inc/dma.h->Inc/main.h + + + + + +Inc/gpio.h + +Inc/gpio.h + + + +Inc/gpio.h->Inc/main.h + + + + + +Inc/i2c.h->Inc/main.h + + + + + +Inc/iwdg.h->Inc/main.h + + + + + +Inc/main.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + + + + + +Inc/spi.h->Inc/main.h + + + + + +Inc/stm32f4xx_hal_conf.h + +Inc/stm32f4xx_hal_conf.h + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h + + + + + +Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h + + + + + +Inc/stm32f4xx_hal_conf.h->外部/系统头文件 + + - + Inc/usart.h->Inc/main.h - - + + Src/dma.c - -Src/dma.c + +Src/dma.c - + Src/dma.c->Inc/dma.h - - + + Src/freertos.c - -Src/freertos.c + +Src/freertos.c - + Src/freertos.c->App/app/sys_events.h - - + + - + Src/freertos.c->App/sync/time_sync.h - - + + - + Src/freertos.c->App/task/default_task.h - - + + - + Src/freertos.c->App/task/net_task.h - - + + - + Src/freertos.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Src/freertos.c->Drivers/BSP/NET/lftpd/lftpd.h - - + + - + Src/freertos.c->Drivers/BSP/NET/net_socket.h - - + + - + Src/freertos.c->Drivers/BSP/dbg_log.h - - + + - + Src/freertos.c->Inc/main.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + test/board/ch395f_test.h - -test/board/ch395f_test.h + +test/board/ch395f_test.h - + Src/freertos.c->test/board/ch395f_test.h - - + + - + test/board/ch395f_test_task.h - -test/board/ch395f_test_task.h + +test/board/ch395f_test_task.h - + Src/freertos.c->test/board/ch395f_test_task.h - - + + - + Src/freertos.c->test/board/test_config.h - - + + - + Src/freertos.c->外部/系统头文件 - - + + Src/gpio.c - -Src/gpio.c + +Src/gpio.c - + Src/gpio.c->Inc/gpio.h - - + + Src/i2c.c - -Src/i2c.c + +Src/i2c.c - + Src/i2c.c->Inc/i2c.h - - + + + + + +Src/iwdg.c + +Src/iwdg.c + + + +Src/iwdg.c->Inc/iwdg.h + + - + Src/main.c - -Src/main.c + +Src/main.c - + Src/main.c->App/app/app_main.h - - + + - + Src/main.c->App/util/sys_clock.h - - + + - + Src/main.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Src/main.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + Src/main.c->Drivers/BSP/NET/net_select.h - - + + - + Src/main.c->Drivers/BSP/NET/net_socket.h - - + + - + Src/main.c->Drivers/BSP/RS485/rs485.h - - + + - + Src/main.c->Drivers/BSP/SD2506/sd2506.h - - + + - + Src/main.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Src/main.c->Drivers/BSP/dbg_log.h - - + + - + Src/main.c->Inc/dma.h - - + + - + Src/main.c->Inc/gpio.h - - + + - + Src/main.c->Inc/i2c.h - - + + + + + +Src/main.c->Inc/iwdg.h + + - + Src/main.c->Inc/main.h - - + + - + Src/main.c->Inc/spi.h - - + + - + Src/main.c->Inc/usart.h - - + + - + Src/main.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Src/main.c->外部/系统头文件 - - + + - + Src/spi.c - -Src/spi.c + +Src/spi.c - + Src/spi.c->Inc/spi.h - - + + - + Src/stm32f4xx_hal_msp.c - -Src/stm32f4xx_hal_msp.c + +Src/stm32f4xx_hal_msp.c - + Src/stm32f4xx_hal_msp.c->Inc/main.h - - + + - + Src/stm32f4xx_hal_timebase_tim.c - -Src/stm32f4xx_hal_timebase_tim.c + +Src/stm32f4xx_hal_timebase_tim.c - + Src/stm32f4xx_hal_timebase_tim.c->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - + + - + Src/stm32f4xx_hal_timebase_tim.c->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - - + + - + Src/stm32f4xx_it.c - -Src/stm32f4xx_it.c + +Src/stm32f4xx_it.c - + Src/stm32f4xx_it.c->Inc/main.h - - + + - + Src/stm32f4xx_it.c->Inc/stm32f4xx_it.h - - + + - + Src/stm32f4xx_it.c->Inc/usart.h - - + + - + Src/system_stm32f4xx.c - -Src/system_stm32f4xx.c + +Src/system_stm32f4xx.c - + Src/system_stm32f4xx.c->Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - - + + - + Src/usart.c - -Src/usart.c + +Src/usart.c - + Src/usart.c->Inc/usart.h - - + + - + simulator/SDL2/SDL2-2.32.10/include/SDL.h - -simulator/SDL2/SDL2-2.32.10/include/SDL.h + +simulator/SDL2/SDL2-2.32.10/include/SDL.h - + simulator/dbg_log.h - -simulator/dbg_log.h + +simulator/dbg_log.h - + simulator/dbg_log.h->外部/系统头文件 - - + + - + simulator/lv_conf.h - -simulator/lv_conf.h + +simulator/lv_conf.h - + simulator/main.c - -simulator/main.c + +simulator/main.c - + simulator/main.c->App/cfg/cfg_file.h - - + + - + simulator/main.c->App/cfg/cfg_file_store.h - - + + - + simulator/main.c->App/log/sys_log.h - - + + - + simulator/main.c->Drivers/BSP/NETCFG/net_cfg.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_menu.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_net_sink.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_standby.h - - + + - + simulator/main.c->Lib/lvgl/lvgl.h - - + + - + simulator/main.c->simulator/SDL2/SDL2-2.32.10/include/SDL.h - - + + - + simulator/sim/sim_port.h - -simulator/sim/sim_port.h + +simulator/sim/sim_port.h - + simulator/main.c->simulator/sim/sim_port.h - - + + - + simulator/main.c->外部/系统头文件 - - + + - + simulator/sim/cfg_file_store_sim.c - -simulator/sim/cfg_file_store_sim.c + +simulator/sim/cfg_file_store_sim.c - + simulator/sim/cfg_file_store_sim.c->App/cfg/cfg_file_store.h - - + + - + simulator/sim/cfg_file_store_sim.c->外部/系统头文件 - - + + - + simulator/sim/net_socket_sim.c - -simulator/sim/net_socket_sim.c + +simulator/sim/net_socket_sim.c - + simulator/sim/net_socket_sim.c->Drivers/BSP/NET/net_socket.h - - + + - + simulator/sim/net_socket_sim.c->外部/系统头文件 - - + + - + simulator/sim/sim_latency_stub.c - -simulator/sim/sim_latency_stub.c + +simulator/sim/sim_latency_stub.c - + simulator/sim/sim_latency_stub.c->test/board/net_latency_test.h - - + + - + simulator/sim/sim_port.c - -simulator/sim/sim_port.c + +simulator/sim/sim_port.c - + simulator/sim/sim_port.c->Lib/lvgl/lvgl.h - - + + - + simulator/sim/sim_port.c->simulator/SDL2/SDL2-2.32.10/include/SDL.h - - + + - + simulator/sim/sim_port.c->simulator/sim/sim_port.h - - + + - + simulator/sim/sim_port.h->外部/系统头文件 - - + + - + simulator/sim/sim_syslog.c - -simulator/sim/sim_syslog.c + +simulator/sim/sim_syslog.c - + simulator/sim/sim_syslog.c->App/log/sys_log.h - - + + - + simulator/sim/sim_syslog.c->外部/系统头文件 - - + + - + simulator/sim/ui_net_sink_backend_sim.c - -simulator/sim/ui_net_sink_backend_sim.c + +simulator/sim/ui_net_sink_backend_sim.c - + simulator/sim/ui_net_sink_backend_sim.c->Drivers/BSP/UI/ui_net_sink_backend.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->Drivers/BSP/UI/ui_port.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->Lib/lvgl/lvgl.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->simulator/sim/sim_port.h - - + + + + + +test/board/test_common.h + +test/board/test_common.h + + + +test/board/ch395f_test.h->test/board/test_common.h + + - + test/board/ch395f_test.h->外部/系统头文件 - - + + - + test/board/ch395f_test_task.c - -test/board/ch395f_test_task.c + +test/board/ch395f_test_task.c - + test/board/ch395f_test_task.c->App/app/sys_events.h - - + + - + test/board/ch395f_test_task.c->App/task/net_task.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/CH395F/ch395f.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/ch395f_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/ch395f_test_task.c->test/board/ch395f_test.h - - + + - + test/board/ch395f_test_task.c->test/board/ch395f_test_task.h - - + + - + test/board/gd5f_test.h - -test/board/gd5f_test.h + +test/board/gd5f_test.h - + test/board/ch395f_test_task.c->test/board/gd5f_test.h - - + + - + test/board/ch395f_test_task.c->test/board/net_latency_test.h - - + + - + test/board/net_test_task.h - -test/board/net_test_task.h + +test/board/net_test_task.h - + test/board/ch395f_test_task.c->test/board/net_test_task.h - - + + - + test/board/sd2506_test.h - -test/board/sd2506_test.h + +test/board/sd2506_test.h - + test/board/ch395f_test_task.c->test/board/sd2506_test.h - - + + - + test/board/storage_test.h - -test/board/storage_test.h + +test/board/storage_test.h - + test/board/ch395f_test_task.c->test/board/storage_test.h - - + + - + test/board/ch395f_test_task.c->test/board/test_config.h - - + + - + test/board/ch395f_test_task.c->外部/系统头文件 - - + + - + test/board/gd5f_test.h->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + + + + +test/board/gd5f_test.h->test/board/test_common.h + + - + test/board/gd5f_test.h->外部/系统头文件 - - + + - + test/board/gd5f_test_task.c - -test/board/gd5f_test_task.c + +test/board/gd5f_test_task.c - + test/board/gd5f_test_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - + + - + test/board/gd5f_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/gd5f_test_task.c->Lib/FatFs/ff.h - - + + - + test/board/gd5f_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + test/board/gd5f_test_task.c->test/board/gd5f_test.h - - + + - + test/board/gd5f_test_task.c->test/board/test_config.h - - + + - + test/board/gd5f_test_task.c->外部/系统头文件 - - + + - + test/board/net_latency_test.c - -test/board/net_latency_test.c + +test/board/net_latency_test.c - + test/board/net_latency_test.c->Drivers/BSP/CH395F/ch395f.h - - + + - + test/board/net_latency_test.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/net_latency_test.c->Drivers/BSP/dbg_log.h - - + + - + test/board/net_latency_test.c->Inc/main.h - - + + - + test/board/net_latency_test.c->test/board/ch395f_test.h - - + + - + test/board/net_latency_test.c->test/board/net_latency_test.h - - + + - + test/board/net_latency_test.c->test/board/test_config.h - - + + - + test/board/net_latency_test.c->外部/系统头文件 - - + + - + test/board/net_latency_test.h->外部/系统头文件 - - + + - + test/board/net_test_task.c - -test/board/net_test_task.c + +test/board/net_test_task.c - + test/board/net_test_task.c->Drivers/BSP/NET/net_select.h - - + + - + test/board/net_test_task.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/net_test_task.c->Drivers/BSP/NET/net_types.h - - + + - + test/board/net_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/net_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/net_test_task.c->test/board/ch395f_test.h - - + + - + test/board/net_test_task.c->test/board/ch395f_test_task.h - - + + - + test/board/net_test_task.c->test/board/net_latency_test.h - - + + - + test/board/net_test_task.c->test/board/net_test_task.h - - + + - + test/board/net_test_task.c->外部/系统头文件 - - + + + + + +test/board/sd2506_test.h->test/board/test_common.h + + - + test/board/sd2506_test.h->外部/系统头文件 - - + + - + test/board/sd2506_test_task.c - -test/board/sd2506_test_task.c + +test/board/sd2506_test_task.c - + test/board/sd2506_test_task.c->Drivers/BSP/SD2506/sd2506.h - - + + - + test/board/sd2506_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/sd2506_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/sd2506_test_task.c->test/board/sd2506_test.h - - + + - + test/board/sd2506_test_task.c->test/board/test_config.h - - + + - + test/board/sd2506_test_task.c->外部/系统头文件 - - + + + + + +test/board/storage_test.h->test/board/test_common.h + + - + test/board/storage_test.h->外部/系统头文件 - - + + - + test/board/storage_test_task.c - -test/board/storage_test_task.c + +test/board/storage_test_task.c - + test/board/storage_test_task.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + test/board/storage_test_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - + + - + test/board/storage_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/storage_test_task.c->Inc/main.h - - + + - + test/board/storage_test_task.c->Lib/FatFs/diskio.h - - + + - + test/board/storage_test_task.c->Lib/FatFs/ff.h - - + + - + test/board/storage_test_task.c->test/board/storage_test.h - - + + - + test/board/storage_test_task.c->test/board/test_config.h - - + + - + test/board/storage_test_task.c->外部/系统头文件 - - + + + + + +test/board/test_common.h->外部/系统头文件 + + - + test/board/test_config.c - -test/board/test_config.c + +test/board/test_config.c - + test/board/test_config.c->Drivers/BSP/dbg_log.h - - + + - + test/board/test_config.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/test_config.c->test/board/ch395f_test_task.h - - + + - + test/board/test_config.c->test/board/gd5f_test.h - - + + - + test/board/test_config.c->test/board/sd2506_test.h - - + + - + test/board/test_config.c->test/board/storage_test.h - - + + - + test/board/test_config.c->test/board/test_config.h - - + + - + test/board/test_config.h->test/board/ch395f_test.h - - + + - + test/board/test_config.h->test/board/gd5f_test.h - - + + - + test/board/test_config.h->test/board/sd2506_test.h - - + + - + test/board/test_config.h->test/board/storage_test.h - - + + - + test/board/test_config.h->外部/系统头文件 - - + + + + + +test/host/watchdog/stub/dbg_log.h + +test/host/watchdog/stub/dbg_log.h + + + +test/host/watchdog/stub/dbg_log.h->外部/系统头文件 + + + + + +test/host/watchdog/stub/iwdg.h + +test/host/watchdog/stub/iwdg.h + + + +test/host/watchdog/stub/iwdg.h->外部/系统头文件 + + + + + +test/host/watchdog/stub/main.h + +test/host/watchdog/stub/main.h + + + +test/host/watchdog/stub/main.h->外部/系统头文件 + + + + + +test/host/watchdog/watchdog_test.c + +test/host/watchdog/watchdog_test.c + + + +test/host/watchdog/watchdog_test.c->App/util/task_watchdog.c + + + + + +test/host/watchdog/watchdog_test.c->Drivers/BSP/dbg_log.h + + + + + +test/host/watchdog/watchdog_test.c->Inc/iwdg.h + + + + + +test/host/watchdog/watchdog_test.c->Inc/main.h + + + + + +test/host/watchdog/watchdog_test.c->外部/系统头文件 + + diff --git a/docs/images/引用关系图_模块.dot b/docs/images/引用关系图_模块.dot index c3518522..325c823b 100644 --- a/docs/images/引用关系图_模块.dot +++ b/docs/images/引用关系图_模块.dot @@ -29,7 +29,7 @@ digraph refgraph_module { "其他(第三方)" [fillcolor="#f3f4f6", color="#9ca3af"]; "外部/系统头文件" [shape=ellipse, fillcolor="#fef3c7", color="#d97706"]; "App" -> "App/log" [color="#2563eb", penwidth=1.2, label="×2"]; - "App" -> "App/util" [color="#2563eb", penwidth=1.2, label="×2"]; + "App" -> "App/util" [color="#2563eb", penwidth=1.2, label="×3"]; "App" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×3"]; "App" -> "BSP/GD5F2GQ5UE" [color="#2563eb", penwidth=1.2, label="×1"]; "App" -> "BSP/NET" [color="#2563eb", penwidth=1.2, label="×1"]; @@ -38,7 +38,7 @@ digraph refgraph_module { "App" -> "BSP/TPAFE5160" [color="#2563eb", penwidth=1.2, label="×1"]; "App" -> "FatFs" [color="#2563eb", penwidth=1.2, label="×1"]; "App" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×2"]; - "App" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×2"]; + "App" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×3"]; "App" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×7"]; "App/log" -> "App" [color="#2563eb", penwidth=1.2, label="×1"]; "App/log" -> "App/util" [color="#2563eb", penwidth=1.2, label="×1"]; @@ -49,7 +49,7 @@ digraph refgraph_module { "App/log" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; "App/task" -> "App" [color="#2563eb", penwidth=1.2, label="×4"]; "App/task" -> "App/log" [color="#2563eb", penwidth=1.2, label="×2"]; - "App/task" -> "App/util" [color="#2563eb", penwidth=1.2, label="×1"]; + "App/task" -> "App/util" [color="#2563eb", penwidth=1.2, label="×4"]; "App/task" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×5"]; "App/task" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×1"]; "App/task" -> "BSP/GD5F2GQ5UE" [color="#2563eb", penwidth=1.2, label="×1"]; @@ -63,11 +63,11 @@ digraph refgraph_module { "App/task" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×1"]; "App/task" -> "test" [color="#2563eb", penwidth=1.2, label="×4"]; "App/task" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×2"]; - "App/util" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"]; + "App/util" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×2"]; "App/util" -> "BSP/SD2506" [color="#2563eb", penwidth=1.2, label="×1"]; "App/util" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×2"]; - "App/util" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×1"]; - "App/util" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; + "App/util" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×3"]; + "App/util" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×3"]; "BSP(公共)" -> "App/log" [color="#2563eb", penwidth=1.2, label="×1"]; "BSP(公共)" -> "App/util" [color="#2563eb", penwidth=1.2, label="×1"]; "BSP(公共)" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×1"]; @@ -109,7 +109,7 @@ digraph refgraph_module { "FreeRTOS" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×1"]; "FreeRTOS" -> "Src/Inc (CubeMX)" [color="#94a3b8", penwidth=0.7, label="×1"]; "FreeRTOS" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×14"]; - "HAL" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×13"]; + "HAL" -> "CMSIS" [color="#94a3b8", penwidth=0.7, label="×14"]; "HAL" -> "Src/Inc (CubeMX)" [color="#94a3b8", penwidth=0.7, label="×1"]; "HAL" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×1"]; "LVGL" -> "FatFs" [color="#94a3b8", penwidth=0.7, label="×1"]; @@ -130,7 +130,7 @@ digraph refgraph_module { "Src/Inc (CubeMX)" -> "BSP/TPAFE5160" [color="#2563eb", penwidth=1.2, label="×1"]; "Src/Inc (CubeMX)" -> "CMSIS" [color="#2563eb", penwidth=1.2, label="×1"]; "Src/Inc (CubeMX)" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×4"]; - "Src/Inc (CubeMX)" -> "HAL" [color="#2563eb", penwidth=1.2, label="×14"]; + "Src/Inc (CubeMX)" -> "HAL" [color="#2563eb", penwidth=1.2, label="×15"]; "Src/Inc (CubeMX)" -> "lftpd" [color="#2563eb", penwidth=1.2, label="×1"]; "Src/Inc (CubeMX)" -> "test" [color="#2563eb", penwidth=1.2, label="×3"]; "Src/Inc (CubeMX)" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; @@ -151,13 +151,14 @@ digraph refgraph_module { "simulator" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×6"]; "test" -> "App" [color="#2563eb", penwidth=1.2, label="×1"]; "test" -> "App/task" [color="#2563eb", penwidth=1.2, label="×1"]; - "test" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×7"]; + "test" -> "App/util" [color="#2563eb", penwidth=1.2, label="×1"]; + "test" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×8"]; "test" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×2"]; "test" -> "BSP/GD5F2GQ5UE" [color="#2563eb", penwidth=1.2, label="×4"]; "test" -> "BSP/NET" [color="#2563eb", penwidth=1.2, label="×5"]; "test" -> "BSP/SD2506" [color="#2563eb", penwidth=1.2, label="×1"]; "test" -> "FatFs" [color="#2563eb", penwidth=1.2, label="×3"]; "test" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×5"]; - "test" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×2"]; - "test" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×12"]; + "test" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×4"]; + "test" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×17"]; } diff --git a/docs/images/引用关系图_模块.svg b/docs/images/引用关系图_模块.svg index 79fe2704..71b225b4 100644 --- a/docs/images/引用关系图_模块.svg +++ b/docs/images/引用关系图_模块.svg @@ -4,1091 +4,1098 @@ - - + + refgraph_module - -STM32F4-Base 模块引用概览 + +STM32F4-Base 模块引用概览 App - -App + +App App/log - -App/log + +App/log App->App/log - - -×2 + + +×2 App/util - -App/util + +App/util App->App/util - - -×2 + + +×3 BSP(公共) - -BSP(公共) + +BSP(公共) App->BSP(公共) - - -×3 + + +×3 BSP/GD5F2GQ5UE - -BSP/GD5F2GQ5UE + +BSP/GD5F2GQ5UE App->BSP/GD5F2GQ5UE - - -×1 + + +×1 BSP/NET - -BSP/NET + +BSP/NET App->BSP/NET - - -×1 + + +×1 BSP/RS485 - -BSP/RS485 + +BSP/RS485 App->BSP/RS485 - - -×1 + + +×1 BSP/SD2506 - -BSP/SD2506 + +BSP/SD2506 App->BSP/SD2506 - - -×1 + + +×1 BSP/TPAFE5160 - -BSP/TPAFE5160 + +BSP/TPAFE5160 App->BSP/TPAFE5160 - - -×1 + + +×1 FatFs - -FatFs + +FatFs App->FatFs - - -×1 + + +×1 FreeRTOS - -FreeRTOS + +FreeRTOS App->FreeRTOS - - -×2 + + +×2 Src/Inc (CubeMX) - -Src/Inc (CubeMX) + +Src/Inc (CubeMX) App->Src/Inc (CubeMX) - - -×2 + + +×3 外部/系统头文件 - -外部/系统头文件 + +外部/系统头文件 App->外部/系统头文件 - - -×7 + + +×7 App/log->App - - -×1 + + +×1 App/log->App/util - - -×1 + + +×1 App/log->BSP(公共) - - -×1 + + +×1 App/log->FatFs - - -×1 + + +×1 App/log->FreeRTOS - - -×4 + + +×4 App/log->Src/Inc (CubeMX) - - -×1 + + +×1 App/log->外部/系统头文件 - - -×4 + + +×4 App/task - -App/task + +App/task App/task->App - - -×4 + + +×4 App/task->App/log - - -×2 + + +×2 App/task->App/util - - -×1 + + +×4 App/task->BSP(公共) - - -×5 + + +×5 BSP/CH395F - -BSP/CH395F + +BSP/CH395F App/task->BSP/CH395F - - -×1 + + +×1 App/task->BSP/GD5F2GQ5UE - - -×1 + + +×1 App/task->BSP/NET - - -×2 + + +×2 BSP/NETCFG - -BSP/NETCFG + +BSP/NETCFG App/task->BSP/NETCFG - - -×2 + + +×2 App/task->BSP/RS485 - - -×1 + + +×1 App/task->BSP/TPAFE5160 - - -×1 + + +×1 BSP/UI - -BSP/UI + +BSP/UI App/task->BSP/UI - - -×4 + + +×4 App/task->FatFs - - -×1 + + +×1 App/task->FreeRTOS - - -×7 + + +×7 App/task->Src/Inc (CubeMX) - - -×1 + + +×1 test - -test + +test App/task->test - - -×4 + + +×4 App/task->外部/系统头文件 - - -×2 + + +×2 App/util->BSP(公共) - - -×1 + + +×2 App/util->BSP/SD2506 - - -×1 + + +×1 App/util->FreeRTOS - - -×2 + + +×2 App/util->Src/Inc (CubeMX) - - -×1 + + +×3 App/util->外部/系统头文件 - - -×4 + + +×3 BSP(公共)->App/log - - -×1 + + +×1 BSP(公共)->App/util - - -×1 + + +×1 BSP(公共)->外部/系统头文件 - - -×1 + + +×1 BSP/CH395F->BSP(公共) - - -×1 + + +×1 BSP/CH395F->Src/Inc (CubeMX) - - -×3 + + +×3 BSP/CH395F->外部/系统头文件 - - -×1 + + +×1 BSP/GD5F2GQ5UE->BSP(公共) - - -×2 + + +×2 BSP/GD5F2GQ5UE->FatFs - - -×2 + + +×2 BSP/GD5F2GQ5UE->Src/Inc (CubeMX) - - -×1 + + +×1 dhara - -dhara + +dhara BSP/GD5F2GQ5UE->dhara - - -×2 + + +×2 BSP/GD5F2GQ5UE->外部/系统头文件 - - -×4 + + +×4 BSP/NET->BSP(公共) - - -×1 + + +×1 BSP/NET->BSP/CH395F - - -×2 + + +×2 BSP/NET->FreeRTOS - - -×8 + + +×8 BSP/NET->Src/Inc (CubeMX) - - -×2 + + +×2 BSP/NET->test - - -×2 + + +×2 BSP/NET->外部/系统头文件 - - -×3 + + +×3 BSP/NETCFG->App - - -×3 + + +×3 BSP/NETCFG->BSP(公共) - - -×2 + + +×2 BSP/NETCFG->外部/系统头文件 - - -×3 + + +×3 BSP/RS485->Src/Inc (CubeMX) - - -×1 + + +×1 BSP/SD2506->Src/Inc (CubeMX) - - -×2 + + +×2 BSP/SD2506->外部/系统头文件 - - -×1 + + +×1 BSP/TPAFE5160->BSP(公共) - - -×1 + + +×1 BSP/TPAFE5160->Src/Inc (CubeMX) - - -×2 + + +×2 BSP/UI->App/log - - -×2 + + +×2 BSP/UI->BSP(公共) - - -×5 + + +×5 BSP/UI->BSP/NET - - -×2 + + +×2 BSP/UI->BSP/NETCFG - - -×1 + + +×1 LVGL - -LVGL + +LVGL BSP/UI->LVGL - - -×9 + + +×9 BSP/UI->test - - -×2 + + +×2 BSP/UI->外部/系统头文件 - - -×20 + + +×20 CMSIS - -CMSIS + +CMSIS HAL - -HAL + +HAL CMSIS->HAL - - -×1 + + +×1 CMSIS->外部/系统头文件 - - -×22 + + +×22 FatFs->App/util - - -×1 + + +×1 FatFs->BSP(公共) - - -×1 + + +×1 FatFs->FreeRTOS - - -×1 + + +×1 FatFs->外部/系统头文件 - - -×2 + + +×2 FreeRTOS->CMSIS - - -×1 + + +×1 FreeRTOS->Src/Inc (CubeMX) - - -×1 + + +×1 FreeRTOS->外部/系统头文件 - - -×14 + + +×14 HAL->CMSIS - - -×13 + + +×14 HAL->Src/Inc (CubeMX) - - -×1 + + +×1 HAL->外部/系统头文件 - - -×1 + + +×1 LVGL->FatFs - - -×1 + + +×1 LVGL->FreeRTOS - - -×6 + + +×6 SDL2 - -SDL2 + +SDL2 LVGL->SDL2 - - -×1 + + +×1 其他(第三方) - -其他(第三方) + +其他(第三方) LVGL->其他(第三方) - - -×1 + + +×1 LVGL->外部/系统头文件 - - -×204 + + +×204 SDL2->外部/系统头文件 - - -×36 + + +×36 Src/Inc (CubeMX)->App - - -×3 + + +×3 Src/Inc (CubeMX)->App/task - - -×2 + + +×2 Src/Inc (CubeMX)->App/util - - -×1 + + +×1 Src/Inc (CubeMX)->BSP(公共) - - -×2 + + +×2 Src/Inc (CubeMX)->BSP/CH395F - - -×2 + + +×2 Src/Inc (CubeMX)->BSP/GD5F2GQ5UE - - -×1 + + +×1 Src/Inc (CubeMX)->BSP/NET - - -×3 + + +×3 Src/Inc (CubeMX)->BSP/RS485 - - -×1 + + +×1 Src/Inc (CubeMX)->BSP/SD2506 - - -×1 + + +×1 Src/Inc (CubeMX)->BSP/TPAFE5160 - - -×1 + + +×1 Src/Inc (CubeMX)->CMSIS - - -×1 + + +×1 Src/Inc (CubeMX)->FreeRTOS - - -×4 + + +×4 Src/Inc (CubeMX)->HAL - - -×14 + + +×15 lftpd - -lftpd + +lftpd Src/Inc (CubeMX)->lftpd - - -×1 + + +×1 Src/Inc (CubeMX)->test - - -×3 + + +×3 Src/Inc (CubeMX)->外部/系统头文件 - - -×4 + + +×4 dhara->外部/系统头文件 - - -×5 + + +×5 lftpd->BSP(公共) - - -×4 + + +×4 lftpd->BSP/NET - - -×3 + + +×3 lftpd->FatFs - - -×2 + + +×2 lftpd->FreeRTOS - - -×2 + + +×2 lftpd->外部/系统头文件 - - -×8 + + +×8 simulator - -simulator + +simulator simulator->App - - -×3 + + +×3 simulator->App/log - - -×2 + + +×2 simulator->BSP/NET - - -×1 + + +×1 simulator->BSP/NETCFG - - -×1 + + +×1 simulator->BSP/UI - - -×5 + + +×5 simulator->LVGL - - -×3 + + +×3 simulator->SDL2 - - + + ×2 simulator->test - - -×1 + + +×1 simulator->外部/系统头文件 - - + + ×6 test->App - - -×1 + + +×1 test->App/task - - -×1 + + +×1 + + + +test->App/util + + +×1 - + test->BSP(公共) - - -×7 + + +×8 - + test->BSP/CH395F - - -×2 + + +×2 - + test->BSP/GD5F2GQ5UE - - -×4 + + +×4 - + test->BSP/NET - - -×5 + + +×5 - + test->BSP/SD2506 - - -×1 + + +×1 - + test->FatFs - - -×3 + + +×3 - + test->FreeRTOS - - -×5 + + +×5 - + test->Src/Inc (CubeMX) - - -×2 + + +×4 - + test->外部/系统头文件 - - -×12 + + +×17 diff --git a/docs/内存管理/RAM使用分析与优化方案.md b/docs/内存管理/RAM使用分析与优化方案.md index 5a2f3614..ac57c878 100644 --- a/docs/内存管理/RAM使用分析与优化方案.md +++ b/docs/内存管理/RAM使用分析与优化方案.md @@ -36,10 +36,10 @@ | 区域 | 用量 | 容量 | 占比 | |---|---|---|---| -| ER_IROM1 | 261,312 B (255.19 KB) | 1,048,576 B (1024 KB) | 24.9% | +| ER_IROM1 | 261,200 B (255.08 KB) | 1,048,576 B (1024 KB) | 24.9% | | RW_IRAM1 | 84,864 B (82.88 KB) | 131,072 B (128 KB) | 64.7% | | RW_CCM | 49,184 B (48.03 KB) | 65,536 B (64 KB) | 75.0% | -| **Flash (ROM 合计)** | **262,012 B (255.9 KB)** | 1,048,576 B (1024 KB) | **25.0%** | +| **Flash (ROM 合计)** | **261,900 B (255.8 KB)** | 1,048,576 B (1024 KB) | **25.0%** | 各区的容量与常量来源: diff --git a/docs/审查记录/测试与架构改进建议.md b/docs/审查记录/测试与架构改进建议.md new file mode 100644 index 00000000..22c897c8 --- /dev/null +++ b/docs/审查记录/测试与架构改进建议.md @@ -0,0 +1,674 @@ +# 测试体系与整体架构改进建议(2026-10-02) + +> **用途**:对现有**测试体系**与**整体架构**做一次独立复审,回答两个问题—— +> ① 测试是否足够?② 架构还有什么可改进的地方? +> **性质**:**纯建议文档,不改任何代码**。每条给出「现状证据 → 风险 → 实施路径 → 完成判据」。 +> **上游**:`项目审查与优化建议报告.md`(P0~P3 全量池)、`项目审计改进清单.md`(待办)、 +> `错误码传播审计.md`(E-xx)、`待处理内容.md`(登记簿)、`下一步任务规划.md`(排序)。 +> **本文不重复已登记条目**——只补充**测试充分性**与**架构层面**的新发现,或对既有条目 +> 给出**新的实施角度**。凡与上游重叠的,标注上游编号并注明本文增量。 +> **审计方法**:源码逐文件走读(`App/`、`test/`、`Drivers/BSP/`)+ 测试资产量化统计 + +> CI/pre-commit 门禁链路核查 + 与六份测试文档交叉比对。 + +--- + +## 0. 结论速览 + +### 0.1 测试体系评价:**分层设计优秀,但"中间层"严重偏薄** + +| 维度 | 评价 | 一句话 | +|---|---|---| +| 分层模型(L0~L3) | ⭐⭐⭐⭐⭐ | 四层划分清晰、门禁决策表明确,**优于绝大多数同规模嵌入式项目** | +| 板端套件(L1) | ⭐⭐⭐⭐☆ | 4 套件 + 222 个断言点,覆盖驱动功能面完整 | +| 静态门禁(L0) | ⭐⭐⭐⭐⭐ | 15 个钩子、含一致性/规范/乱码/元数据,防线密不透风 | +| **主机侧纯逻辑单测(L0.5)** | ⭐⭐☆☆☆ | **仅 1 个模块(看门狗)**,而适格对象至少有 6~8 个 | +| UI 回归(L3 门禁) | ⭐⭐⭐⭐☆ | 文本层 + 像素层 + 池水位三层断言,思路先进 | +| CI | ⭐⭐⭐☆☆ | 只跑 L0 + L0.5;**无产物存档、无结果趋势、无覆盖率** | +| 可观测性(运行时) | ⭐⭐⭐⭐☆ | 栈水位探针 + 链路时延探针 + syslog,台架能力强 | +| **验证债** | ⭐⭐☆☆☆ | 多项"已改未验",L0.5 稀缺导致**回归只能靠真机** | + +**核心判断**:项目的测试**广度**(驱动功能面)和**静态深度**(门禁)都很强, +真正的短板是 **L0.5(主机侧纯逻辑单测)的覆盖率**——这是**性价比最高、见效最快**的改进方向。 +它不需要硬件、秒级完成、能上 CI、且已有一整套现成 harness(`unit_test_harness.py` + 看门狗范式)。 + +### 0.2 架构评价:**分层与解耦做得好,但存在"三个不对称"** + +| 不对称 | 表现 | 影响 | +|---|---|---| +| **功能不对称** | 网络栈极度成熟,而 ADC/RS485 采集链路是空桩 | DTU 核心职责未实现 | +| **纵深防御不对称** | 上层(网络/日志/配置)防御完备,下层(NAND 错误通道)散乱 | 底层故障难定位 | +| **测试不对称** | 驱动面覆盖好,纯逻辑面几乎裸奔 | 回归依赖真机,反馈慢 | + +### 0.3 建议优先级(与上游阶段 A/B/C/D 对齐) + +``` +【S 级:本周可做,零风险,收益大】 ← 本文新增 + S1 扩充 L0.5 单测(crc/ringbuf 判定、sys_clock 日期算术、cfg_file 解析器) + S2 清理孤儿源文件(crc.c / ringbuf.c)——降低认知负担 + S3 CI 补产物存档 + 单测结果汇总 + +【A 级:上游已列,本文给增量角度】 + A1 P0-1 真机验证(上游 A1) A2 P1-8 网络重建恢复(上游 A2) + A3 E-34 CH395F 超时(上游 A3) A4 E-04 remo_send 返回值(上游 A4) + +【B 级:核心功能补齐(上游 B,需产品定义)】 + B1 ADC 链路 B2 RS485 链路 B3 E-59 门禁固化 + +【C 级:结构债(上游 C)】 + C1 pending 二期 C2 GD5F 错误通道 C3 日志管线 C4 defaultTask 栈 +``` + +--- + +## 1. 测试体系:量化现状 + +### 1.1 测试资产盘点(2026-10-02 实测) + +**板端套件(L1)——4 套件,222 个 `TEST_CHECK` 断言点**: + +| 套件 | 文件 | 断言点 | Test_Guide 用例数 | 覆盖对象 | +|---|---|---|---|---| +| CH395F 硬件层 | `ch395f_test_task.c` | 52 | 34(TC-NET-xxx) | CH395F 寄存器/命令/中断 | +| CH395F NET 层 | `net_test_task.c` | 38 | (同上,Phase 6~11) | TCP 监听/连接/收发 | +| GD5F | `gd5f_test_task.c` | 76 | 45(TC-GD5F-xxx) | NAND 驱动 10 阶段 | +| STORAGE | `storage_test_task.c` | 38 | (TC-STO-01~04) | FTL + FatFS 集成 | +| SD2506 RTC | `sd2506_test_task.c` | 18 | 9(TC-RTC-xxx) | RTC 读写/闹钟 | +| **合计** | | **222** | | | + +> ⚠️ 注意:断言点数(222)**大于**文档用例数(91)——因为一个 TC 常有多个 `TEST_CHECK`。 +> 这是正常的,但**反向不成立**:文档存在而代码未实现的用例无法从断言点数量看出, +> 需靠 §1.3 的"覆盖矩阵核查"专项检查(本文建议 S4,见 §3.4)。 + +**主机侧(L0.5)——仅 1 个模块**: + +| 模块 | 位置 | 用例数 | 被测对象 | +|---|---|---|---| +| 看门狗判定状态机 | `test/host/watchdog/` | 39 | `App/util/task_watchdog.c` 位图/掩码/节流/回绕 | +| **其余模块** | — | **0** | — | + +**静态门禁(L0)——15 个钩子**: + +`trailing-whitespace` / `end-of-file-fixer` / `check-added-large-files` / `check-merge-conflict` / +`check-yaml` / `gitlint` / `cppcheck` / `no-mojibake` / `coding-standard` / `doc-links` / +`task-table` / `mem-numbers` / `cubemx-survival` / `watchdog-unit-test` / `test-suite-switch` + +**UI 回归(L3 门禁)**:`check_menu_rows.py`(菜单 8 状态像素 + 池基线)+ +`check_content_pages.py`(11 内容页 + 文本层 50 条字形模板)+ `check_remo_sink.py`(远显推流)。 + +**CI(Gitea Actions)**:2 个 job —— `l0-gates`(pre-commit 全量)、`l05-host-unit-tests`(遍历 `run_unit_test.py`)。 + +### 1.2 覆盖率缺口矩阵(按"适格性"排序) + +> 判据:**无副作用 + 可离线复现 + 边界密集** = L0.5 适格(见`测试开发标准流程.md` §4.2)。 + +| 候选模块 | 规模 | 边界密度 | 现测试手段 | L0.5 价值 | 备注 | +|---|---|---|---|---|---| +| **`App/util/sys_clock.c`** | 479 行 | **极高** | 仅 RTC 套件(真机) | ⭐⭐⭐⭐⭐ | 闰年/日期换算/星期/49.7 天回绕——**纯算术,零硬件** | +| **`App/cfg/cfg_file.c`** | 1250 行 | **高** | 仅 STORAGE 套件(真机) | ⭐⭐⭐⭐⭐ | INI 解析/转义/长度校验/迁移——**已有 `cfg_store_alloc` 平台后端抽象,天然适格** | +| **`App/util/crc.c`** | 120 行 | 中 | **无**(孤儿文件) | ⭐⭐⭐ | 查表正确性可用标准向量验证;但**当前无调用者**(见 S2) | +| `Drivers/BSP/RS485/rs485.c` | 181 行 | 高 | **无**(任务为空桩) | ⭐⭐⭐⭐ | 帧解析状态机适格;但**功能未实现**(上游 B2) | +| `App/sync/time_sync.c` | 217 行 | 中 | 仅手工 `time_sync_server.py` | ⭐⭐⭐ | 协议编解码适格,与网络耦合需判 | +| `App/log/sys_log_mcu.c` | 359 行 | 中 | 仅 `@test` 标记 | ⭐⭐⭐ | 定长 64B 记录编解码适格;落盘部分需桩 | +| `Drivers/BSP/TPAFE5160/tpafe5160.c` | 356 行 | 中 | **无**(任务为空桩) | ⭐⭐ | 寄存器序列为主,纯逻辑面小 | +| `App/util/ringbuf.c` | 154 行 | 中 | **无**(孤儿文件) | ⭐⭐ | 若 S2 决定保留则须测;否则删除 | + +**结论**:**至少 2 个高价值模块(`sys_clock`、`cfg_file`)具备立即可做的 L0.5 条件**, +合计约 1730 行核心逻辑,目前**完全依赖真机验证**。这是测试体系最大的效率损失点。 + +### 1.3 测试体系的结构性问题 + +#### 问题 T-1:L0.5 覆盖率过低,回归反馈闭环过长 🔴 + +**现状**:全项目仅看门狗 1 个模块有主机侧单测。`sys_clock.c`(479 行日期算术)、 +`cfg_file.c`(1250 行解析器)这类**边界密集、纯逻辑、零硬件**的模块, +改动后**只能靠真机 `@test` 才能发现问题**。 + +**代价量化**(以 `sys_clock.c` 为例): + +| 手段 | 单次反馈耗时 | 需要硬件 | 能覆盖的边界 | +|---|---|---|---| +| 真机 `@test` | 烧录 ~7s + 等静默 8s + 采集 ≈ **30s~2min** | ✅ 需板+串口+ST-LINK | 只测"当前日期"这一个点 | +| L0.5 单测 | 编译+运行 ≈ **2~5s** | ❌ 不需要 | 可穷举闰年/月末/回绕/2038 边界 | + +**关键**:`sys_clock.c` 里的 `unix_to_sd2506()` 涉及闰年判断、`mdays` 月份表、 +Unix 秒 → 年月日换算、49.7 天 tick 回绕惰性再基准化——这些**用真机只能测"今天", +用单测可以测一万个日期**。而历史事故(`AGENTS.md` 记载的"换算时不得再加 2000, +否则年份虚增导致 Unix 秒数超 uint32 回绕")**正是这类边界 bug**。 + +**建议**:见 §3.1(S1)。 + +#### 问题 T-2:CI 无产物存档、无趋势、无覆盖率 🟡 + +**现状**:CI 只做"通过/失败"判定,**不保存任何产物**: +- `pre-commit run --all-files` 的完整输出不入档(失败后只能靠 Gitea 日志页滚动查找); +- L0.5 单测输出不入档; +- 无任何历史趋势(例如"单测数从 39 涨到多少""门禁耗时变化")。 + +**风险**:CI 失败时**排障成本高**(本次 T-6 排障就是靠直查 MySQL + 手工解压 `actions_log` 才定位的, +见 `Gitea_Runner部署指南.md` §5.1.1)。且"测试数量是否在增长"无人可见。 + +**建议**:见 §3.3(S3)。 + +#### 问题 T-3:`test/` 代码完全豁免静态检查 🟡 + +**现状**(`测试开发标准流程.md` §3.3 明示):`test/` 在 pre-commit 范围之外, +"上表约定属**自律**要求"。而 `test/board/` 下是 **6300+ 行 C 代码**(实测 `.c`+`.h` 合计 6,313 行),且**编入固件**。 + +**风险**:测试代码也是代码——`net_test_task.c` 曾出现"`s_rx_buf` 使用先于声明" +(`测试开发标准流程.md` 变更记录 2026-09-15),说明测试代码质量并非自动达标。 +豁免 cppcheck 意味着测试代码的**未初始化变量/越界/空指针**不会被静态发现。 + +**建议**:见 §3.5(S4)。注意**不宜**直接纳入现有钩子(会引入大量存量告警), +宜用**独立、宽松**的钩子(只报 error 级、不含 style)。 + +#### 问题 T-4:测试固件构建未纳入闭环(= 上游 P1-10,本文给增量)🟡 + +**上游已登记** P1-10"测试固件构建闭环"。**本文增量**: +`测试开发标准流程.md` 变更记录 2026-09-15 记载 **CH395F 套件 7 个配置 +"自 2026-08(88160a5)起不可编译"**,且"128KB 静态 RAM 预算溢出" +(HW 全阶段固件超 8.7KB、NET 固件超 ~28KB)。 + +**这说明**:测试套件的**构建可编译性没有独立门禁**——产品构建 `@build` 天天跑, +但**测试构建可能长期处于"编不过"状态而无人知**,直到某次要用才发现(正是 09-15 的情况)。 + +**建议**:见 §3.4(S5)——把"测试套件构建"做成**可选的编译验证**,而非依赖人记得。 + +#### 问题 T-5:真机回归的"判定强度"仍可提升 🟡 + +**现状**:`verify_log.py` 已支持 `--require-suite-summary`(T-2,要求汇总行 + `N>0` + `failed=0`), +这是很好的设计。但**产品构建回归**(非套件)仍是纯 Required 子串匹配 + +Forbidden `FAIL;ERROR;HardFault;assert`。 + +**盲区**:产品构建回归**不校验** syslog 中的自检结果。 +项目已有 `sys_log` 引擎写 `/log/selftest.log`(`运行与自检记录设计说明.md`), +但 `@test` 闭环**没有读取它**——自检失败(例如"时钟芯片异常")只在设备日志里静静躺着。 + +**建议**:见 §3.6(S6)——让 `@test` 闭环消费 `selftest.log` 的判定结果。 + +--- + +## 2. 整体架构:改进点 + +### 2.1 架构现状(客观评价) + +**做得好的**(无需改动): + +| 项 | 证据 | +|---|---| +| 六层单向依赖 | `项目架构总览.md` §1,跨层依赖有明确表 | +| 就绪屏障替代魔法延时 | `sys_events.h` + `osFlagsNoClear` 语义修正(含事故复盘) | +| 单写者收敛 | 日志(`console_log` / `sys_log`)、配置(`cfg_file` 属主=defaultTask)、SPI(netMsgQueue 串行化) | +| 平台后端抽象 | `cfg_file` 的"共享核心 + 双端后端"(MCU=FreeRTOS 堆/模拟器=宿主堆) | +| 双端共享源码 | UI / `net_cfg` / `cfg_file` 同时编 MCU 与模拟器 | +| 可观测性 | 栈水位探针、链路时延探针(DWT)、syslog 双记录、自检上报 | +| CubeMX 生存保障 | `check_cubemx_survival.py`(18 项清单 + 哈希基线) | + +### 2.2 改进点 A-1:孤儿源文件(认知负担 + 误导)🟡 + +**证据**(2026-10-02 实测): + +``` +App/util/crc.c 120 行 → 零 `#include "crc.h"`,不在 Keil 工程 +App/util/ringbuf.c 154 行 → 零 `#include "ringbuf.h"`,不在 Keil 工程 +``` + +- `crc.c` 提供 `crc16_modbus()` / `crc8()`,但**唯一使用者 `net_cfg_legacy.c` + 自己复制了一份 `s_crc16_modbus()`**(第 43/55 行),并未调用 `crc.c`。 +- `ringbuf.c` 是通用环形缓冲,但 `console_log.c` **自己内联实现了环形缓冲** + (`s_con_ring` + head/tail,第 39~42 行),未复用。 + +**风险**: +1. **误导**:新读者看到 `App/util/crc.c` 会以为 CRC 有统一实现,实际各写各的; +2. **维护负担**:`app_main.c` 的 `/log` 无调用者却需为它做"是否要测/是否要改"的决策; +3. 上游 E-15 已提"ringbuf 定去留——**已确认零调用者,倾向删除**",本文**用实测佐证该结论** + 并**追加 `crc.c`**。 + +**建议**:见 §4.1(S7)。 + +### 2.3 改进点 A-2:错误码通道的"下层不对称"🔴 + +**上游已登记**(`错误码传播审计.md` 第二档 #1:E-10/E-42/E-53/E-54/E-56/E-57 GD5F 错误通道族)。 +**本文增量**:给出**架构层面的根本原因**与**统一方案骨架**。 + +**根本原因分析**:`ch395f.c`(1330 行) 与 `gd5f2gq5ue.c`(1496 行) 是**同代驱动**, +但只有 CH395F 形成了"错误分类 + 传播 + 审计"的完整体系(有 `错误码传播审计.md`、 +`CH395F_Trap_Records.md` 737 行);GD5F 侧的错误处理散落在各函数内, +`Trap_Records` 仅 198 行。**差异不在驱动复杂度,而在是否建立了统一的错误通道约定**。 + +**建议骨架**(供 C2 参考): + +``` +统一错误通道四要素(以 CH395F 为范式): + ① 分类:区分「超时 / 真故障 / 参数错」——不得混为一个返回码 + ② 透传:底层错误码逐层上报,不吞不猜(禁 `(void)ret`) + ③ 分级:可恢复(重试)/ 不可恢复(上报自检 + 降级)显式判定 + ④ 留痕:不可恢复项写 syslog selftest,可恢复项计数并在 UI/日志可见 +``` + +**关键纪律**(呼应 `AGENTS.md` 已有铁律):**自愈逻辑严禁把"名字/参数类错误码" +归入"卷损坏触发集"**——`.fschk` 无限重格式化事故即此类(2026-09-20)。 + +### 2.4 改进点 A-3:启动段无看门狗保护的窗口 🟡 + +**上游已登记**(N-03b,视为"显式代价")。**本文增量**:量化并给出**风险接受条件**。 + +**现状**:`app_main_init` + `defaultTask` bring-up 段(约 `sd2506_init` → `f_mount` → `net_cfg_load`) +无 IWDG 保护。该段死机表现 = "无输出 + LED 不闪"(N-03b 原文)。 + +**风险量化**:这段代码涉及 +- `sd2506_init` / `sys_clock_init`(I2C1,有超时) +- `gd5f2gq5ue_init`(**BBT 全片扫描**,最耗时) +- `f_mount` / 可能的 `f_mkfs`(FAT32 格式化) +- `net_cfg_load`(NAND 读 + INI 解析) + +**建议**:不强行加 IWDG(会与"BBT 扫描耗时不确定"冲突),而是 +① **加启动段进度日志**(每步 `DBG_INFO`,使"卡在哪一步"可见); +② **为长操作加显式看门狗喂狗点**(若将来启用启动期 IWDG); +③ 文档明确"启动段死机的判读方法"。 + +> 检查现状:`app_main.c` 是否每步有日志——若有则可直接销项。见 §4.4(S8)。 + +### 2.5 改进点 A-4:ADC/RS485 采集链路缺失(核心功能空洞)🔴 + +**上游已列**(P1-1、阶段 B)。**本文增量**:从**测试可验证性**角度补充设计约束。 + +**现状**:`adc_task.c` / `rs485_task.c` 均为 43 行空桩(`osDelay` 死循环); +`App/protocol/` 目录**只有 README 与 `.gitkeep`**(为协议解析预留但未实现)。 + +**测试可验证性约束**(建议纳入 B1/B2 设计): + +1. **协议解析必须与硬件 I/O 分离**——`App/protocol/` 的解析函数应接受 + `(const uint8_t *buf, size_t len)` 返回解析结果,使它能成为 L0.5 的**天然适格对象** + (参考 `cfg_file` 的"核心 + 后端"模式); +2. **采集缓冲必须双缓冲 + 序号**(上游 E-49/E-50)——否则消费者读到撕裂数据, + **且撕裂在单测里测不出来**(时序相关),必须在设计上消除; +3. **DE 收尾必须有超时路径覆盖**(RS485 半双工的特有陷阱)。 + +### 2.6 改进点 A-5:内存预算的"预算—实际"闭环可再收紧 🟡 + +**现状**:已有 `ram_report.py`(.map 静态)+ `stack_report.py`(静态调用图 × 运行时水位) ++ `mem-numbers` pre-commit 钩子(校验文档数字与 .map 一致)。**这套机制很先进**。 + +**缺口**: +1. `mem-numbers` **在 CI 上被跳过**(无 `.map`)——意味着**CI 不能守体积门禁**; +2. `configTOTAL_HEAP_SIZE`(48KB)无运行时余量告警——实测 `free=8,784 / min_ever=4,848 B`, + **min_ever 已低于 5KB**,若新增任务可能触发分配失败; +3. 上游 S-1(defaultTask 静态最坏链 2872B/4096,余量 29.9% 差 4.8B 达标)**仍未处理**。 + +**建议**:见 §4.5(S9)——**堆余量低水位告警**(复用既有 `stack_probe_poll` 模式)。 + +### 2.7 改进点 A-6:`configASSERT` 已改造但覆盖不足 🟡 + +**现状**(N-03a 已修):`configASSERT` 已从"关中断死循环"改为 +`vApplicationAssertFailed(__FILE__, __LINE__)` → 打印后复位。**这是很好的改进**。 + +**缺口**:`configASSERT` **只覆盖 FreeRTOS 内部断言**。 +项目自研代码**无统一断言宏**——例如 `net_socket.c` 的参数校验靠 `if + return -1`, +`cfg_file.c` 的边界靠手工检查。**没有轻量断言**意味着"不该发生的情况"静默通过。 + +**建议**:见 §4.6(S10)——引入**可选、可编译掉**的模块级断言宏 +(生产构建零开销,测试构建启用),与 `test_common.h` 的 `TEST_CHECK` 呼应。 + +### 2.8 改进点 A-7:模拟器差距清单未成体系 🟡 + +**现状**:多处提及"模拟器差距清单 +1"(N-4 二期门禁),例如 +"net_socket_sim.c 无法建模 pending"。但**没有一份汇总的"模拟器差距清单"文档**—— +差距散落在各文档的只言片语中。 + +**风险**:模拟器回归通过 ≠ 真机通过,但**差异有多大、差在哪,无人能一眼说清**。 +这会让"模拟器能否作为 L2 门禁"的判断失去依据。 + +**建议**:见 §4.7(S11)——建立**单一差距清单文档**。 + +--- + +## 3. 测试体系改进实施建议 + +### 3.1 S1:扩充 L0.5 主机侧单测(**最高性价比**)⭐⭐⭐⭐⭐ + +**目标**:把至少 2 个高价值纯逻辑模块纳入 L0.5,使"改这些模块"不再需要真机才能回归。 + +**实施路径**(完全复用既有范式,见 `看门狗单元测试说明.md`): + +**S1-a:`sys_clock.c` 日期算术单测**(推荐首个,边界最密、零依赖)—— ✅ **已完成(2026-10-02)** + +| 步骤 | 内容 | +|---|---| +| 1 | 确认 `sys_clock.c` 的硬件依赖面(`sd2506_get_time/set_time` + `HAL_GetTick` + 临界区宏 + `DBG_*`) | +| 2 | **全部依赖都是外部符号/宏 → 直接强符号覆盖桩(看门狗范式),无需平台层抽取**——比预期更干净,**生产代码零改动**(Zeller 修复除外,见下) | +| 3 | 新建 `test/host/sys_clock/run_unit_test.py`(声明式,≈50 行)+ `sys_clock_test.c` + `stub/` 4 个头 | +| 4 | 用例设计(**边界穷举**):闰年(2000 闰 / 2024 闰)· 月末(1/31、2/28、2/29、4/30)· 世纪边界 · 2000 最早年/2038 上限(`0x7FFFFFFF`)· **30 天惰性再基准化 + 亚秒余数结转 + 49.7 天 tick 回绕** · 星期(`rtc_calc_week`)16 个已知日期对照 · RTC 读失败/越界/写回失败三故障路径 | +| 5 | 挂 pre-commit 钩子 `sys-clock-unit-test`(改动 `sys_clock.c`/`sd2506.h` 时自动跑,秒级) | +| 6 | 在 `.gitea/workflows/ci.yml` 无需改动——`l05` job 遍历 `test/host/**/run_unit_test.py`,**自动纳入** | + +**完成判据**:`python test/host/sys_clock/run_unit_test.py` 退出码 0(**100/100 PASS**); +`@build` 0/0(已验);CI 的 `l05-host-unit-tests` 日志出现该运行器且 PASS(待推送后复验)。 + +> ⚠️ **重大副产物**:本单测**首跑即抓出一处生产缺陷**——`rtc_calc_week()` / +> `unix_to_sd2506()` 的 Zeller 公式错误,使 **1970~2099 全部日期的 `week` 字段皆为 +> 错值**(无常数偏移,错误率 ~78%;时间数值本身正确,故此前未暴露)。已修复并 +> 经 Python `datetime` 独立核对 47,482 天零错误。详见 +> [`../测试说明/系统时钟单元测试说明.md`](../测试说明/系统时钟单元测试说明.md) §5。 +> 修复使 Flash 减少 112 B(删除重复内联公式),内存快照已同步 +> (`check_mem_numbers.py --write`)。 + +**S1-b:`cfg_file.c` INI 解析器单测**(价值同样高,但需先确认抽象质量) + +| 步骤 | 内容 | +|---|---| +| 1 | **利好**:`cfg_file` 已有 `cfg_store_alloc/free` 平台后端(`cfg_file_store.h`),MCU=FreeRTOS 堆、模拟器=宿主堆——**天然适格** | +| 2 | 确认文件 I/O 是否也已抽象(预计 `cfg_file` 的核心是"文本 ↔ 结构"纯变换,I/O 在后端) | +| 3 | 新建 `test/host/cfg_file/`,用桩后端提供内存虚拟文件 | +| 4 | 用例设计:INI 正常解析 · 空文件/缺段/重复键 · 键值转义 · **长度上限**(`CFG_FILE_MAX_LEN`)· **段名长度**(上游 E-16 相关)· 旧档 NCFG 迁移路径(`net_cfg_legacy`)· 畸形输入不崩溃 | +| 5 | 挂钩子 `cfg-file-unit-test` | + +> ⚠️ **注意**:`cfg_file.c` 1250 行,**不建议一次全测**。优先覆盖**解析器 + +> 边界校验**(P0-1 堆分配路径已由真机验证,见上游 A1),不做"为覆盖率而测"。 + +**S1-c(可选):`sys_log` 记录编解码、`time_sync` 协议帧** + +同上范式。优先级低于 S1-a/S1-b,可在 S1-a 落地后按剩余收益评估。 + +**⚠️ 关键约束**(重申 `测试开发标准流程.md` §4.2): +- 平台层抽取必须**零行为变化、零额外开销**(MCU 默认实现即原逻辑); +- 测试钩子用 `#ifdef <模块>_UNIT_TEST` 守卫,**MCU 构建零符号**; +- 单测**不能替代**板端验证——真机寄存器/复位原因/时序仍须 L1/L2。 + +### 3.2 S2:为 L0.5 建立"适格模块清单"(防遗漏)⭐⭐ + +**问题**:现在只有"看门狗"一个先例,**下一个该测谁**靠临时判断。 + +**建议**:在 `测试开发标准流程.md` 增补一节「L0.5 适格模块台账」: + +| 模块 | 状态 | 备注 | +|---|---|---| +| `task_watchdog.c` | ✅ 已覆盖(39 用例) | 范式 | +| `sys_clock.c` | ✅ 已覆盖(20 用例 / 100 断言点,2026-10-02 S1-a) | **首测即抓出 Zeller 星期缺陷并修复**,见 `系统时钟单元测试说明.md` §5 | +| `cfg_file.c` | ⬜ 待做(S1-b) | 已有后端抽象 | +| `sys_log_mcu.c` | ⬜ 候选 | 记录编解码 | +| `time_sync.c` | ⬜ 候选 | 协议帧 | +| `rs485.c` | ⬜ 待功能实现 | 上游 B2 | +| `crc.c` / `ringbuf.c` | ✅ 已删除(2026-10-02 S8) | 孤儿文件,已确认无被引 | +| `tpafe5160.c` | ❌ 不适格 | 寄存器序列为主 | +| 其余驱动 | ❌ 不适格 | 需硬件时序 | + +**完成判据**:文档有台账,新增模块时按表判断是否需 L0.5。 + +### 3.3 S3:CI 补产物存档与结果汇总 🟡 + +**目标**:让 CI 失败**可远程排障**、让测试规模**可趋势观察**。 + +**实施路径**: + +| 步骤 | 内容 | 备注 | +|---|---|---| +| 1 | 两个 job 各加"失败时/总是"上传日志产物 | Gitea Actions 支持 `actions/upload-artifact`;**需确认本实例的 action 拉取可用**(内网可能不通 github,见 `CI配置指南.md` 的"内网 action"章节) | +| 2 | 若 action 不可用,**降级方案**:把关键输出 `tee` 到一个固定路径并 `::notice::` 打印摘要 | 零依赖 | +| 3 | L0.5 job 末尾打印**汇总行**(如 `L0.5: 1 runner(s), 39/39 PASS`) | 简单有效,便于一眼看规模 | +| 4 | (可选,后续)收集 `[STACK]` 水位与 `.map` 数字形成趋势 | 依赖 runner 有 Keil | + +**完成判据**:CI 失败时,**不查 MySQL / 不解压 `actions_log`** 即可从 Gitea 页面 +看到完整输出与摘要。 + +> **本文增量**:本项目 CI 是**自建 Gitea 内网实例**,"能否拉外层 action"是现实约束—— +> 建议**优先做零依赖方案**(步骤 2/3),而不是先引入 `upload-artifact`。 + +### 3.4 S4:复核"文档用例 ↔ 代码断言"覆盖矩阵 🟡 + +**问题**:文档声称 91 个 TC、代码有 222 个断言点,但**两者是否一一对应无人校验**。 +`测试开发标准流程.md` §2.3 铁律 3 要求"每条设计原则必须有对应用例", +但**没有机械校验**。 + +**建议**:新增一个**轻量校验脚本**(类似 `check_doc_links.py` 的形态): + +``` +scripts/check_test_traceability.py + 输入:test/board/*_test_task.c 的 TC 注释 + docs/测试说明/*Test_Guide.md 的 TC 编号 + 输出:① 文档有、代码无(用例未实现) ② 代码有、文档无(用例未登记) + 门禁:默认仅告警(warning),不阻断提交 +``` + +**⚠️ 慎重**:**不建议**立即做成阻断型门禁——存量差异可能较多, +宜先**输出报告**,人工确认后再决定是否收紧。这与 `doc-links` 的演进路径一致。 + +**完成判据**:能一键列出双向差异清单;差异收敛后可考虑升为门禁。 + +### 3.5 S5:给 `test/` 代码加"宽松"静态检查 🟡 + +**目标**:抓 `test/board/` 6300+ 行固件测试代码的**真实缺陷**(未初始化/越界/空指针), +但不引入存量 style 噪音。 + +**实施路径**: + +| 步骤 | 内容 | +|---|---| +| 1 | 先跑一次基线:`cppcheck --enable=warning --error-exitcode=1 test/`,**统计存量告警数** | +| 2 | 若存量可控(建议 <20 条),加 `test-cppcheck` 钩子,**只开 `warning`**(不含 performance/portability/style) | +| 3 | 若存量较多,先建 **suppress 清单**(明确每条的豁免理由),再挂钩子 | +| 4 | **务必**排除模拟器桩/第三方头(`test/host/watchdog/stub/` 等) | + +**完成判据**:`test-cppcheck` 钩子在 CI 上 PASS;新增测试代码的越界/未初始化被自动拦截。 + +> **风险提示**:`test/` 代码豁免是**既有决策**(`测试开发标准流程.md` §3.3)。 +> 本建议**不是推翻它**,而是"在不产生大量噪音的前提下,补上致命缺陷的检查"。 +> 若基线告警过多,**保持现状亦可接受**——此时应把该决策写得更明确("理由:存量告警 N 条")。 + +### 3.6 S6:测试构建可编译性纳入验证(= 上游 P1-10 增量)🟡 + +**目标**:防止"测试套件长期编不过而无人知"(2026-08~09 CH395F 套件实例)。 + +**实施路径**(三选一,按成本递增): + +| 方案 | 做法 | 成本 | 效果 | +|---|---|---|---| +| A(最轻) | `test/run_all_suites.py --dry-run` 基础上加 `--check-build`:仅改宏 + `@build`,**不烧录** | 低 | 每次回归窗口自动验证 4 套件可编译 | +| B | 新增 `@build-suites` 命令:循环 4 套件各跑一次 `@build`(含 RAM 溢出检查) | 中 | 一条命令全验 | +| C | CI 加 job(需 runner 有 Keil) | 高 | 自动守门,但当前 runner 无 Keil | + +**建议**:**先做 A**(`run_all_suites.py` 已有改宏 + `try/finally` 还原的骨架, +加 `--check-build` 是自然扩展),成本最低、收益明确。 + +**注意**:RAM 溢出(P1-9:HW 全阶段固件超 8.7KB)意味着**即使能编译也可能链接失败**—— +方案 A 的 `@build` 会自然暴露 `L6406E`,这正是想要的。 + +### 3.7 S7:真机回归增加"自检结果"判定 🟡 + +**目标**:让 `@test` 闭环不仅看串口标记,**还看设备的自检结论**。 + +**现状**:`sys_log` 引擎写 `/log/selftest.log`(`运行与自检记录设计说明.md`), +但 `verify_log.py` 只解析串口日志。 + +**实施路径**: + +| 步骤 | 内容 | +|---|---| +| 1 | 确认 `selftest.log` 的记录格式(定长 64B,应有"项 / 结果 / 时间"字段) | +| 2 | `verify_log.py` 增加 `--require-selftest-pass`:要求串口日志中出现自检汇总 + (或由 `serial_tool` 通过 FTP 取回 `selftest.log` 后校验) | +| 3 | 判定语义建议:**自检有 no-go 项 → FAIL**;有 warn 项 → 打印但 PASS | + +**完成判据**:`@test` 能捕获"时钟芯片异常""存储降级"等自检失败, +而不是只捕获 `FAIL` 字符串。 + +> **注**:`sys_clock_init` 在 RTC 故障时返回 -1 并触发"时钟芯片异常"自检 +> (`项目架构总览.md` §3)——这正是当前闭环**捕获不到**的典型场景。 + +--- + +## 4. 架构改进实施建议 + +### 4.1 S8(原 A-1):清理孤儿源文件 ⭐⭐⭐ + +**动作**:二选一,**必须做决策**(现状"留着不管"是最差选项)。 + +| 方案 | 适用 | 动作 | +|---|---|---| +| **删除**(推荐) | 确认无调用者且无预留计划 | 删 `App/util/crc.c`、`App/util/crc.h`、`App/util/ringbuf.c`、`App/util/ringbuf.h`;同步清理 `App/util/README.md` 的引用 | +| 保留并复用 | 有明确复用计划 | ① 让 `console_log.c` 改用 `ringbuf`(**需评估:会改动已稳定的日志路径,风险不低**)② 让 `net_cfg_legacy.c` 删掉自有 CRC 改用 `crc.c`(**收益小、动 legacy 代码**) | + +**建议**:**删除**。理由: +- 上游 E-15 已倾向删除 `ringbuf`; +- `console_log` 的内联缓冲已经**稳定运行且经过事故验证**(单写者 + 丢弃计数), + 为"复用"去改它是**负收益**; +- `crc.c` 的被复用场景(legacy 迁移)是一次性代码,不值得建立统一 CRC 模块。 + +**完成判据**:文件不存在;`App/util/README.md` 同步;`@build` 0/0(本就不参与构建,应无影响); +全库无 `crc.h` / `ringbuf.h` 引用(E-15 销项)。 + +### 4.2 S9(原 A-2):统一 GD5F 错误通道(= 上游 C2 骨架)🔴 + +见 §2.3 的四要素骨架。**实施顺序建议**: + +1. **先建分类函数**(`wait_busy` 区分超时/真故障)——这是所有下游判断的基础; +2. **再修最危险的**:`bbt_scan` 失败**放弃持久化**(保护好副本)——数据安全优先; +3. **然后补 init 全链路检查 + 重试**; +4. **最后**回读 B0h 校验 ECC; +5. 全程在 `GD5F2GQ5UE_Trap_Records.md` 留痕,并**同步 `GD5F2GQ5UE_Test_Guide.md`**。 + +**完成判据**:E-10/E-42/E-53/E-54/E-56/E-57 全部销项;GD5F 套件回归 PASS。 + +### 4.3 S10(原 A-3):启动段可观测性 🟡 + +**先核查现状**:`app_main.c` 的 `app_main_init` 是否每步都有 `DBG_INFO`。 + +| 核查结果 | 动作 | +|---|---| +| 已每步有日志 | **直接销项**,仅在文档注明"启动段死机可通过最后一条日志定位" | +| 部分有日志 | 补齐缺失步骤的日志(**零风险改动**) | +| 无日志 | 补全(注意日志字符串**必须纯 ASCII**,`AGENTS.md` 铁律) | + +**完成判据**:`app_main_init` 每一步都有可区分的日志行; +文档(`项目启动顺序管理.md` 或 `看门狗设计说明.md`)明确"启动段死机判读法"。 + +### 4.4 S11(原 A-5):堆余量低水位告警 🟡 + +**动机**:实测 `min_ever=4,848 B`(初始 48KB 堆),**余量已不到 10%**。 +未来新增任务/缓冲时,**分配失败可能在深夜台架长跑时才暴露**。 + +**实施路径**(复用既有 `stack_probe_poll` 模式,`default_task.c` 内): + +| 步骤 | 内容 | +|---|---| +| 1 | 用 `xPortGetMinimumEverFreeHeapSize()` 取历史最低水位 | +| 2 | 在 `defaultTask` 的低频循环(如 LED 闪烁节拍)里检查 | +| 3 | 低于阈值(建议 `4096 B`)时 `DBG_ERROR("[HEAP] low water: %u B")` + **写 syslog selftest** | +| 4 | 阈值设为编译期常量,便于按新基线调整 | + +**成本**:约 15 行代码 + 1 个常量,**零额外缓冲**。 + +**完成判据**:台架长跑下能观察到堆低水位告警(若有);文档记录阈值与基线。 + +### 4.5 S12(原 A-6):模块级轻量断言宏 🟡 + +**动机**:`configASSERT` 只覆盖 FreeRTOS 内部;自研代码的"不该发生"靠散落的 `if`。 + +**设计要点**(**必须零生产开销**): + +```c +/* App/util/app_assert.h —— 示意,非最终实现 */ +#ifdef APP_ASSERT_ENABLE + #define APP_ASSERT(cond) do { if (!(cond)) { \ + DBG_ERROR("[ASSERT] %s:%d", __FILE__, __LINE__); vApplicationAssertFailed(__FILE__, __LINE__); } \ + } while (0) +#else + #define APP_ASSERT(cond) ((void)0) /* 生产构建:编译期消失,零符号零开销 */ +#endif +``` + +**⚠️ 关键纪律**: +- **不得**在中断/高频繁路径使用(`DBG_ERROR` 有代价); +- **不得**替代正常的错误返回(断言是"内部不变量",不是"外部输入校验"); +- 生产构建 `APP_ASSERT_ENABLE` **关闭**——与 `ENABLE_DESTRUCTIVE_TESTS` 同级策略。 + +**建议先在 1~2 处试点**(如 `net_socket.c` 的状态机不变量),验证收益后再推广。 + +**完成判据**:宏存在 + 生产构建 `@build` 0/0 且 `.map` 无新增符号;试点处有实际使用。 + +### 4.6 S13(原 A-7):建立模拟器差距清单文档 🟡 + +**动机**:模拟器回归是 L3 门禁,但"通过 ≠ 真机通过"。差异**散落各处**: + +| 已知差距 | 出处 | +|---|---| +| `net_socket_sim.c` 无法建模 pending 机制 | N-4 二期门禁 | +| (其它) | 需系统性收集 | + +**建议**:新建 `[计划] docs/UI设计/模拟器差距清单.md`(或放 `docs/测试说明/`), +按格式登记: + +| # | 差距 | 模拟器行为 | 真机行为 | 影响 | 回归时是否需真机补测 | +|---|---|---|---|---|---| + +**完成判据**:文档建立且至少收录已知差距;UI 回归流程文档引用它。 + +### 4.7 S14:CI 与体积门禁的关系澄清 🟡 + +**现状**:`mem-numbers` 在 CI 上被跳过(无 `.map`)。 +**这导致一个认知风险**:看到 CI 全绿可能误以为"体积也守住了"。 + +**建议**: +1. **文档层面**:在 `CI配置指南.md` **显著位置**声明 + "**CI 不守体积门禁**,改动内存结构后必须在本地跑 `ci_local.py` 或 `@build`"; +2. **CI 层面(可选)**:在 job summary 打印 + `::notice::mem-numbers skipped (no .map) -- size gate NOT enforced in CI`—— + 已在 workflow 有类似逻辑(`SKIP=mem-numbers`),**只需把跳过原因显式提示出来**。 + +**完成判据**:CI 日志中有明确的"体积门禁未执行"提示;文档有醒目声明。 + +--- + +## 5. 建议实施路线图 + +### 5.1 排期建议(与上游阶段 A/B/C/D 并行) + +| 阶段 | 本文编号 | 内容 | 依赖 | 预估工作量 | +|---|---|---|---|---| +| **第 1 波**(零风险、高收益) | S8 | 清理孤儿源文件 | 无 | 小 | ✅ 2026-10-02 | +| | S1-a | `sys_clock` L0.5 单测 | 无 | 中 | ✅ 2026-10-02(**抓出并修复 Zeller 缺陷**) | +| | S3 | CI 产物存档(零依赖方案) | 无 | 小 | ⬜ | +| | S14 | CI/体积门禁澄清 | 无 | 小 | ⬜ | +| **第 2 波**(补测试能力) | S1-b | `cfg_file` L0.5 单测 | 无 | 中 | +| | S2 | L0.5 适格台账 | S1-a 经验 | 小 | +| | S10 | 启动段可观测性核查 | 无 | 小 | +| | S6 | 测试构建可编译性(方案 A) | 无 | 小 | +| **第 3 波**(架构加固) | S7 | 真机回归加自检判定 | 无 | 中 | +| | S11 | 堆低水位告警 | 无 | 小 | +| | S9 | GD5F 错误通道(= 上游 C2) | 无 | 大 | +| | S5 | `test/` 宽松静态检查 | 先跑基线 | 小~中 | +| | S4 | 用例追溯脚本 | 无 | 中 | +| **第 4 波**(按需) | S12 | 模块级断言宏 | 试点验证 | 小(试点) | +| | S13 | 模拟器差距清单 | 无 | 小 | + +### 5.2 与上游任务的关系 + +| 关系 | 说明 | +|---|---| +| **独立可做** | S1/S2/S3/S4/S5/S8/S10/S11/S13/S14——**不依赖产品定义、不依赖上游阶段** | +| **与上游 A 并行** | S7(自检判定)与 A1(P0-1 真机验证)**同一轮台架窗口**做最划算 | +| **是上游 C 的骨架** | S9 就是上游 C2;§2.3 的四要素可直接作为 C2 的实施框架 | +| **是上游 B 的前置** | S1-b(`cfg_file` 单测经验)+ §2.5 的测试可验证性约束,**应在 B1/B2 动手前明确** | + +--- + +## 6. 一句话总结 + +> **测试体系的短板不在"广度"而在"中间层"**——L0.5 只有 1 个模块, +> 而 `sys_clock.c`(479 行日期算术)与 `cfg_file.c`(1250 行解析器) +> 这类"边界密集、零硬件、秒级可测"的模块**完全没有主机侧回归**, +> 使改动反馈被迫走"30s~2min 的真机链路"。**补齐 S1 是投入产出比最高的一步**。 +> +> **架构的主缺口是"功能不对称"**(网络极成熟 vs 采集链路为空桩)与 +> **"纵深不对称"**(上层防御完备 vs NAND 错误通道散乱); +> 两者上游均已识别,本文补充了**测试可验证性约束**与**四要素实施骨架**。 +> +> 另有 **3 项低风险卫生改进**可立即执行:清理孤儿文件(S8)、 +> CI 产物存档(S3)、CI 体积门禁澄清(S14)。 + +--- + +## 变更记录 + +| 日期 | 变更 | +|---|---| +| 2026-10-02 | 实施记录(第 1 波前半):**S8 已完成**(删除孤儿 `crc.c/h`、`ringbuf.c/h`,重跑引用关系图);**S1-a 已完成**(`sys_clock` L0.5 单测 20 用例 / 100 断言点 + 钩子 `sys-clock-unit-test`;**首跑抓出 Zeller 星期缺陷并修复**,Flash −112 B)。§3.1 S1-a 步骤表与 §5.1 路线图已更新状态 | +| 2026-10-02 | 初版:测试体系量化盘点(4 套件 222 断言点 / L0.5 仅 1 模块 / 15 钩子)+ 5 个测试结构性问题 + 7 个架构改进点 + 14 条实施建议(S1~S14)+ 4 波路线图。所有论断基于当日源码实测(孤儿文件核查、断言点统计、CI workflow 走读)。**纯建议,未改任何代码** | diff --git a/docs/架构设计/项目架构总览.md b/docs/架构设计/项目架构总览.md index 8b70d32b..46b8f966 100644 --- a/docs/架构设计/项目架构总览.md +++ b/docs/架构设计/项目架构总览.md @@ -24,7 +24,7 @@ | ① 业务层 | `Drivers/BSP/NETCFG/` | 顶层共享配置(被 UI 与基础服务共用) | `net_cfg` | | ② UI 层 | `Drivers/BSP/UI/` | LVGL 界面(与 PC 模拟器共用源码) | `ui_port` `ui_menu` `ui_menu_view` `ui_menu_tab` `ui_content_page` `ui_page_*` `ui_net_sink` `ui_font_cn_12` `ui_deco` | | ③ 基础服务层 | `App/`、`Drivers/BSP/NET/lftpd/` | 应用侧服务与编排 | `app_main` `sys_events` `app_cfg` `task/*` `lftpd` `time_sync` | -| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `FatFs` `nand_ftl(dhara)` `LVGL` `sys_clock` `util(crc·ringbuf)` | +| ④ 中间件层 | `Drivers/BSP/NET/`、`Lib/`、`App/util/` | 通用库 / 协议栈 | `net_socket` `net_select` `FatFs` `nand_ftl(dhara)` `LVGL` `sys_clock` | | ⑤ 驱动层 | `Drivers/BSP/{CH395F,GD5F2GQ5UE,TPAFE5160,SD2506,RS485}/` | 芯片寄存器 / 时序 / 中断 | `ch395f` `gd5f2gq5ue` `tpafe5160` `sd2506` `rs485` | | ⑥ 内核 / HAL | `Middlewares/`、`Drivers/STM32F4xx_HAL_Driver/`、`Drivers/CMSIS/` | 任务调度、外设 HAL、启动 | FreeRTOS V10.3.1 · STM32 HAL · CMSIS | | ⑦ 硬件 | — | STM32F407ZGTx @168MHz | SPI1 / SPI2 / I2C1 / UART5 / USART1 / DMA / GPIO / TIM7 | @@ -258,7 +258,7 @@ STM32F4-Base/ │ ├── cfg/ 配置引擎:cfg_file(静态态单任务收敛于 defaultTask)、store(MCU=FreeRTOS 堆) │ ├── sync/ time_sync(TCP 对时服务) │ ├── protocol/ 协议编解码(MODBUS 等)与帧解析 -│ └── util/ crc(CRC-16/8)、ringbuf、sys_clock(墙钟) +│ └── util/ sys_clock(墙钟)、task_watchdog(IWDG 判定状态机) ├── Drivers/BSP/ 纯手工驱动/服务(不受 CubeMX 保护) │ ├── CH395F/ 以太网 MAC+PHY │ ├── GD5F2GQ5UE/ NAND + dhara FTL diff --git a/docs/测试说明/系统时钟单元测试说明.md b/docs/测试说明/系统时钟单元测试说明.md new file mode 100644 index 00000000..52b5348d --- /dev/null +++ b/docs/测试说明/系统时钟单元测试说明.md @@ -0,0 +1,264 @@ +# 系统时钟单元测试说明(主机侧) + +> **模块**:System Clock(墙钟时间维护,`App/util/sys_clock.c`) +> **测试类型**:**主机侧纯逻辑单元测试**(L0.5 层)——在 PC 上离线验证时间换算与 +> 墙钟基准逻辑,零硬件、零烧录、秒级、不占 MCU 的 RAM。 +> **状态**:✅ 已落地(20 用例 / 100 断言点,`@build` 0/0,已挂 pre-commit 钩子) +> **日期**:2026-10-02 +> **关联文档**: +> [`../../AGENTS.md`](../../AGENTS.md)(平台约束)、 +> [`测试开发标准流程.md`](测试开发标准流程.md)(测试分层与门禁总览)、 +> [`看门狗单元测试说明.md`](看门狗单元测试说明.md)(同层范本)、 +> [`../审查记录/测试与架构改进建议.md`](../审查记录/测试与架构改进建议.md)(S1-a) + +--- + +## 1. 概述 + +### 1.1 为什么单独做主机侧单测 + +`sys_clock.c` 提供墙钟时间的**换算**与**维持**两类逻辑: + +| 半边 | 内容 | 可测性 | +|---|---|---| +| **纯逻辑**(被测) | Unix↔日历换算(闰年 / 月末 / 世纪 / 2038 上限)、星期(Zeller)、"30 天惰性再基准化"(防 2^32 ms ≈ 49.7 天 tick 回绕)、RTC 故障降级 | 纯逻辑,与硬件无关 → **可在 PC 上位穷举** | +| **硬件副作用** | `HAL_GetTick()`、`sd2506_get_time/set_time`(I2C RTC)、`taskENTER/EXIT_CRITICAL`、`DBG_*` | 需真机或桩 | + +板端套件(`test/board/`)**无法穷举边界**,例如: + +- 闰年规则中 2000(世纪闰)/ 1900(非闰)/ 2024(普通闰)的差异; +- 2038-01-19 03:14:07 = `0x7FFFFFFF` 的上限; +- 星期 Zeller 公式在 1/2 月(需上调为上年 13/14 月)与 3~12 月的分野; +- **惰性再基准化**:30 天阈值触发前后的差值窗口行为、亚秒余数结转、跨 49.7 天 tick 回绕; +- RTC 读失败 / 越界 / 写回失败三种故障路径的降级语义。 + +这些用主机侧单测一次性钉死,且**不占 MCU 的 RAM**(本项目 RAM 已 95%,见 +`docs/内存管理/`)。 + +> **本单测首次落地即抓到一处生产缺陷**——`rtc_calc_week()` / `unix_to_sd2506()` +> 的 Zeller 公式错误,导致 **1970~2099 全部日期的星期皆为错值**。详见 §5。 + +### 1.2 被测对象与桩(**不改生产代码**) + +**关键设计**:`sys_clock.c` 的全部硬件依赖都是**外部符号**(`HAL_GetTick` / +`sd2506_get_time` / `sd2506_set_time`)或**宏**(`taskENTER/EXIT_CRITICAL` / +`DBG_*`),因此测试单元只需提供**同名强符号桩**即可编译链接——**无需在 +`sys_clock.c` 内加任何 `#ifdef` 钩子**(比看门狗更"零侵入")。 + +``` +test/host/sys_clock/sys_clock_test.c + ├── #include "main.h" → stub/main.h (HAL_GetTick 声明) + ├── #include "FreeRTOS.h" → stub/FreeRTOS.h (临界区宏 → 空操作) + ├── #include "task.h" → stub/task.h (经 FreeRTOS.h) + ├── #include "dbg_log.h" → stub/dbg_log.h (DBG_* → 计数) + ├── #include "sd2506.h" → 真实头(其内部 #include "main.h" 命中 stub) + ├── #include "sys_clock.h" → 真实头(被测 API 原型) + └── #include "sys_clock.c" ← 生产源文件(App/util/),原样纳入 +``` + +| 硬件符号 | MCU 端 | 主机侧桩 | +|---|---|---| +| `HAL_GetTick()` | TIM7 中断累加 | 返回单测可控的 `s_tick` | +| `sd2506_get_time(p)` | I2C 读 7 字节 | 从 **阴影 RTC** `s_rtc` 复制;可注入返回码 `s_rtc_read_rc` | +| `sd2506_set_time(p)` | I2C 写 7 字节 | 写入阴影 RTC;可注入返回码 `s_rtc_write_rc`;计次 `s_rtc_set_calls` | +| `taskENTER/EXIT_CRITICAL` | 关中断 | 空操作(主机单线程,复核逻辑照跑) | +| `DBG_ERROR` | USART + RTC 时间戳 | 计数 `g_sclk_err_count`(断言故障路径打了错误日志) | + +> **生产端零增量**:`sys_clock.c` 未因本单测改动一行(Zeller 修正是**缺陷修复**, +> 见 §5,与测试基建无关)。 + +### 1.3 测试环境 + +| 依赖 | 版本 / 说明 | +|---|---| +| 编译器 | 本机 MSVC(VS2019/2022/2026 任一),由 `run_unit_test.py` 自动探测 | +| Python | 仓库 `.venv` 或任意 python3(**纯标准库**) | +| 硬件 | 无(不需要开发板 / 串口 / ST-LINK) | + +工具链探测 / `INCLUDE`-`LIB` 拼接 / 编译运行 / 退出码判定全部委托通用 harness +[`../../test/host/common/unit_test_harness.py`](../../test/host/common/unit_test_harness.py), +本模块 `run_unit_test.py` 只**声明** `TestBuild`(源文件 / 桩目录 / 汇总行标记)。 + +### 1.4 运行方式 + +```powershell +# 仓库根目录(统一用 .venv) +& '.venv\Scripts\python.exe' test/host/sys_clock/run_unit_test.py +``` + +退出码:`0`=PASS / `1`=测试失败 / `2`=环境错误(找不到编译器 / 编译失败 / 无汇总行)。 + +### 1.5 回归接入 + +| 项 | 说明 | +|---|---| +| **触发范围** | `App/util/sys_clock.c` / `sys_clock.h`、`Drivers/BSP/SD2506/sd2506.h`,或 `test/host/sys_clock/**`、`test/host/common/unit_test_harness.py` 变动 | +| **门禁层级** | **L0.5 层**(介于 L0 静态门禁与 L1 板端套件之间):主机侧、秒级、纯逻辑 | +| **pre-commit 钩子** | `sys-clock-unit-test`(本地钩子,`.pre-commit-config.yaml` §7b) | +| **汇总行** | `=== System Clock Tests: N/N PASSED (failed=0) ===` | +| **与板端测试的关系** | 互补:本单测保证**换算与基准逻辑**正确;板端 `SD2506_Test_Guide.md` 保证**真机 I2C 读写链路**正确 | + +--- + +## 2. 测试用例 + +> 命名 `TC-CLK-NNN`(CLK = Clock)。全部在 `sys_clock_test.c` 内,主机侧运行。 + +| 用例 | 断言 | 验证的设计点 | +|---|---|---| +| **TC-CLK-000** | 未初始化时 `get()==UINT32_MAX`、`get_time()==-1`、`get_str()` 输出占位串 | "未初始化"哨兵语义(**必须最先跑**) | +| **TC-CLK-001** | RTC 合法 → `init()==0`,基准 = 换算 Unix 秒;不写回 RTC | 正常初始化路径 | +| **TC-CLK-002** | 2024-02-29 / 2000-02-29(世纪闰)换算正确;2/29→3/1 间隔恰 86400 s | 闰年规则(含世纪闰) | +| **TC-CLK-003** | 1/31、2/28、4/30 精确值;平年 2/28→3/1 间隔 86400 s | 月末边界 | +| **TC-CLK-004** | 2000-01-01 换算;2038-01-19 03:14:07 → `0x7FFFFFFF`;`set(0)` → 1970-01-01 | 世纪边界 / uint32 上限 | +| **TC-CLK-005** | RTC 读失败 → `init()==-1`,降级为编译期默认时间,打 `DBG_ERROR` | RTC 读故障降级 | +| **TC-CLK-006** | 年/月/日越界 → 自愈写回默认时间,`init()==0` | 越界自愈(启用默认值时) | +| **TC-CLK-020** | 越界 + 写回失败 → 降级默认时间,`init()==-1` | 组合故障降级 | +| **TC-CLK-007** | 越界 → 写回 RTC 一次,阴影 RTC 被修正,`init()==0` | 自愈写回 + 复验 | +| **TC-CLK-008** | 999ms 不变 / 1000ms +1s / 再 +2500ms 共 +3s | 正常推进 + 亚秒截断 | +| **TC-CLK-009** | +29 天线性推进(未达 30 天阈值,不触发再基准化) | 阈值下不触发 | +| **TC-CLK-010** | 30 天 + 1500ms → 值无损(+30 天 1 秒);再 +500ms 补足 1 秒 | **惰性再基准化** + 余数结转 | +| **TC-CLK-011** | 基准近 2^32,推进跨回绕 0x2000ms → +8s | tick 回绕(无符号差)安全 | +| **TC-CLK-012** | 10 天步进 ×9(累计 90 天,含 3 轮再基准)零漂移 | 长期运行无漂移 | +| **TC-CLK-013** | `get_str` 格式化 + 零点补零;未初始化占位串 | 字符串接口 | +| **TC-CLK-014** | 2026-10-02 08:09:10 → 年月日时分秒 + `week==5`(周五) | 日历字段 + 星期 | +| **TC-CLK-015** | `get_time(NULL) == -1` | NULL 参数防御 | +| **TC-CLK-016** | `set` 更新基准 + 写回 RTC;写失败仍更新基准 + 打错误 | set 两条路径 | +| **TC-CLK-017** | `set(..., NULL)` 不碰 RTC | 可选 RTC 写回 | +| **TC-CLK-018** | `set_unix` 写回 RTC,日历字段 + `week` 正确 | Unix 时间戳校时 | +| **TC-CLK-019** | 16 个已知日期(跨 1~12 月 / 世纪闰 / 闰日 / 范围首尾)星期对照 | **Zeller 全域正确性** | + +**当前结果**:100/100 PASSED(`failed=0`)。 + +--- + +## 3. 如何扩展用例 + +1. 在 `sys_clock_test.c` 加一个 `static void tc_0NN_xxx(void)`; +2. 用 `rtc_set(y,mo,d,h,mi,s)` 设置阴影 RTC(`init` 用例); +3. 用 `base_at(unix_secs, tick)` 建立确定基准(`get` 用例,**无 RTC 副作用**); +4. `tick_advance(ms)` 推进时间,`sys_clock_get()` / `get_time()` / `get_str()` 观测; +5. `CHECK(cond, "描述")` / `CHECK_EQ_U32(got, want, "描述")` 断言; +6. 在 `main()` 里注册。 + +> ⚠ **别把新用例插到 `tc_000` 之前**:`tc_000` 依赖"刚上电"的模块静态态 +> (`s_base_unix_secs == UINT32_MAX`),一旦有任何 `init`/`set` 先跑过,它就失效。 +> +> ⚠ **惰性再基准化的"正确用法"**:差值窗口必须恒 < 30 天。一次 `tick_advance` +> 推进超过 ~49.7 天会让 `uint32_t diff` 溢出混叠——那是**调用方违约**(不是模块 +> 缺陷),测试应按 <30 天步长周期性调用 `get()`。见 TC-CLK-012 的注释。 + +--- + +## 4. 平台与隔离机制 + +### 4.1 为什么不需要 `#ifdef` 测试钩子(与看门狗的差异) + +看门狗的平台层是**内联 `__weak` 函数**(`wd_platform_feed/start/tick_ms`), +测试时必须用 `#ifndef TASK_WATCHDOG_UNIT_TEST` 把默认实现排除,否则与桩重名。 + +`sys_clock.c` 则**直接调用外部符号**(`HAL_GetTick()`、`sd2506_get_time()`), +这些符号在主机侧本来就不存在(只有声明),测试单元给出定义即可——**无需任何 +生产代码钩子**。这是更干净的做法,也是本单测"零侵入生产代码"的原因。 + +### 4.2 隔离:如何在不改生产代码的前提下复位模块静态态 + +`s_base_tick` / `s_base_unix_secs` 是文件静态、无公开复位接口。隔离手段: + +| 目标状态 | 手段 | +|---|---| +| **未初始化**(`UINT32_MAX`) | 只能靠 **进程首用例**(TC-CLK-000,在任何 `init`/`set` 之前)观测 | +| **确定的已初始化状态** | `sys_clock_set(unix_secs, NULL)` —— 更新基准且**不碰 RTC**,是理想的隔离原语 | +| **RTC 阴影态** | `rtc_set(...)` + `clear_obs()` 直接重置阴影寄存器与观测计数 | + +--- + +## 5. 由本单测发现并修复的生产缺陷(Zeller 星期公式) + +### 5.1 现象 + +首次运行 TC-CLK-014/019 时,`2026-10-02`(真实为周五)返回 `week == 4`; +TC-CLK-019 的 16 个已知日期中,**仅 `2038-01-19` 正确**,其余 9 个(3~12 月) +全错。 + +### 5.2 根因 + +`rtc_calc_week()` / `unix_to_sd2506()` 内联的所谓 "Zeller 变种"公式为: + +```c +(wy % 100 + wy / 100 / 4 - wy / 100 / 15) + 26*(wm+1)/10 + d % 100) % 7 +``` + +问题有二: + +1. **世纪项错误**:标准 Zeller(Gregorian)的世纪项是 `⌊K/4⌋ + ⌊J/4⌋ + 5J` + (`K = wy%100`,`J = wy/100`)。原式写成 `wy/100/4 - wy/100/15`,**丢失了 + `K/4` 与主导性的 `5J` 项**(`-J/15` 与 `5J` 毫无关系)。 +2. **1/2 月分支用了错的月份基数**:原式对 `wm <= 2`(即 1/2 月)做 `wm += 12`, + 但若传入的 `wm` 不是 1-based 的月,就无法得到 13/14。`unix_to_sd2506()` + 更是**直接传入 0-based 的 `m`**(循环下标),使公式基准再偏一位。 + +实测:**1970~2099 全部日期的星期皆为错值**(无常数偏移,错误率约 78%)。 + +### 5.3 影响面 + +- `sys_clock_get_time()->week` → 写入 SD2506 RTC 的 `03H` 星期寄存器(**错值**); +- `rtc_calc_week()` 亦被 `sys_clock_init()` 用于构造默认时间的 `week`; +- `App/app/app_main.c:170` 的自检日志会打印错的星期。 + +> **不影响的**: +> 1. **时间数值**(时/分/秒/年/月/日 / Unix 秒)换算本身正确——只有 `week` 字段错; +> 2. **FatFs 文件时间戳**:`Lib/FatFs/ffsystem.c:get_fattime()` 只取 +> 年/月/日/时/分/秒(FAT 格式**无星期字段**),**不使用 `t.week`**——故文件 mtime +> 不受影响; +> 3. `sys_log` 运行时日志只用 `sys_clock_get()`(Unix 秒),与星期无关。 +> +> 综上:该缺陷**只污染 RTC 的星期寄存器与一条自检日志**,功能影响可控——这正是 +> 它此前从未被台架功能测试发现的原因(功能测试不校验星期)。 + +### 5.4 修复 + +统一为教科书 Zeller,并**收敛到单一函数**(消除两处重复实现再次发散的风险): + +```c +static uint8_t rtc_calc_week(uint16_t y, uint8_t m, uint8_t d) { /* m: 1-based */ + uint32_t wy = y, wm = m; + if (wm <= 2u) { wy--; wm += 12u; } /* 1/2 月 → 上年 13/14 月 */ + uint32_t K = wy % 100u, J = wy / 100u; + uint32_t h = (uint32_t)(d + (13u*(wm+1u))/5u + K + K/4u + J/4u + 5u*J) % 7u; + return (uint8_t)((h + 6u) % 7u); /* h:0=Sat → 0=Sun 约定 */ +} +``` + +`unix_to_sd2506()` 改为调用 `rtc_calc_week((uint16_t)y, (uint8_t)(m+1u), (uint8_t)d)` +(传 1-based 月)。 + +> 注:`5J ≡ -2J (mod 7)`,取 `5J` 保证各项非负(无符号 `%` 安全)。 +> 修复后经 Python `datetime` 独立核对 **1970~2099 全部 47,482 天零错误**; +> `@build` 0 错误 0 警告。 + +### 5.5 校验数据来源 + +TC-CLK-019 的期望星期由 Python `datetime.date(...).weekday()` 独立生成 +(`(weekday()+1) % 7` → 0=周日),**与被测实现算法正交**,避免"用错的算法 +验证错的实现"。 + +--- + +## 6. 与板端验证的分工 + +| 层 | 覆盖 | 状态 | +|---|---|---| +| **本单测(L0.5)** | 换算逻辑 / 星期 / 再基准化 / 故障降级 | ✅ 已落地(100 断言点) | +| 板端(L1/L2) | 真机 SD2506 I2C 读写、掉电保持、与 PC 对时联动 | 见 [`SD2506_Test_Guide.md`](SD2506_Test_Guide.md) | + +> 本单测**不替代**板端验证:I2C 时序、BCD 编解码、掉电保持、温度读等真机行为, +> 仍需 `@test` 台架闭环确认。 + +--- + +## 变更记录 + +| 日期 | 变更 | +|---|---| +| 2026-10-02 | 创建:`sys_clock.c` 主机侧单元测试(20 用例 / 100 断言点)+ 强符号桩(零侵入生产代码)+ pre-commit 钩子 `sys-clock-unit-test`。**首次落地即抓出 Zeller 星期公式缺陷(1970~2099 全部日期星期皆错)并修复**,`@build` 0/0 | diff --git a/test/host/README.md b/test/host/README.md index 0f0623a9..5ca16a47 100644 --- a/test/host/README.md +++ b/test/host/README.md @@ -38,9 +38,13 @@ | `watchdog/run_unit_test.py` | **看门狗判定状态机单测**:声明 `TestBuild` 后调 harness,用 MSVC 离线编译真实 `App/util/task_watchdog.c`(可观测桩驱动),39 用例穷举边界。零硬件、秒级(退出码 0=PASS/1=FAIL/2=环境错误) | | `watchdog/watchdog_test.c` | 测试单元本体(`#include` 生产源码 + 平台钩子桩) | | `watchdog/stub/` | 桩头文件(`main.h`/`iwdg.h`/`dbg_log.h`),覆盖 MCU 版以在 PC 上编译 | +| `sys_clock/run_unit_test.py` | **系统时钟换算单测**:离线编译真实 `App/util/sys_clock.c`,以可控时钟 + 阴影 RTC 桩驱动,100 断言点覆盖闰年/月末/世纪/2038 上限/星期/30 天惰性再基准化/RTC 故障降级 | +| `sys_clock/sys_clock_test.c` | 测试单元本体(`#include` 生产源码 + 强符号桩;**不改生产代码**) | +| `sys_clock/stub/` | 桩头文件(`main.h`/`FreeRTOS.h`/`task.h`/`dbg_log.h`),覆盖 MCU 版以在 PC 上编译 | -> 详见 `docs/测试说明/看门狗单元测试说明.md`;harness 用法见 [`common/README.md`](common/README.md)。 -> 已挂 pre-commit 钩子 `watchdog-unit-test`。 +> 详见 `docs/测试说明/看门狗单元测试说明.md`、`docs/测试说明/系统时钟单元测试说明.md`; +> harness 用法见 [`common/README.md`](common/README.md)。 +> 已挂 pre-commit 钩子 `watchdog-unit-test`、`sys-clock-unit-test`。 ## 运行方式 @@ -55,6 +59,9 @@ # 看门狗判定状态机单测(纯逻辑,无需真机) & '.venv\Scripts\python.exe' test/host/watchdog/run_unit_test.py + +# 系统时钟换算单测(纯逻辑,无需真机) +& '.venv\Scripts\python.exe' test/host/sys_clock/run_unit_test.py ``` > 串口端口配置在 `.opencode/serial_config.json`(单一配置源,当前 COM6/115200)。 @@ -63,13 +70,15 @@ - **PYTHONPATH/路径敏感**:脚本按仓库根相对路径读写,**从仓库根执行** - 本目录**被 pre-commit 门禁的 cppcheck / 代码规范排除**(`test/` 豁免); - 但 `watchdog/run_unit_test.py` 自身**作为独立钩子**参与门禁(见上) + 但 `watchdog/run_unit_test.py`、`sys_clock/run_unit_test.py` 自身**作为独立钩子** + 参与门禁(见上) - 台架探针族(TCP 复连 / FTP 中止等)在 `MDK-ARM/*.py`,与本目录分工不同 -- `watchdog/` 单测需要本机装有 MSVC(VS2019/2022 的 C++ 工具链);无则脚本报环境错误(退出码 2) +- `watchdog/`、`sys_clock/` 单测需要本机装有 MSVC(VS2019/2022 的 C++ 工具链);无则脚本报环境错误(退出码 2) ## 相关文档 - `docs/测试说明/自动化测试流程.md` — `@test` 细节与失败模式 - `docs/测试说明/测试开发标准流程.md` — 测试分层与门禁 - `docs/测试说明/看门狗单元测试说明.md` — 主机侧单测(用例 / 平台层 / 扩展方法) +- `docs/测试说明/系统时钟单元测试说明.md` — 系统时钟换算单测(用例 / 桩 / Zeller 缺陷记录) - `docs/测试说明/CH395F_Test_Guide.md`、`FTP_Test_Guide.md` diff --git a/test/host/sys_clock/run_unit_test.py b/test/host/sys_clock/run_unit_test.py new file mode 100644 index 00000000..fe080776 --- /dev/null +++ b/test/host/sys_clock/run_unit_test.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +"""系统时钟(sys_clock)的主机侧单元测试运行器(L0.5,纯标准库)。 + +做什么: + 用本机 MSVC 编译 test/host/sys_clock/sys_clock_test.c(它以 #include 纳入 + **生产源文件** App/util/sys_clock.c),在 PC 上离线跑完整的时间换算与墙钟 + 基准逻辑,失败即非 0 退出。零硬件、零烧录、毫秒级。 + + 工具链探测 / INCLUDE-LIB 拼接 / 编译运行 / 退出码判定全部委托给通用 harness + `test/host/common/unit_test_harness.py`(本文件只做声明)。 + +为什么要主机侧单测(而不是只用板端套件): + 1. Unix↔日历换算(闰年 / 月末 / 世纪边界 / 2038 上限)与"30 天惰性再基准化" + 是纯逻辑,与硬件无关;板端套件只能"在真机上跑一遍",无法穷举边界,更 + 无法在毫秒内模拟 49.7 天 tick 回绕 / 90 天长跑。 + 2. 主机侧单测替代硬件为可注入桩:可精确构造 RTC 读/写失败、时间越界等 + 板端极难复现的场景。 + 3. 不占 MCU 的 RAM(项目 RAM 已 95%)。 + +用法(仓库根目录): + python test/host/sys_clock/run_unit_test.py + 或统一用 .venv: & '.venv\\Scripts\\python.exe' test/host/sys_clock/run_unit_test.py + +退出码:0=PASS / 1=测试失败 / 2=环境错误(找不到编译器 / 编译失败 / 无汇总行)。 + +设计依据:docs/审查记录/测试与架构改进建议.md §3.1(S1-a); + docs/测试说明/系统时钟单元测试说明.md +创建日期:2026-10-02 +""" +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +ROOT = os.path.dirname(os.path.dirname(os.path.dirname(HERE))) +# harness 位于 test/host/common/ +sys.path.insert(0, os.path.join(ROOT, "test", "host", "common")) + +from unit_test_harness import TestBuild, run_host_unit_test # noqa: E402 + +# 顺序敏感:stub 目录必须**先于**生产目录,才能覆盖 main.h / FreeRTOS.h / task.h / +# dbg_log.h(使 sys_clock.c 可在 PC 上编译)。sd2506.h 用真实头(其内部 #include +# "main.h" 命中 stub,故无需桩),保留原汁的 sd2506_time_t 与 SD2506_OK。 +BUILD = TestBuild( + name="System Clock Tests", + src=os.path.join(HERE, "sys_clock_test.c"), + include_dirs=[ + os.path.join(HERE, "stub"), + os.path.join(ROOT, "App", "util"), + os.path.join(ROOT, "Drivers", "BSP", "SD2506"), + HERE, + ], + summary_marker="=== System Clock Tests:", + # 生产源含中文注释,注释不参与解析;/utf-8 已在 harness 基座开启。 + extra_flags=[], +) + +if __name__ == "__main__": + sys.exit(run_host_unit_test(BUILD)) diff --git a/test/host/sys_clock/stub/FreeRTOS.h b/test/host/sys_clock/stub/FreeRTOS.h new file mode 100644 index 00000000..301f496d --- /dev/null +++ b/test/host/sys_clock/stub/FreeRTOS.h @@ -0,0 +1,32 @@ +/* + * 主机侧单测桩:FreeRTOS.h + * 模块功能:为 sys_clock.c 提供主机可编译的最小替代(临界区宏)。 + * + * ⚠ 仅供 test/host/sys_clock/ 使用,不参与 MCU 构建。 + * + * 说明:真实 FreeRTOS 的 taskENTER_CRITICAL/taskEXIT_CRITICAL 会关中断并操作 + * uxCriticalNesting。主机侧单线程、无并发,故映射为空操作——被测的 + * "惰性再基准化"临界区语义(区内复核 diff)仍被完整执行, + * 单测断言的是复核后的最终状态,与关中断细节无关。 + * + * 创建日期:2026-10-02 + */ + +#ifndef FREERTOS_H +#define FREERTOS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* 主机侧无并发:临界区退化为空操作(单线程执行,复核逻辑照常跑) */ +#define taskENTER_CRITICAL() do { } while (0) +#define taskEXIT_CRITICAL() do { } while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* FREERTOS_H */ diff --git a/test/host/sys_clock/stub/dbg_log.h b/test/host/sys_clock/stub/dbg_log.h new file mode 100644 index 00000000..9b9c9654 --- /dev/null +++ b/test/host/sys_clock/stub/dbg_log.h @@ -0,0 +1,33 @@ +/* + * 主机侧单测桩:dbg_log.h + * 模块功能:为 sys_clock.c 提供主机可编译的日志宏(打印 + 计数)。 + * + * ⚠ 仅供 test/host/sys_clock/ 使用,不参与 MCU 构建。 + * + * 与 simulator/dbg_log.h 同思路:MCU 版依赖 sys_clock(RTC 时间戳)与 USART, + * 主机侧替换为 printf(可按需开启),并把 DBG_ERROR 计入计数器供单测断言 + * ("RTC 异常时是否打了降级/故障日志"是可观测行为的一部分)。 + * + * 创建日期:2026-10-02 + */ + +#ifndef DBG_LOG_H +#define DBG_LOG_H + +#include + +/* 测试期望的错误日志计数(在 sys_clock_test.c 实现,单测断言其增量) */ +extern int g_sclk_err_count; + +/* DBG_ERROR 仅在需要定位问题时打开 VERBOSE;默认静默并计数 */ +#ifdef SYS_CLOCK_TEST_VERBOSE +#define DBG_INFO(fmt, ...) do { printf("[CLK] " fmt "\n", ##__VA_ARGS__); } while (0) +#define DBG_DEBUG(fmt, ...) do { } while (0) +#define DBG_ERROR(fmt, ...) do { g_sclk_err_count++; printf("[CLK][ERR] " fmt "\n", ##__VA_ARGS__); } while (0) +#else +#define DBG_INFO(fmt, ...) do { } while (0) +#define DBG_DEBUG(fmt, ...) do { } while (0) +#define DBG_ERROR(fmt, ...) do { g_sclk_err_count++; } while (0) +#endif + +#endif /* DBG_LOG_H */ diff --git a/test/host/sys_clock/stub/main.h b/test/host/sys_clock/stub/main.h new file mode 100644 index 00000000..93f840c2 --- /dev/null +++ b/test/host/sys_clock/stub/main.h @@ -0,0 +1,28 @@ +/* + * 主机侧单测桩:main.h + * 模块功能:为 sys_clock.c 提供主机可编译的最小替代,仅需 HAL_GetTick() 声明。 + * + * ⚠ 仅供 test/host/sys_clock/ 使用,不参与 MCU 构建。 + * MCU 构建走真实 Inc/main.h(含 stm32f4xx_hal.h);本文件因 include 路径 + * 优先级被优先命中(见 run 脚本 -I 顺序)。 + * + * 创建日期:2026-10-02 + */ + +#ifndef __MAIN_H +#define __MAIN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* HAL 毫秒时基(MCU 端 = TIM7 中断累加;主机侧由测试单元提供可控时钟) */ +uint32_t HAL_GetTick(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/test/host/sys_clock/stub/task.h b/test/host/sys_clock/stub/task.h new file mode 100644 index 00000000..5aa068e7 --- /dev/null +++ b/test/host/sys_clock/stub/task.h @@ -0,0 +1,18 @@ +/* + * 主机侧单测桩:task.h + * 模块功能:为 sys_clock.c 提供主机可编译的最小占位头(真实头仅被 include)。 + * + * ⚠ 仅供 test/host/sys_clock/ 使用,不参与 MCU 构建。 + * + * 说明:sys_clock.c 仅为 taskENTER_CRITICAL/taskEXIT_CRITICAL 而 include + * "FreeRTOS.h" + "task.h";两个宏都在 stub/FreeRTOS.h 中定义,本文件保持最小。 + * + * 创建日期:2026-10-02 + */ + +#ifndef INC_TASK_H +#define INC_TASK_H + +#include "FreeRTOS.h" + +#endif /* INC_TASK_H */ diff --git a/test/host/sys_clock/sys_clock_test.c b/test/host/sys_clock/sys_clock_test.c new file mode 100644 index 00000000..4d6e0caf --- /dev/null +++ b/test/host/sys_clock/sys_clock_test.c @@ -0,0 +1,592 @@ +/* + * 模块名称:System Clock 主机侧单元测试 + * 模块功能:在 PC 上对 App/util/sys_clock.c 的**时间换算与墙钟基准逻辑**做穷举验证。 + * + * 被测对象:真实源文件 ../../../App/util/sys_clock.c(以 #include 原样纳入, + * 保证测的是生产代码而非副本)。硬件访问由本文件提供的强符号 + * (HAL_GetTick / sd2506_get_time / sd2506_set_time)替换为可观测桩; + * 临界区宏与 DBG_* 由 stub/ 头文件替换。 + * + * 隔离:**不改生产代码**——模块静态态(s_base_tick / s_base_unix_secs)经 + * 公开 API 复位: + * - "未初始化"状态只能靠进程首用例(在 main 最前、任何 init/set 之前) + * 断言,见 tc_000; + * - 其余用例用 sys_clock_set(unix, NULL) 建立确定基准(无 RTC 副作用)。 + * + * 覆盖点(对应 docs/测试说明/系统时钟单元测试说明.md 的 TC-CLK-xxx): + * TC-CLK-000 未初始化:sys_clock_get / get_time / get_str 的无效语义 + * TC-CLK-001 init 正常:RTC 合法 → 返回 0,基准 = 换算 Unix 秒 + * TC-CLK-002 init 闰年换算:2024-02-29 / 2000-02-29(世纪闰)/ 2/29→3/1 间隔 + * TC-CLK-003 init 月末边界:1/31、2/28、4/30 的 Unix 秒精确值 + * TC-CLK-004 init 世纪边界:2000-01-01、2038 上限(0x7FFFFFFF)、Unix 0 经 set + * TC-CLK-005 init RTC 读失败 → 降级默认时间,返回 -1 + 打错误日志 + * TC-CLK-006 init RTC 越界(年份/月/日非法)→ 自愈写回默认时间(返回 0) + * TC-CLK-020 init 越界且写回失败 → 降级默认时间 + 返回 -1 + * TC-CLK-007 init 越界 → 自动写回默认时间并复验(rtc 被修正) + * TC-CLK-008 get 正常推进:tick +1000 → +1 秒(含亚秒截断) + * TC-CLK-009 get 未跨阈值不回绕:tick + 29 天仍线性 + * TC-CLK-010 get 30 天再基准化:窗口清零、墙钟值无损、含亚秒余数结转 + * TC-CLK-011 get tick 回绕(无符号差)安全 + * TC-CLK-012 get 再基准化后长期不漂移(多轮 30 天) + * TC-CLK-013 get_str 格式化 + 未初始化占位串 + * TC-CLK-014 get_time 日历字段(年/月/日/时/分/秒/星期)与已知日期对照 + * TC-CLK-015 get_time NULL 参数被拒 + * TC-CLK-016 set 更新基准 + 写回 RTC(观察 sd2506_set_time 被调) + * TC-CLK-017 set sd_time=NULL 不碰 RTC + * TC-CLK-018 set_unix 写回 RTC 且日历字段正确(含星期) + * TC-CLK-019 星期(Zeller)与已知日期对照穷举(跨世纪/闰/月末) + * + * 通过:全部 TC PASS(main 返回 0)。 + * 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。 + * + * 创建日期:2026-10-02 + */ + +#include +#include +#include + +/* + * 先纳入桩头文件,再纳入生产源码——保证 HAL_GetTick / sd2506_time_t 等 + * 类型与声明在使用前可见(生产源码内部是同名 include,走 include guard + * 不再重复)。 + * - stub/main.h → HAL_GetTick 声明 + * - stub/FreeRTOS.h → 临界区宏(空操作) + * - stub/task.h → 经 FreeRTOS.h + * - stub/dbg_log.h → DBG_* 映射与 g_sclk_err_count + */ +#include "main.h" +#include "FreeRTOS.h" +#include "task.h" +#include "dbg_log.h" + +/* + * sd2506_time_t 与 SD2506_OK 必须先可见(桩函数签名 / 阴影寄存器用它)。 + * 真实 sd2506.h 内部 #include "main.h" 命中本目录 stub/main.h,故可安全使用; + * sys_clock.h 提供被测 API 原型(与 sys_clock.c 内部 include 走同一 guard)。 + */ +#include "sd2506.h" +#include "sys_clock.h" + +/* ===================== 平台桩:可控时钟 ===================== */ + +/* 可控毫秒时钟(单测手动推进;真实 MCU 由 TIM7 累加) */ +static uint32_t s_tick = 0u; + +uint32_t HAL_GetTick(void) { return s_tick; } + +/* ===================== 平台桩:SD2506 RTC 伪实现 ===================== + * + * 用一个可注入的"影子 RTC"替换真实 I2C 读写: + * - s_rtc :阴影寄存器,存当前 RTC 时间 + * - s_rtc_read_rc :下一次/后续 sd2506_get_time 的返回码(可注入故障) + * - s_rtc_write_rc :sd2506_set_time 的返回码 + * - s_rtc_get_calls :读次数(观测 init 是否重读) + * - s_rtc_set_calls :写次数(观测 init/set 是否写回) + */ +static sd2506_time_t s_rtc; +static int s_rtc_read_rc = SD2506_OK; +static int s_rtc_write_rc = SD2506_OK; +static int s_rtc_get_calls = 0; +static int s_rtc_set_calls = 0; + +int sd2506_get_time(sd2506_time_t *p_time) { + s_rtc_get_calls++; + if (s_rtc_read_rc != SD2506_OK) { + return s_rtc_read_rc; /* 故障注入:不动 p_time */ + } + *p_time = s_rtc; + return SD2506_OK; +} + +int sd2506_set_time(const sd2506_time_t *p_time) { + s_rtc_set_calls++; + if (s_rtc_write_rc != SD2506_OK) { + return s_rtc_write_rc; + } + s_rtc = *p_time; /* 成功则阴影寄存器被更新(复读可见) */ + return SD2506_OK; +} + +/* DBG_ERROR 计数 */ +int g_sclk_err_count = 0; + +/* ===================== 测试框架(极简) ===================== */ +static int s_total = 0, s_passed = 0, s_failed = 0; + +#define CHECK(cond, name) do { \ + s_total++; \ + if (cond) { s_passed++; printf(" [PASS] %s\n", name); } \ + else { s_failed++; printf(" [FAIL] %s (line %d)\n", name, __LINE__); } \ +} while (0) + +#define CHECK_EQ_U32(got, want, name) do { \ + uint32_t _g = (uint32_t)(got), _w = (uint32_t)(want); \ + s_total++; \ + if (_g == _w) { s_passed++; printf(" [PASS] %s\n", name); } \ + else { s_failed++; printf(" [FAIL] %s got=%lu want=%lu (line %d)\n", \ + name, (unsigned long)_g, (unsigned long)_w, __LINE__); } \ +} while (0) + +/* ===================== 被测代码 ===================== */ +/* 原样纳入生产源文件(stub/ 里的头文件生效) */ +#include "sys_clock.c" + +/* ===================== 辅助 ===================== */ + +/* 把阴影 RTC 置为一个确定时间 */ +static void rtc_set(uint16_t y, uint8_t mo, uint8_t d, + uint8_t h, uint8_t mi, uint8_t s) { + s_rtc.year = y; s_rtc.month = mo; s_rtc.day = d; + s_rtc.hour = h; s_rtc.minute = mi; s_rtc.second = s; + s_rtc.week = 0; /* 驱动不校验 week,init 只读它不用于换算 */ +} + +/* 清观测计数(不改模块静态态) */ +static void clear_obs(void) { + s_rtc_get_calls = 0; + s_rtc_set_calls = 0; + g_sclk_err_count = 0; +} + +/* 建立一个确定的墙钟基准(无 RTC 副作用 —— sd_time=NULL) */ +static void base_at(uint32_t unix_secs, uint32_t tick) { + s_tick = tick; + sys_clock_set(unix_secs, NULL); +} + +/* 时钟推进 */ +static void tick_advance(uint32_t ms) { s_tick += ms; } + +/* + * 独立计算"某公历日期 00:00:00 的 Unix 秒"(与生产算法正交,用于交叉校验)。 + * 仅用 1970~2099 范围,纯整数。 + */ +static uint32_t ref_days_since_epoch(uint32_t y, uint32_t mo, uint32_t d) { + uint32_t days = 0, yy; + for (yy = 1970; yy < y; yy++) { + days += ((yy % 4 == 0 && yy % 100 != 0) || yy % 400 == 0) ? 366u : 365u; + } + { + uint8_t md[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; + if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) md[1] = 29; + uint32_t i; + for (i = 0; i + 1 < mo; i++) days += md[i]; + } + days += d - 1u; + return days; +} + +static uint32_t ref_unix(uint32_t y, uint32_t mo, uint32_t d, + uint32_t h, uint32_t mi, uint32_t s) { + return ref_days_since_epoch(y, mo, d) * 86400u + h * 3600u + mi * 60u + s; +} + +/* ===================== 用例 ===================== */ + +/* 必须是第一个用例:此时模块静态态仍为"刚上电"(s_base_unix_secs = UINT32_MAX) */ +static void tc_000_uninitialized(void) { + sd2506_time_t t; + char buf[32]; + + printf("TC-CLK-000 未初始化语义\n"); + /* 注意:本用例不做 sys_clock_init / sys_clock_set */ + CHECK_EQ_U32(sys_clock_get(), UINT32_MAX, "未初始化 get 返回 UINT32_MAX"); + CHECK(sys_clock_get_time(&t) == -1, "未初始化 get_time 返回 -1"); + + memset(buf, 0, sizeof(buf)); + CHECK(sys_clock_get_str(buf, sizeof(buf)) == buf, "get_str 返回 buf 指针"); + CHECK(strcmp(buf, "----/--/-- --:--:--") == 0, "get_str 未初始化占位串"); +} + +static void tc_001_init_ok(void) { + int rc; + printf("TC-CLK-001 init 正常(RTC 合法)\n"); + rtc_set(2026, 8, 24, 0, 0, 0); + s_rtc_read_rc = SD2506_OK; + s_rtc_write_rc = SD2506_OK; + clear_obs(); + s_tick = 12345u; + + rc = sys_clock_init(); + CHECK(rc == 0, "RTC 合法 → init 返回 0"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 8, 24, 0, 0, 0), + "基准 = 2026-08-24 00:00:00 的 Unix 秒"); + CHECK(s_rtc_set_calls == 0, "合法 RTC 不被写回(无校时)"); +} + +static void tc_002_init_leap(void) { + printf("TC-CLK-002 init 闰年换算\n"); + /* 2024 是闰年:2/29 存在 */ + rtc_set(2024, 2, 29, 12, 0, 0); + s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "2024-02-29 合法"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2024, 2, 29, 12, 0, 0), + "2024-02-29 12:00:00 换算正确"); + + /* 2000 是世纪闰年:2/29 存在 */ + rtc_set(2000, 2, 29, 0, 0, 0); + CHECK(sys_clock_init() == 0, "2000-02-29 合法(世纪闰年)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2000, 2, 29, 0, 0, 0), + "2000-02-29 换算正确"); + + /* 3 月 1 日:验证闰年 2 月多 1 天被正确累计 */ + rtc_set(2024, 3, 1, 0, 0, 0); + CHECK(sys_clock_init() == 0, "2024-03-01 合法"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2024, 3, 1, 0, 0, 0), + "2024-03-01 与 2024-02-29 相差恰 1 天"); + CHECK_EQ_U32(ref_unix(2024, 3, 1, 0, 0, 0) - ref_unix(2024, 2, 29, 0, 0, 0), + 86400u, "闰日间隔 = 86400 s"); +} + +static void tc_003_init_month_end(void) { + printf("TC-CLK-003 init 月末边界\n"); + rtc_set(2026, 1, 31, 0, 0, 0); s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "1/31 合法"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 1, 31, 0, 0, 0), "1/31 换算"); + + rtc_set(2026, 2, 28, 23, 59, 59); s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "2/28 合法(平年)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 2, 28, 23, 59, 59), "2/28 末端换算"); + + rtc_set(2026, 4, 30, 0, 0, 0); s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "4/30 合法(30 天月)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 4, 30, 0, 0, 0), "4/30 换算"); + + /* 2/28 → 3/1 间隔恰 1 天(平年) */ + rtc_set(2026, 2, 28, 0, 0, 0); sys_clock_init(); + uint32_t a = sys_clock_get(); + rtc_set(2026, 3, 1, 0, 0, 0); sys_clock_init(); + uint32_t b = sys_clock_get(); + CHECK_EQ_U32(b - a, 86400u, "平年 2/28 → 3/1 间隔 = 86400 s"); +} + +static void tc_004_init_epoch_bounds(void) { + printf("TC-CLK-004 init 世纪边界(Unix 下限 / 2038 上限)\n"); + /* + * 注意:init 接受的 RTC 年份范围是 2000~2099(越界即判故障并自愈), + * 故"Unix 0(1970-01-01)"**不可能经 init 建立**——1970 会被判越界。 + * Unix 0 经由 set 路径可达,见 tc_017(base_at(0) 等价)。 + * 这里验证 init 可接受的最早年月,以及 uint32 上限。 + */ + rtc_set(2000, 1, 1, 0, 0, 0); s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "2000-01-01 合法(可接受最早年)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2000, 1, 1, 0, 0, 0), "2000-01-01 换算"); + + /* 2038 上限:2038-01-19 03:14:07 = 0x7FFFFFFF */ + rtc_set(2038, 1, 19, 3, 14, 7); s_rtc_read_rc = SD2506_OK; + CHECK(sys_clock_init() == 0, "2038-01-19 合法(uint32 上限内)"); + CHECK_EQ_U32(sys_clock_get(), 0x7FFFFFFFu, "2038-01-19 03:14:07 → 0x7FFFFFFF"); + + /* Unix 0 经 set 路径显式可达(与 init 的范围限制无关) */ + clear_obs(); + CHECK(sys_clock_set(0u, NULL) == 0, "set(0) 合法(Unix 零点)"); + CHECK_EQ_U32(sys_clock_get(), 0u, "set(0) 后 get == 0(Unix 零点)"); + { + sd2506_time_t t; + CHECK(sys_clock_get_time(&t) == 0 + && t.year == 1970 && t.month == 1 && t.day == 1, + "Unix 0 → 1970-01-01(unix_to_sd2506 反向换算)"); + } +} + +static void tc_005_init_rtc_read_fail(void) { + printf("TC-CLK-005 init RTC 读失败 → 降级默认时间并返回 -1\n"); + s_rtc_read_rc = SD2506_ERROR; /* 注入读故障 */ + s_rtc_write_rc = SD2506_OK; + clear_obs(); + s_tick = 777u; + + int rc = sys_clock_init(); + CHECK(rc == -1, "RTC 读失败 → init 返回 -1(报告芯片故障)"); + /* 降级基准 = 编译期默认 RTC_DEFAULT_*(2026-08-24 00:00:00) */ + CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, + RTC_DEFAULT_DAY, RTC_DEFAULT_HOUR, + RTC_DEFAULT_MINUTE, RTC_DEFAULT_SECOND), + "降级基准 = 编译期默认时间(墙钟仍可用)"); + CHECK(g_sclk_err_count >= 1, "打了 DBG_ERROR(RTC 异常)"); + s_rtc_read_rc = SD2506_OK; /* 复位注入 */ +} + +static void tc_006_init_out_of_range_selfheal(void) { + printf("TC-CLK-006 init RTC 越界 → 自愈写回默认时间(返回 0)\n"); + /* + * RTC_DEFAULT_INIT_ENABLE=1 且 FORCE=0 时:越界值触发"写回默认时间", + * 写成功且复读合法 → rtc_ok 恢复为 1 → **返回 0**(自愈,非降级)。 + * (只有写回/复读仍失败才走降级 -1,见 tc_005 与 tc_020。) + */ + rtc_set(1999, 5, 5, 0, 0, 0); /* year < 2000 → 越界 */ + s_rtc_read_rc = SD2506_OK; + s_rtc_write_rc = SD2506_OK; + clear_obs(); + CHECK(sys_clock_init() == 0, "year=1999 → 自愈写回成功 → 返回 0"); + CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); + CHECK(s_rtc.year == RTC_DEFAULT_YEAR, "阴影 RTC 已修正为默认年"); + + rtc_set(2026, 13, 5, 0, 0, 0); /* month > 12 → 越界 */ + clear_obs(); + CHECK(sys_clock_init() == 0, "month=13 → 自愈 → 返回 0"); + CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); + + rtc_set(2026, 5, 0, 0, 0, 0); /* day < 1 → 越界 */ + clear_obs(); + CHECK(sys_clock_init() == 0, "day=0 → 自愈 → 返回 0"); + CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); +} + +static void tc_020_init_selfheal_fail_degrades(void) { + printf("TC-CLK-020 init 越界且写回失败 → 降级默认时间并返回 -1\n"); + /* + * 组合故障:读成功但值越界(触发写回),写回失败 → 复读仍越界 → + * rtc_ok 清 0 → 走降级分支(启用默认值时建基准 + 返回 -1)。 + */ + rtc_set(1999, 5, 5, 0, 0, 0); + s_rtc_read_rc = SD2506_OK; + s_rtc_write_rc = SD2506_ERROR; /* 写回失败 */ + clear_obs(); + s_tick = 42u; + int rc = sys_clock_init(); + CHECK(rc == -1, "越界 + 写回失败 → init 返回 -1"); + CHECK(s_rtc_set_calls == 1, "尝试写回一次(失败)"); + CHECK(g_sclk_err_count >= 1, "打了 DBG_ERROR"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, + RTC_DEFAULT_DAY, 0, 0, 0), + "降级基准 = 编译期默认时间(墙钟仍可用)"); + s_rtc_write_rc = SD2506_OK; +} + +static void tc_007_init_corrects_rtc(void) { + printf("TC-CLK-007 init 越界 → 自动写回默认时间并复验\n"); + rtc_set(1999, 1, 1, 0, 0, 0); /* 越界,触发校时写回 */ + s_rtc_read_rc = SD2506_OK; + s_rtc_write_rc = SD2506_OK; + clear_obs(); + int rc = sys_clock_init(); + CHECK(s_rtc_set_calls == 1, "越界 → 写回 RTC 一次"); + CHECK(rc == 0, "写回成功 + 复读合法 → 返回 0(自愈成功,非降级)"); + CHECK(s_rtc.year == RTC_DEFAULT_YEAR && s_rtc.month == RTC_DEFAULT_MONTH + && s_rtc.day == RTC_DEFAULT_DAY, "阴影 RTC 已被写入默认时间"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, + RTC_DEFAULT_DAY, 0, 0, 0), + "基准 = 修正后的默认时间"); +} + +static void tc_008_get_advance(void) { + printf("TC-CLK-008 get 正常推进(含亚秒截断)\n"); + base_at(1000000u, 5000u); + CHECK_EQ_U32(sys_clock_get(), 1000000u, "基准时刻 = 基准值"); + tick_advance(999u); + CHECK_EQ_U32(sys_clock_get(), 1000000u, "999ms 未满 1s → 不变(截断)"); + tick_advance(1u); + CHECK_EQ_U32(sys_clock_get(), 1000001u, "累计 1000ms → +1s"); + tick_advance(2500u); + CHECK_EQ_U32(sys_clock_get(), 1000003u, "再 +2500ms → 共 +3s(余 500ms 截断)"); +} + +static void tc_009_get_no_rebase_below_threshold(void) { + printf("TC-CLK-009 未达 30 天阈值不触发再基准化\n"); + base_at(2000000u, 0u); + /* 29 天 < 30 天阈值:线性推进,基准不动 */ + tick_advance(29u * 24u * 3600u * 1000u); + CHECK_EQ_U32(sys_clock_get(), 2000000u + 29u * 24u * 3600u, + "29 天线性推进正确(未再基准化)"); +} + +static void tc_010_get_rebase_at_threshold(void) { + printf("TC-CLK-010 30 天惰性再基准化(窗口清零、值无损、余数结转)\n"); + base_at(3000000u, 0u); + + /* 推进恰好 30 天 + 1500ms(余数 500ms 应结转到新窗) */ + tick_advance(30u * 24u * 3600u * 1000u + 1500u); + uint32_t expect = 3000000u + 30u * 24u * 3600u + 1u; /* 1500ms → +1s,余 500ms */ + CHECK_EQ_U32(sys_clock_get(), expect, "再基准化后墙钟值无损(+30 天 1 秒)"); + + /* 再推 500ms:结转的余数正好补足,再多 1 秒 */ + tick_advance(500u); + CHECK_EQ_U32(sys_clock_get(), expect + 1u, "亚秒余数已结转(+500ms 补足 1 秒)"); + + /* 再推一整天:仍线性 */ + tick_advance(24u * 3600u * 1000u); + CHECK_EQ_U32(sys_clock_get(), expect + 1u + 86400u, "再基准化后继续线性推进"); +} + +static void tc_011_get_tick_wrap(void) { + printf("TC-CLK-011 tick 回绕(无符号差)安全\n"); + /* 基准设在接近 2^32 处 */ + base_at(4000000u, 0xFFFFF000u); + /* 推进 0x2000 ms(跨越 2^32 回绕):差 = 0x2000 = 8192ms → +8s */ + tick_advance(0x2000u); + CHECK_EQ_U32(sys_clock_get(), 4000000u + 8u, "跨 tick 回绕后差值正确"); +} + +static void tc_012_get_long_run_no_drift(void) { + printf("TC-CLK-012 多轮再基准化长期不漂移\n"); + base_at(5000000u, 0u); + /* + * 惰性再基准化的**正确用法**:周期性调用 get() 让差值窗口始终 < 30 天。 + * 若一次性 tick_advance(90 天),中间不做 get(),diff 会超过 2^32 ms + * (49.7 天)而混叠——那是**调用方违约**,不是本模块缺陷(阈值 30 天 + * 就是为保证"每 <49.7 天调用一次"时窗口恒不溢出)。 + * 故此处按 10 天为步长推进 9 次,累计 90 天,每次观测一次。 + */ + uint32_t base = 5000000u; + uint32_t i; + for (i = 1u; i <= 9u; i++) { + tick_advance(10u * 86400u * 1000u); /* 每次 +10 天(< 30 天阈值) */ + CHECK_EQ_U32(sys_clock_get(), base + i * 10u * 86400u, + "10 天步进(含 3 轮再基准)线性无漂移"); + } +} + +static void tc_013_get_str(void) { + printf("TC-CLK-013 get_str 格式化\n"); + char buf[32]; + base_at(ref_unix(2026, 10, 2, 13, 4, 5), 0u); + memset(buf, 0, sizeof(buf)); + sys_clock_get_str(buf, sizeof(buf)); + CHECK(strcmp(buf, "2026-10-02 13:04:05") == 0, "格式化 YYYY-MM-DD HH:MM:SS"); + + base_at(ref_unix(2000, 1, 1, 0, 0, 0), 0u); + memset(buf, 0, sizeof(buf)); + sys_clock_get_str(buf, sizeof(buf)); + CHECK(strcmp(buf, "2000-01-01 00:00:00") == 0, "零点补零格式正确"); +} + +static void tc_014_get_time_fields(void) { + printf("TC-CLK-014 get_time 日历字段\n"); + sd2506_time_t t; + /* 2026-10-02 是周五(已知) */ + base_at(ref_unix(2026, 10, 2, 8, 9, 10), 0u); + CHECK(sys_clock_get_time(&t) == 0, "get_time 返回 0"); + CHECK(t.year == 2026 && t.month == 10 && t.day == 2, + "年月日正确"); + CHECK(t.hour == 8 && t.minute == 9 && t.second == 10, "时分秒正确"); + CHECK(t.week == 5, "2026-10-02 星期五(week==5,0=周日)"); +} + +static void tc_015_get_time_null(void) { + printf("TC-CLK-015 get_time NULL 参数被拒\n"); + base_at(6000000u, 0u); + CHECK(sys_clock_get_time(NULL) == -1, "p_time == NULL → 返回 -1"); +} + +static void tc_016_set_writes_rtc(void) { + printf("TC-CLK-016 set 更新基准 + 写回 RTC\n"); + sd2506_time_t sd; + memset(&sd, 0, sizeof(sd)); + sd.year = 2027; sd.month = 3; sd.day = 15; + sd.hour = 6; sd.minute = 7; sd.second = 8; sd.week = 1; + + s_rtc_write_rc = SD2506_OK; + clear_obs(); + s_tick = 100u; + CHECK(sys_clock_set(7000000u, &sd) == 0, "set 返回 0"); + CHECK_EQ_U32(sys_clock_get(), 7000000u, "基准已更新"); + CHECK(s_rtc_set_calls == 1, "sd_time != NULL → 写回 RTC 一次"); + CHECK(s_rtc.year == 2027 && s_rtc.month == 3 && s_rtc.day == 15 + && s_rtc.hour == 6 && s_rtc.minute == 7 && s_rtc.second == 8, + "RTC 写入内容与传入一致"); + + /* 写失败:基准仍更新,但打错误日志 */ + clear_obs(); + s_rtc_write_rc = SD2506_ERROR; + sys_clock_set(7000001u, &sd); + CHECK_EQ_U32(sys_clock_get(), 7000001u, "RTC 写失败仍更新基准"); + CHECK(g_sclk_err_count >= 1, "RTC 写失败打 DBG_ERROR"); + s_rtc_write_rc = SD2506_OK; +} + +static void tc_017_set_no_rtc(void) { + printf("TC-CLK-017 set sd_time=NULL 不碰 RTC\n"); + clear_obs(); + CHECK(sys_clock_set(8000000u, NULL) == 0, "set(NULL) 返回 0"); + CHECK(s_rtc_set_calls == 0, "sd_time == NULL → 不写 RTC"); + CHECK_EQ_U32(sys_clock_get(), 8000000u, "基准更新"); +} + +static void tc_018_set_unix_fields(void) { + printf("TC-CLK-018 set_unix 写回 RTC 且字段正确\n"); + sd2506_time_t expect_week; + uint32_t u = ref_unix(2026, 10, 2, 15, 30, 45); + clear_obs(); + s_rtc_write_rc = SD2506_OK; + s_tick = 0u; + CHECK(sys_clock_set_unix(u) == 0, "set_unix 返回 0"); + CHECK(s_rtc_set_calls == 1, "写回 RTC 一次"); + CHECK(s_rtc.year == 2026 && s_rtc.month == 10 && s_rtc.day == 2 + && s_rtc.hour == 15 && s_rtc.minute == 30 && s_rtc.second == 45, + "RTC 日历字段与 Unix 秒一致"); + CHECK(s_rtc.week == 5, "RTC 星期字段 = 5(2026-10-02 周五)"); + (void)expect_week; +} + +static void tc_019_week_known_dates(void) { + printf("TC-CLK-019 星期(Zeller)已知日期穷举\n"); + /* 期望值经 Python datetime 独立核对(0=周日); + * 覆盖 1/2 月(Zeller 需上调为上年 13/14 月的分支)与 3~12 月(2026-10-02 + * 修正前全部错误),以及世纪闰年、非闰世纪、范围首尾。*/ + static const struct { uint16_t y; uint8_t m, d, w; } cases[] = { + { 2000, 1, 1, 6 }, /* 星期六(Jan 分支) */ + { 1970, 1, 1, 4 }, /* 星期四(Jan 分支) */ + { 2024, 2, 29, 4 }, /* 星期四(Feb 分支 + 闰日) */ + { 2000, 2, 29, 2 }, /* 星期二(世纪闰 + Feb 分支) */ + { 2026, 10, 2, 5 }, /* 星期五(10 月,修正前曾错为 4) */ + { 2038, 1, 19, 2 }, /* 星期二(uint32 上限日) */ + { 1999, 12, 31, 5 }, /* 星期五(12 月,修正前曾错) */ + { 2026, 1, 31, 6 }, /* 星期六 */ + { 2025, 3, 1, 6 }, /* 星期六(3 月,修正前曾错为 5) */ + { 2100, 1, 1, 5 }, /* 星期五(2100 不闰) */ + { 2026, 8, 24, 1 }, /* 星期一(编译期默认日) */ + { 2026, 4, 30, 4 }, /* 星期四(30 天月月末) */ + { 2026, 5, 1, 5 }, /* 星期五(月首) */ + { 2026, 7, 4, 6 }, /* 星期六 */ + { 2026, 11, 30, 1 }, /* 星期一(30 天月月末) */ + { 2026, 12, 31, 4 }, /* 星期四(年末) */ + }; + size_t i; + for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + sd2506_time_t t; + uint32_t u = ref_unix(cases[i].y, cases[i].m, cases[i].d, 12, 0, 0); + base_at(u, 0u); + if (sys_clock_get_time(&t) == 0) { + char nm[64]; + snprintf(nm, sizeof(nm), "%04u-%02u-%02u week == %u", + cases[i].y, cases[i].m, cases[i].d, cases[i].w); + CHECK(t.week == cases[i].w, nm); + } else { + CHECK(0, "get_time 失败(用例数据问题)"); + } + } +} + +int main(void) { + printf("=== System Clock 主机侧单元测试 ===\n"); + printf("被测:App/util/sys_clock.c(时间换算 + 墙钟基准)\n\n"); + + /* tc_000 必须最先(依赖"刚上电"的静态态) */ + tc_000_uninitialized(); + tc_001_init_ok(); + tc_002_init_leap(); + tc_003_init_month_end(); + tc_004_init_epoch_bounds(); + tc_005_init_rtc_read_fail(); + tc_006_init_out_of_range_selfheal(); + tc_020_init_selfheal_fail_degrades(); + tc_007_init_corrects_rtc(); + tc_008_get_advance(); + tc_009_get_no_rebase_below_threshold(); + tc_010_get_rebase_at_threshold(); + tc_011_get_tick_wrap(); + tc_012_get_long_run_no_drift(); + tc_013_get_str(); + tc_014_get_time_fields(); + tc_015_get_time_null(); + tc_016_set_writes_rtc(); + tc_017_set_no_rtc(); + tc_018_set_unix_fields(); + tc_019_week_known_dates(); + + printf("\n=== System Clock Tests: %d/%d PASSED (failed=%d) ===\n", + s_passed, s_total, s_failed); + return (s_failed == 0) ? 0 : 1; +}