嵌入式文档技能
嵌入式固件文档生成和维护的专家技能。提供Doxygen注释生成、API文档结构、硬件接口文档和与文档系统的集成。
概述
嵌入式文档技能使嵌入式固件项目的全面文档化成为可能:
- Doxygen注释生成和维护
- API文档结构和组织
- 硬件接口文档
- 内存映射文档
- 调用图和依赖关系可视化
- 版本变更日志管理
- 注册文档格式化
- 与Sphinx/MkDocs集成
能力
1. Doxygen注释生成
生成Doxygen兼容的文档注释:
/**
* @file uart_driver.h
* @brief STM32F4系列的UART外设驱动程序
* @author 固件团队
* @version 1.2.0
* @date 2026-01-24
*
* @details
* 该驱动程序为UART外设提供了一个硬件抽象层。
* 它支持:
* - 轮询、中断和DMA传输模式
* - 硬件流控制(RTS/CTS)
* - 可配置的波特率高达10.5 Mbps
* - 错误检测和处理
*
* @note 在RTOS互斥使用时线程安全
*
* @par 示例用法:
* @code
* uart_config_t config = {
* .baudrate = 115200,
* .parity = UART_PARITY_NONE,
* .stop_bits = UART_STOP_1
* };
* uart_init(UART1, &config);
* uart_transmit(UART1, data, len, 100);
* @endcode
*
* @copyright (c) 2026 公司名称。版权所有。
*/
2. 函数文档
用完整的参数和返回信息记录函数:
/**
* @brief 使用指定配置初始化UART外设
*
* 使用指定设置配置UART硬件并准备
* 用于数据传输和接收。在任何
* 其他UART操作之前必须调用。
*
* @param[in] uart UART外设实例(UART1、UART2等)
* @param[in] config 指向配置结构的指针
*
* @return 状态码,指示成功或失败
* @retval UART_OK 初始化成功
* @retval UART_ERR_INVALID 无效参数(NULL指针或无效实例)
* @retval UART_ERR_BUSY 外设忙或已初始化
* @retval UART_ERR_CLOCK 时钟配置失败
*
* @pre 系统时钟必须在调用此函数之前配置
* @post UART外设准备就绪进行数据传输
*
* @note 此函数自动启用外设时钟
* @warning 不要在中断上下文中调用
*
* @see uart_deinit()
* @see uart_config_t
*
* @par 线程安全:
* 此函数不是线程安全的。当
* 从多个线程调用时使用互斥保护。
*
* @par 示例:
* @code
* uart_status_t status = uart_init(UART1, &config);
* if (status != UART_OK) {
* handle_error(status);
* }
* @endcode
*/
uart_status_t uart_init(uart_instance_t uart, const uart_config_t *config);
3. 硬件寄存器文档
记录硬件寄存器定义:
/**
* @defgroup UART_Registers UART寄存器定义
* @brief UART外设的内存映射寄存器定义
* @{
*/
/**
* @brief UART控制寄存器1(CR1)
*
* @verbatim
* 位字段 | 名称 | 读/写 | 复位 | 描述
* ------------|---------|-----|-------|---------------------------
* [31:16] | - | - | 0 | 保留
* [15] | OVER8 | 读/写 | 0 | 过采样模式(0=16x, 1=8x)
* [14] | - | - | 0 | 保留
* [13] | UE | 读/写 | 0 | UART启用
* [12] | M | 读/写 | 0 | 字长(0=8位,1=9位)
* [11] | WAKE | 读/写 | 0 | 唤醒方法
* [10] | PCE | 读/写 | 0 | 奇偶校验控制使能
* [9] | PS | 读/写 | 0 | 奇偶校验选择(0=偶数,1=奇数)
* [8] | PEIE | 读/写 | 0 | PE中断使能
* [7] | TXEIE | 读/写 | 0 | TXE中断使能
* [6] | TCIE | 读/写 | 0 | TC中断使能
* [5] | RXNEIE | 读/写 | 0 | RXNE中断使能
* [4] | IDLEIE | 读/写 | 0 | IDLE中断使能
* [3] | TE | 读/写 | 0 | 发送器使能
* [2] | RE | 读/写 | 0 | 接收器使能
* [1] | RWU | 读/写 | 0 | 接收器唤醒
* [0] | SBK | 读/写 | 0 | 发送中断
* @endverbatim
*/
#define UART_CR1_OVER8_Pos (15U)
#define UART_CR1_OVER8_Msk (0x1UL << UART_CR1_OVER8_Pos)
#define UART_CR1_OVER8 UART_CR1_OVER8_Msk
/** @} */ /* 结束UART_Registers组 */
4. 内存映射文档
记录内存布局和区域:
/**
* @defgroup Memory_Map 内存映射
* @brief 系统内存映射文档
*
* @verbatim
* 内存映射概览(STM32F407VG)
* ==================
*
* 地址范围 | 大小 | 区域 | 描述
* -----------------------|---------|-----------------|------------------
* 0x00000000-0x07FFFFFF | 128 MB | 别名 | 启动内存别名
* 0x08000000-0x080FFFFF | 1 MB | Flash | 主Flash内存
* 0x10000000-0x1000FFFF | 64 KB | CCMRAM | 核心耦合RAM
* 0x1FFF0000-0x1FFF7A0F | 30 KB | 系统内存 | 引导程序ROM
* 0x1FFFC000-0x1FFFC007 | 8 B | OTP | 选项字节
* 0x20000000-0x2001FFFF | 128 KB | SRAM | 主SRAM
* 0x40000000-0x400FFFFF | 1 MB | APB1 | APB1外设
* 0x40010000-0x4001FFFF | 64 KB | APB2 | APB2外设
* 0x40020000-0x4007FFFF | 384 KB | AHB1 | AHB1外设
* 0x50000000-0x5003FFFF | 256 KB | AHB2 | AHB2外设
* 0xE0000000-0xE00FFFFF | 1 MB | Cortex-M4 | 系统控制
*
* Flash内存布局
* ===================
*
* 扇区 | 地址 | 大小 | 用途
* -------|-------------|--------|------------------
* 0 | 0x08000000 | 16 KB | 引导程序
* 1 | 0x08004000 | 16 KB | 引导程序
* 2 | 0x08008000 | 16 KB | 应用程序(开始)
* 3 | 0x0800C000 | 16 KB | 应用程序
* 4 | 0x08010000 | 64 KB | 应用程序
* 5-11 | 0x08020000 | 896 KB | 应用程序/数据
*
* @endverbatim
*/
5. API文档结构
用模块分组组织文档:
/**
* @mainpage 固件API参考
*
* @section intro 引言
* 本文档描述了XYZ产品的固件API。
*
* @section modules 模块概览
* - @ref HAL_Module "硬件抽象层"
* - @ref Driver_Module "设备驱动程序"
* - @ref App_Module "应用层"
* - @ref Utils_Module "实用函数"
*
* @section getting_started 快速入门
* 参见@ref quick_start以获取初始化示例。
*
* @section architecture 架构
* @image html architecture.png "固件架构"
*/
/**
* @defgroup HAL_Module 硬件抽象层
* @brief 低级硬件接口模块
* @{
*/
/**
* @defgroup HAL_GPIO GPIO驱动程序
* @brief 通用输入/输出驱动程序
*/
/**
* @defgroup HAL_UART UART驱动程序
* @brief 通用异步接收/发送器驱动程序
*/
/** @} */ /* 结束HAL_Module */
流程集成
此技能与以下流程集成:
| 流程 | 集成点 |
|---|---|
firmware-api-documentation.js |
主要文档生成 |
hw-sw-interface-specification.js |
接口文档 |
version-control-config-management.js |
版本文档 |
工作流程
1. 分析代码库
# 查找未记录的函数
grep -rn "^[a-z_]*\s\+[a-z_]*(" src/ | grep -v "/\*\*"
# 计算记录和未记录的数量
find src/ -name "*.h" -exec grep -l "@brief" {} \; | wc -l
find src/ -name "*.h" | wc -l
2. 生成文档注释
该技能为以下内容生成文档注释:
- 头文件(模块概览、包含、定义)
- 函数声明(参数、返回、示例)
- 数据结构(字段、用途)
- 枚举(值、描述)
- 宏(目的、用途)
3. 配置Doxygen
# Doxyfile配置亮点
PROJECT_NAME = "固件API"
PROJECT_NUMBER = 1.2.0
OUTPUT_DIRECTORY = docs/api
GENERATE_HTML = YES
GENERATE_LATEX = NO
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
INPUT = src include
FILE_PATTERNS = *.c *.h
RECURSIVE = YES
EXCLUDE = src/third_party
HAVE_DOT = YES
CALL_GRAPH = YES
CALLER_GRAPH = YES
4. 生成输出
# 生成HTML文档
doxygen Doxyfile
# 生成PDF(需要LaTeX)
cd docs/api/latex && make pdf
# 本地服务以供审查
python -m http.server 8000 -d docs/api/html
输出架构
{
"documentation": {
"type": "doxygen",
"format": "html",
"outputDir": "docs/api"
},
"coverage": {
"files": {
"total": 45,
"documented": 42,
"coverage": 0.933
},
"functions": {
"total": 156,
"documented": 148,
"coverage": 0.949
},
"parameters": {
"total": 312,
"documented": 298,
"coverage": 0.955
}
},
"warnings": [
"src/legacy.c:45: Missing @return documentation",
"include/config.h:12: Undocumented macro CONFIG_MAX_SIZE"
],
"artifacts": [
"docs/api/html/index.html",
"docs/api/Doxyfile",
"docs/memory-map.md",
"docs/register-reference.md"
]
}
文档模板
头文件模板
/**
* @file module_name.h
* @brief 模块简述
* @author 作者姓名
* @version X.Y.Z
* @date YYYY-MM-DD
*
* @details
* 模块目的和功能的详细描述。
*
* @par 依赖项:
* - dependency1.h
* - dependency2.h
*
* @par 示例:
* @code
* // 使用示例
* @endcode
*/
#ifndef MODULE_NAME_H
#define MODULE_NAME_H
#ifdef __cplusplus
extern "C" {
#endif
/* 包含 */
/* 定义 */
/* 类型 */
/* 函数原型 */
#ifdef __cplusplus
}
#endif
#endif /* MODULE_NAME_H */
驱动程序函数模板
/**
* @brief 简短描述(祈使语气)
*
* 详细描述说明该函数的作用,
* 何时使用它,以及任何重要的考虑事项。
*
* @param[in] param1 输入参数描述
* @param[out] param2 输出参数描述
* @param[in,out] param3 输入/输出参数描述
*
* @return 返回值描述
* @retval VALUE1 VALUE1的含义
* @retval VALUE2 VALUE2的含义
*
* @pre 必须满足的先决条件
* @post 成功执行后的后置条件
*
* @note 用户的附加说明
* @warning 关于潜在问题的警告
*
* @see 相关函数或文档
*/
最佳实践
注释风格
- 使用以动词开头的简短描述(初始化、配置、获取)
- 完整记录所有公共API函数
- 为每个参数包含@param
- 为返回值包含@return和@retval
- 添加@pre/@post以说明状态要求
组织
- 使用@defgroup对相关函数进行分组
- 使用@ingroup将项添加到组中
- 创建@mainpage以便于导航
- 使用@see和@ref链接相关项
维护
- 更新@version标签中的版本号
- 保持@date为最后修改日期
- 在代码审查期间审查和更新文档
- 在CI中运行Doxygen以捕获警告
与文档系统集成
Sphinx集成
.. doxygenfile:: uart_driver.h
:project: firmware
.. doxygenfunction:: uart_init
:project: firmware
MkDocs集成
# mkdocs.yml
plugins:
- mkdoxy:
projects:
firmware:
src-dirs: src include
full-doc: True
参考资料
- Doxygen手册:https://www.doxygen.nl/manual/
- MISRA C文档指南
- 嵌入式艺术家文档标准
- Linux内核文档指南
另请参阅
firmware-api-documentation.js- 文档生成过程hw-sw-interface-specification.js- 接口规范过程- AG-012: 技术文档代理