mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-27 06:28:54 +00:00
v1.2.2
This commit is contained in:
@@ -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)))
|
||||
//eg:0x50 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user