ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RT-Thread 社区贡献指南:编程风格、BSP 移植规范与 Doxygen 文档编写全解析

RT-Thread 社区贡献指南:编程风格、BSP 移植规范与 Doxygen 文档编写全解析 操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载RT-Thread 是一个开源物联网实时操作系统RTOS其内核与全部开源组件均可免费用于商业产品。本文基于仓库documentation/7.contribution/INDEX.md所串联的三份核心规范——编程风格Coding Style、BSP 贡献规范BSP Contribution Guide与 Doxygen 文档编写指南How to write doxygen documentation系统讲解贡献者从提交代码到贡献 BSP再到维护 API 文档的完整流程。读完本文你将掌握 RT-Thread 社区认可的代码书写习惯、目录组织原则与文档注释标准并能在实际提交中直接落地执行。一、开源许可与贡献流程总览documentation/7.contribution/INDEX.md是整个贡献规范的入口页它首先明确了 RT-Thread 的开源许可边界与贡献方式许可证演进RT-Thread 3.1.0 版本及其更早版本遵循GPL V2开源许可协议自 3.1.0 版本起全部代码遵循Apache License 2.0开源许可协议。仓库根目录的LICENSE文件与各源文件头部的SPDX-License-Identifier: Apache-2.0声明详见下文文件头注释一节与此对应。商用友好内核与所有开源组件均可免费用于商业产品无潜在商业风险不会被要求公开应用层源码——这正是项目从 GPL V2 转向 Apache 2.0 的核心理由。贡献方式官方欢迎通过 GitHub 的 fork 与 Pull RequestPR流程提交代码。该入口页通过 Doxygen 的subpage机制串联起三份子规范对应仓库中的实际文档文件子规范对应文档文件RT-Thread 编程风格documentation/7.contribution/coding_style_cn.md 与 coding_style_en.mdBSP 贡献规范documentation/7.contribution/bsp_contribution_guide_cn.md 与 bsp_contribution_guide_en.mdDoxygen 文档编写documentation/0.doxygen/example/INDEX.md二、RT-Thread 编程风格规范编程风格文档是开发人员的指引RT-Thread 由不同开发者协作完成遵循统一的书写风格不仅能保证代码可读性也能让使用者更容易把握内核的实现方式。规范共 14 节逐条如下。2.1 目录与文件命名目录名称无特殊需求一律全小写且应能反映目录含义。例如芯片移植目录由芯片名称或芯片类别构成仓库中bsp/stm32、bsp/nxp、bsp/wch等即为此风格components/下的目录应反映组件功能如 components/dfs、components/drivers。文件名称无特殊需求一律全小写若文件是引用其他地方如原厂 SDK可保留原名。避免使用通用化、使用频率高的名称防止重名。设备驱动源码文件采用drv_class.c的命名方式如drv_spi.c、drv_gpio.c。这在仓库bsp各厂商的驱动目录中随处可见。2.2 头文件定义C 头文件为避免重复包含需要定义包含保护符号形式如下符号两侧加__避免重名多词文件名用_连接即 snake case#ifndef __FILE_H__ #define __FILE_H__ /* header file content */ #endif2.3 文件头注释每个源文件头部应包含版权信息与 Change Log 记录统一格式如下/* * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2006-03-18 Bernard the first version * 2006-04-26 Bernard add semaphore APIs */仓库中的绝大多数源文件如 src/ipc.c、include/rtdbg.h都遵循这一模板SPDX-License-Identifier: Apache-2.0一行与 3.1.0 版本以来的 Apache 2.0 许可直接呼应。2.4 结构体定义结构体名称使用小写英文单词间用_连接{、}独立占行成员缩进定义struct rt_list_node { struct rt_list_node *next; struct rt_list_node *prev; };类型定义以结构体名加_t结尾内核对象为便于引用直接以对象指针作为类型定义typedef struct rt_list_node rt_list_t; typedef struct rt_timer* rt_timer_t;2.5 宏定义宏定义使用大写英文名单词间用_连接例如#define RT_TRUE 1。RT-Thread 的公共宏集中在 include/rtdef.h 中如RT_THREAD_PRIORITY_MAX、RT_TICK_MAX等均遵循此规则。2.6 函数命名与声明函数名使用小写英文单词间用_连接提供给上层应用的 API 必须在头文件中声明无参函数必须显式声明为voidrt_thread_t rt_thread_self(void);内部静态函数以下划线开头采用_class_method格式不带_rt_前缀如static rt_err_t _ipc_object_init(); /* IPC object init */ static rt_err_t _uart_configure(); /* UART driver ops */调用注册设备接口的函数使用rt_hw_class_init()格式如int rt_hw_uart_init(void); int rt_hw_spi_init(void);2.7 注释编写语言一律使用英文注释便于与国际开发者交流也避免编写时反复切换输入法。语句注释注释不应过多重点是说明代码做了什么仅在关键点如复杂算法给出提示性注释语句注释只能写在语句上方或右方其他位置非法。函数注释以/**开头、*/结尾组成元素包括brief简述函数作用、note补充说明、see相关 API、param以参数为主语 be 动词描述含义、return返回值含义、warning使用注意要点各元素间空一行且首列对齐。官方指定模板见 src/ipc.c例如rt_event_init的完整注释块英文措辞可参考 grammarly 与谷歌翻译。完整示例摘录自规范文档/** * brief The function will initialize a static event object. * * note For the static event object, its memory space is allocated by the compiler during compiling, * and shall placed on the read-write data segment or on the uninitialized data segment. * By contrast, the rt_event_create() function will allocate memory space automatically * and initialize the event. * * see rt_event_create() * * param event is a pointer to the event to initialize. It is assumed that storage for the event * will be allocated in your application. * * return Return the operation status. When the return value is RT_EOK, the initialization is successful. * If the return value is any other values, it represents the initialization failed. * * warning This function can ONLY be called from threads. */ rt_err_t rt_event_init(rt_event_t event, const char *name, rt_uint8_t flag);2.8 缩进与分行缩进采用4 个空格首选无特殊意义时在{后换行并缩进if (condition) { /* others */ }switch 例外case与switch对齐后续代码块缩进switch (value) { case value1: break; }分行上不要在代码中连续使用两个以上空行。2.9 大括号与空格每个大括号单独占一行不跟在语句后使匹配的代码块层次清晰。非函数调用的括号前留一个空格涉及if、for、while、switch等关键字如if (x y)、for (index 0; index MAX_NUMBER; index )。运算表达式中二元/三元运算符与操作数之间留一个空格括号表达式内侧不留空格if ( x y )是错误示范。2.10 日志信息trace/log首选 ulog 方式通过LOG_D、LOG_I、LOG_W、LOG_E输出日志用DBG_TAG区分日志类别、DBG_LVL控制输出等级#define DBG_TAG Driver #define DBG_LVL DBG_INFO #include rtdbg.h LOG_D(this is a debug log.);在 include/rtdbg.h 的源码中可以看到这套宏的实际定义LOG_D/LOG_I/LOG_W/LOG_E分别映射到dbg_log_line(D/I/W/E, ...)并通过DBG_TAG→DBG_SECTION_NAME、DBG_LVL→DBG_LEVEL完成配置传递DBG_LVL可选DBG_ERROR、DBG_WARNING、DBG_INFO、DBG_LOG等档位。日志应以易懂、易定位问题为目标天书式日志是不合理的。禁止在头文件中重定义DBG_TAG防止其他模块包含时DBG_TAG不可控。严禁在 timer 或中断中打印大量日志尽可能避免或轻量化。不建议使用rt_kprintf输出日志英文版规范指出rt_kprintf是轮询、非中断式的字符串输出适合中断上下文等即时场景但会影响日志输出的时序频繁使用会拖慢代码运行中文版明确它一般作为终端命令行交互使用。日志默认应关闭可通过变量或宏开关打开。2.11 函数与对象化命名函数 K.I.S.S.内核函数应精简、只完成相对独立的简单功能函数过长应拆分使每个子函数易读易懂。C 语言对象化RT-Thread 内核用 C 实现面向对象风格命名表现是对象名结构体 类定义对象名 动词短语 类方法。例如struct rt_timer是 timer 对象的类定义rt_timer_create、rt_timer_delete、rt_timer_start、rt_timer_stop是应用于 timer 对象的方法这些 API 的实际实现位于 src/timer.c。创建新对象时应想清楚内存策略允许静态对象存在还是仅支持从堆动态分配。2.12 使用 clang-format 统一格式化RT-Thread 现已采用clang-format作为统一代码格式化工具仓库根目录提供.clang-format配置文件bsp/nxp/mcx/mcxe、components/net/lwip等子目录还维护了各自的.clang-format。提交 C/C 源码与头文件前必须格式化clang-format -stylefile -i path/to/file.c clang-format -stylefile -i path/to/file.h使用要点批量格式化时只处理本次修改相关的源文件避免对无关文件做大范围格式化若子目录存在自己的.clang-format以离文件最近的配置为准禁止再使用与该配置不一致的手工排版或旧的 astyle 参数此外还需保持源文件UTF-8 编码、行尾使用\n、删除行尾多余空格并避免提交由编辑器自动产生的无关格式化变更。三、BSP 贡献规范BSP 贡献规范规定了新增或调整 BSP 时应遵循的目录层级关系核心目的是避免把板级、芯片级和架构级代码混放让代码分层清晰、便于跨开发板复用。3.1 目录层级基本原则board/放置板级初始化、引脚、时钟、链接脚本等只属于当前开发板的内容共享libraries/放置同一厂商或同一系列 BSP 共用的芯片库、HAL、CMSIS、SDK、驱动和驱动适配代码驱动目录也应放在libraries/下同级tools/放置同一厂商或同一系列 BSP 共用的辅助脚本多个 BSP 共用同一软件包/SDK 时不得在每个 BSP 下重复维护应放共享层级或用软件包机制引用新增 BSP 不要随意新建额外层级不要把 BSP 代码放入components/、src/、include/等非 BSP 目录抽象驱动框架属于 components/drivers芯片或 CPU 架构公共移植代码属于 libcpu。3.2 厂商级共享目录结构STM32 示例STM32 BSP 通常直接位于bsp/stm32/board同一厂商下多个 BSP 共用的驱动适配、模板、工具和软件包选择放在bsp/stm32/libraries/与bsp/stm32/tools/。仓库实际的 bsp/stm32 目录正是这一结构bsp/stm32/ ├── libraries/ │ ├── HAL_Drivers/ # STM32 BSP 共用的驱动适配 │ ├── drivers/ # 多个 STM32 BSP 共用的驱动如有 │ ├── templates/ # 新增 BSP 参考模板 │ └── Kconfig # 原厂 HAL/CMSIS 软件包选择 ├── tools/ # 厂商级辅助脚本 ├── stm32f407-atk-explorer/ │ ├── board/ # 当前开发板专用的初始化、引脚、时钟、链接脚本 │ ├── Kconfig │ ├── SConscript │ └── SConstruct └── stm32f429-atk-apollo/ ├── board/ ├── Kconfig ├── SConscript └── SConstruct每个 BSP 的Kconfig提供菜单配置、SConscript/SConstruct负责 scons 构建接入。3.3 厂商 系列级共享目录结构NXP 示例NXP 这类 BSP 先按厂商、产品线或芯片系列分层再把系列共用的代码放在系列目录下i.MX RT 使用bsp/nxp/imx/imxrt/libraries/LPC55S 使用bsp/nxp/lpc/lpc55sxx/libraries/MCX 按mcxa、mcxc、mcxe、mcxn等系列分别维护libraries/。仓库实际的 bsp/nxp 目录与此一致bsp/nxp/ ├── imx/ │ └── imxrt/ │ ├── libraries/ │ │ ├── drivers/ # i.MX RT 系列共用的驱动和驱动适配 │ │ ├── templates/ # 新增 BSP 参考模板 │ │ └── Kconfig # NXP i.MX RT SDK 软件包选择 │ ├── tools/ # 当前系列 BSP 共用的辅助脚本 │ └── imxrt1052-nxp-evk/ │ ├── board/ # 当前开发板专用的初始化、引脚、时钟、链接脚本 │ ├── Kconfig │ ├── SConscript │ └── SConstruct ├── lpc/ │ └── lpc55sxx/ │ ├── libraries/ # LPC55S 系列共用的驱动适配、模板和软件包选择 │ ├── tools/ │ └── lpc55s69_nxp_evk/ │ ├── board/ │ ├── Kconfig │ ├── SConscript │ └── SConstruct └── mcx/ ├── tools/ # MCX 系列共用工具 └── mcxn/ ├── libraries/ # MCXN 系列共用的 CMSIS、系列驱动和软件包选择 └── frdm-mcxn947/ ├── board/ ├── Kconfig ├── SConscript └── SConstruct注意NXP 目录下存在历史遗留结构如lpc176x这类单 BSP 目录、少量旧目录的Libraries/大写命名新增或重构 BSP 时不应继续扩散旧结构若驱动、SDK 或模板需要被多个 BSP 复用应迁移或放入对应系列的libraries/与tools/层级。3.4 原厂 HAL/SDK 软件包机制若原厂 HAL、CMSIS 或 SDK 已经以 RT-Thread 软件包形式提供BSP不应再提交或维护重复的完整源码副本通过Kconfig选择相应PKG_USING_*软件包并在SConscript中按配置引用软件包内容pkgs --update负责下载软件包源码这种情况下libraries/主要保留驱动适配、可复用驱动、模板、工具脚本和软件包选择逻辑不要把pkgs --update下载出的软件包目录作为 BSP 源码提交不要让scons --dist打包当前 BSP 没有启用的软件包或库文件。3.5 提交要求汇总保持层级清晰只提交当前开发板必需的板级文件同一厂商/系列共用的库、驱动适配、可复用驱动、模板和脚本放在共享libraries/或tools/层级避免重复拷贝驱动适配和可复用驱动放在libraries/下不应放在单个开发板目录中原厂 HAL/CMSIS/SDK 已软件包化时优先走软件包机制不重复提交源码构建脚本从共享层级引用公共代码scons --dist不打包当前 BSP 不需要的软件包或库文件。四、Doxygen 文档编写指南RT-Thread 在线文档基于 Doxygen 生成由两部分构成一是内核的详细介绍Markdown 编写通过 Doxygen 转成 HTML显示在浏览器左侧 Treeview 的 RT-Thread User Guide 下二是 API 描述从源码注释自动提取类、函数、变量信息显示在 Modules 下。documentation/0.doxygen/example/INDEX.md详细讲解了 API 文档的写法。4.1 页面组织机制使用page命令定义页面页面名以page_前缀开头且必须唯一——例如本贡献指南入口页 documentation/7.contribution/INDEX.md 的page page_code_contribution编程风格页的page page_rtt_code_style_enBSP 规范页的page page_bsp_contribution_guide_en使用subpage命令将子页面组织进层级结构如 INDEX.md 中subpage page_rtt_code_style_en三行即完成对三份子规范的挂载API 模块则通过 Doxygen 的topics 机制defgroup/addtogroup组织例如 documentation/0.doxygen/4.doxygen.h 中的defgroup group_doxygen_example Doxygen Example定义了示例分组并用ref page_howto_doxygen反向引用本指南。4.2 API 注释通用规则适用范围指南中涉及的结构体、常量宏、枚举值、联合体值、全局函数、全局变量均属于RT-Thread 内核 API范围内部函数、变量如 static 函数不属于 API 范畴不在讨论之列。默认情况下 API 文档写在头文件中但函数是例外可写在.c实现文件中如 documentation/0.doxygen/example/src/function.c。JavaDoc 风格C 风格注释块是首选标记方式/** * ... text ... */成员成员变量等的文档放在成员之后时使用Qt 风格int var; /** Detailed description after the member */注释中会用到 Doxygen 定义的若干命令brief、param、return、see、note、ref等完整命令列表参见 Doxygen 官方手册的 commands 章节。示例讲解按主题拆分为多节groups分组、macro宏、struct结构体、union联合体、enum枚举、typedef类型定义、function函数对应示例文件位于 documentation/0.doxygen/example/include 下的groups.h、macro.h、struct.h、union.h、enum.h、typedef.h、function.h。4.3 在 Ubuntu 上构建 HTML 文档以下步骤已在 Ubuntu 22.04 验证。首先安装依赖sudo apt update sudo apt install doxygen sudo apt install graphviz假设 RT-Thread 代码树路径为$RTT在documentation目录下执行构建cd $RTT/documentation rm -rf html doxygen构建完成后会生成新的html目录所有 HTML 文件位于其中。仓库的 documentation 目录内提供Doxyfile.1.9.1、Doxyfile.1.9.8等 Doxygen 配置及 run.sh 一键脚本cd $RTT/documentation ./run.sh即可自动完成上述操作。本地浏览 HTML 时可进入html目录用 Python 启动简易 HTTP 服务器cd html python3 -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...随后打开浏览器访问http://IP:8000/index.html本地访问时IP替换为localhost远程访问时替换为机器实际可访问的 IP。4.4 使用 Doxywizard 构建从 Doxygen 官网下载并安装 Doxywizard打开DoxywizardFile→Open打开仓库 documentation 目录下的Doxyfile切到Run标签页点击Run doxygen。4.5 在 VS Code 中高效编写 Doxygen 注释规范文档提供了一组 VS Code 配置写入.vscode/settings.json的doxdocgen插件配置可自动生成符合 RT-Thread 风格的注释骨架doxdocgen.c.triggerSequence: /**, doxdocgen.c.firstLine: /**, doxdocgen.c.commentPrefix: * , doxdocgen.c.lastLine: */, doxdocgen.generic.briefTemplate: brief , //You can set param to param[in] or param[out] for your preference doxdocgen.generic.paramTemplate: param[] {param} \n , //You can comment out returnTemplate to auto add of return value type after return doxdocgen.generic.returnTemplate: return , //You can comment out customTags to unconfig note line, meanwhile comment out empty item before custom item will make comment more compliant doxdocgen.generic.customTags:[ note ], doxdocgen.generic.order:[ brief, empty, param, return, empty, custom, ],若偏好在一个 Doxygen 命令后写多行注释可配合 Auto Comment Blocks 插件在换行时自动补全行首的*。五、结语与延伸阅读至此一条完整的 RT-Thread 贡献路径已经清晰以documentation/7.contribution/INDEX.md为入口先按编程风格规范写出风格统一的代码再按 BSP 贡献规范把板级、芯片级、架构级代码放到正确的层级最后用 Doxygen 注释规范为新增 API 补齐可供自动生成的可检索文档。三份规范相互配合共同保证 RT-Thread 社区代码的可读性、可复用性与文档完备性。想深入实践的读者可以在仓库中对照以下关键文件继续研究编程风格实例src/ipc.c、include/rtdbg.h、include/rtdef.h格式化配置仓库根目录.clang-format及各子目录的.clang-formatBSP 层级实例bsp/stm32、bsp/nxpDoxygen 示例与构建documentation/0.doxygen/example、documentation/run.sh赞分享操作系统嵌入式物联网嵌入式OSRTOS【免费下载链接】rt-threadRT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/项目地址https://gitcode.com/gh_mirrors/rt/rt-thread点击查看免费下载相关推荐RT-Thread BSP 贡献指南BSP 目录分层规范与提交要求RT Thread BSP 贡献指南BSP 目录分层规范与提交要求 本篇技术指南以 RT Thread 仓库 BSP Contribution Guide h操作系统嵌入式物联网嵌入式OSRTOSPaddleOCR 社区贡献指南Python 编码规范、文档规范与 Pull Request 全流程PaddleOCR 社区贡献指南Python 编码规范、文档规范与 Pull Request 全流程 本文是 PaddleOCR 开源社区贡献者的入门手册系人工智能计算机视觉OCR深度学习大模型RAGRT-Thread Doxygen 文档书写指南从 API 注释规范到 HTML 文档构建RT Thread Doxygen 文档书写指南从 API 注释规范到 HTML 文档构建 本篇技术指南以 RT Thread 官方文档目录 document操作系统嵌入式物联网嵌入式OSRTOS上一篇lib-shim-v2性能优化技巧提升容器操作效率的10个方法下一篇Komi Store 开发者贡献指南从本地构建到落地合入 PR 的完整实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表