功能简介
31服务,即RoutineControl(例程控制)服务,该服务允许客户端使用RoutineControl(例程控制)服务执行指定的步骤顺序并获取任何相关结果
该服务具有较大的灵活性,但一般应用可以包括清除内存、重置或学习自适应数据、运行自检、覆盖正常的服务器控制策略和控制服务器值随时间而变化,以及预定义序列(如关闭敞篷车顶)等。
在某些情况下2F服务的基本功能也是能够通过31服务来实现,可以理解2F实现的功能31服务均可以实现,不过如果能够用2F实现的功能来用31服务,未免大材小用,因此31服务则是用于更为复杂的输入输出控制场景。而2F服务则可用于较为简单常见的输入输出控制场景。
应用场景
常见场景:
- 比如用于某传感器特定工况下的操作集合,如进行摄像头或者雷达内参标定流程
- 在整车制造过程中较为常见的便是某Sensor的外参标定工位,在该工位中需要用到31服务开启标定例程,标定流程- 结束后也能够31服务获取标定例程的最终结果;
- 如雷达使用过程中的非正常工况下的发波波形配置调整可以通过31服务来实现;
- 在进行UDS刷写过程中可以通过31服务来触发内存的擦除操作等;
注意事项
- 31服务针对同一控制场景一般可分为开始,停止,获取结果三个过程,这三个过程并不是同时存在,是否需要同时存在完全可以客户自定义;
- 31服务针对每一个控制场景均可以通过 Routine ID来进行唯一的区别,因此不同的控制场景应采用唯一的Routine ID来进行区别
- 通过AUTOSAR工具链配置的31 Routine回调函数命名时,函数名除了说明其基本功能以外,也需要将对应的Routine ID体现在函数名称中,这样便于搜索排查问题,是一种不错的代码实践;
- 对于31服务涉及的回调函数,一般不建议走RTE,主要是从代码可维护角度而言,更加简洁明了,实现效率高,走RTE接口还需增加额外的工作量,没有必要且容易出错。
31服务控制原理
如下图所示,针对31服务的通信控制过程会经过如下几个AUTOSAR BSW模块进行处理,然后完成最终的Routine控制,具体步骤如下:
- Client 发送诊断指令给到Server,Server接收到指令后通过确认Routine Type来决定调用不同的回调函数;
- 在每个回调函数中便可以实现客户自定义的控制场景,具体场景就是要根据客户需求来自定义来实现的。

请求和响应
1、请求
基本格式
归纳起来,诊断的request格式无非以下两种:
SID + Sub-function + Parameter
SID + Parameter
即有无sub-function的区别。Parameter可以是DID,可以是输入参数,可以是自定义的值,字节数视具体要求而定。

2、子功能
子功能参数定义(1字节数据):
Bit7:抑制肯定响应消息指示位suppressPosRspMsgIndicationBit
0=False:需要肯定响应
1=True:禁止肯定响应
Bit6-0:子功能参数值(0x00~0x7F)
3、肯定响应
基本格式:
SID + 0x40 + Sub-function + Parameter
SID + 0x40 + Parameter
要注意,第一个字节是由SID和0x40的和构成。这里的Parameter项是optional的,具体要看协议规定。

4、否定响应
基本格式:
0x7F + SID + NRC
看起来比较简单,格式比较固定,只要是Negative Response,第一字节就是0x7F,第二字节照抄原来的SID,第三个字节是错误响应码,指示具体错误响应的原因

5、NRC优先级
在ISO14229-1中未明确定义NRC优先级,可以参考下方优先级顺序:
0x11 > 0x7F > 0x13 > 0x12 > 0x7E > 0x33 > 0x24 > 0x31 > 0x22 > 0x78

报文示例
示例 1:子功能 = startRoutine
本小节说明了在服务器中启动例程的测试条件,在技术员"扭动"所有受试系统线束接头时,间歇性的不断测试(尽可能快的)所有输入和输出信号。通过 routineIdentifier 0x0201 引用该程序。
测试条件: ignition = on, engine = off, vehicle speed = 0 [kph](点火开关打开,发动机熄火,车辆速度为 0 [kph])
客户端通过将 suppressPosRspMsgIndicationBit(抑制肯定响应消息指示位)(子功能参数的第 7位)设置为"FALSE(假) "("0")来请求响应消息。

示例 2:子功能 = stopRoutine
本小节说明了在服务器中停止例程的测试条件,在技术员"扭动"所有受试系统线束接头时,间歇性的不断测试(尽可能快的)所有输入和输出信号。通过 routineIdentifier 0x0201 引用该程序。
测试条件: ignition = on, engine = off, vehicle speed = 0 [kph](点火开关打开,发动机熄火,车辆速度为 0 [kph])
客户端通过将 suppressPosRspMsgIndicationBit(抑制肯定响应消息指示位)(子功能参数的第 7位)设置为"FALSE(假) "("0")来请求响应消息。

示例 3:子功能 = requestRoutineResults
本示例说明了如何在结束例程后获取结果值。在技术员"扭动"所有受试系统线束接头时,间歇性的不断测试(尽可能快的)所有输入和输出信号。 routineIdentifier 0x0201 引用该例程。
测试条件:ignition = on, engine = off, vehicle speed = 0 [kph](点火开关打开,发动机熄火,车辆速度为 0[kph])。
客户端通过将 suppressPosRspMsgIndicationBit(抑制肯定响应消息指示位)(子功能参数第 7位)设置为"假"('0')请求响应消息。
