This commit is contained in:
刘可亮
2025-10-21 13:59:50 +08:00
parent 33c375efac
commit 3e10f578d3
7070 changed files with 998841 additions and 1402535 deletions

View File

@@ -5,6 +5,31 @@
*/
#include "uds_def.h"
//Negative Response
#define IS_NEGATIVE_RESPONSE(frame_buf) (frame_buf[0] == 0x7F)
//Positive Response
#define IS_POSITIVE_RESPONSE(frame_buf, service_id) (frame_buf[1] == (0x40 + (service_id)))
//eg0x50 03
#define IS_RESPONSE_WITH_SUBFUNC(frame_buf, service_id, subfunc) \
(frame_buf[1] == (0x40 + (service_id)) && frame_buf[2] == (subfunc))
//Check if it is a negative response for a specific service
#define IS_NEGATIVE_RESPONSE_FOR_SERVICE(frame_buf, service_id) \
(IS_NEGATIVE_RESPONSE(frame_buf) && frame_buf[1] == (service_id))
#define UDS_SERVICE_DIAG_SESSION_CTRL 0x10
#define UDS_SERVICE_ECU_RESET 0x11
#define UDS_SERVICE_READ_DATA 0x22
#define UDS_SERVICE_SECURITY_ACCESS 0x27
#define UDS_SERVICE_COMMUNICATION_CTRL 0x28
#define UDS_SERVICE_ROUTINE_CTRL 0x31
#define UDS_SERVICE_REQUEST_DOWNLOAD 0x34
#define UDS_SERVICE_REQUEST_UPLOAD 0x35
#define UDS_SERVICE_TRANSFER_DATA 0x36
#define UDS_SERVICE_REQUEST_TRANSFER_EXIT 0x37
#define UDS_SERVICE_WRITE_DATA 0x3E
#define UDS_SERVICE_CTRL_DTC 0x85
static rt_timer_t response_timer;
void response_timeout(void *param)
@@ -14,8 +39,198 @@ void response_timeout(void *param)
void init_uds_timers()
{
response_timer = rt_timer_create("uds_tout", response_timeout, RT_NULL, 2000,
RT_TIMER_FLAG_ONE_SHOT);
response_timer =
rt_timer_create("uds_tout", response_timeout, RT_NULL, 2000, RT_TIMER_FLAG_ONE_SHOT);
}
static uint8_t g_key[4] = { 0 };
typedef struct {
uint8_t data[8];
uint8_t len;
uint8_t next_state;
} UdsRequest;
static const UdsRequest uds_requests[] = {
[UDS_STATE_ENTER_EXT_SESSION] = {
.data = {0x03, 0x22, 0xF1, 0x86},
.len = 4,
.next_state = UDS_STATE_READ_ECU_INFO,
},
[UDS_STATE_READ_ECU_INFO] = {
.data = {0x02, 0x10, 0x02},
.len = 3,
.next_state = UDS_STATE_ENTER_PROG_SESSION,
},
[UDS_STATE_ENTER_PROG_SESSION] = {
.data = {0x02, 0x27, 0x01},
.len = 3,
.next_state = UDS_STATE_SAFE_ACCESS,
},
[UDS_STATE_REQUEST_UPLOAD_EXIT] = {
.data = {0x01, 0x37},
.len = 2,
.next_state = UDS_STATE_APP_CHECK,
}
};
#define UDS_STATE_COUNT (UDS_STATE_ENTER_DEFAULT_SESSION + 1)
void send_uds_service(void)
{
uint8_t uds_request[8] = { 0 };
uint8_t uds_request_len = 0;
if (g_current_state >= UDS_STATE_COUNT) {
rt_kprintf("[UDS] Invalid state: %d\n", g_current_state);
return;
}
const UdsRequest *req = &uds_requests[g_current_state];
if (g_current_state == UDS_STATE_SAFE_ACCESS) {
uds_request[0] = 0x06;
uds_request[1] = 0x27;
uds_request[2] = 0x02;
if (g_key[0] || g_key[1] || g_key[2] || g_key[3]) {
uds_request[3] = g_key[0];
uds_request[4] = g_key[1];
uds_request[5] = g_key[2];
uds_request[6] = g_key[3];
uds_request_len = 7;
g_current_state = UDS_STATE_REQUEST_UPLOAD_WAIT;
} else {
rt_kprintf("[UDS] Error: Key not initialized\n");
return;
}
} else {
if (req->len > 0 && req->len <= 8) {
memcpy(uds_request, req->data, req->len);
uds_request_len = req->len;
g_current_state = req->next_state;
} else {
rt_kprintf("[UDS] Invalid request length: %d\n", req->len);
return;
}
}
if (uds_request_len > 0) {
uds_send_frame(UDS_REQUEST_ID, uds_request, uds_request_len, 1);
} else {
rt_kprintf("[UDS] Error: Attempting to send empty frame\n");
}
}
int uds_calculate_key_direct(const uint8_t *frame_buf, uint8_t *key_buf)
{
if (frame_buf == NULL || key_buf == NULL) {
return -1;
}
uint8_t frame_len = frame_buf[0];
if (frame_len < 6) {
return -1;
}
if (frame_buf[1] != 0x67 || frame_buf[2] != 0x01) {
return -1;
}
uint32_t seed = (uint32_t)frame_buf[3] << 24 | (uint32_t)frame_buf[4] << 16 |
(uint32_t)frame_buf[5] << 8 | (uint32_t)frame_buf[6];
uint32_t calculated_key = ~seed;
key_buf[0] = (uint8_t)(calculated_key >> 24);
key_buf[1] = (uint8_t)(calculated_key >> 16);
key_buf[2] = (uint8_t)(calculated_key >> 8);
key_buf[3] = (uint8_t)calculated_key;
return 0;
}
/******************************************************************************
* 函数名称: static void handle_uds_state_machine(uint32_t id, uint8_t* frame_buf, uint8_t frame_dlc)
* 功能说明: UDS状态机处理
* 输入参数: uint32_t id --消息帧 ID
    uint8_t* frame_buf --接收报文帧数据首地址
    uint8_t frame_dlc --接收报文帧数据长度
* 输出参数: 无
* 函数返回: 无
* 其它说明: ecu响应处理状态机
******************************************************************************/
static void handle_uds_state_machine(uint32_t id, uint8_t *frame_buf, uint8_t frame_dlc)
{
if (frame_dlc < 2) {
return;
}
rt_mutex_take(g_uds_state_mutex, RT_WAITING_FOREVER);
switch (g_current_state) {
case UDS_STATE_ENTER_EXT_SESSION:
if (IS_RESPONSE_WITH_SUBFUNC(frame_buf, UDS_SERVICE_DIAG_SESSION_CTRL, 0x03)) {
send_uds_service();
}
break;
case UDS_STATE_READ_ECU_INFO:
if (IS_POSITIVE_RESPONSE(frame_buf, UDS_SERVICE_READ_DATA)) {
send_uds_service();
}
break;
case UDS_STATE_ENTER_PROG_SESSION:
if (IS_RESPONSE_WITH_SUBFUNC(frame_buf, UDS_SERVICE_DIAG_SESSION_CTRL, 0x02)) {
send_uds_service();
}
break;
case UDS_STATE_SAFE_ACCESS:
if (IS_RESPONSE_WITH_SUBFUNC(frame_buf, UDS_SERVICE_SECURITY_ACCESS, 0x01)) {
// Calculate the key
uds_calculate_key_direct(frame_buf, g_key);
send_uds_service();
}
break;
case UDS_STATE_SAFE_ACCESS_SEND_VERIFY:
if (IS_RESPONSE_WITH_SUBFUNC(frame_buf, UDS_SERVICE_SECURITY_ACCESS, 0x02)) {
send_uds_service();
}
break;
case UDS_STATE_ERASE_CODE:
if (IS_RESPONSE_WITH_SUBFUNC(frame_buf, UDS_SERVICE_ROUTINE_CTRL, 0x01)) {
send_uds_service();
}
break;
case UDS_STATE_REQUEST_UPLOAD:
break;
case UDS_STATE_SEND_UPLOAD:
break;
case UDS_STATE_REQUEST_UPLOAD_EXIT:
break;
case UDS_STATE_APP_CHECK:
break;
case UDS_STATE_CODE_CHECK:
break;
case UDS_STATE_REQUEST_UPLOAD_WAIT:
g_current_state = UDS_STATE_REQUEST_UPLOAD;
break;
case UDS_STATE_WAIT_DOWNLOAD_RESPONSE:
if (frame_dlc >= 5 && IS_POSITIVE_RESPONSE(frame_buf, UDS_SERVICE_REQUEST_DOWNLOAD)) {
g_max_block_size = (frame_buf[3] << 8) | frame_buf[4];
g_bytes_per_block = (g_max_block_size > 0) ? g_max_block_size : 32;
g_current_state = UDS_STATE_SEND_UPLOAD;
} else if (IS_NEGATIVE_RESPONSE_FOR_SERVICE(frame_buf, UDS_SERVICE_REQUEST_DOWNLOAD)) {
g_current_state = UDS_STATE_ERROR;
} else {
uds_tp_recv_frame(0, frame_buf, frame_dlc);
}
break;
case UDS_STATE_WAIT_TRANSFER_RESPONSE:
if (IS_POSITIVE_RESPONSE(frame_buf, UDS_SERVICE_TRANSFER_DATA)) {
rt_sem_release(&g_flow_control_sem);
} else if (IS_NEGATIVE_RESPONSE_FOR_SERVICE(frame_buf, UDS_SERVICE_TRANSFER_DATA)) {
g_current_state = UDS_STATE_ERROR;
} else {
uds_tp_recv_frame(0, frame_buf, frame_dlc);
}
break;
default:
break;
}
rt_mutex_release(g_uds_state_mutex);
}
/******************************************************************************
@@ -28,12 +243,14 @@ void init_uds_timers()
* 函数返回: 无
* 其它说明: frame_dlc 长度必须等于 FRAME_SIZE否则会被判断为无效帧
******************************************************************************/
void uds_recv_frame(uint32_t id, uint8_t* frame_buf, uint8_t frame_dlc)
void uds_recv_frame(uint32_t id, uint8_t *frame_buf, uint8_t frame_dlc)
{
if(UDS_REQUEST_ID == id)
if (UDS_REQUEST_ID == id)
uds_tp_recv_frame(0, frame_buf, frame_dlc);
else if(UDS_FUNCTION_ID == id)
else if (UDS_FUNCTION_ID == id)
uds_tp_recv_frame(1, frame_buf, frame_dlc);
else if (UDS_RESPONSE_ID == id)
handle_uds_state_machine(id, frame_buf, frame_dlc);
}
/******************************************************************************
@@ -48,49 +265,21 @@ void uds_recv_frame(uint32_t id, uint8_t* frame_buf, uint8_t frame_dlc)
******************************************************************************/
void uds_send_frame(uint32_t id, uint8_t *data, uint8_t len, uint8_t expect_response)
{
rt_err_t ret = 0;
rt_size_t size;
struct rt_can_msg msg = {
.id = id,
.ide = (id > 0x7FF) ? 1 : 0,
.rtr = 0,
.len = len
};
rt_size_t size;
struct rt_can_msg msg = { 0 };
msg.id = id;
msg.ide = (id > 0x7FF) ? 1 : 0;
msg.rtr = 0;
msg.len = len;
memcpy(msg.data, data, len);
rt_kprintf("[UDS] REQUEST: ID=0x%03X LEN=%d DATA: ", id, len);
for(int i=0; i<len; i++)
rt_kprintf("%02X ", data[i]);
rt_kprintf("\n");
rt_device_t can_tx_dev = rt_device_find(CAN_TX_DEV_NAME);
if (can_tx_dev) {
ret = rt_device_open(can_tx_dev,
RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
if (ret)
{
rt_kprintf("%s open failed!\n", CAN_TX_DEV_NAME);
return;
}
ret = rt_device_control(can_tx_dev, RT_CAN_CMD_SET_BAUD, (void *)CAN1MBaud);
if (ret)
{
rt_kprintf("%s set baudrate failed!\n", CAN_TX_DEV_NAME);
return;
}
rt_device_control(can_tx_dev, RT_DEVICE_CTRL_SET_INT, NULL);
size = rt_device_write(can_tx_dev, 0, &msg, sizeof(msg));
if (size != sizeof(msg))
{
rt_kprintf("can dev write data failed!\n");
return;
}
size = rt_device_write(g_can_tx_dev, 0, &msg, sizeof(msg));
if (size != sizeof(msg)) {
rt_kprintf("[UDS] Error: Failed to send frame\n");
return;
}
if(expect_response) {
rt_kprintf("[UDS] Waiting for response... (timeout=2000ms)\n");
if (expect_response) {
// rt_kprintf("[UDS] Waiting for response... (timeout=2000ms)\n");
}
}