NXP S32K MPC5748 ,Renesas Rh850 ,Tricore Tc397 ...
NXP S32K MPC5748 ,Renesas Rh850 ,Tricore Tc397 UDS Doip 以太网 刷写,CAN/LIN UDS刷写 多个汽车开发诊断刷写量产工程。 可定制开发 AUTOSAR BSW代码移植开发。
最近在搞汽车诊断刷写的兄弟应该都发现了,现在车厂对刷写速度和稳定性的要求越来越变态。以前用CAN总线刷个500MB的校准文件得半小时,现在上了以太网DoIP之后直接缩短到5分钟,这酸爽谁用谁知道。
先说说NXP的S32K MPC5748平台,这货的FlexCAN模块是真省心。上次给某新能源车做UDS刷写,遇到个奇葩问题——进扩展会话死活不成功。后来发现是BSW层的会话层状态机没正确跳转,上代码:
void DiagSession_Handler(uint8_t sessionType) {
if(sessionType == EXTENDED_DIAG) {
// 坑点:必须等待安全解锁完成
while(!Security_Unlock_Status()) {
CanIf_Transmit(0x732, "WaitSecurity", 8);
Delay_ms(50);
}
CurrentSession = sessionType;
Nvm_Write(SESSION_STORAGE_ADDR, &sessionType, 1);
}
}
这段代码里的while循环卡死了诊断线程,后来改成事件触发机制才解决。搞汽车软件的都知道,NVM写操作耗时堪比老太太过马路,这里必须用异步处理。
转到瑞萨RH850平台又是另一个画风,特别是它的DCL库对多核刷写的支持。见过最骚的操作是同时刷两个ECU的校准文件:
with DoIPClient() as router:
for ecu in [0x7E0, 0x7E1]:
router.create_task(
flash_ecu(ecu, "app_v2.hex"),
timeout=300
)
router.monitor_progress(bps=500000)
这里用到了Python的asyncio库,实测能省40%的刷写时间。但要注意RH850的PHY初始化有个隐藏条件——必须在系统时钟稳定后延迟100ms才能操作MAC寄存器,否则会随机出现丢包。
NXP S32K MPC5748 ,Renesas Rh850 ,Tricore Tc397 UDS Doip 以太网 刷写,CAN/LIN UDS刷写 多个汽车开发诊断刷写量产工程。 可定制开发 AUTOSAR BSW代码移植开发。
英飞凌TC397的AUTOSAR移植才是真刺激。某次移植CAN驱动时,CanIf模块和Port驱动死活对不上号:
<CONTAINER UUID="CanIf_Config">
<PARAMETER NAME="ControllerBaudrate" VALUE="500"/>
<!-- 必须和Port模块的Pad配置一致 -->
<REFERENCE DEST="PORT_PAD">Can0_Tx</REFERENCE>
</CONTAINER>
结果发现是MCAL版本和AUTOSAR4.3不兼容,手动修改了27处ARXML配置才跑通。这里推荐用西门子的DaVinci Developer做差异对比,比人工排查效率高十倍。
量产工程最头疼的是处理各种奇葩上位机。有次遇到某国产工具链发的CAN帧间隔超标,直接在TC397里加了个动态滤波:
void Can_Filter_Adjust(uint32_t currentBaudrate) {
uint16_t nominalWidth = (currentBaudrate > 500000) ? 12 : 17;
CAN_NODE->NBTP = (nominalWidth << 16) | (5 << 24);
// 动态调整采样点位置
if(Can_Get_ErrorCounter() > 100) {
nominalWidth += 2;
CAN_NODE->NBTP = (nominalWidth << 16) | (5 << 24);
}
}
这招让产线不良率从3%降到0.2%。不过要注意不同CAN控制器的寄存器操作时序差异,瑞萨的RH850必须用MMIO方式操作,而NXP的FlexCAN可以直接位操作。
现在做刷写方案没点骚操作真混不下去。最近在搞的增量刷写黑科技,通过对比新旧文件的差异块,把刷写数据量压缩了70%。核心算法大概长这样:
vector<DiffBlock> compareBinaries(const uint8_t* old, const uint8_t* new, size_t size) {
vector<DiffBlock> diffs;
size_t blockSize = 256; // 根据NVM页大小调整
for(size_t i=0; i<size; i+=blockSize){
if(memcmp(old+i, new+i, blockSize) != 0){
diffs.emplace_back(i, blockSize, new+i);
}
}
return diffs;
}
但实际应用中要考虑NVM的擦写次数限制,某德系车厂要求每个block最多擦写1000次,这个算法就得加上磨损均衡策略。
刷写这行当,三分靠技术七分靠玄学。上周遇到个灵异事件:TC397在-40℃时UDS响应变慢,最后发现是Ethernet Switch的低温启动时序问题。解决办法是在DoIP激活前加了2秒延时,还专门在代码里写了注释:"此处有鬼,勿删!"。

更多推荐
所有评论(0)