[AUTOSAR][诊断管理][$11] 复位服务

文章目录

  • 一、简介
    • (1) 应用场景
    • (2) 请求格式
    • (3) 重启类型
  • 二、示例代码
    • (1) 11_ecu_reset.c

[AUTOSAR][诊断管理][$11] 复位服务_第1张图片

一、简介

ECU复位服务就是可以此诊断指令来命令ECU执行自复位,复位有多种形式,依据子功能参数来区分(即客户端使用ECU复位服务来请求服务端重置,重置成功后,将直接进入默认会话)。

通常来说,ECU在收到一条诊断指令后,要先进行相应的处理,执行某些诊断操作,完毕后再发送肯定响应。但是ECU复位服务是个特例,因为它的诊断操作是复位,这时候这个ECU就会重新开始运行,此时ECU也不会记得你前面发过诊断指令,所以复位后没办法ECU就没办法再去发送诊断响应,所以要先发送肯定响应,再执行复位。

注意:从发送完肯定响应到执行复位的这段时间内,ECU是否还可以响应其它诊断请求,标准中没有规定。建议此期间ECU不接受任何请求消息,也不发送任何响应消息。

(1) 应用场景

一般而言,对于11诊断服务,主要应用场景为以下场合:

  1. ECU被刷写新的软件后,此时需通过11诊断服务重启该ECU使其回复到初始状态,保证一个十分干净的运行环境;
  2. 在产线下线标定的过程中,对于KL30供电的ECU存在一些仅在下电存储的数据,此时需要通过11诊断服务使ECU走下电流程进而完成相应数据的保存;
  3. 为满足特定功能的需要,输入相关标定参数给到ECU后,只有通过发送诊断服务11才能使得标定参数生效的场景;
  4. 对于KL30供电的ECU节点,可以使用诊断服务11使ECU快速进入休眠的场景;
    上述这些应用场景较为常见,除此以外,当然还有很多面向ECU内部测试的应用场合,这里就不一一列举。

注意事项:

根据ISO14229-1标准所述,当Client向Server发送11诊断服务请求时,Server可在重置行为完成之后或者开始重启行为之前给到Client

诊断响应,但14229-1强烈推荐的一种做法是:”当Server接受到来自Client的11诊断服务请求时,Server应当先给出诊断响应然后开始重启行为“。

至于为什么如此,我想到一个场景:如果功能寻址请求11诊断服务时(未抑制正响应),在复位未完成之前,一般都会先回复NRC78让Client进行等待,那么对于Client需要根据不同的ECU节点的回复做超时监控,这无疑增加了Client负担,对于Client而言,最为简单的方法就发送完请求,各ECU节点回复正响应,然后各自完成复位操作即可。

(2) 请求格式

在这里插入图片描述
[AUTOSAR][诊断管理][$11] 复位服务_第2张图片

(3) 重启类型

由上图2所提到复位类型,复位类型作为subfunction参数来传递给到Server发生相应的重启行为,具体由以下几种类型:

  • HardReset:硬复位;
  • keyOffOnReset:点火开关复位;
  • SoftReset: 软复位;
  • enableRapidPowerShutDown:使能快速休眠流程;
  • disableRapidPowerShutDown:抑制快速休眠流程;
  • vehicleManufacturerSpecific:供整车制造商使用的自定义复位类型;
  • systemSupplierSpecific:供系统供应商使用的自定义复位类型;

[AUTOSAR][诊断管理][$11] 复位服务_第3张图片

二、示例代码

(1) 11_ecu_reset.c

/********************************************************************************
* @file    11_ecu_reset.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2023-05-30
* @brief   ECU 复位功能
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include 
#include 
#include 
#include 
#include "modules.h"
#include "os_api.h"
#include "edebug.h"
#include "kv_sys.h"
#include "ecu_ble_uart.h"

/* Private includes ----------------------------------------------------------*/
#include "std_math.h"
#include "app_can.h"
#include "can_nm.h"
#include "app_nm.h"
#include "diag_main.h"
/* Private define ------------------------------------------------------------*/
#define UDS_ID    0x11

/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t ecu_reset_req = 0;
/***************软定时器创建***************/
/* Private func --------------------------------------------------------------*/
void post_func(uint8_t val) {
    (void)val;
    if (ecu_reset_req) {
        diag_main_send_signal(SIGNAL_DIAG_RESET);
    }
}

void uds11_main(nwl_msg_t* p) {
    uint8_t data[10];
    ecu_reset_req = 0;
    if (p->len != 2) {
        send_nrc_data(UDS_ID, NRC_INCORRECT_MESSAGE_LENTH);
        goto end;
    }
    switch (p->data[1] & 0x7F) { // 子功能,bit7为应答位。  =1则不允许应答
        case 0x01: // 硬件复位
            if ((g_car_ste.IPB.bit.VehicleSpeedVld == 1) && (get_car_speed() > 3)) {
                send_nrc_data(UDS_ID, NRC_CONDITION_NOT_CORRECT);
                goto end;
            }
            if (p->data[1] & 0x80) {
                // 应用无需应答
            } else {
                // 回复正响应码  单帧格式: len, 服务ID|0x40, 子功能ID,
                data[0] = 2;  // 数据总长度=数据长度+服务号
                data[1] = UDS_ID | 0x40;   // 服务号,回复上位机需要 |0x40
                data[2] = p->data[1];
                memset(&data[3], 0xAA, 5);
                app_can_enqueue_msg(CAN_MSG_EVENT_SEND, NWL_RES_ADDR, data, 8);
                g_p2_service_time_remaining = 0; // 如果发送诊断报文,则清除倒计时。P2_SERVER_MAX
                os_delay(1);
            }
            ecu_reset_req = 1;
            break;

        default:
            send_nrc_data(UDS_ID, NRC_SUBFUNCTION_NOT_SUPPORTED);
            break;
    }
end:
    return;
}

#if AUTOSAR_DIAG_SWITCH && USE_UDS_11
DIAG_SERVICE_REG(UDS_ID, DIAG_NO_SECURITY_LEVEL, (DEFAULT_SESSION|PROGRAMMING_SESSION|EXTENDED_SESSION),
                 (DIAG_PHYS_REQ|DIAG_FUNC_REQ), NULL, post_func, uds11_main);
#endif

你可能感兴趣的:(AUTOSAR,ECU,诊断管理,复位,11)