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



    在这里插入图片描述

    一、简介

    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) 请求格式

    在这里插入图片描述
    在这里插入图片描述

    (3) 重启类型

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

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

    在这里插入图片描述

    二、示例代码

    (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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
  • 相关阅读:
    大学生HTML作业节日网页 HTML作业节日文化网页期末作业 html+css+js节日网页 HTML学生节日介绍 HTML学生作业网页视频
    如何将 huggingface上的模型文件下载到本地
    网络安全(黑客技术)—2024自学手册
    Fiddler抓包使用教程
    Paddle模型性能分析工具Profiler:定位瓶颈点、优化程序、提升性能
    uniapp实现App弹窗更新升级(完整版)热更新
    SqlServer_idea连接问题
    yolov5部署到android studio
    从磁盘刷新频率,文件大小,重启性能,数据安全,等五方面对比 RDB 备份和 AOF 备份的区别,并说明项目最终使用 RDB 的原因
    【RabbitMQ实战】07 3分钟部署一个RabbitMQ集群
  • 原文地址:https://blog.csdn.net/qq_29246181/article/details/133963590