编码指南
Main rules
编码指南规则基于 MISRA-C 2012,是 MISRA-C 的一个 子集。该子集在下表中列出,并附有规则摘要、其 MISRA-C 严重性以及来自其他标准的等效规则,供参考。
下表中的严重性和其他参考信息仅供参考。所列规则对 Zephyr 来说都是必需的,所有新代码都应遵守下面列出的规则。
备注
对于现有的 Zephyr 维护者和协作者,如果你无法通过雇主获得一份副本,项目将提供数量有限的副本。如果你需要 MISRA-C 2012 的副本,请发送邮件至 safety@lists.zephyrproject.org,并详细说明你为何无法通过其他途径获得,以及拿到副本后预计会做出哪些贡献。安全委员会将审核所有申请。
附加规则
规则 A.1:条件编译
- 严重性
必需
- 描述
不要在头文件中条件编译函数声明。不要在头文件中条件编译结构体声明。可以条件排除结构体定义中的字段,以便在它们所支持的特性未启用时避免浪费内存。
- 理由
基于编译期选项把头文件中的声明排除在外,可能会导致无法生成这些声明的文档。当代码路径需要根据所选选项变化时,这些声明的缺失也会使
if (IS_ENABLED(CONFIG_FOO)) {}无法作为预处理条件表达式的替代方案使用。
规则 A.2:包容性语言
- 严重性
必需
- 描述
不要引入下面列出的冒犯性术语的新用法。本规则适用于源代码、注释、文档和分支名称,但不限于这些。替代术语可能因领域或子系统而异,但应尽可能遵循更新后的行业标准。
在维护现有实现,或为 Zephyr 项目外部管理的行业标准规范添加新实现时,允许有例外。
建议在更新后的行业标准规范发布或管理机构公开宣布新术语后,尽快更改现有用法;如果没有任何规范适用,则应立即更改。
冒犯性术语
建议的替代术语
{master,leader} / slave{primary,main} / {secondary,replica}{initiator,requester} / {target,responder}{controller,host} / {device,worker,proxy,target}director / performercentral / peripheral
blacklist / whitelistdenylist / allowlistblocklist / allowlistrejectlist / acceptlist
grandfather policylegacy
sanitycoherenceconfidence
- 理由
冒犯性术语无法营造包容的社区环境,因此违反了 Zephyr 项目的 Code of Conduct。本编码规则受到 Linux 中类似规则的启发。
- 状态
相关的 GitHub Issue 和 Pull Request 会打上 Inclusive Language Label 标签。
领域
选定的替代术语
状态
CAN
这篇 CAN in Automation Inclusive Language news post 列出了一般性建议。关于规范文档更新中应使用的术语,请参阅 CAN in Automation Inclusive Language。
eSPI
master / slave=>controller / target
关于新术语,请参阅 eSPI Specification
gPTP
master / slave=> TBD
master / slave=>controller / target
关于新术语,请参阅 I2C Specification。
master / slave=>controller / target
关于新术语,请参阅 I2S Specification。Zephyr I2S API 已在 Zephyr 4.4 中迁移到这些术语;原有的宏名称作为已弃用的别名保留,并将在 Zephyr 5.0 中移除。
SMP/AMP
master / slave=> TBD
master / slave=>controller / peripheralMOSI / MISO / SS=>SDO / SDI / CS
Open Source Hardware Association 选定了这些替代术语。请参阅 OSHWA Resolution to Redefine SPI Signal Names。Zephyr SPI API 和代码树已在 v4.5 中迁移到这些术语;原有名称作为兼容性别名保留,自 v4.5 起弃用,并计划在 v5.0 中移除。
platform_whitelist=>platform_allowsanitycheck=>twister
规则 A.3:宏名称冲突
- 严重性
必需
- 描述
MIN、MAX、ARRAY_SIZE这类常用名称的宏,不得为了避开与其他实现的名称冲突而修改或加保护。特别地,不得为它们添加前缀以放入 Zephyr 专用的命名空间,不得使用#undef重新定义,也不得使用#ifndef条件排除其编译。反之,如果与来自 模块 的既有定义发生冲突,则需要修改该模块自身的代码,最好在上游修改,或者通过 Zephyr 自己分支中的改动来实现。本规则普遍适用于 Zephyr 项目,与宏的引入时间或它在代码树中的当前名称无关。如果某个宏名称在其他几个知名开源项目中普遍使用,那么 Zephyr 中的实现就应使用该名称。虽然“普遍使用”的含义带有主观且无法量化的成分,但最终目标是向用户提供他们熟悉的宏。
最后,本规则同样适用于模块之间的名称冲突:在这种情况下,应在引入这两个模块之前,将它们修改为使用发生冲突的宏名称的模块专属版本。
- 理由
Zephyr 是一个 RTOS,它以模块的形式带来额外的功能和依赖。这些模块通常是独立的项目,可能会使用与其他模块或 Zephyr 本身冲突的宏名称。由于在本文档的语境中 Zephyr 被视为核心或主项目,因此它应实现不带命名空间的宏版本。鉴于 Zephyr 为每个模块都使用了相应上游的分支,总是可以通过修补各模块中的宏实现来避免冲突。
规则 A.4:Zephyr 内核中 C 标准库的使用限制
- 严重性
必需
- 描述
Zephyr 内核中 C 标准库函数和宏的使用应限于 ISO/IEC 9899:2011 标准(也称为 C11)中的以下函数和宏及其扩展:
上面列出的所有函数都必须由 minimal libc 实现,以确保 Zephyr 内核能够使用 minimal libc 构建。
此外,上述列表中不属于 ISO/IEC 9899:2011 标准的任何函数都必须由 common libc 实现,以确保它们在多种 C 标准库中都可用。
在满足上述要求的前提下,如果有正当理由,允许向 Zephyr 内核引入新的 C 标准库函数。
请注意,上面列出的函数的使用仍受安全可靠编码实践的约束,不应因为本规则列出了它们,就认为在 Zephyr 内核中使用它们是无条件允许的。
在此语境中,“Zephyr 内核”由以下组件组成:
内核(
kernel)OS 库(
lib/os)架构移植层(
arch)日志子系统(
subsys/logging)
- 理由
Zephyr 内核必须能够使用 minimal libc 构建,这是 Zephyr RTOS 的一部分、由 Zephyr 项目维护的一个精简 C 标准库实现,从而可以对内核和核心 OS 服务进行自包含的测试和验证。
为了确保 Zephyr 内核能够使用 minimal libc 构建,有必要将 Zephyr 内核中 C 标准库函数和宏的使用限制为 minimal libc 所提供的那些函数和宏。
规则 A.5:Zephyr 代码库中 C 标准库的使用限制
- 严重性
必需
- 描述
Zephyr 代码库中 C 标准库函数和宏的使用应限于 ISO/IEC 9899:2011 标准(也称为 C11)中的函数,但不包括附录 K“边界检查接口”,除非本规则另有豁免。
在此语境中,“Zephyr 代码库”指提交到 main Zephyr repository 的所有嵌入式源代码文件,但不包括 规则 A.3:宏名称冲突 所定义的 Zephyr 内核。嵌入式源代码指要在嵌入式目标上执行的代码,因此不包括主机工具,也不包括专用于 native 测试目标的代码。
以下非 ISO 9899:2011 的函数和宏(下称非标准函数和宏)不受本规则约束,允许在 Zephyr 代码库中使用:
允许使用的非标准 libc 函数列表 Function
Source
POSIX.1-2001
POSIX.1-2008
POSIX.1-2001
上面列出的所有非标准函数和宏都必须由 common libc 实现,以确保在使用未实现这些函数的 C 标准库时也能提供这些函数。
在满足上述要求的前提下,如果有正当理由,允许将常见 C 标准库中的新非标准函数加入上述列表。但是,如果存在功能等价的标准函数,则应使用该标准函数。
- 理由
一些 C 标准库(例如 Newlib 和 Picolibc)包含由扩展 ISO C 标准的各种标准和事实标准(例如 POSIX、Linux)所定义的额外函数和宏。
ISO/IEC 9899:2011 标准并不要求 C 编译器工具链支持这些非标准函数,因此使用这些函数可能会导致与自带 C 标准库的第三方工具链出现兼容性问题。