Обновление

This commit is contained in:
cfif 2025-11-17 16:28:51 +03:00
parent a675460804
commit 97954edfd6
2 changed files with 272 additions and 9 deletions

View File

@ -215,6 +215,10 @@ typedef struct __attribute__ ((packed)) {
} eXcpCommand_SET_DAQ_PTR;
#define PROGRAM_MASTER_BLOCK_MODE 1
#define PROGRAM_MAX_SECTOR 8
#define MAX_CTO 8
#define MAX_DTO 8
@ -452,6 +456,80 @@ typedef struct __attribute__ ((packed)) {
} eXcpCommand_GET_DAQ_EVENT_INFO;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t RESERVED1;
uint8_t MASTER_BLOCK_MODE: 1;
uint8_t INTERLEAVED_MODE: 1;
uint8_t RESERVED2: 1;
uint8_t RESERVED3: 1;
uint8_t RESERVED4: 1;
uint8_t RESERVED5: 1;
uint8_t SLAVE_BLOCK_MODE: 1;
uint8_t RESERVED6: 1;
uint8_t MAX_CTO_PGM;
uint8_t MAX_BS_PGM;
uint8_t MIN_ST_PGM;
uint8_t QUEUE_SIZE_PGM;
} eXcpCommand_PROGRAM_START;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t MODE;
uint16_t RESERVED;
uint32_t CLEAR_RANGE;
} eXcpCommand_XCP_PROGRAM_CLEAR_209;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t COUNT;
} eXcpCommand_Program_ProgramNext_208_202;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t ABSOLUTE_MODE: 1;
uint8_t FUNCTIONAL_MODE: 1;
uint8_t COMPRESSION_SUPPORTED: 1;
uint8_t COMPRESSION_REQUIRED: 1;
uint8_t ENCRYPTION_SUPPORTED: 1;
uint8_t ENCRYPTION_REQUIRED: 1;
uint8_t NON_SEQ_PGM_SUPPORTED: 1;
uint8_t NON_SEQ_PGM_REQUIRED: 1;
uint8_t MAX_SECTOR;
} eXcpCommand_PGM_PROCESSOR_INFO_206;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t MODE;
uint8_t SECTOR_NUMBER;
} eXcpCommand_REQ_GET_SECTOR_INFO_205;
typedef struct __attribute__ ((packed)) {
eXcpTypeCommand COM;
uint8_t CLEAR_SEQUENCE_NUMBER;
uint8_t PROGRAM_SEQUENCE_NUMBER;
uint8_t ABSOLUTE_MODE: 1;
uint8_t FUNCTIONAL_MODE: 1;
uint8_t PAGED_MODE: 1;
uint8_t SEQUENTIAL_ONLY: 1;
uint8_t ERASE_BEFORE_WRITE: 1;
uint8_t VERIFY_AFTER_WRITE: 1;
uint8_t RESERVED1: 1;
uint8_t RESERVED2: 1;
uint32_t SECTOR_INFO;
} eXcpCommand_RESP_GET_SECTOR_INFO_205;
typedef bool (xcp_clear_flash_func)(uint32_t firstPageAddr, uint32_t totalSize);
typedef bool (xcp_write_flash_func)(uint32_t beginPageAddr, void *sourceRamAddr, uint32_t size);
typedef struct {
tSerialPortFrameIO *ioCanFrame;
tLoggerInterface *logger;
@ -478,6 +556,15 @@ typedef struct {
osMutexId_t access;
uint32_t startRamAdr;
uint32_t endRamAdr;
uint32_t startFlashAdr;
uint32_t endFlashAdr;
xcp_clear_flash_func *clear_flash_func;
xcp_write_flash_func *write_flash_func;
tStaticThreadBlock(512) T_can_Listener_XCP;
tStaticThreadBlock(512) T_can_Listener_Dto_Stim_XCP;
tStaticThreadBlock(512) T_can_Listener_Dto_Daq_XCP;
@ -486,11 +573,16 @@ typedef struct {
typedef uint8_t (*xcp_func_ptr)(tCanSerialPortFrameXCP *env);
void CanSerialPortFrameXcpInit(
tCanSerialPortFrameXCP *env,
tSerialPortFrameIO *ioCanFrame,
tRtcIO *rtcIO,
uint32_t startRamAddr,
uint32_t endRamAdr,
uint32_t startFlashAdr,
uint32_t endFlashAdr,
xcp_clear_flash_func *clear_flash_func,
xcp_write_flash_func *write_flash_func,
tLoggerInterface *logger
);

View File

@ -34,6 +34,12 @@ void CanSerialPortFrameXcpInit(
tCanSerialPortFrameXCP *env,
tSerialPortFrameIO *ioCanFrame,
tRtcIO *rtcIO,
uint32_t startRamAdr,
uint32_t endRamAdr,
uint32_t startFlashAdr,
uint32_t endFlashAdr,
xcp_clear_flash_func *clear_flash_func,
xcp_write_flash_func *write_flash_func,
tLoggerInterface *logger
) {
env->ioCanFrame = ioCanFrame;
@ -41,6 +47,14 @@ void CanSerialPortFrameXcpInit(
env->rtcIO = rtcIO;
env->logger = logger;
env->startRamAdr = startRamAdr;
env->endRamAdr = endRamAdr;
env->startFlashAdr = startFlashAdr;
env->endFlashAdr = endFlashAdr;
env->clear_flash_func = clear_flash_func;
env->write_flash_func = write_flash_func;
env->access = osMutexNew(NULL);
InitThreadBlock(env->T_can_Listener_XCP, "CanListenerXCP", osPriorityNormal);
@ -173,6 +187,15 @@ static uint8_t XCP_UNLOCK_247(tCanSerialPortFrameXCP *env) {
static uint8_t XCP_COMMAND_SET_MTA_246(tCanSerialPortFrameXCP *env) {
eXcpCommand_SET_MTA *request = (eXcpCommand_SET_MTA *) env->canFrame.data;
if (((request->ADR < env->startRamAdr) || (request->ADR > env->endRamAdr)) &&
((request->ADR < env->startFlashAdr) || (request->ADR > env->endFlashAdr))) {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_ACCESS_DENIED;
return 2;
}
env->ADR_EXT = request->ADR_EX;
env->ADR_MTA = request->ADR;
@ -248,8 +271,9 @@ static uint8_t XCP_COMMAND_DOWNLOAD_NEXT_239(tCanSerialPortFrameXCP *env) {
if (request->COUNT != env->downloadRemaining) {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_SEQUENCE;
env->response[2] = env->downloadRemaining;
return 2;
return 3;
}
env->downloadRemaining -= COUNT;
@ -637,6 +661,153 @@ static uint8_t XCP_GET_DAQ_STM(tCanSerialPortFrameXCP *env) {
return 0;
}
static uint8_t XCP_PROGRAM_START_210(tCanSerialPortFrameXCP *env) {
eXcpCommand_PROGRAM_START *response = (eXcpCommand_PROGRAM_START *) env->response;
response->COM = XCP_COMMAND_CONNECT;
response->RESERVED1 = 0;
response->MASTER_BLOCK_MODE = PROGRAM_MASTER_BLOCK_MODE;
response->INTERLEAVED_MODE = 0;
response->RESERVED2 = 0;
response->RESERVED3 = 0;
response->RESERVED4 = 0;
response->RESERVED5 = 0;
response->SLAVE_BLOCK_MODE = 1;
response->RESERVED6 = 0;
response->MAX_CTO_PGM = 8;
response->MAX_BS_PGM = 255; // Максимальный размер блока в режиме программирования. Определяет, сколько пакетов можно отправить подряд в блочном режиме
response->MIN_ST_PGM = 1; // Минимальное время шага (Minimum Separation Time). Определяет минимальную паузу (в миллисекундах)
response->QUEUE_SIZE_PGM = 10; // Размер очереди. Указывает, сколько пакетов типа CTO мастер может отправить "подряд"
return 8;
}
static uint8_t XCP_PROGRAM_CLEAR_209(tCanSerialPortFrameXCP *env) {
eXcpCommand_XCP_PROGRAM_CLEAR_209 *request = (eXcpCommand_XCP_PROGRAM_CLEAR_209 *) env->canFrame.data;
if (request->MODE == 0) {
if ((env->ADR_MTA < env->startFlashAdr) || ((env->ADR_MTA + request->CLEAR_RANGE) > env->endFlashAdr)) {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_ACCESS_DENIED;
return 2;
}
env->clear_flash_func(env->ADR_MTA, request->CLEAR_RANGE);
} else {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_OUT_OF_RANGE;
return 2;
}
env->response[0] = XCP_COMMAND_CONNECT;
return 1;
}
static uint8_t XCP_PROGRAM_208(tCanSerialPortFrameXCP *env) {
eXcpCommand_Program_ProgramNext_208_202 *request = (eXcpCommand_Program_ProgramNext_208_202 *) env->canFrame.data;
uint8_t COUNT = env->canFrame.dlc - 2;
env->write_flash_func(env->ADR_MTA, &env->canFrame.data[2], request->COUNT);
env->ADR_MTA += request->COUNT;
#ifndef PROGRAM_MASTER_BLOCK_MODE
env->response[0] = XCP_COMMAND_CONNECT;
return 1;
#else
if (request->COUNT == 0) {
env->response[0] = XCP_COMMAND_CONNECT;
return 1;
}
return 0;
#endif
}
static uint8_t XCP_PROGRAM_NEXT_202(tCanSerialPortFrameXCP *env) {
eXcpCommand_Program_ProgramNext_208_202 *request = (eXcpCommand_Program_ProgramNext_208_202 *) env->canFrame.data;
uint8_t COUNT = env->canFrame.dlc - 2;
env->write_flash_func(env->ADR_MTA, &env->canFrame.data[2], request->COUNT);
env->ADR_MTA += request->COUNT;
return 0;
}
static uint8_t XCP_PROGRAM_RESET_207(tCanSerialPortFrameXCP *env) {
env->response[0] = XCP_COMMAND_CONNECT;
return 1;
}
static uint8_t XCP_GET_PGM_PROCESSOR_INFO_206(tCanSerialPortFrameXCP *env) {
eXcpCommand_PGM_PROCESSOR_INFO_206 *response = (eXcpCommand_PGM_PROCESSOR_INFO_206 *) env->response;
response->COM = XCP_COMMAND_CONNECT;
response->ABSOLUTE_MODE = 1;
response->FUNCTIONAL_MODE = 0;
response->COMPRESSION_SUPPORTED = 0;
response->COMPRESSION_REQUIRED = 0;
response->ENCRYPTION_SUPPORTED = 0;
response->ENCRYPTION_REQUIRED = 0;
response->NON_SEQ_PGM_SUPPORTED = 0;
response->NON_SEQ_PGM_REQUIRED = 0;
response->MAX_SECTOR = PROGRAM_MAX_SECTOR;
return 3;
}
static uint8_t XCP_GET_SECTOR_INFO_205(tCanSerialPortFrameXCP *env) {
eXcpCommand_REQ_GET_SECTOR_INFO_205 *request = (eXcpCommand_REQ_GET_SECTOR_INFO_205 *) env->canFrame.data;
if (request->SECTOR_NUMBER > PROGRAM_MAX_SECTOR) {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_OUT_OF_RANGE;
return 2;
}
eXcpCommand_RESP_GET_SECTOR_INFO_205 *response = (eXcpCommand_RESP_GET_SECTOR_INFO_205 *) env->response;\
response->COM = XCP_COMMAND_CONNECT;
response->CLEAR_SEQUENCE_NUMBER = request->SECTOR_NUMBER;
response->PROGRAM_SEQUENCE_NUMBER = request->SECTOR_NUMBER;
response->ABSOLUTE_MODE = 1;
response->FUNCTIONAL_MODE = 0;
response->PAGED_MODE = 0;
response->SEQUENTIAL_ONLY = 1;
response->ERASE_BEFORE_WRITE = 1;
response->VERIFY_AFTER_WRITE = 0;
response->RESERVED1 = 0;
response->RESERVED2 = 0;
if (request->MODE == 0) {
response->SECTOR_INFO = request->SECTOR_NUMBER * FLASH_PAGE_SIZE + env->startFlashAdr;
} else if (request->MODE == 1) {
response->SECTOR_INFO = FLASH_PAGE_SIZE;
} else if (request->MODE == 2) {
env->response[1] = 0;
return 2;
} else {
env->response[0] = XCP_COMMAND_DISCONNECT;
env->response[1] = XCP_ERR_CMD_SYNTAX;
return 2;
}
return 8;
}
const xcp_func_ptr fXcp_func_ptr[256] = {
NULL,
NULL,
@ -840,15 +1011,15 @@ const xcp_func_ptr fXcp_func_ptr[256] = {
NULL,
NULL,
NULL,
XCP_PROGRAM_NEXT_202,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
XCP_GET_SECTOR_INFO_205,
XCP_GET_PGM_PROCESSOR_INFO_206,
XCP_PROGRAM_RESET_207,
XCP_PROGRAM_208,
XCP_PROGRAM_CLEAR_209,
XCP_PROGRAM_START_210,
XCP_ALLOC_ODT_ENTRY_211,
XCP_ALLOC_ODT_212,
XCP_ALLOC_DAQ_213,