前言

2021年在360搭了一套ID.4台架环境,本来快要出成果了(拿到了ODIS内网权限,还有ICAS3的root),被安排出差去搭建展示车,后续工作计划被打乱。这期间不管是工作还是生活都遇到了许多糟心事,便停止了研究。

算是一个怨念项目吧,今年5月我在机缘巧合下又研究了ID.4的ICAS1的车控逻辑,还有一个怨念项目是CAN-Pick NG,写了一半又搁置了,不知道2025可不可以完成。

ID.4 是大众MEB平台,EE架构总共有两个域控制器,ICAS1, ICAS3。其中ICAS1(J533)与车身控制有关。
下图是J533的位置,位于序号13。将线控模块装载到此处,可以实现车身监测和控制。

icas1

车内ECU拓扑

Classic CAN: 500k

CAN-FD:仲裁域500k, 数据域2M。若要分析CAN-FD,ZLG设备最合适。

通过分析 ELSA电路图 和 大众内部培训资料,发现总线命名混乱,必须重新整理才能得到正确的CAN拓扑图。

J533总共有9路CAN,4路LIN(暂不需要),关键ECU如下。

  • Running-Gear CAN (CAN-FD)
    • J104 - ABS
    • J500 - EPS,转向助力控制单元
    • NX6 - 制动控制器 (Brake Booster)
  • Powertrain CAN (CAN-FD)
    • J623 - 电机控制模块 Engine/Motor Control Module
    • J841/J944 - 电驱单元
    • J234 - 气囊 (不能在这里Fuzzing,危险)
  • Driver Assistance CAN,CAN-FAS (CAN-FD)
    • J428 - 车距调节控制单元
    • J446 - 泊车雷达控制单元
    • J769/J770 - 行驶换道辅助系统控制单元
    • J928 - 全景摄像头控制单元
  • Convenience CAN (Classic)
    • J527 - 电控换档模块 (Steering Column Electronics Control Module)
    • J605 - 行李箱盖控制单元
    • J764 - 转向柱锁
    • …其他车身控制
  • CAN-EV (CAN-FD)
    • J979 - 加热与空调控制模块 (Heater and Air Conditioning Control Module)

topicdiagram

J533连接器T40a定义

T40a 连接器和表格对应如下。

T40a_datasheet

T40a

总线安全策略

网关隔离

多功能方向盘控制信号,由Convenience CAN接收,但是底盘CAN的ECU也能收到。底盘CAN发出的多功能方向盘控制信号,不会被J533转发到目标ECU。

CRC 校验

分析CAN总线变化,可以看到大部份报文的变化规律,第一字节随机,第二字节有规律递增。第一字节是CRC,第二字节是计数器。

CRC 初始值

参考OpenDBC github
/opendbc/can/common.cc volkswagen_mqb_checksum

可以获取VM MQB平台的 Checksum 初始值,但是ID.4有很多新的CRC初始值,我通过逆向分析并记录在下面了。

大部份控制信号有CRC和计数器,ECU不会校验某些不重要功能的CRC,比如天窗,车窗,鸣笛。但是会校验转向助力,行李箱盖开启,雨刮等影响驾驶的功能。

