|
xt-sdk 文档 v1.0.3
xt-sdk 嵌入式 SDK API 参考
|
版本:0.1 | 日期:2026-07-03 | 路径: components/xt_std/
xt_std 是 xt-sdk 的基础工具库,提供嵌入式开发中高频使用的类型定义、位操作、链表、环形缓冲区、CRC 校验、错误码和通用宏。所有子模块均为 header-only (仅头文件),函数以 static inline 或宏实现,未被引用的代码不产生任何二进制开销。
| 子模块 | 头文件 | @defgroup | 职责 |
|---|---|---|---|
| xt_types(类型定义) | xt_types.h | xt_types(类型定义) | 引入 stddef.h 、 stdint.h 、 stdbool.h ,统一基础类型来源 |
| xt_macro(通用宏) | xt_macro.h | xt_macro(通用宏) | 数组大小、对齐、MIN/MAX、container_of、静态断言 |
| xt_bit(位操作) | xt_bit.h | xt_bit(位操作) | 单位/多位操作宏:置位、清零、翻转、掩码、字段读写 |
| xt_list(链表) | xt_list.h | xt_list(链表) | 双向循环链表 + 单向链表,container_of 迭代器 |
| xt_rb(环形缓冲区) | xt_rb.h | xt_rb | 环形缓冲区:字节级读写、强制覆盖、连续空间查询 |
| xt_crc(CRC 校验) | xt_crc.h | xt_crc(CRC 校验) | 27 种 CRC 变体(CRC-4 ~ CRC-32),按位实现 |
| xt_error(错误码) | xt_error.h | xt_error(错误码) | 统一错误码( xt_err_t )与 XT_E* 宏 |
| xt_utils(工具函数) | xt_utils.h | xt_utils(工具函数) | 字节序转换、对齐读取、log2(总头文件,含 #include 全部子模块) |
| 依赖 | 用途 |
|---|---|
| stdint.h | 定长整数类型 |
| stddef.h | size_t |
| stdbool.h | bool |
| string.h | xt_rb.h 内部 memcpy |
无外部组件依赖。
xt_list(链表) 和 xt_slist 采用 侵入式设计 :链表节点 xt_list_node 直接嵌入到业务结构体中,而非通过指针指向数据。这使得同一个结构体可以同时挂在多个链表上(只需嵌入多个 node 成员),且节点操作无需知道宿主类型。
从节点指针反查宿主结构体使用 xt_container_of 宏:
xt_macro.h 也提供了功能相同的 XT_CONTAINER_OF 宏。两者实现一致,选择哪个取决于是否已引入对应头文件。
xt_bit.h 将位操作分为两类,命名遵循严格约定:
| 前缀 | 行为 | 示例 |
|---|---|---|
| BIT_GET_* / BITS_GET_* | **返回**修改后的值,不改变原变量 | val = BIT_GET_MDF1(reg, 3) |
| BIT_SET_* / BITS_* | **原地修改**,等价于 src = BIT_GET_*(src, ...) | BIT_SET1(reg, 3) |
单位操作( BIT_* )按单个 bit 索引操作;多位操作( BITS_* )按掩码操作。字段读写( BITSn_* )按 "n 位 + offset" 操作,适用于寄存器字段定义。
xt_rb 的 write 函数接受 b_force 参数:
强制覆盖模式适用于 不可丢失的实时数据流 (如日志缓冲),但会丢失历史数据。此外, read 传入 dst = NULL 时仅移动读指针,不复制数据——用于跳过不需要的数据段。
xt_crc.h 提供了 27 种 CRC 变体,覆盖 4 位到 32 位宽度。每个函数头注释包含完整参数(Poly、Init、Refin、Refout、Xorout),可在 http://www.ip33.com/crc.html 验证。常见选择:
| 协议 | 推荐 CRC 函数 |
|---|---|
| Modbus RTU | xt_crc16_modbus |
| USB | xt_crc16_usb |
| 蓝牙 BLE | xt_crc24_ble |
| SD/MMC | xt_crc7_mmc |
| 通用文件校验 | xt_crc32 |
| XMODEM | xt_crc16_xmodem |
所有函数均为按位实现(非查表), 代码体积小但速度较慢 ,适合资源受限的嵌入式场景。
以下为函数签名大纲,完整的参数说明、返回值、注意事项请查看 标准工具库 。 各子模块的 API 请查看上方子模块表格中的 @ref 链接。
| 函数签名 | 说明 |
|---|---|
| uint32_t xt_log2_u32(uint32_t n) | 计算 log2(向下取整) |
| uint16_t xt_bswap16(uint16_t val16) | 16 位字节序翻转 |
| uint32_t xt_bswap32(uint32_t val32) | 32 位字节序翻转 |
| uint16_t xt_read16p(const void *ptr16) | 按字节读取 16 位(小端) |
| uint32_t xt_read32p(const void *ptr32) | 按字节读取 32 位(小端) |
| 函数签名 | 说明 |
|---|---|
| void xt_rb_init(struct xt_rb *rb, uint8_t *buf, uint32_t size) | 初始化环形缓冲区 |
| void xt_rb_reset(struct xt_rb *rb) | 重置(清空数据) |
| bool xt_rb_is_empty(const struct xt_rb *rb) | 判断是否为空 |
| bool xt_rb_is_full(const struct xt_rb *rb) | 判断是否已满 |
| uint32_t xt_rb_get_continuous_read_space(const struct xt_rb *rb) | 获取连续可读空间 |
| uint32_t xt_rb_get_continuous_write_space(const struct xt_rb *rb, uint8_t b_force) | 获取连续可写空间 |
| uint32_t xt_rb_get_size(const struct xt_rb *rb) | 获取总大小 |
| uint32_t xt_rb_get_filled(const struct xt_rb *rb) | 获取已填充字节数 |
| uint32_t xt_rb_get_empty(const struct xt_rb *rb) | 获取空闲字节数 |
| void xt_rb_putc(struct xt_rb *rb, uint8_t ch) | 写入单个字节 |
| bool xt_rb_getc(struct xt_rb *rb, uint8_t *ch) | 读取单个字节 |
| uint32_t xt_rb_write(struct xt_rb *rb, const uint8_t *src, uint32_t size, uint8_t b_force) | 写入数据 |
| uint32_t xt_rb_read(struct xt_rb *rb, uint8_t *dst, uint32_t size) | 读取数据 |
| 函数签名 | 说明 |
|---|---|
| void xt_list_init(struct xt_list_node *l) | 初始化双向链表 |
| void xt_list_insert_after(struct xt_list_node *l, struct xt_list_node *n) | 在节点后插入 |
| void xt_list_insert_before(struct xt_list_node *l, struct xt_list_node *n) | 在节点前插入 |
| void xt_list_remove(struct xt_list_node *n) | 从链表中移除节点 |
| int xt_list_isempty(const struct xt_list_node *l) | 判断链表是否为空 |
| void xt_slist_init(struct xt_slist_node *l) | 初始化单向链表 |
| void xt_slist_append(struct xt_slist_node *l, struct xt_slist_node *n) | 追加到单向链表末尾 |
| void xt_slist_insert(struct xt_slist_node *l, struct xt_slist_node *n) | 插入到单向链表 |
| int xt_slist_isempty(struct xt_slist_node *l) | 判断单向链表是否为空 |
共 29 种 CRC 变体(CRC-4 ~ CRC-32),函数签名统一为 uintN_t xt_crcXX_YYY(uint8_t *data, uint16_t length) ,详见 xt_crc(CRC 校验) 。
以上子模块为纯宏和类型定义,无函数 API。详见 xt_bit(位操作) 、 xt_macro(通用宏) 、 xt_types(类型定义) 、 xt_error(错误码) 。 子模块已按 xt_types(类型定义) 、 xt_macro(通用宏) 、 xt_bit(位操作) 、 xt_list(链表) 、 xt_rb 、 xt_crc(CRC 校验) 、 xt_error(错误码) 、 xt_utils(工具函数) 分组,直接在 doxygen 页面查看。
| 反模式 | 问题 | 正确做法 |
|---|---|---|
| 宏参数有副作用(如 BIT_SET1(reg++, 3) ) | 宏展开后 reg 自增多次 | 宏参数只用简单变量,不传自增表达式 |
| 链表节点未初始化就插入 | next / prev 野指针导致 HardFault | 插入前调用 xt_list_init 或用 XT_LIST_OBJECT_INIT |
| 环形缓冲区 write 时 src = NULL 且 b_force = XT_RB_NO_FORCE | 不写入数据也不移动指针 | NULL src 仅配合 XT_RB_FORCE 使用 |
| CRC 函数返回值类型不匹配 | 32 位 CRC 返回 uint32_t ,赋值给 uint16_t 截断 | 检查函数返回类型, CRC-24/32 用 uint32_t |
| xt_container_of 和 XT_CONTAINER_OF 混用 | 重复定义,引入两个头文件的宏 | 统一使用一个,保持代码一致 |
| BITSn_GET_MDF 的 n + offset > 32 | 整数溢出,结果未定义 | 确保字段不跨越 32 位边界,或将 BIT_IE 设为 1ULL |
| 静态断言使用 XT_STATIC_ASSERT 但未引用 xt_macro.h | 宏未定义,编译错误 | xt_utils.h 已包含 xt_macro.h ,优先使用总头文件 |
xt_bit.h 中的所有宏使用 #if !defined() 保护,若平台 SDK 已定义同名宏(如 BIT0 、 BIT_GET ),则跳过 xt_std 的定义,避免冲突。无需额外编译选项。
xt_rb.h 提供便捷宏:
| 宏 | 说明 |
|---|---|
| XT_RB_IS_VALID(rb) | 检查 rb 指针、缓冲区指针、大小是否有效 |
| XT_RB_IS_EMPTY(rb) | 等价于 xt_rb_is_empty(rb) |
| XT_RB_IS_FULL(rb) | 等价于 xt_rb_is_full(rb) |