// // Created by cfif on 16.03.2024. // #include #include "CanSerialPortFrameXCP.h" #include "memory.h" #include "AsciiStringAssmeblingUtils.h" #include "SystemMutexCmsis.h" #include "CanPorts.h" #define LOG_SIGN "CAN_XCP" #define LOGGER &env->logger static unsigned long SeedToKeyHVAC_NAMI(unsigned char rnd, unsigned long dwSeedInfo) { #define Mask 0x55F388A6UL unsigned char i; unsigned long key = dwSeedInfo; rnd += 35; if (rnd < 35) rnd = 255; for (i = 0; i < rnd; i++) { if (key & 0x80000000UL) key = (key << 1) ^ Mask; else key <<= 1; } return key; } void CanSerialPortFrameXcpInit( tCanSerialPortFrameXCP *env, tSerialPortFrameIO *ioCanFrame, tRtcIO *rtcIO, tLoggerInterface *logger ) { env->ioCanFrame = ioCanFrame; env->rtcIO = rtcIO; env->logger = logger; env->access = osMutexNew(NULL); InitThreadBlock(env->T_can_Listener_XCP, "CanListenerXCP", osPriorityNormal); } uint8_t XCP_COMMAND_CONNECT_255(tCanSerialPortFrameXCP *env) { eXcpCommand_CONNECT *xcpCommand_CONNECT = (eXcpCommand_CONNECT *) env->response; xcpCommand_CONNECT->COM = XCP_COMMAND_CONNECT; xcpCommand_CONNECT->CAL_PAG = 0; // Калибровка и пагинация xcpCommand_CONNECT->reserve1 = 0; xcpCommand_CONNECT->DAQ = 1; // Поддержка DAQ xcpCommand_CONNECT->STIM = 1; // Стимуляция (формирование инициативных запросов) xcpCommand_CONNECT->PGM = 1; // Программирование FLASH xcpCommand_CONNECT->reserve2 = 0; xcpCommand_CONNECT->reserve3 = 0; xcpCommand_CONNECT->reserve4 = 0; xcpCommand_CONNECT->BYTE__ORDER = 0; // 0 - Intel 1 - Motorola xcpCommand_CONNECT->ADDRESS_GRANULARITY_0 = 0; xcpCommand_CONNECT->ADDRESS_GRANULARITY_1 = 0; xcpCommand_CONNECT->reserve5 = 0; xcpCommand_CONNECT->reserve6 = 0; xcpCommand_CONNECT->reserve7 = 0; xcpCommand_CONNECT->SLAVE_BLOCK_MODE = 0; // Блочный режим не поддерживается xcpCommand_CONNECT->OPTIONAL = 1; // Поддержка команды XCP_COMMAND_GET_STATUS xcpCommand_CONNECT->MAX_CTO_ = MAX_CTO; xcpCommand_CONNECT->MAX_DTO_ = MAX_DTO; xcpCommand_CONNECT->XCP_PROTOCOL_VER = 1; xcpCommand_CONNECT->XCP_TRANSPORT_VER = 1; return 8; } uint8_t XCP_COMMAND_DISCONNECT_254(tCanSerialPortFrameXCP *env) { env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_COMMAND_GET_STATUS_253(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_STATUS *xcpCommand_GET_STATUS = (eXcpCommand_GET_STATUS *) env->response; xcpCommand_GET_STATUS->COM = XCP_COMMAND_CONNECT; xcpCommand_GET_STATUS->STORE_CAL_REQ = 0; xcpCommand_GET_STATUS->reserve1 = 0; xcpCommand_GET_STATUS->STORE_DAQ_REQ = 0; xcpCommand_GET_STATUS->CLEAR_DAQ_REQ = 0; xcpCommand_GET_STATUS->reserve2 = 0; xcpCommand_GET_STATUS->reserve3 = 0; xcpCommand_GET_STATUS->DAQ_RUNNING = 0; xcpCommand_GET_STATUS->RESUME = 0; xcpCommand_GET_STATUS->CAL_PAG = 0; xcpCommand_GET_STATUS->reserve5 = 0; xcpCommand_GET_STATUS->DAQ = 0; xcpCommand_GET_STATUS->STIM = 0; xcpCommand_GET_STATUS->PGM = 0; xcpCommand_GET_STATUS->reserve6 = 0; xcpCommand_GET_STATUS->reserve7 = 0; xcpCommand_GET_STATUS->reserve8 = 0; xcpCommand_GET_STATUS->STATE_NUMBER = 0; xcpCommand_GET_STATUS->SESSION_CONFIGURATION_ID = 0; return 8; } uint8_t XCP_COMMAND_SYNCH_252(tCanSerialPortFrameXCP *env) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_CMD_SYNCH; return 2; } uint8_t XCP_GET_COMM_MODE_INFO_251(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_COMM_MODE_INFO *xcpCommand_GET_COMM_MODE_INFO = (eXcpCommand_GET_COMM_MODE_INFO *) env->response; xcpCommand_GET_COMM_MODE_INFO->RESERVED1 = 0; xcpCommand_GET_COMM_MODE_INFO->MASTER_BLOCK_MODE = 1; xcpCommand_GET_COMM_MODE_INFO->INTERLEAVED_MODE = 0; xcpCommand_GET_COMM_MODE_INFO->RESERVED2 = 0; xcpCommand_GET_COMM_MODE_INFO->RESERVED3 = 0; xcpCommand_GET_COMM_MODE_INFO->MAX_BS = 255; xcpCommand_GET_COMM_MODE_INFO->MIN_ST = 0; xcpCommand_GET_COMM_MODE_INFO->QUEUE_SIZE = 0; xcpCommand_GET_COMM_MODE_INFO->VERSION = 1; return 8; } uint8_t XCP_GET_SEED_248(tCanSerialPortFrameXCP *env) { eXcpCommand_REQ_GET_SEED *request = (eXcpCommand_REQ_GET_SEED *) env->canFrame.data; eXcpCommand_GET_SEED *xcpCommand_GET_SEED = (eXcpCommand_GET_SEED *) env->response; xcpCommand_GET_SEED->COM = XCP_COMMAND_CONNECT; xcpCommand_GET_SEED->LEN = 4; xcpCommand_GET_SEED->KEY = 0x11223344; env->RND = request->RESOURCE; return 6; } uint8_t XCP_UNLOCK_247(tCanSerialPortFrameXCP *env) { eXcpCommand_REQ_UNLOCK *request = (eXcpCommand_REQ_UNLOCK *) env->canFrame.data; uint32_t securitySeedMy = SeedToKeyHVAC_NAMI(env->RND, 0x11223344); if (securitySeedMy != request->KEY) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_ACCESS_LOCKED; } else { env->response[0] = XCP_COMMAND_CONNECT; env->response[1] = 0; } return 2; } uint8_t XCP_COMMAND_SET_MTA_246(tCanSerialPortFrameXCP *env) { eXcpCommand_SET_MTA *request = (eXcpCommand_SET_MTA *) env->canFrame.data; env->ADR_EXT = request->ADR_EX; env->ADR_MTA = request->ADR; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_COMMAND_UPLOAD_245(tCanSerialPortFrameXCP *env) { eXcpCommand_Upload *request = (eXcpCommand_Upload *) env->canFrame.data; env->response[0] = XCP_COMMAND_CONNECT; uint8_t fullBlock = request->COUNT / 7; uint8_t tailBlock = request->COUNT % 7; for (uint8_t i = 0; i < fullBlock; ++i) { memcpy(&env->response[1], (uint8_t *) (env->ADR_MTA), request->COUNT); env->ADR_MTA += 7; env->ioCanFrame->transmit(env->ioCanFrame->env, env->response, 7, 1000); } if (tailBlock > 0) { memcpy(&env->response[1], (uint8_t *) (env->ADR_MTA), tailBlock); env->ADR_MTA += tailBlock; env->ioCanFrame->transmit(env->ioCanFrame->env, env->response, tailBlock, 1000); } return 0; } uint8_t XCP_COMMAND_SHORT_UPLOAD_244(tCanSerialPortFrameXCP *env) { eXcpCommand_SHORT_UPLOAD *request = (eXcpCommand_SHORT_UPLOAD *) env->canFrame.data; if (request->COUNT > (MAX_CTO - 1)) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } env->response[0] = XCP_COMMAND_CONNECT; memcpy(&env->response[1], (uint8_t *) request->ADR, request->COUNT); return request->COUNT + 1; } uint8_t XCP_COMMAND_DOWNLOAD_240(tCanSerialPortFrameXCP *env) { eXcpCommand_Download *request = (eXcpCommand_Download *) env->canFrame.data; uint8_t COUNT = env->canFrame.dlc - 2; memcpy((uint8_t *) (env->ADR_MTA), &env->response[2], COUNT); env->ADR_MTA += COUNT; env->response[0] = XCP_COMMAND_CONNECT; env->downloadRemaining = request->COUNT - COUNT; return 1; } uint8_t XCP_COMMAND_DOWNLOAD_NEXT_239(tCanSerialPortFrameXCP *env) { eXcpCommand_Download *request = (eXcpCommand_Download *) env->canFrame.data; uint8_t COUNT = env->canFrame.dlc - 2; memcpy((uint8_t *) (env->ADR_MTA), &env->response[2], COUNT); env->ADR_MTA += COUNT; if (request->COUNT != env->downloadRemaining) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_SEQUENCE; return 2; } env->downloadRemaining -= COUNT; if (env->downloadRemaining == 0) { env->response[0] = XCP_COMMAND_CONNECT; return 1; } return 0; } uint8_t XCP_COMMAND_DOWNLOAD_MAX_238(tCanSerialPortFrameXCP *env) { uint8_t COUNT = env->canFrame.dlc - 1; memcpy((uint8_t *) (env->ADR_MTA), &env->response[1], COUNT); env->ADR_MTA += COUNT; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_CLEAR_DAQ_LIST_227(tCanSerialPortFrameXCP *env) { env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_GET_DAQ_LIST_INFO_216(tCanSerialPortFrameXCP *env) { eXcpCommand_Get_DAQ_List_Info_Request *request = (eXcpCommand_Get_DAQ_List_Info_Request *) env->canFrame.data; if (request->DAQ_LIST_NUMBER > MAX_DAO) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } eXcpCommand_Get_DAQ_List_Info *xcpCommand_Get_DAQ_List_Info = (eXcpCommand_Get_DAQ_List_Info *) env->response; xcpCommand_Get_DAQ_List_Info->COM = XCP_COMMAND_CONNECT; xcpCommand_Get_DAQ_List_Info->PREDEFINED = 0; xcpCommand_Get_DAQ_List_Info->EVENT_FIXED = 0; xcpCommand_Get_DAQ_List_Info->DAQ = 1; xcpCommand_Get_DAQ_List_Info->STIM = 1; xcpCommand_Get_DAQ_List_Info->RESERVER = 0; xcpCommand_Get_DAQ_List_Info->MAX_ODT_ = MAX_ODT; xcpCommand_Get_DAQ_List_Info->MAX_ODT_ENTRIES_ = MAX_ODT_ENTRIES_SIZE; xcpCommand_Get_DAQ_List_Info->FIXED_EVENT = 0; return 6; } uint8_t XCP_FREE_DAQ_214(tCanSerialPortFrameXCP *env) { env->DAQ_COUNT = 0; for (uint16_t i = 0; i < MAX_DAO; ++i) { env->DAQ[i].SELECTED = 0; env->DAQ[i].RUNNING = 0; env->DAQ[i].ODT_COUNT = 0; for (uint8_t j = 0; j < MAX_ODT; ++j) { env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_COUNT = 0; } } env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_ALLOC_DAQ_213(tCanSerialPortFrameXCP *env) { eXcpCommand_ALLOC_DAQ *request = (eXcpCommand_ALLOC_DAQ *) env->canFrame.data; env->DAQ_COUNT = request->DAQ_COUNT; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_ALLOC_ODT_212(tCanSerialPortFrameXCP *env) { eXcpCommand_ALLOC_ODT *request = (eXcpCommand_ALLOC_ODT *) env->canFrame.data; env->DAQ[request->DAQ_LIST_NUMBER].ODT_COUNT = request->ODT_COUNT; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_ALLOC_ODT_ENTRY_211(tCanSerialPortFrameXCP *env) { eXcpCommand_ALLOC_ODT_ENTRY *request = (eXcpCommand_ALLOC_ODT_ENTRY *) env->canFrame.data; env->DAQ[request->DAQ_LIST_NUMBER].ODT_NUMBER[request->ODT_NUMBER].ODT_ENTRIES_COUNT = request->ODT_ENTRIES_COUNT; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_SET_DAQ_PTR_226(tCanSerialPortFrameXCP *env) { eXcpCommand_SET_DAQ_PTR *request = (eXcpCommand_SET_DAQ_PTR *) env->canFrame.data; if ((request->DAQ_LIST_NUMBER > MAX_DAO) || (request->ODT_NUMBER > MAX_ODT) || (request->ODT_ENTRY_NUMBER > MAX_ODT_ENTRIES_SIZE)) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } env->DAQ_LIST_NUMBER = request->DAQ_LIST_NUMBER; env->ODT_NUMBER = request->ODT_NUMBER; env->ODT_ENTRY_NUMBER = request->ODT_ENTRY_NUMBER; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_WRITE_DAQ_225(tCanSerialPortFrameXCP *env) { eXcpCommand_WRITE_DAQ *request = (eXcpCommand_WRITE_DAQ *) env->canFrame.data; if (env->ODT_ENTRY_NUMBER > MAX_ODT_ENTRIES_SIZE) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].BIT_OFFSET[env->ODT_ENTRY_NUMBER] = request->BIT_OFFSET; env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ADR_EXT[env->ODT_ENTRY_NUMBER] = request->ADR_EXT; env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ODT_ENTRIES_ADR[env->ODT_ENTRY_NUMBER] = request->ADR; env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ODT_ENTRIES_SIZE[env->ODT_ENTRY_NUMBER] = request->ODT_ENTRY_SIZE; ++env->ODT_ENTRY_NUMBER; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_SET_DAQ_LIST_MODE_224(tCanSerialPortFrameXCP *env) { eXcpCommand_SET_DAQ_LIST_MODE *request = (eXcpCommand_SET_DAQ_LIST_MODE *) env->canFrame.data; if ((request->DAQ_LIST_NUMBER > MAX_DAO) || (request->EVENT_CHANNEL_NUMBER > MAX_EVENT_CHANNEL)) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } env->DAQ[request->DAQ_LIST_NUMBER].EVENT_CHANNEL = request->EVENT_CHANNEL_NUMBER; env->DAQ[request->DAQ_LIST_NUMBER].ALTERNATING = request->ALTERNATING; env->DAQ[request->DAQ_LIST_NUMBER].DIRECTION = request->DIRECTION; env->DAQ[request->DAQ_LIST_NUMBER].DTO_CTR = request->DTO_CTR; env->DAQ[request->DAQ_LIST_NUMBER].TIMESTAMP = request->TIMESTAMP; env->DAQ[request->DAQ_LIST_NUMBER].PID_OFF = request->PID_OFF; env->DAQ[request->DAQ_LIST_NUMBER].TRANSMISSION_RATE_PRESCALER = request->TRANSMISSION_RATE_PRESCALER; env->DAQ[request->DAQ_LIST_NUMBER].DAQ_LIST_PRIORITY = request->DAQ_LIST_PRIORITY; env->DAQ[request->DAQ_LIST_NUMBER].COUNTER = request->TRANSMISSION_RATE_PRESCALER; env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_START_STOP_DAQ_LIST_222(tCanSerialPortFrameXCP *env) { eXcpCommand_START_STOP_DAQ_LIST *request = (eXcpCommand_START_STOP_DAQ_LIST *) env->canFrame.data; if (request->DAQ_LIST_NUMBER > MAX_DAO) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } if (request->MODE == XCP_STOP) { env->DAQ[request->DAQ_LIST_NUMBER].RUNNING = 0; } if (request->MODE == XCP_START) { env->DAQ[request->DAQ_LIST_NUMBER].RUNNING = 1; } if (request->MODE == XCP_SELECT) { env->DAQ[request->DAQ_LIST_NUMBER].SELECTED = 1; } env->response[0] = XCP_COMMAND_CONNECT; return 1; } uint8_t XCP_START_STOP_SYNCH_221(tCanSerialPortFrameXCP *env) { eXcpCommand_START_STOP_SYNCH *request = (eXcpCommand_START_STOP_SYNCH *) env->canFrame.data; if (request->MODE == XCP_SYNC_START_SEL) { for (uint16 i = 0; i < MAX_DAO; ++i) { if (env->DAQ[i].SELECTED) { env->DAQ[i].RUNNING = 1; } } } if (request->MODE == XCP_SYNC_STOP_ALL) { for (uint16 i = 0; i < MAX_DAO; ++i) { env->DAQ[i].RUNNING = 0; } } if (request->MODE == XCP_SYNC_STOP_SEL) { for (uint16 i = 0; i < MAX_DAO; ++i) { if (env->DAQ[i].SELECTED) { env->DAQ[i].RUNNING = 1; } } } env->response[0] = XCP_COMMAND_CONNECT; return 2; } uint8_t XCP_READ_DAQ_219(tCanSerialPortFrameXCP *env) { eXcpCommand_WRITE_DAQ *response = (eXcpCommand_WRITE_DAQ *) env->response; response->COM = XCP_COMMAND_CONNECT; response->BIT_OFFSET = env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].BIT_OFFSET[env->ODT_ENTRY_NUMBER]; response->ADR_EXT = env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ADR_EXT[env->ODT_ENTRY_NUMBER]; response->ADR = env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ODT_ENTRIES_ADR[env->ODT_ENTRY_NUMBER]; response->ODT_ENTRY_SIZE = env->DAQ[env->DAQ_LIST_NUMBER].ODT_NUMBER[env->ODT_NUMBER].ODT_ENTRIES_SIZE[env->ODT_ENTRY_NUMBER]; ++env->ODT_ENTRY_NUMBER; return 8; } uint8_t XCP_GET_DAQ_PROCESSOR_INFO_218(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_DAQ_PROCESSOR_INFO *response = (eXcpCommand_GET_DAQ_PROCESSOR_INFO *) env->response; response->COM = XCP_COMMAND_CONNECT; response->DAQ_CONFIG_TYPE = 1; // dynamic DAQ list configuration response->PRESCALER_SUPPORTED = 1; // prescaler supported response->RESUME_SUPPORTED = 0; // DAQ lists can not be set to RESUME mode response->BIT_STIM_SUPPORTED = 0; // bitwise data stimulation not supported response->TIMESTAMP_SUPPORTED = 0; // time-stamped mode not supported response->PID_OFF_SUPPORTED = 0; // Identification field can not be switched off response->OVERLOAD_MSB = 0; // No overload indication response->OVERLOAD_EVENT = 0; // No overload indication response->MAX_DAQ = MAX_DAO; response->MAX_EVENT_CHANNEL_ = MAX_EVENT_CHANNEL; response->MIN_DAQ = 0; response->Optimisation_Type_0 = 0; response->Optimisation_Type_1 = 1; response->Optimisation_Type_2 = 0; response->Optimisation_Type_3 = 1; response->Address_Extension_ODT = 0; response->Address_Extension_DAQ = 0; response->Identification_Field_Type_0 = 1; // Relative ODT number, absolute DAQ list number (BYTE) response->Identification_Field_Type_1 = 0; // Relative ODT number, absolute DAQ list number (BYTE) return 8; } uint8_t XCP_GET_DAQ_RESOLUTION_INFO_217(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_DAQ_RESOLUTION_INFO *response = (eXcpCommand_GET_DAQ_RESOLUTION_INFO *) env->response; response->COM = XCP_COMMAND_CONNECT; response->GRANULARITY_ODT_ENTRY_SIZE_DAQ = 1; response->MAX_ODT_ENTRY_SIZE_DAQ = MAX_ODT_ENTRIES_SIZE; response->GRANULARITY_ODT_ENTRY_SIZE_STIM = 1; response->MAX_ODT_ENTRY_SIZE_STIM = MAX_ODT_ENTRIES_SIZE; response->TIMESTAMP_MODE = 0; response->TIMESTAMP_TICKS = 0; return 8; } uint8_t XCP_GET_DAQ_LIST_MODE_223(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_DAQ_LIST_MODE_GET *request = (eXcpCommand_GET_DAQ_LIST_MODE_GET *) env->canFrame.data; if (request->DAQ_LIST_NUMBER > MAX_DAO) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } eXcpCommand_GET_DAQ_LIST_MODE *response = (eXcpCommand_GET_DAQ_LIST_MODE *) env->response; response->COM = XCP_COMMAND_CONNECT; response->SELECTED = env->DAQ[request->DAQ_LIST_NUMBER].SELECTED; response->DIRECTION = env->DAQ[request->DAQ_LIST_NUMBER].DIRECTION; response->RESERVED1 = 0; response->DTO_CTR = env->DAQ[request->DAQ_LIST_NUMBER].DTO_CTR; response->TIMESTAMP = env->DAQ[request->DAQ_LIST_NUMBER].TIMESTAMP; response->PID_OFF = env->DAQ[request->DAQ_LIST_NUMBER].PID_OFF; response->RUNNING = env->DAQ[request->DAQ_LIST_NUMBER].RUNNING; response->RESUME = 0; response->RESERVED2 = 0; response->CURRENT_EVENT_CHANNEL_NUMBER = env->DAQ[request->DAQ_LIST_NUMBER].EVENT_CHANNEL; response->CURRENT_PRESCALER = env->DAQ[request->DAQ_LIST_NUMBER].TRANSMISSION_RATE_PRESCALER; response->CURRENT_DAQ_LIST_PRIORITY = env->DAQ[request->DAQ_LIST_NUMBER].DAQ_LIST_PRIORITY; return 8; } uint8_t XCP_GET_DAQ_EVENT_INFO_215(tCanSerialPortFrameXCP *env) { eXcpCommand_GET_DAQ_EVENT_INFO_GET *request = (eXcpCommand_GET_DAQ_EVENT_INFO_GET *) env->canFrame.data; if (request->EVENT_CHANNEL_NUMBER > MAX_EVENT_CHANNEL) { env->response[0] = XCP_COMMAND_DISCONNECT; env->response[1] = XCP_ERR_OUT_OF_RANGE; return 2; } eXcpCommand_GET_DAQ_EVENT_INFO *response = (eXcpCommand_GET_DAQ_EVENT_INFO *) env->response; response->COM = XCP_COMMAND_CONNECT; response->RESERVED1 = 0; response->RESERVED2 = 0; response->DAQ = 1; response->STM = 1; response->RESERVED3 = 0; response->RESERVED4 = 0; response->CONSISTENCY_DAQ = 0; response->CONSISTENCY_EVENT = 0; response->MAX_DAQ_LIST = 255; response->EVENT_CHANNEL_NAME_LENGTH = 0; response->EVENT_CHANNEL_TIME_CYCLE = 1; response->EVENT_CHANNEL_TIME_UNIT = 7; // EVENT_CHANNEL _TIME_UNIT_10MS response->EVENT_CHANNEL_PRIORITY = 255; return 7; } const xcp_func_ptr fXcp_func_ptr[256] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, XCP_ALLOC_ODT_ENTRY_211, XCP_ALLOC_ODT_212, XCP_ALLOC_DAQ_213, XCP_FREE_DAQ_214, XCP_GET_DAQ_EVENT_INFO_215, XCP_GET_DAQ_LIST_INFO_216, XCP_GET_DAQ_RESOLUTION_INFO_217, XCP_GET_DAQ_PROCESSOR_INFO_218, XCP_READ_DAQ_219, NULL, XCP_START_STOP_SYNCH_221, XCP_START_STOP_DAQ_LIST_222, XCP_GET_DAQ_LIST_MODE_223, XCP_SET_DAQ_LIST_MODE_224, XCP_WRITE_DAQ_225, XCP_SET_DAQ_PTR_226, XCP_CLEAR_DAQ_LIST_227, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, XCP_COMMAND_DOWNLOAD_MAX_238, XCP_COMMAND_DOWNLOAD_NEXT_239, XCP_COMMAND_DOWNLOAD_240, NULL, NULL, NULL, XCP_COMMAND_SHORT_UPLOAD_244, XCP_COMMAND_UPLOAD_245, XCP_COMMAND_SET_MTA_246, XCP_UNLOCK_247, XCP_GET_SEED_248, NULL, NULL, XCP_GET_COMM_MODE_INFO_251, XCP_COMMAND_SYNCH_252, XCP_COMMAND_GET_STATUS_253, XCP_COMMAND_DISCONNECT_254, XCP_COMMAND_CONNECT_255 }; uint8_t vCanSerialPortFrameXcpReceive(tCanSerialPortFrameXCP *env, uint32 timeout) { uint8_t response_size = 0; uint16_t recv = env->ioCanFrame->receive(env->ioCanFrame->env, PROTOCOL_XCP, (uint8_t *) &env->canFrame, 1, timeout); if (recv == 0) return 0; if (osMutexAcquire(env->access, 100) == osOK) { eXcpTypeCommand com = env->canFrame.data[0]; if (fXcp_func_ptr[com] != NULL) { response_size = fXcp_func_ptr[com](env); if (response_size) { env->ioCanFrame->transmit(env->ioCanFrame->env, env->response, response_size, timeout); } } else { } osMutexRelease(env->access); } return response_size; } _Noreturn void CanXcpProcessing_ServiceTask(tCanSerialPortFrameXCP *env) { uint8_t response_size; while (1) { if (osMutexAcquire(env->access, 100) == osOK) { for (uint16 i = 0; i < env->DAQ_COUNT; ++i) { if (env->DAQ[i].RUNNING) { if ((env->DAQ[i].EVENT_CHANNEL == 0) && (env->DAQ[i].COUNTER == 0)) { env->DAQ[i].COUNTER = env->DAQ[i].TRANSMISSION_RATE_PRESCALER; if (env->DAQ[i].DIRECTION == 0) { // DAQ - DTO for (uint8_t j = 0; j < env->DAQ[i].ODT_COUNT; ++j) { env->response[0] = j; // ODT env->response[1] = i; // DAQ response_size = 0; for (uint8_t k = 0; k < env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_COUNT; ++k) { memcpy(&env->response[2] + response_size, (uint8_t *) env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_ADR[k], env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_SIZE[k]); response_size += env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_SIZE[k]; } if (response_size) { env->ioCanFrame->transmit(env->ioCanFrame->env, env->response, response_size, 1000); } } } else { // STIM - DTO for (uint8_t j = 0; j < env->DAQ[i].ODT_COUNT; ++j) { for (uint8_t k = 0; k < env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_COUNT; ++k) { memcpy(&env->response[2] + response_size, (uint8_t *) env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_ADR[k], env->DAQ[i].ODT_NUMBER[j].ODT_ENTRIES_SIZE[k]); } } } } else { --env->DAQ[i].COUNTER; } } } osMutexRelease(env->access); } SystemDelayMs(10); } } void CanXcpProcessing_Service_Start(tCanSerialPortFrameXCP *env) { ThreadBlock_Start(env->T_can_Listener_XCP, env, CanXcpProcessing_ServiceTask); } _Noreturn void CanXcpProcessing_ListenerTask(tCanSerialPortFrameXCP *env) { while (1) { vCanSerialPortFrameXcpReceive(env, 1000); } } void CanXcpProcessing_Listener_Start(tCanSerialPortFrameXCP *env) { ThreadBlock_Start(env->T_can_Listener_XCP, env, CanXcpProcessing_ListenerTask); CanXcpProcessing_Service_Start(env); }