Signal CAN ID CRC Seed
AAA_01 0x12DD5502 0x62,0x14,0x7c,0xa1,0x49,0x95,0x43,0x04,0x78,0x46,0x74,0x19,0x39,0x17,0x9f,0x1c
ACC_18 0x14D 0x1a,0x65,0x81,0x96,0xc0,0xdf,0x11,0x92,0xd3,0x61,0xc6,0x95,0x8c,0x29,0x21,0xb5
Airbag_01 0x040 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40
Airbag_02 0x520 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44
APS_Master 0x380 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13
AWV_03 0x0DB 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97
BEM_06 0x48B 0x54,0xaf,0x8a,0xfb,0x0d,0x87,0x6a,0x0f,0x47,0x78,0x31,0x4f,0x35,0x28,0x82,0x6d
Blinkmodi_02 0x366 0xa9,0xbd,0xfb,0x3c,0x95,0x0f,0x75,0x3a,0x4f,0x19,0x59,0x6d,0xb2,0xe9,0xd1,0x97
EA_01 0x1A4 0x69,0xbb,0x54,0xe6,0x4e,0x46,0x8d,0x7b,0xea,0x87,0xe9,0xb3,0x63,0xce,0xf8,0xbf
EA_02 0x1F0 0x2f,0x3c,0x22,0x60,0x18,0xeb,0x63,0x76,0xc5,0x91,0x0f,0x27,0x34,0x04,0x7f,0x02
ELV_01 0x656 0xab,0x2f,0xd3,0x39,0x6f,0x37,0xfa,0x59,0xa4,0x70,0xce,0x11,0x54,0x82,0x62,0x56
EM1_01 0x0C0 0x2f,0x44,0x72,0xd3,0x07,0xf2,0x39,0x09,0x8d,0x6f,0x57,0x20,0x37,0xf9,0x9b,0xfa
EML_02 0x1A555541 0x3e,0xb4,0x25,0xc1,0x31,0x1f,0xf1,0xd7,0xb1,0xbe,0xcc,0xe0,0x0f,0x46,0x51,0xb2
EML_06 0x20A 0x9d,0xe8,0x36,0xa1,0xca,0x3b,0x1d,0x33,0xe0,0xd5,0xbb,0x5f,0xae,0x3c,0x31,0x9f
ESC_50 0x102 0xd7,0x12,0x85,0x7e,0x0b,0x34,0xfa,0x16,0x7a,0x25,0x2d,0x8f,0x04,0x8e,0x5d,0x35
ESC_51 0x0FC 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd
ESP_10 0x116 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac
ESP_20 0x65D 0xac,0xb3,0xab,0xeb,0x7a,0xe1,0x3b,0xf7,0x73,0xba,0x7c,0x9e,0x06,0x5f,0x02,0xd9
ESP_21 0x0FD 0xb4,0xef,0xf8,0x49,0x1e,0xe5,0xc2,0xc0,0x97,0x19,0x3c,0xc9,0xf1,0x98,0xd6,0x61
ESP_24 0x31B 0x67,0x8a,0xae,0x22,0x4d,0xd0,0x51,0x80,0x5c,0xb9,0xce,0x1e,0xdf,0x02,0x2d,0xd4
Getriebe_11 0x0AD 0x3f,0x69,0x39,0xdc,0x94,0xf9,0x14,0x64,0xd8,0x6a,0x34,0xce,0xa2,0x55,0xb5,0x2c
GRA_ACC_01 0x12B 0x6a,0x38,0xb4,0x27,0x22,0xef,0xe1,0xbb,0xf8,0x80,0x84,0x49,0xc7,0x9e,0x1e,0x2b
HCA_01 0x126 0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda
HVL_01 0x12DD553D 0x1d,0x82,0x7b,0x79,0xa5,0xee,0x3a,0xb9,0xb7,0xf9,0xe4,0x67,0x7f,0x97,0x11,0xad
IPA_01 0x138 0x77,0x4e,0x14,0x87,0xf2,0xf8,0xb2,0x61,0xf6,0xa4,0x52,0x94,0xd4,0x81,0x2a,0xb1
IPA_02 0x16A9545F 0xc6,0x7f,0x85,0xb6,0xe6,0xae,0xf8,0x26,0xb0,0x8c,0x19,0x10,0x5b,0x33,0x64,0x6c
Klemmen_Status_01 0x3C0 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3
LH_EPS_02 0x11D 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c
LH_EPS_03 0x09F 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5
Licht_Anf_01 0x3D5 0xc5,0x39,0xc7,0xf9,0x92,0xd8,0x24,0xce,0xf1,0xb5,0x7a,0xc4,0xbc,0x60,0xe3,0xd1
LWI_01 0x086 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86
Motor_14 0x3BE 0x1f,0x28,0xc6,0x85,0xe6,0xf8,0xb0,0x19,0x5b,0x64,0x35,0x21,0xe4,0xf7,0x9c,0x24
Motor_51 0x10B 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd
Motor_54 0x14C 0x16,0x35,0x59,0x15,0x9a,0x2a,0x97,0xb8,0x0e,0x4e,0x30,0xcc,0xb3,0x07,0x01,0xad
Motor_Code_01 0x641 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47
Parken_01 0x206 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97
PLA_04 0x407 0xef,0x60,0x04,0xa8,0x0c,0x1c,0xda,0x07,0x36,0xd7,0x28,0x92,0xa9,0x88,0x2c,0x4a
QFK_01 0x13D 0x20,0xca,0x68,0xd5,0x1b,0x31,0xe2,0xda,0x08,0x0a,0xd4,0xde,0x9c,0xe4,0x35,0x5b
RCTA_01 0x2B7 0x5e,0xc7,0x04,0x11,0x4d,0x27,0x0d,0x31,0x91,0xb8,0x62,0x76,0x64,0x09,0xeb,0xec
SAL_01 0x12DD54C9 0xde,0xa9,0x83,0x0b,0x0c,0x64,0x79,0x44,0x0f,0xf6,0xc6,0xc7,0x05,0x45,0xb7,0x59
SAM_01 0x205 0x19,0x36,0xd4,0x1e,0x80,0x22,0xf4,0xb8,0xad,0x41,0x0b,0x3f,0x87,0x42,0x25,0x40
SMLS_01 0x3D4 0xc3,0x79,0xbf,0xdb,0xe9,0x11,0x46,0x86,0x69,0xb6,0x9b,0x29,0x15,0x9c,0x45,0x0d
TA_01 0x26B 0xce,0xcc,0xbd,0x69,0xa1,0x3c,0x18,0x76,0x0f,0x04,0xf2,0x3a,0x93,0x24,0x19,0x51
TSG_FT_02 0x3E5 0xc4,0x6a,0x69,0x30,0xcf,0x61,0x58,0x51,0x1b,0x86,0x99,0xd3,0xf6,0x1d,0x9a,0x37
VMM_01 0x105 0xde,0x0e,0xa7,0x1d,0xc3,0x83,0xbd,0x82,0x8c,0xa2,0x0c,0x7b,0x4d,0x3c,0x58,0x79
VMM_02 0x139 0xed,0x03,0x1c,0x13,0xc6,0x23,0x78,0x7a,0x8b,0x40,0x14,0x51,0xbf,0x68,0x32,0xba

