#ifndef __THER_UID_HPP__ #define __THER_UID_HPP__ #include #include #include namespace ther { /// 生产 UID 存储:优先使用写入 storage 分区的自定义 UID,否则回退 MCU 芯片 UID。 /// /// UID 共 10 字节(生产编码,见 doc/UID编码规则.md): /// [0] 设备类型 /// [1] 产品代次 /// [2..6) 生产年月(4 字节) /// [6..10) 唯一序列号(4 字节) /// /// 存储记录(24 字节,位于 storage 分区起始,与 8 字节写对齐): /// [0..4] magic "UID1" /// [4] ver 0x02 /// [5..15) uid 10 字节 /// [15..17) crc16 CRC16-Modbus([0..15)),LSB 在前 /// [17..24) pad 0xFF class Uid { public: static constexpr size_t kUidLen = 10; ///< 生产 UID 长度 static constexpr size_t kChipUidLen = 12; ///< MCU 芯片 UID 长度(STM32G0 96bit) static constexpr size_t kRecordLen = 24; /// 上电读取:存在有效存储记录则使用之,否则回退芯片 UID。 static auto Init() -> void; /// 当前生效的 UID(10 字节)。 static auto Get() -> etl::span; /// 是否使用自定义存储 UID(否则为芯片 UID)。 static auto IsCustom() -> bool; /// 写入自定义 UID(必须 10 字节);空 span 表示清除记录(恢复芯片 UID)。 /// 返回 0 成功,负数为错误码。 static auto Write(etl::span uid) -> int; private: static auto LoadRecord() -> void; static auto RecordValid(const uint8_t *rec) -> bool; static auto EraseRecord() -> int; static auto SaveRecord(const uint8_t *rec) -> int; inline static uint8_t s_chip_uid[kChipUidLen]{}; inline static size_t s_chip_uid_len = 0; inline static uint8_t s_custom_uid[kUidLen]{}; inline static etl::span s_active{}; inline static bool s_custom{false}; }; } // namespace ther #endif // __THER_UID_HPP__