UDS 代码生成示例
本示例演示了如何使用 EcuBus-Pro 的 UDS 代码生成 系统与 Handlebars 模板。uds.hbs 模板基于您的 UDS 服务定义生成 DCM(诊断通信管理器)配置的 C 代码。
模板文件分析:uds.hbs
模板结构概览
该模板生成包含两个主要配置数组的 C 代码:
Dcm[]- 主服务配置数组DcmRoutineControlConfig[]- 例程控制特定配置
详细代码分析
1. 许可证头部
将包含在所有生成文件中的静态许可证头部。
2. 包含语句
用于 DCM 功能的标准 C 包含。
3. 服务数量计算
逐行解释:
{{logFile 'Calculate active service type except JobFunction'~}}- 调试输出到日志文件{{setVar 'serviceNum' 0~}}- 将计数器变量初始化为 0{{#each tester.allServiceList~}}- 遍历测试器中的所有服务{{#if (not (eq @key 'Job'))}}- 检查当前服务键是否不是 'Job'{{setVar 'serviceNum' (add @root.serviceNum 1)~}}- 为非 Job 服务递增计数器{{/if~}}- 结束 if 语句{{/each~}}- 结束 each 循环#define SUPPORTED_SERVICE_NUM {{@root.serviceNum}}- 生成包含总计数量的 C 宏
4. 主 DCM 配置数组
解释:
DcmConfig_t Dcm[]={- 开始 C 数组声明{{#each tester.allServiceList}}- 遍历所有 UDS 服务
4.1 会话控制服务 (0x10)
解释:
{{#if (eq @key '0x10')}}- 检查当前服务 ID 是否等于 0x10(会话控制)- 生成会话控制服务的 DCM 配置
- 使用按位 OR 启用多个会话类型
- 将安全级别设置为 NULL(无需安全)
- 分配回调函数
4.2 按标识符读取数据服务 (0x22)
解释:
{{#if (eq @key '0x22')}}- 检查服务 ID 0x22(按标识符读取数据)- 与会话控制类似的结构,但使用不同的回调函数
4.3 例程控制服务 (0x31)
解释:
{{#if (eq @key '0x31')}}- 检查服务 ID 0x31(例程控制)- 使用适当的回调函数配置例程控制服务
5. 例程控制特定配置
逐行解释:
DcmRoutineControlConfig_t DcmRoutineControlConfig[]={- 开始例程控制配置数组{{#each (get tester.allServiceList '0x31')}}- 遍历所有 0x31(例程控制)服务/* {{name}} */- 生成包含服务名称的注释{- 开始配置结构.routineControlType={{get (first (filter params 'routineControlType' property='name')) 'phyValue' }},- 从参数中提取例程控制类型.routineIdentifier=[{{get (first (filter params 'routineIdentifier' property='name')) 'value.data'}}],- 提取例程标识符.session={{#if generateConfigs}}{{get generateConfigs 'session'}}{{else}}DCM_DEFAULT_SESSION_EN{{/if}},- 设置会话类型(自定义或默认).security={{#if generateConfigs}}{{get generateConfigs 'security'}}{{else}}DCM_SECURITY_LEVEL_NULL{{/if}},- 设置安全级别(自定义或默认)},- 结束配置结构{{/each}}- 结束循环};- 关闭数组
使用的辅助方法
数据访问辅助方法
{{get object property}}- 安全访问对象属性{{first array}}- 获取数组的第一个元素{{filter array value property='name'}}- 按属性值过滤数组
逻辑辅助方法
{{#if condition}}...{{else}}...{{/if}}- 条件逻辑{{eq a b}}- 相等比较{{not condition}}- 逻辑非
实用工具助手
{{setVar name value}}- 设置模板变量{{add a b}}- 数学加法{{logFile message}}- 调试日志记录
迭代助手
{{#each array}}...{{/each}}- 遍历数组元素{{@key}}- 迭代中的当前键{{@root}}- 访问根上下文
使用说明
- 配置 UDS 服务:在 EcuBus-Pro 测试器中设置您的 UDS 服务
- 添加模板:选择
uds.hbs模板文件 - 设置生成路径:指定生成的 C 代码的输出目录
- 生成代码:运行代码生成过程
- 集成:将生成的文件包含到您的 DCM 实现中
生成输出示例
该模板将生成类似于以下的 C 代码:
c
/**
* 开源许可证
*
* EcuBus-Pro 基于 Apache License 2.0 的修改版本进行许可,并附加以下条件:
*
* 1. EcuBus-Pro 可用于商业用途,包括作为诊断工具或企业开发平台。若满足以下条件,必须从生产商处获取商业许可证:
*
* a. 设备支持和许可:
* - EcuBus-Pro 源代码包含对一组标准 USB 设备的支持。
* - 如果您希望添加对专有设备的支持而不开源实现,必须从 EcuBus-Pro 获取商业许可证。
*
* b. LOGO 和版权信息:在使用 EcuBus-Pro 前端的过程中,您不得移除或修改 EcuBus-Pro 控制台或应用程序中的 LOGO 或版权信息。此限制不适用于不涉及 EcuBus-Pro 前端的用途。
* - 前端定义:就本许可证而言,EcuBus-Pro 的“前端”包括从原始源代码运行 EcuBus-Pro 时位于 `src/renderer/` 目录中的所有组件,或使用 Electron 运行 EcuBus-Pro 时的“渲染器”组件。
*
* 2. 作为贡献者,您应同意:
*
* a. 生产商可根据需要调整开源协议,使其更严格或更宽松。
* b. 您贡献的代码可用于商业目的,包括但不限于其诊断业务运营。
*
*
* 除上述特定条件外,所有其他权利和限制均遵循 Apache License 2.0。有关 Apache License 2.0 的详细信息,请访问 http://www.apache.org/licenses/LICENSE-2.0。
*
* 本产品的交互设计和硬件接口受专利保护。
* EcuBus-Pro 及其徽标是 Whyengineer, Inc. 的注册商标。
*
* © 2025 Whyengineer, Inc.
*
* 有关商业许可的咨询,请联系:frankie.zengfu@gmail.com
*/
#include "Dcm.h"
#define SUPPORTED_SERVICE_NUM 9
DcmConfig_t Dcm[]={
/* Diagnostic Session Control (0x10) */
{
DCM_DIAGNOSTIC_SESSION_CONTROL,
DCM_DEFAULT_SESSION_EN | DCM_PROGRAMMING_SESSION_EN | DCM_EXTENDED_DIAGNOSTIC_SESSION_EN,
DCM_SECURITY_LEVEL_NULL,
Dcm_SessionControlCallback,
},
/* RoutineControl (0x31) */
{
DCM_ROUNTINE_CONTROL,
DCM_DEFAULT_SESSION_EN | DCM_PROGRAMMING_SESSION_EN | DCM_EXTENDED_DIAGNOSTIC_SESSION_EN,
DCM_SECURITY_LEVEL_NULL,
Dcm_RoutineControlCallback,
},
};
DcmRoutineControlConfig_t DcmRoutineControlConfig[]={
/* RoutineControl490 */
{
.routineControlType=1,
.routineIdentifier=[2,2],
.session=DCM_EXTENDED_DIAGNOSTIC_SESSION_EN,
.security=DCM_SECURITY_LEVEL_1 | DCM_SECURITY_LEVEL_2,
},
/* RoutineControl491 */
{
.routineControlType=2,
.routineIdentifier=[255,0],
.session=DCM_DEFAULT_SESSION_EN,
.security=DCM_SECURITY_LEVEL_NULL,
},
};