CRC 算法

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
MEB_Kennungsfolge = {
# LWI_01 Steering Angle
0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86],
# LH_EPS_03 Electric Power Steering
0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5],
# HCA_01 Heading Control Assist
0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA],
# GRA_ACC_01 Steering wheel controls for ACC
0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B]
}

def gen_crc_lookup_table_8(poly):
crc_lut = [0] * 256
for i in range(256):
crc = i
for j in range(8):
if crc & 0x80:
crc = (crc << 1) ^ poly
else:
crc <<= 1
crc_lut[i] = crc & 0xFF
return crc_lut

def volkswagen_mqb_checksum(address, data):
global crc8_lut_8h2f
crc = 0xFF # CRC8 8H2F/AUTOSAR

for i in range(1, len(data)):
crc = crc ^ data[i]
# print(hex(crc), hex(i))
crc = crc8_lut_8h2f[crc]

counter = data[1] & 0x0F
if address in MEB_Kennungsfolge:
crc ^= MEB_Kennungsfolge[address][counter]
else:
# 无需校验
crc ^= [0x00] * 16 # 默认情况下,返回全 0

crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR
return crc ^ 0xFF

can_id = 0x126
data = bytearray(bytes(8))
crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f)
crc = volkswagen_mqb_checksum(can_id, data)
data[0] = crc

