CANoe_UDS-Bootloader刷写系列-含源码(五)CAPL实现$31服务例程控制

发布时间:2026/8/20 19:09:31

CANoe_UDS-Bootloader刷写系列-含源码(五)CAPL实现$31服务例程控制
学习是个漫长且痛苦的过程道路艰辛而曲折希望我们都在时代的长河中做一颗闪闪发光的尘埃。只有持之以恒才能有所成就目录前言目录目录系列目录一RoutineControl例程控制0x31服务二协议相关请求报文格式肯定响应 否定响应NRC三CAPL实现系列目录《CANoe_UDS-Bootloader刷写系列-含源码一刷写基本流程》《CANoe_UDS-Bootloader刷写系列-含源码二CAPL实现$10服务》《CANoe_UDS-Bootloader刷写系列-含源码三CAPL实现$27服务密钥解锁》《CANoe_UDS-Bootloader刷写系列-含源码四CAPL实现$34 $36 $37服务数据传输》《CANoe_UDS-Bootloader刷写系列-含源码五CAPL实现$31服务例程控制》 --待续《CANoe_UDS-Bootloader刷写系列-含源码六CAPL实现$22 $2E 服务读写配置》《CANoe_UDS-Bootloader刷写系列-含源码七CAPL实现$85 $28服务预编程步骤》《CANoe_UDS-Bootloader刷写系列-含源码七干货 CAPL实现CRC数据校验》《CANoe_UDS-Bootloader刷写系列-含源码八干货 CANoe_Panel刷写上位机面板制作》《CANoe_UDS-Bootloader刷写系列-含源码九CAPL框架全流程测试及报文分析-查漏补缺》接上篇所述我们通过CAPL实现了$36服务$37服务的数据的写入传输。今天我们学习如何实现31服务的例程控制。在14229协议中对于31服务有很大的扩展部分企业可以自定义企标的内容进行RID定制以实现想要的功能。本篇仅对刷写方面需要执行的31服务RID进行实例化解读。一RoutineControl例程控制0x31服务客户端使用RoutineControl例程控制请求启动停止服务器的例程或请求例程结果。在刷写中0x31服务主要用于在做软件升级时应用于检查刷写前置条件是否满足、传输数据完整性擦除程序以及独立性检测。就拿编程前置条件检查为例如我们需要检查当前的车速电压挡位等情况是否是满足刷写条件此时测试仪发送一个31 特定RID给ECUECU会返回当前的状态来告知测试仪是否可以执行升级。二协议相关请求报文格式从下图我们知道31服务是由N个字节组成第一个字节是服务RoutineControl0x31此字段是不变的。第二个字节是子服务sub_function(0x00-0xFF)子服务由下图2所示从0x04 - 0x7F 为已保留字段此子服务允许由厂商根据实际情况在企标内自定义。下图为子服务的具体协议要求肯定响应 否定响应NRCNRC三CAPL实现发送逻辑与$10服务类似。区别在于发送31服务时需要将本地升级包计算成相关的CRC值与71返回的数值进行比较若相同则完整性校验通过若不相同则升级过程中传输的包有中断或者丢包。如以下代码所示int routine_control(byte MessageSelectFlag,int data_record_length,int block_number){ byte request[BUFFER_SIZE_1024]; int index0; dword key_secu; dword seed0; char k[20]; char m[20]; int n0; int h0; char CRCbyte1[10]0x; char CRCbyte2[10]0x; char CRCbyte3[10]0x; char CRCbyte4[10]0x; char CRC1byte[10]; char CRC2byte[10]; char CRC3byte[10]; char CRC4byte[10]; char CRC1byte_NULL[10]; char CRC2byte_NULL[10]; char CRC3byte_NULL[10]; char CRC4byte_NULL[10]; char dest[10]; request[0]0x31; request[1]0x01; if(MessageSelectFlag0block_number0) //MessageSelectFlag0发送;31/01/FF/00 { request[2]0xFF; request[3]0x00; request[4]0x01; //调试添加 } if(MessageSelectFlag0block_number1) //MessageSelectFlag0发送;31/01/FF/01 { request[2]0xFF; request[3]0x01; //调试添加 } if(MessageSelectFlag1) //MessageSelectFlag1发送31/01/02/03 { request[2]0x02; request[3]0x03; } if(MessageSelectFlag2block_number1){ //调试添加 request[2]0xDF; request[3]0x01; request[4]0x01; } if(MessageSelectFlag2) //MessageSelectFlag2发送31/01/02/02 { request[2]0xDF; request[3]0x01; /*********以下代码为将4个Byte组成的AppCRC转成16进制字符串然后拆成4个Byte的数值**********/ strncpy(CRCbyte1,CRC1byte_NULL,elCount(CRC1byte_NULL)); //执行下面代码之前先清空CRCbyte1 strncpy(CRCbyte2,CRC2byte_NULL,elCount(CRC2byte_NULL)); //执行下面代码之前先清空CRCbyte2 strncpy(CRCbyte3,CRC3byte_NULL,elCount(CRC3byte_NULL)); //执行下面代码之前先清空CRCbyte3 strncpy(CRCbyte4,CRC4byte_NULL,elCount(CRC4byte_NULL)); //执行下面代码之前先清空CRCbyte4 write(Null CRC1byte%s,CRCbyte1); write(Null CRC2byte%s,CRCbyte2); write(Null CRC3byte%s,CRCbyte3); write(Null CRC4byte%s,CRCbyte4); strncat(CRCbyte1,0x, 15); strncat(CRCbyte2,0x, 15); strncat(CRCbyte3,0x, 15); strncat(CRCbyte4,0x, 15); ltoa(AppCRC,k,16);//将AppCRC值转成16进制字符串 write(AppCRC%s,k); snprintf(m,elcount(m),%8s,k); for(n0;n8;n) { if(m[n] ) m[n]0; } write(m%s,m); substr_cpy(CRC1byte,m,0,2,elcount(CRC1byte));//提取CRC中的第一个Byte字符串 substr_cpy(CRC2byte,m,2,2,elcount(CRC2byte));//提取CRC中的第二个Byte字符串 substr_cpy(CRC3byte,m,4,2,elcount(CRC3byte));//提取CRC中的第三个Byte字符串 substr_cpy(CRC4byte,m,6,2,elcount(CRC4byte));//提取CRC中的第四个Byte字符串 strncat(CRCbyte1,CRC1byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte2,CRC2byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte3,CRC3byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte4,CRC4byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 write(CRC1byte%s,CRCbyte1); write(CRC2byte%s,CRCbyte2); write(CRC3byte%s,CRCbyte3); write(CRC4byte%s,CRCbyte4); request[4]atol(CRCbyte1);//将CRC的第一个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[5]atol(CRCbyte2);//将CRC的第二个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[6]atol(CRCbyte3);//将CRC的第三个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[7]atol(CRCbyte4);//将CRC的第四个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 } if(MessageSelectFlag3) //(STP2-e) EraseMemory:31/01/FF/00/44 xx xx xx xx xx xx xx xx;71 01 FF 00 { request[2]0xFF; request[3]0x00; request[4]0x44; request[5]AppBinFileData[33]; request[6]AppBinFileData[34]; request[7]AppBinFileData[35]; request[8]AppBinFileData[36]; request[9]AppBinFileData[37]; request[10]AppBinFileData[38]; request[11]AppBinFileData[39]; request[12]AppBinFileData[40]; } if(MessageSelectFlag7block_number5){ request[2]0xDF; request[3]0x01; request[4]0x00; } if(MessageSelectFlag4) //MessageSelectFlag2FlashDriver校验CRC发送31/01/02/02 { request[2]0xDF; request[3]0x01; /*********以下代码为将4个Byte组成的DriverCRC转成16进制数然后拆成4个Byte的数值**********/ strncpy(CRCbyte1,CRC1byte_NULL,elCount(CRC1byte_NULL)); //执行下面代码之前先清空CRCbyte1 strncpy(CRCbyte2,CRC2byte_NULL,elCount(CRC2byte_NULL)); //执行下面代码之前先清空CRCbyte2 strncpy(CRCbyte3,CRC3byte_NULL,elCount(CRC3byte_NULL)); //执行下面代码之前先清空CRCbyte3 strncpy(CRCbyte4,CRC4byte_NULL,elCount(CRC4byte_NULL)); //执行下面代码之前先清空CRCbyte4 write(Null CRC1byte%s,CRCbyte1); write(Null CRC2byte%s,CRCbyte2); write(Null CRC3byte%s,CRCbyte3); write(Null CRC4byte%s,CRCbyte4); strncat(CRCbyte1,0x, 15); strncat(CRCbyte2,0x, 15); strncat(CRCbyte3,0x, 15); strncat(CRCbyte4,0x, 15); ltoa(DriverCRC,k,16);//将AppCRC值转成16进制字符串 write(DriverCRC%s,k); snprintf(m,elcount(m),%8s,k); for(n0;n8;n) { if(m[n] ) m[n]0; } write(m%s,m); substr_cpy(CRC1byte,m,0,2,elcount(CRC1byte));//提取CRC中的第一个Byte字符串 substr_cpy(CRC2byte,m,2,2,elcount(CRC2byte));//提取CRC中的第二个Byte字符串 substr_cpy(CRC3byte,m,4,2,elcount(CRC3byte));//提取CRC中的第三个Byte字符串 substr_cpy(CRC4byte,m,6,2,elcount(CRC4byte));//提取CRC中的第四个Byte字符串 strncat(CRCbyte1,CRC1byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte2,CRC2byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte3,CRC3byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 strncat(CRCbyte4,CRC4byte,20);//在提取的每个Byte字符串前面增加0x比如输出0x11,0x12 write(CRC1byte%s,CRCbyte1); write(CRC2byte%s,CRCbyte2); write(CRC3byte%s,CRCbyte3); write(CRC4byte%s,CRCbyte4); request[4]atol(CRCbyte1);//将CRC的第一个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[5]atol(CRCbyte2);//将CRC的第二个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[6]atol(CRCbyte3);//将CRC的第三个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 request[7]atol(CRCbyte4);//将CRC的第四个Byte十六进制字符串转成数值显示比如字符串0x11转成数值17 } if(MessageSelectFlag5) //(STP2-e) EraseMemory:31/01/FF/00/44 xx xx xx xx xx xx xx xx;71 01 FF 00 { request[2]0xFF; request[3]0x00; request[4]0x44; request[5]AppBinFileData[1]; request[6]AppBinFileData[2]; request[7]AppBinFileData[3]; request[8]AppBinFileData[4]; request[9]AppBinFileData[5]; request[10]AppBinFileData[6]; request[11]AppBinFileData[7]; request[12]AppBinFileData[8]; } //SOC升级 if (MessageSelectFlag8){ request[2]0xFF; request[3]0x00; request[4]0x02; } if (MessageSelectFlag9){ request[2]0xDF; request[3]0x01; request[4]0x00; } if (MessageSelectFlag10){ request[2]0xFF; request[3]0x01; } if (MessageSelectFlag11){ request[2]0xDF; request[3]0x01; request[4]0x02; } OSEKTL_DataReq(request,data_record_length); write(runing routine_control 31 Success); OSEKTL_DataInd(rxCount); return wait_server_response(request,timeout); }

相关新闻

3 分钟装好一套会养成、能专注的桌面宠物:DyberPet 完整上手指南

3 分钟装好一套会养成、能专注的桌面宠物:DyberPet 完整上手指南

2026/8/20 18:59:31

3 分钟装好一套会养成、能专注的桌面宠物:DyberPet 完整上手指南 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 每天对着屏幕工作八小时以上的人,大概都经…

数据处理故障复盘应留下什么

数据处理故障复盘应留下什么

2026/8/20 18:59:31

数据处理故障复盘应留下什么 这篇要解决什么 数据处理故障复盘应留下什么讨论的是一个可复查的工程问题。数据处理故障复盘应留下什么不拿未经记录的事故、跑分或成本当作论据;判断需要回到当前项目的输入、版本和运行条件。 从边界开始 处理数据处理故障复盘应留下…

分析任务上线前的配置收口

分析任务上线前的配置收口

2026/8/20 18:59:31

分析任务上线前的配置收口 这篇要解决什么 分析任务上线前的配置收口讨论的是一个可复查的工程问题。分析任务上线前的配置收口不拿未经记录的事故、跑分或成本当作论据;判断需要回到当前项目的输入、版本和运行条件。 从边界开始 处理分析任务上线前的配置收口时&a…

klog JSON 接口教程:把时间追踪数据接入脚本自动化的完整指南

klog JSON 接口教程:把时间追踪数据接入脚本自动化的完整指南

2026/8/20 19:59:33

klog JSON 接口教程:把时间追踪数据接入脚本自动化的完整指南 【免费下载链接】klog Command-line tool for time tracking in a human-readable, plain-text file format. 项目地址: https://gitcode.com/gh_mirrors/klog/klog klog 是一款基于纯文本文件的…

Qwen3.8-9B 函数调用实战教程:三步让模型自动使用外部工具

Qwen3.8-9B 函数调用实战教程:三步让模型自动使用外部工具

2026/8/20 19:59:33

Qwen3.8-9B 函数调用实战教程:三步让模型自动使用外部工具 【免费下载链接】Qwen3.8-9B 项目地址: https://ai.gitcode.com/hf_mirrors/empero-ai/Qwen3.8-9B Qwen3.8-9B 函数调用(Function Calling)能力,能让 90 亿参数的…

一篇文章讲透结构化提示词:用 LangGPT 从 0 到 1 写出专业级提示词

一篇文章讲透结构化提示词:用 LangGPT 从 0 到 1 写出专业级提示词

2026/8/20 19:59:33

一篇文章讲透结构化提示词:用 LangGPT 从 0 到 1 写出专业级提示词 【免费下载链接】LangGPT LangGPT: Empowering everyone to become a prompt expert! 🚀 📌 结构化提示词(Structured Prompt)提出者 📌 …

Typeplate响应式标题排版:Media Query动态字阶调整技巧

Typeplate响应式标题排版:Media Query动态字阶调整技巧

2026/8/20 19:59:33

Typeplate响应式标题排版:Media Query动态字阶调整技巧 【免费下载链接】starter-kit Typeplate is a “Typographic Starter Kit.” We don’t make aesthetic design choices, but define proper markup with extensible styling for common typographic patterns…

TabSTAR源码深度导读:从forward()到argmax的完整推理链路

TabSTAR源码深度导读:从forward()到argmax的完整推理链路

2026/8/20 19:59:33

TabSTAR源码深度导读:从forward()到argmax的完整推理链路 【免费下载链接】tabstar-npu 项目地址: https://ai.gitcode.com/atlasleong/tabstar-npu 核心关键词:TabSTAR源码、表格基础模型、昇腾NPU推理、forward()源码、argmax推理链路 一句话…

vue-star-rating 发光与动画效果:4 个技巧让评分交互更出彩

vue-star-rating 发光与动画效果:4 个技巧让评分交互更出彩

2026/8/20 19:49:33

vue-star-rating 发光与动画效果:4 个技巧让评分交互更出彩 【免费下载链接】vue-star-rating :star: A simple, highly customisable star rating component for Vue 2.x. / 3.x 项目地址: https://gitcode.com/gh_mirrors/vu/vue-star-rating vue-star-rat…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/19 3:36:59

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/19 9:17:18

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/19 8:02:16

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

微信聊天记录如何完整导出?WeChatMsg备份指南:HTML/Word/CSV一键转换

微信聊天记录如何完整导出?WeChatMsg备份指南:HTML/Word/CSV一键转换

2026/8/20 0:08:45

微信聊天记录如何完整导出?WeChatMsg备份指南:HTML/Word/CSV一键转换 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com…

B站缓存m4s打不开?m4s-converter无损合成MP4,实测1.46GB仅5秒

B站缓存m4s打不开?m4s-converter无损合成MP4,实测1.46GB仅5秒

2026/8/20 0:08:45

B站缓存m4s打不开?m4s-converter无损合成MP4,实测1.46GB仅5秒 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 判断你是否…

告别白模时代:Blender3mfFormat 让 3MF 导入导出一次跑通设计到打印

告别白模时代:Blender3mfFormat 让 3MF 导入导出一次跑通设计到打印

2026/8/20 0:08:45

告别白模时代:Blender3mfFormat 让 3MF 导入导出一次跑通设计到打印 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 按 3MF 官方规范的字面意思,一…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/18 12:20:24

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…