XCP或者CCP标定,A2L标定文件,基于map文件自动更新A2L的地址和结构体变量的地址 源...
XCP或者CCP标定A2L标定文件基于map文件自动更新A2L的地址和结构体变量的地址 源码基于C需要开发编译器为VS2022搞汽车电子的兄弟应该都遇到过这样的问题——辛辛苦苦标定的A2L文件程序稍微改两行代码地址全跑偏了。这时候要是手动改地址那酸爽程度堪比在早高峰的北京西二旗挤地铁。今天咱们就来聊聊怎么用C#写个自动化工具让map文件自己生娃更新A2L。先扒拉一下map文件这玩意儿就是个内存布局的身份证。比如用IAR编译器生成的map里全局变量长这样.section.bss 0x20000000 0x400 ... EngineSpeed 0x200001a4 4 main.c.o CoolantTemp 0x200001a8 4 sensor.c.o注意这些十六进制地址这就是咱们要找的黄金矿点。用C#整段正则表达式先挖矿var addressRegex new Regex(^(?name\w)\s(?addr0x[0-9a-fA-F])\s\d\s\S$); var varDict new Dictionarystring, string(); foreach (var line in File.ReadLines(project.map)) { var match addressRegex.Match(line); if (match.Success) { varDict[match.Groups[name].Value] match.Groups[addr].Value; } }这波操作相当于把map文件里的变量名和地址打包成字典后面直接当电话簿查。XCP或者CCP标定A2L标定文件基于map文件自动更新A2L的地址和结构体变量的地址 源码基于C需要开发编译器为VS2022接下来看看A2L文件里的变量声明典型的结构像这样/begin CHARACTERISTIC EngineSpeed_Rpm Engine Speed Actual VALUE 0x200001a4 RATE_DIRECT UWORD ECU_ADDRESS -15.0 15.0 COEFFS 1.0 0.0 0.0 0.0 /begin IF_DATA XCP DAQ_BY_PID /end IF_DATA /end CHARACTERISTIC关键是要把十六进制地址0x200001a4换成map里的新值。这时候直接上文本处理大法比XML解析快得多var sb new StringBuilder(); foreach (var line in File.ReadLines(original.a2l)) { if (line.Trim().StartsWith(VALUE)) { var currentLine line; var nextLine sr.ReadLine(); if (nextLine ! null) { var addrMatch Regex.Match(nextLine, 0x[\da-fA-F]); if (addrMatch.Success varDict.TryGetValue(varName, out var newAddr)) { nextLine nextLine.Replace(addrMatch.Value, newAddr); } } sb.AppendLine(currentLine); sb.AppendLine(nextLine); } //...其他处理 }这里有个坑要注意——A2L里的变量名可能有下划线后缀比如EngineSpeed_Rpm在map里可能是EngineSpeed。得处理这种命名差异可以写个转换规则string MapToA2LName(string rawName) { return rawName.Replace(_, ); //根据实际命名规则调整 }遇到结构体这种硬骨头map文件里能看到这样的记录struct EngineStatus .RunningFlag 0x20000200 1 .FaultCode 0x20000201 2这时候得把整个结构体当棵圣诞树来挂装饰var structRegex new Regex(^struct\s(?name\w)\s*$); string currentStruct null; foreach (var line in File.ReadLines(project.map)) { if (structRegex.IsMatch(line)) { currentStruct structRegex.Match(line).Groups[name].Value; } else if (line.StartsWith( .)) { var memberMatch Regex.Match(line, ^\s\.(?member\w)\s(?addr0x\w)\s\d); if (memberMatch.Success currentStruct ! null) { var fullName ${currentStruct}_{memberMatch.Groups[member].Value}; varDict[fullName] memberMatch.Groups[addr].Value; } } }最后给整个流程加个批处理外壳用VS2022的Task Runner绑定到编译后事件每次编译完自动更新A2L。实测下来原本半小时的手动改地址现在点下编译就搞定还能少喝两杯咖啡提神。代码仓库里记得放几个测试用的map和A2L文件方便新人上手调试。毕竟这玩意儿就像汽车ECU光看文档不实操永远不知道哪里会漏油。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2477366.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!