CAN 信号

  • Convenience CAN有以下信号通信,可用于状态读取,车身功能基本上可以通过此路CAN进行控制。包括空调,前后大灯,鸣笛,雨刮,车窗,车锁,车辆状态等信息。
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
0x12B	GRA_ACC_01	自适应巡航,GRA系统,ACC,
0x1F0 EA_02 应急辅助
0x205 SAM_01 开关和执行模块
0x2B7 RCTA_01 Rear Cross Traffic Alert,后方交通警示
0x31B ESP_24
0x366 Blinkmodi_02 闪烁模式
0x397 LDW_02 车道偏离警示系统
0x3BE Motor_14 电机控制
0x3C0 Klemmen_Status_01 端子状态
0x3CE TSG_HFS_01 后座门窗功能系统
0x3CF TSG_HBFS_01 后门窗户功能系统
0x3D0 TSG_FT_01 前门功能系统
0x3D4 SMLS_01 转向柱开关模块
0x3D5 Licht_Anf_01 灯光要求
0x3D6 Licht_hinten_01 后部灯光状态
0x3DC Gateway_73 这些信息涉及车辆的各种信号和状态,包括系统提示、安全提示、故障诊断、信号更新和旧信号的替换
0x48B BEM_06 低电压能源管理
0x520 Airbag_02 气囊2
0x551 WFS_01 车钥匙防盗
0x582 HDSG_01 后备箱管理状态
0x583 ZV_02 中央门锁系统
0x585 Systeminfo_01 诊断和生产模式设置
0x592 Kessy_04 智能钥匙系统(Kessy)以及远程停车功能的状态和控制
0x5A0 RLS_01 光传感器和雨量传感器
0x5A7 TM_01 Telematics
0x5F0 Dimmung_01 调光
0x5F4 Innenlicht_11 车内灯光
0x641 Motor_Code_01 电机设码
0x643 Einheiten_01 单位设置
0x656 ELV_01 电子转向柱锁
0x658 Licht_vorne_01 前灯状态
0x65D ESP_20
0x668 Klima_12 空调系统
0x670 Motor_18
0x6AE Spiegel_01 后视镜
0x6AF Rear_View_01 后视摄像头
0x6B2 Diagnose_01
0x6B4 VIN_01
0x12DD54C9 SAL_01 照明模块

其他信号

DBC已经分析出来了,暂时不公开。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0x184
1. 锁车
1. 第二字节 后视镜开 0x20 开
2. 第三字节 后视镜关 0x40 关
2. 车窗
1. 第六字节 车窗 04 左前下,02 左前上,40 左后下,08右前上,10右前下
2. 第七字节,01右后下
0x185
1. 车窗控制,10 20 up 40 80 down
1. 第一字节 前排
2. 第二字节 后排
0x598
1. 天窗控制
1. 第三字节 0x20 无 0x21 tap 0x22 滑动 0x25 长按
2. 第七字节:04 关一下,08 一直关,0C 开一下,10 一直开, 14,1c其他

控制转向

要求档位在D/B或者R档。以下五个信号可以用于控制方向盘。

  • LWI_01 Lenkwinkelsensor
  • LH_EPS_03 Lenkhilfe Electric Power Steering
  • HCA_01 Heading Control Assist
  • GRA_ACC_01 Geschwindigkeitsregelanlage & Adaptive Cruise Control
  • PLA_05 Park Lane Assist

提示

  • 组合使用0x86, 0x9f, 0x126, 0x12b, 0x302信号,在CAN-FAS发送,可以实现泊车方向盘转向功能。
  • 组合使用0x86, 0x9f, 0x302信号,在Gear-Running CAN发送,可以实现方向盘转向。
  • 其中0x9f(LH_EPS_03)和0x302(PLA_05)两个信号都可以直接控制方向盘。
  • 0x302没有CRC校验,因此控制方向盘比0x9f容易

DEMO

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
def create_pla_control(sendestatus, positive, degree):
data = bytearray(bytes(24))
data[1] = 0x40
# PLA_QFK_Spuerb
data[2] = 0xFA
# PLA_QFK_KruemmSoll
data = set_value(data, degree, 32, 15)
# PLA_QFK_KruemmSoll_VZ
if positive:
data = set_value(data, 1, 47, 1)
else:
data = set_value(data, 0, 47, 1)

# PLA_05_Sendestatus
if sendestatus:
data = set_value(data, 1, 74, 1)
else:
data = set_value(data, 0, 74, 1)
return data

hca_01_counter = 0
degree = 0
for i in range(20):
# data = create_steering_control(10 * i, 1)
# meb_can_send(0x126, 0.1, data)
degree += 0x10
data = create_pla_control(1, 1, degree)
can_send(0x302, 0.1, data)

RPi CAN HAT

控制方向盘Demo,仅让方向盘动起来,真正要实现远控,需要有力学的知识,还要设计控制算法。

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
import can
import time

can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan', fd=True, bitrate=500000)

# msg = can.Message(is_extended_id=False, arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5, 6, 7])
# can0.send(msg)

MEB_Kennungsfolge = {
# LWI_01 Steering Angle
0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86],
# LH_EPS_03 Electric Power Steering
0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5],
# HCA_01 Heading Control Assist
0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA],
# GRA_ACC_01 Steering wheel controls for ACC
0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B]
}

