尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

新能源汽车软件设计规范:从流程到可评审的技术资产

发布时间:2026/9/17 16:49:03

资讯中心
01
ARTICLE

新能源汽车软件设计规范:从流程到可评审的技术资产

新能源汽车软件设计规范:从流程到可评审的技术资产
简介新能源汽车软件开发设计规范是一份面向新能源汽车软件工程师的标准化开发指南围绕AUTOSAR分层架构展开适合需要掌握汽车电子软件架构、理顺应用层与基础软件层关系的研发人员。文档系统讲解了软件架构设计、应用层软件设计、软件编程规范与软件开发流程重点拆解了运行时环境之下的微控制器抽象层、ECU抽象层、服务层和复杂驱动的职责划分并从Unit单元、Component模块、System系统三个层面介绍应用层设计方法。同时覆盖变量管理、Simulink工程目录与工程配置、定制工具开发、命名规则与建模规则等实操内容可用于统一团队开发规范、降低软硬件耦合度提升代码可维护性与复用性。资源包中仅包含一个PDF文件大小约1.53MB便携易查。已有912人学习下载适合作为新能源车型软件开发的参考手册或内部培训材料。1. 新能源汽车软件开发设计规范从文档标准到可评审的技术资产一个反直觉的结论是绝大多数新能源汽车软件项目出问题并不是因为代码写得不够好而是因为“设计规范”没有建立起来或者建立了却停留在文档层面没有变成可执行、可评审、可追溯的技术约束。在传统嵌入式软件开发里代码能跑往往就意味着交付完成但在新能源汽车领域软件开发流程要同时面对功能安全、ASPICE 过程审核和整车级集成压力设计规范既是技术文档也是质量证据链的一部分。设计规范解决的是软件开发过程中的一致性问题命名、接口、状态管理、诊断实现、安全机制、评审标准。如果这些规则只存在于个别工程师的脑子里项目一扩编、供应商一介入、人员一轮流动软件就开始分叉。这篇文章按照设计规范的建立顺序来写先讲清楚规范和流程的关系再落到规范目录、单元设计、接口设计、诊断设计的具体条目最后讲怎么用工具链把规范变成检查项在持续集成里强制约束团队行为。2. 设计规范怎么建从 ASPICE 流程到单元级质量要求2.1 为什么规范的根在流程而不在代码风格很多团队一提到设计规范第一反应是“统一代码风格”。但风格问题用格式化工具就能解决真正需要设计规范来治理的是软件开发流程中的一致性和可追溯性这一点在 ASPICE 和功能安全体系下尤其明显。ASPICE 是汽车行业用的软件过程评估模型它把软件开发流程拆成系统需求分析、软件需求分析、软件架构设计、软件详细设计和单元验证等关键过程域。ASPICE 审核员在评估一个项目时看的不是代码写得多漂亮而是过程产物之间是否有清晰的追溯关系。设计规范就是连接“需求描述”和“代码实现”的桥梁它在软件详细设计和单元验证阶段发挥了承上启下的作用。ISO 26262 功能安全标准则从另一个维度约束设计规范。ASIL 等级越高的模块对软件设计的要求越严格变量访问要加保护机制关键路径不能有未定义行为错误处理必须有明确的降级策略。这些要求如果不提前写进设计规范里等代码写完了再补代价会非常大。所以设计规范的第一个定位是为流程服务。它要能让开发工程师明确知道拿到一个需求以后软件架构怎么建模块怎么划分接口怎么声明变量怎么命名错误怎么处理测试怎么证明我做对了。规范里面真正值钱的内容不是几条命名约定而是一套从功能需求到代码实现的翻译规则。2.2 一套可落地的设计规范目录结构要建设计规范不要一上来就写长文档。常见做法是先建一套规范目录框架然后分阶段填充条目。我一般会按下面这个结构组织新能源汽车软件设计规范规范模块覆盖内容对应流程阶段架构设计规范分层模型、模块划分、模块间依赖规则、数据流约定软件架构设计接口设计规范函数接口、消息接口、全局变量访问、参数命名详细设计编码实施规范语言子集、防御式编程、断言使用、不可达代码详细设计诊断设计规范UDS 服务实现、DTC 定义、快照与扩展数据软件需求安全设计规范内存保护、看门狗、错误降级、ASIL 分解系统与软件设计测试设计规范单元测试用例设计、覆盖率要求、测试环境单元验证建立这个目录之后不要追求一步到位。先把当前项目中最痛的部分定下来比如诊断这块没有规范DTC 命名全凭个人发挥那第一个版本就写诊断设计规范写清楚状态位怎么表示、故障等级怎么划分、快照数据按什么原则记录。等运行一个迭代以后再补充其他模块。规范里的每条要求必须有可验证性。不能写“代码应具有良好的可读性”因为这句话没法评审。要写成“单个函数的分支数不超过 12 个”“所有对外接口必须声明返回值错误码”“禁止在中断处理函数中调用动态内存分配”。只有这样的条目才能变成评审清单里的勾选项。提示每条规范的描述建议包含三部分规则编号、规则内容、违背规则的后果。后果不一定是惩罚也可以是“评审时必须给出书面豁免理由并抄送项目技术负责人”。2.3 单元设计和编码约束的关键条目单元设计规范最容易被写成“C 语言编程注意事项”这是个大坑。新能源汽车软件的单元设计规范要回答的是一个软件单元应该长成什么样才能被测试、被复用、被安全地集成进整车控制器。单元设计的第一步是对输入做合法性检查。底层的控制器软件经常跑在资源受限的 MCU 上外部输入可能来自传感器、总线报文、其他模块的返回值任何一路信号异常都不应该导致整个模块崩溃。我一般会把这类规则写成强制条款/* 单元入口防御式编程示例 */ int32_t BrakeControl_ApplyPress(int32_t press_raw) { int32_t press_limited 0; /* 规则 NEV-DES-021: 输入值必须先做范围检查再参与后续计算 */ if ((press_raw BRAKE_PRESSURE_MIN) || (press_raw BRAKE_PRESSURE_MAX)) { /* 记录超限事件走错误计数不使用异常值继续计算 */ ErrorCounter_Increase(BRAKE_INPUT_OUT_OF_RANGE); press_limited BRAKE_PRESSURE_SAFE_FALLBACK; } else { press_limited press_raw; } /* 规则 NEV-DES-024: 中间计算结果在使用前必须确认不溢出 */ if (press_limited (INT32_MAX 1)) { press_limited INT32_MAX 1; } return ConvertToActuatorUnit(press_limited); }上面这段代码演示了单元设计的两个典型规则。第一条规则是输入范围检查必须在业务逻辑之前完成保证异常数据进不了计算路径。第二条规则是中间结果的溢出保护这是新能源汽车电控软件里最容易踩的坑。很多 MCU 上 int 是 32 位的传感器原始值经过增益、偏置、补偿系数计算以后结果可能超出预期范围如果不做逐级限幅最终输出的控制量会产生跳变。单元级规范里还应该包含“代码容易写错而编译器又不报错”的内容比如隐式类型转换。这类问题在 PC 上可能只是告警但在车规编译器里会导致不可预期的行为。设计规范里可以直接规定禁止无符号数和有符号数在同一个表达式里运算除非已经显式完成类型转换。做评审的时候重点也不是看代码风格是不是漂亮而是看单元是否满足三个条件输入有保护、状态有归置、错误有上报。满足这三个条件单元代码才有资格进入集成验证阶段。3. 架构、接口与诊断规范把“能跑”变成“可装配、可诊断”3.1 软件架构分层与模块划分原则新能源汽车控制器的软件架构AUTOSAR 是最常见的基础模型。AUTOSAR 把整个软件栈分成应用层、RTE 层和基础软件层。很多团队在实际落地时并不追求完整 AUTOSAR 合规而是会参考这个分层结构做裁剪。无论采用哪种方式架构设计规范要回答的核心问题是某个功能应该放在哪一层模块和模块之间的依赖应该走什么路径。划分模块的常见准则是高内聚、低耦合。在这个基础上新能源汽车软件开发还需要加一条特殊约束每个控制类模块必须带有明确的运行周期、超时检测和失效降级策略。原因在于车辆控制器里的控制功能往往是周期调度的比如电机扭矩控制按 1ms 周期跑整车状态管理按 10ms 周期跑。架构设计规范里要明确每个模块属于哪个任务。调度层级典型周期代表性模块失效影响快任务1ms - 2ms电机电流环控制、扭矩仲裁输出波动严重时导致抖动中速任务10ms - 20ms电池状态估算、能量回收协调能量管理异常慢任务100ms 及以上热管理、诊断服务告警延迟、舒适性下降架构设计规范里还应该规定模块的上层依赖规则比如应用层模块只能通过标准化接口访问基础软件功能禁止直接操作寄存器来绕开驱动层。第一版规范建议只规定最关键的两三条依赖规则等实际项目中真的出现了绕路代码再补充对应约束。这比一开始就写一份“完美但没人读”的大全要好得多。3.2 接口设计规范的统一模板与命名规则接口设计规范是我在实际评审中看到分歧最大的部分。有人认为接口设计就是把函数名命名字母大小写统一一下有人则希望所有接口都能被建模工具识别并生成代码。新能源汽车软件开发里的接口设计规范应该锚定在“可追踪”和“可仿真”这两个目标上。可追踪的意思是接口应该能回溯到软件需求。比如一个泵的控制接口如果命名是Pump_Control_SetSpeed(int16_t speed)那需求的编号可以直接写在注释里。可仿真的意思是接口的描述要完整到可以让测试工程师在不了解内部实现的情况下编写出有效的测试用例。一个推荐的接口定义模板/** * brief 设置冷却水泵目标转速 * nevid SWR-BMS-042 * input speed: 目标转速单位 rpm范围 0~6000 * input ramp_enable: 是否使能斜坡限制 * return 错误码0x00 成功0x11 参数超限0x22 模块未就绪 */ uint8_t CoolantPump_SetSpeed(uint16_t speed, bool ramp_enable);这套接口设计规范里包含了几个关键参数要求。第一接口注释里必须写需求编号这样代码评审时可以直接从接口跳到需求文档。第二参数范围和返回值用可读的枚举或宏定义不能返回裸的魔法数字。第三如果接口带斜坡控制这类“隐含行为”必须在注释里明示不能让调用方靠猜。接口设计规范还要处理全局变量问题。虽然架构上不鼓励用全局变量但 MCU 上批量处理信号时经常绕不开。规范的做法是所有跨模块访问的信号必须通过接口函数或者集中定义的信号路由表不能在业务代码里直接extern一个变量然后到处改。3.3 诊断规范UDS 服务、DTC 与快照数据的强制性定义诊断这块是整个新能源汽车软件里最容易被轻视、也最容易被供应商牵着走的部分。设计规范对诊断的要求不能只写“支持 UDS 协议”要落到具体服务的实现行为上。UDS 服务里最常用的是 0x22 读数据、0x2E 写数据、0x19 读故障码、0x14 清故障码。设计规范要明确的是这些服务对应的数据标识比如电池包电压对应的 DID 是 0x0101电机的当前扭矩对应的 DID 是 0x020A。如果有条件直接在规范里出一张 DID 分配表。DID 范围信号分组读写权限典型示例0x0100 - 0x01FF整车状态信息只读读0x0101 电池总电压0x0200 - 0x02FF动力系统状态只读读0x020A 电机输出扭矩0xF100 - 0xF1FF标定/配置数据读/写0xF150 电池过温阈值DTC 的命名与状态位也必须统一约定。DTC 一般按 ISO 14229 的格式采用 3 字节表示设计规范里要规定每个字节的编码规则。更重要的是故障状态位每个 DTC 要带一个字节的状态位bit0 表示测试是否失败bit1 表示故障当前是否已确认bit4 表示是否有待处理。不同团队对故障确认计数器的处理方式不一致会导致同一辆车在不同诊断仪上读出来的结果完全不同。规范里直接写死故障确认计数器连续 3 次触发才置 confirmed 位连续 40 次通过才清 confirmed 位。诊断规范里还应该有一个“禁止项”列表写明哪些操作不允许做或必须约束比如禁止应用层软件直读写 DTC 状态位而不经过诊断模块、禁止在中断里执行故障码存储、禁止用延时代替状态机迁移。写完诊断规范以后可以用诊断调查表检查某个 DTC 的行为是否符合描述这是入门诊断设计最有效的方式。4. 让规范跑起来静态检查、持续集成与规范评审4.1 用 clang-tidy 把设计规范变成强制检查项设计规范如果没有工具约束很快就会变成贴在墙上的标语。在汽车行业静态代码分析是被广泛接受的验证手段MISRA C/C 规则集加上运行错误检测是标配。不过 MISRA 覆盖面有限我们自己做规范里定的那些额外规则还得靠工具链补齐。clang-tidy 适合用来做自定义规范的自动化检查尤其是命名规则、接口参数规则、注释缺失这类问题。一个典型的检查流程可以这样组织# 针对单元代码跑 clang-tidy启用内置检查与自定义规则 clang-tidy -checks\ -*, \ clang-analyzer-*, \ misc-definitions-in-headers, \ bugprone-branch-clone, \ cppcoreguidelines-init-variables \ src/power/battery_voltage.c -- -I./src -I./include参数说明-checks里的-*表示先禁用所有默认检查避免误报淹没真实问题clang-analyzer-*是编译期静态分析检查能找出空指针、资源泄漏、逻辑分支问题bugprone-branch-clone用来发现复制粘贴修改但条件表达式未同步更新的典型 bug最后--后面是传给编译器的参数-I指定头文件路径保证 clang-tidy 能正确完成语义分析。在设计规范落地阶段不用一下开全量检查项。建议先用 clang-tidy 查出所有违反“函数入口无参数校验”的代码修复一批后再加上下一条检查项。这样团队不会产生抵触情绪。这条命令可以直接丢进本地的 Git 提交钩子里也可以作为 Jenkins 流水线中的一个检查环节。4.2 在持续集成里按规范做构建、测试与覆盖率验证持续集成流水线的核心价值在于让“规范违反”尽早暴露。我一般按下面的顺序组织流水线# 阶段一静态检查让设计的规则先跑通 make scan 21 | tee scan.log # 阶段二编译工程重点捕捉告警和类型错误 make build 21 | tee build.log # 阶段三跑单元测试并统计覆盖率 make unit-test 21 | tee unit.log # 阶段四检查覆盖率阈值不达标直接失败 lcov --extract build/coverage.info -o cov.info lcov --summary cov.info | tee cov_summary.txt这里的关键是每个阶段之间要有依赖关系。静态检查失败后面的编译和测试不会执行因为输出产物不是一个可信的基础。编译时配置里可以加-Werror将警告视为错误。覆盖率检查用 lcov 工具统计如果单元测试的行覆盖率低于 80%、分支覆盖率低于 60%流水线判定为失败并把报告归档到构建记录里。将覆盖率作为设计规范的验证手段本身就是在检查设计是否达到了“可测试”的标准。如果代码里有一段逻辑分支覆盖率始终达不到阈值通常意味着这段逻辑的判定条件缺少边界测试也说明详细设计中对这条分支的输入约束描述不够完整。提示刚开始跑覆盖率时不要直接全量检查。建议先把新增代码覆盖率作为准入门槛存量代码设置一个基础的 50% 阈值随着版本迭代逐步提高这样在项目中期就有能力去推动历史债务的清理。4.3 规范评审不要开成“朗读会”评审是设计规范落地的最后一道关口。常见的做法是准备一份评审检查单把设计规范里的强制约束提取成可勾选的条目每个人都必须逐条确认并由作者签字留痕。一份有效的检查单不需要太长20 条左右即可。评审时我会重点关注“需求编号是否在接口注释中存在”“输入边界和错误码在调用方是否都有处理”这类设计缺陷判定问题。这些条目如果直接靠人读代码来找一上午也看不完。先让 clang-tidy 和脚本把命名、注释、空值检查等机械问题筛掉评审会上只聊逻辑边界和状态迁移这是把时间花在刀刃上的方式。变更管理同样重要。设计规范一旦定稿任何对接口、命名、诊断协议或安全机制的修改都需要走正式的变更流程。一个轻量的做法是在 Git 仓库里同时维护规范文档和代码规范变更通过 MR 合入并在 commit message 里关联变更原因。旧版本规范建议留档不删因为车厂经常要处理底层的售后软件还有 OEM 审计时需要追溯某个版本当时执行的是哪版规范。每一版规范都对应一版真实发布的软件这条记录是审计时最有说服力的证据。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。