Files
luban-lite/packages/artinchip/uds/UDSBase/uds_port.c

312 lines
11 KiB
C
Raw Normal View History

2025-07-22 11:15:46 +08:00
/*
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "uds_def.h"
2025-10-21 13:59:50 +08:00
//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
2025-07-22 11:15:46 +08:00
static rt_timer_t response_timer;
void response_timeout(void *param)
{
rt_kprintf("\n[UDS] ERROR: Response timeout!\n");
}
void init_uds_timers()
{
2025-10-21 13:59:50 +08:00
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);
2025-07-22 11:15:46 +08:00
}
/******************************************************************************
* : void uds_recv_frame(uint32_t id, uint8_t* frame_buf, uint8_t frame_dlc)
* :
* : uint32_t id -- ID
    uint8_t* frame_buf --
    uint8_t frame_dlc --
* :
* :
* : frame_dlc FRAME_SIZE
******************************************************************************/
2025-10-21 13:59:50 +08:00
void uds_recv_frame(uint32_t id, uint8_t *frame_buf, uint8_t frame_dlc)
2025-07-22 11:15:46 +08:00
{
2025-10-21 13:59:50 +08:00
if (UDS_REQUEST_ID == id)
2025-07-22 11:15:46 +08:00
uds_tp_recv_frame(0, frame_buf, frame_dlc);
2025-10-21 13:59:50 +08:00
else if (UDS_FUNCTION_ID == id)
2025-07-22 11:15:46 +08:00
uds_tp_recv_frame(1, frame_buf, frame_dlc);
2025-10-21 13:59:50 +08:00
else if (UDS_RESPONSE_ID == id)
handle_uds_state_machine(id, frame_buf, frame_dlc);
2025-07-22 11:15:46 +08:00
}
/******************************************************************************
* : void uds_send_frame(uint32_t id, uint8_t* frame_buf, uint8_t frame_dlc)
* :
* : uint8_t response_id -- ID
    uint8_t* frame_buf --
    uint8_t frame_dlc --
* :
* :
* : frame_dlc FRAME_SIZE
******************************************************************************/
void uds_send_frame(uint32_t id, uint8_t *data, uint8_t len, uint8_t expect_response)
{
2025-10-21 13:59:50 +08:00
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;
2025-07-22 11:15:46 +08:00
2025-10-21 13:59:50 +08:00
memcpy(msg.data, data, len);
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;
2025-07-22 11:15:46 +08:00
}
2025-10-21 13:59:50 +08:00
if (expect_response) {
// rt_kprintf("[UDS] Waiting for response... (timeout=2000ms)\n");
2025-07-22 11:15:46 +08:00
}
}
/******************************************************************************
* : void uds_init(void)
* : UDS
* :
* :
* :
* :
******************************************************************************/
void uds_init(void)
{
service_init();
}
/******************************************************************************
* : void uds_1ms_task(void)
* : UDS
* :
* :
* :
* : 1ms
******************************************************************************/
void uds_1ms_task(void)
{
network_task();
service_task();
}