def volkswagen_mqb_checksum(address, data):
global crc8_lut_8h2f
crc = 0xFF # CRC8 8H2F/AUTOSAR

for i in range(1, len(data)):
crc = crc ^ data[i]
# print(hex(crc), hex(i))
crc = crc8_lut_8h2f[crc]

counter = data[1] & 0x0F
if address in MEB_Kennungsfolge:
crc ^= MEB_Kennungsfolge[address][counter]
else:
print("Attempt to CRC check undefined Volkswagen message 0x%02X" % address)
crc ^= [0x00] * 16 # 默认情况下,返回全 0

crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR
return crc ^ 0xFF

def gen_crc_lookup_table_8(poly):
crc_lut = [0] * 256
for i in range(256):
crc = i
for j in range(8):
if crc & 0x80:
crc = (crc << 1) ^ poly
else:
crc <<= 1
crc_lut[i] = crc & 0xFF
return crc_lut

def meb_can_send(can_id, interval, data):
global hca_01_counter
data[1] = data[1] | hca_01_counter
crc = volkswagen_mqb_checksum(can_id, data)
data[0] = crc
hca_01_counter += 1
for j in data:
print(hex(j), end=", ")
time.sleep(interval)
msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True)
can0.send(msg)

def can_send(can_id, interval, data):
time.sleep(interval)
msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True)
can0.send(msg)

crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f)

def set_value(data, value, start_pos, value_length):
end_pos = start_pos + value_length
for bit_index in range(start_pos, end_pos):
byte_index = bit_index // 8
bit_offset = bit_index % 8
bit_value = (value >> (bit_index - start_pos)) & 1
# print("\n")
# print("index", bit_index, start_pos, end_pos, "byte_index:", byte_index, "bit_offset:", bit_offset, "v:", bit_value)
if bit_value:
data[byte_index] |= 1 << bit_offset
else:
data[byte_index] &= ~(1 << bit_offset)
# for i in data:
# print(bin(i), end=",")
return data

def set_bit(b, bit, bit_index):
if bit_index < 0 or bit_index > 7:
raise ValueError("bit_index must be between 0 and 7")
mask = 1 << bit_index
flipped_byte = b ^ mask
return flipped_byte

def create_steering_control(apply_steer, lkas_enabled):
data = bytearray(bytes(8))
if lkas_enabled:
# HCA_01_Sendestatus
data = set_value(data, 5, 30, 1)
# HCA_01_Status_HCA
data = set_value(data, 1, 32, 4)
else:
# HCA_01_Sendestatus
data = set_value(data, 3, 30, 1)
# HCA_01_Status_HCA
data = set_value(data, 0, 32, 4)
# HCA_01_LM_Offset
print("create_steering_control", apply_steer)
data = set_value(data, abs(apply_steer), 16, 9)
# HCA_01_LM_OffSign
v = 1 if apply_steer < 0 else 0
data = set_value(data, v, 31, 1)
# HCA_01_Vib_Freq
data = set_value(data, 3, 12, 4)
# HCA_01_Vib_Amp
data = set_value(data, 10, 36, 4)
return data

def create_pla_control(sendestatus, positive, degree):
data = bytearray(bytes(24))
data[1] = 0x40
# PLA_QFK_Spuerb
data[2] = 0xFA
# PLA_QFK_KruemmSoll
data = set_value(data, degree, 32, 15)
# PLA_QFK_KruemmSoll_VZ
if positive:
data = set_value(data, 1, 47, 1)
else:
data = set_value(data, 0, 47, 1)

# PLA_05_Sendestatus
if sendestatus:
data = set_value(data, 1, 74, 1)
else:
data = set_value(data, 0, 74, 1)
return data

hca_01_counter = 0
degree = 0
for i in range(20):
# data = create_steering_control(10 * i, 1)
# meb_can_send(0x126, 0.1, data)
degree += 0x10
data = create_pla_control(1, 1, degree)
can_send(0x302, 0.1, data)

注意事项

  1. 离开车辆之前,确保CAN总线处于接通状态,否则会大量耗电。
  2. 不要对Powertrain 和Running Gear CAN 进行 Fuzzing,可能直接会导致人身伤害,另外,也可能导致ECU异常,产生潜在隐患。比如转向灯失效,后视镜无法打开。