From 00e0875547deb4b4976fecd533c5864c73292f23 Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 23 Jan 2026 14:33:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CanUds.c | 148 +++++++++++++++++++++++++++++++++++++++++-------------- CanUds.h | 40 ++++++++++----- 2 files changed, 141 insertions(+), 47 deletions(-) diff --git a/CanUds.c b/CanUds.c index 434f386..fc2abf9 100644 --- a/CanUds.c +++ b/CanUds.c @@ -7,7 +7,7 @@ #include "memory.h" #include "TesterPresent_3e.h" #include "DiagnosticSessionControl_10.h" - +#include "StatusError.h" #define LOG_SIGN "CAN_UDS" #define LOGGER env->logger @@ -22,7 +22,9 @@ bool ReceivedCan_func(void *arg, can_rx_message_type *canFrame) { void ReceivedTP_func(void *arg, tCanTP_data *data) { tCanUds *env = arg; - if (data->data[0] == UDS_TesterPresent) { + tUdsServiceCommand *com = (tUdsServiceCommand *) data; + + if (com->service == UDS_TesterPresent) { tTesterPresent testerPresent; testerPresent.ServiceId = data->data[0] | 0b1000000; @@ -42,7 +44,7 @@ void ReceivedTP_func(void *arg, tCanTP_data *data) { } -uint8_t setResponseError(tCanUds *env, eUdsServices service, eUdsResponseError error) { +uint16_t setResponseError(tCanUds *env, eUdsServices service, eUdsResponseError error) { env->dataResponse[0] = 0x7F; env->dataResponse[1] = service; env->dataResponse[2] = error; @@ -53,21 +55,23 @@ uint8_t setResponseError(tCanUds *env, eUdsServices service, eUdsResponseError e // начало ----------------------------- Сессия ------------------------------------------------------------- // начало ----------------------------- Сессия ------------------------------------------------------------- // начало ----------------------------- Сессия ------------------------------------------------------------- -static uint8_t DiagnosticSessionControl_10(tCanUds *env) { - - if ((env->data.len != 2) || - (env->data.data[1] != UDS_session_defaultSession) || - (env->data.data[1] != UDS_session_programmingSession) || - (env->data.data[1] != UDS_session_extendedDiagnosticSession)) { +static uint16_t DiagnosticSessionControl_10(tCanUds *env) { + tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; + if (com->service != 2) { return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_incorrectMessageLengthOrInvalidFormat); } + if ((com->sub_function != UDS_session_defaultSession) && + (com->sub_function != UDS_session_programmingSession) && + (com->sub_function != UDS_session_extendedDiagnosticSession)) { + return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_sub_functionNotSupported); + } + tDiagnosticSessionsType *diagnosticSessionsType = (tDiagnosticSessionsType *) env->dataResponse; diagnosticSessionsType->ServiceId = UDS_DiagnosticSessionControl | 0b1000000; diagnosticSessionsType->diagnosticSessionType = env->data.data[1]; - // Нормальный таймаут. Важно: Клиент может отправлять TesterPresent для поддержания сессии до истечения этого таймаута diagnosticSessionsType->sessionParameterRecord[0] = 0; diagnosticSessionsType->sessionParameterRecord[1] = 0x32; @@ -76,7 +80,7 @@ static uint8_t DiagnosticSessionControl_10(tCanUds *env) { diagnosticSessionsType->sessionParameterRecord[2] = 0x01; diagnosticSessionsType->sessionParameterRecord[3] = 0xF4; - return sizeof(tDiagnosticSessionsType); + return 4; } // конец ----------------------------- Сессия -------------------------------------------------------------- // конец ----------------------------- Сессия -------------------------------------------------------------- @@ -86,7 +90,7 @@ static uint8_t DiagnosticSessionControl_10(tCanUds *env) { // начало --------------------------- Чтение --------------------------------------------------------- // начало --------------------------- Чтение --------------------------------------------------------- // начало --------------------------- Чтение --------------------------------------------------------- -static uint8_t ReadDataByIdentifier_22(tCanUds *env) { +static uint16_t ReadDataByIdentifier_22(tCanUds *env) { if (env->data.len != 3) { return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat); @@ -99,7 +103,7 @@ static uint8_t ReadDataByIdentifier_22(tCanUds *env) { if (dataIdentifier_hi == 0xCF) { if (uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].data != NULL) { - uint8_t response_size = uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].size; + uint16_t response_size = uds_ReadDataByIdentifier_22_com_CF[dataIdentifier_lo].size; env->dataResponse[0] = UDS_ReadDataByIdentifier | 0b1000000; env->dataResponse[1] = dataIdentifier_hi; @@ -114,7 +118,7 @@ static uint8_t ReadDataByIdentifier_22(tCanUds *env) { if (dataIdentifier_hi == 0xF1) { if (uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].data != NULL) { - uint8_t response_size = uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].size; + uint16_t response_size = uds_ReadDataByIdentifier_22_com_F1[dataIdentifier_lo].size; env->dataResponse[0] = UDS_ReadDataByIdentifier | 0b1000000; env->dataResponse[1] = dataIdentifier_hi; @@ -136,7 +140,7 @@ static uint8_t ReadDataByIdentifier_22(tCanUds *env) { // начало --------------------------- Запись --------------------------------------------------------- // начало --------------------------- Запись --------------------------------------------------------- -static uint8_t WriteDataByIdentifier_2E(tCanUds *env) { +static uint16_t WriteDataByIdentifier_2E(tCanUds *env) { } @@ -150,17 +154,18 @@ static uint8_t WriteDataByIdentifier_2E(tCanUds *env) { // начало --------------------------- Управление --------------------------------------------------------- // начало --------------------------- Управление --------------------------------------------------------- -static uint8_t InputOutputControlByIdentifier_2F(tCanUds *env) { - - if ((env->data.len < 4) || - (env->data.data[3] != UDS_io_returnControlToECU) || - (env->data.data[3] != UDS_io_resetToDefault) || - (env->data.data[3] != UDS_io_shortTermAdjustment)) { +static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) { + if (env->data.len < 5) { return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat); } + if ((env->data.data[3] != UDS_io_returnControlToECU) && + (env->data.data[3] != UDS_io_shortTermAdjustment)) { + return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_conditionsNotCorrect); + } + uint8_t dataIdentifier_hi = env->data.data[1]; uint8_t dataIdentifier_lo = env->data.data[2]; @@ -175,22 +180,23 @@ static uint8_t InputOutputControlByIdentifier_2F(tCanUds *env) { // начало --------------------------- Перезагрузка --------------------------------------------------------- // начало --------------------------- Перезагрузка --------------------------------------------------------- -static uint8_t ECUReset_11(tCanUds *env) { +static uint16_t ECUReset_11(tCanUds *env) { + tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; if (env->data.len != 2) { return setResponseError(env, UDS_ECUResetService, UDS_error_incorrectMessageLengthOrInvalidFormat); } - if ((env->data.data[1] == 1) || (env->data.data[1] == 3)) { - - env->dataResponse[0] = UDS_ECUResetService | 0b1000000;; - env->dataResponse[1] = env->data.data[1]; - - return 2; + if ((com->sub_function != UDS_reset_hardReset) && + (com->sub_function != UDS_reset_softReset)) { + return setResponseError(env, UDS_ECUResetService, UDS_error_sub_functionNotSupported); } - return setResponseError(env, UDS_ECUResetService, UDS_error_sub_functionNotSupported); + env->dataResponse[0] = UDS_ECUResetService | 0b1000000;; + env->dataResponse[1] = env->data.data[1]; + + return 2; } // конец --------------------------- Перезагрузка --------------------------------------------------------- // конец --------------------------- Перезагрузка --------------------------------------------------------- @@ -201,15 +207,18 @@ static uint8_t ECUReset_11(tCanUds *env) { // начало --------------------------- Очистка ошибок --------------------------------------------------------- // начало --------------------------- Очистка ошибок --------------------------------------------------------- -static uint8_t UDS_ClearDiagnosticInformation_14(tCanUds *env) { +static uint16_t UDS_ClearDiagnosticInformation_14(tCanUds *env) { if (env->data.len != 4) { return setResponseError(env, UDS_ClearDiagnosticInformation, UDS_error_incorrectMessageLengthOrInvalidFormat); } + setDiagnosticData(env->Diagnostic, DIAGNOSTIC_SET_UDS_ClearDiagnosticInformation_14); - return setResponseError(env, UDS_ClearDiagnosticInformation, UDS_error_requestOutOfRange); + env->dataResponse[0] = UDS_ClearDiagnosticInformation | 0b1000000; + + return 1; } // конец --------------------------- Очистка ошибок --------------------------------------------------------- // конец --------------------------- Очистка ошибок --------------------------------------------------------- @@ -219,15 +228,80 @@ static uint8_t UDS_ClearDiagnosticInformation_14(tCanUds *env) { // начало --------------------------- Чтение ошибок --------------------------------------------------------- // начало --------------------------- Чтение ошибок --------------------------------------------------------- -static uint8_t UDS_ReadDTCInformation_19(tCanUds *env) { +void SetUdsDTC_error(tCanUds *env, uint8_t mask, uint16_t *sizeResponse) { - if (env->data.len != 3) { - return setResponseError(env, UDS_ReadDTCInformation, - UDS_error_incorrectMessageLengthOrInvalidFormat); + for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { + + if (dtc_state_error[i] & mask) { + env->dataResponse[*sizeResponse] = dtc_codes[i].DTCHighByte; + env->dataResponse[*sizeResponse + 1] = dtc_codes[i].DTCMiddleByte; + env->dataResponse[*sizeResponse + 2] = dtc_codes[i].DTCLowByte; + env->dataResponse[*sizeResponse + 3] = dtc_state_error[i] & mask; + *sizeResponse += 4; + } + } +} + +uint8_t GetCountUdsDTC_error(uint8_t mask) { + + uint8_t count = 0; + + for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { + + if (dtc_state_error[i] & mask) { + ++count; + } } + return count; +} - return setResponseError(env, UDS_ReadDTCInformation, UDS_error_sub_functionNotSupported); +static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) { + + tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; + + if (env->data.len != 3) { + return setResponseError(env, UDS_ReadDTCInformation, UDS_error_incorrectMessageLengthOrInvalidFormat); + } + + if ((com->sub_function != UDS_dtc_reportNumberOfDTCByStatusMask) && + (com->sub_function != UDS_dtc_reportDTCByStatusMask)) { + return setResponseError(env, UDS_ReadDTCInformation, UDS_error_sub_functionNotSupported); + } + + uint16_t response_size = 0; + + env->dataResponse[0] = UDS_ReadDTCInformation | 0b1000000; + + if (com->sub_function == UDS_dtc_reportNumberOfDTCByStatusMask) { + + env->dataResponse[1] = env->data.data[1]; + + // доступные биты статусов + env->dataResponse[2] = 0xFF; + // формат кодирования DTC + env->dataResponse[3] = 1; + // старший байт количества DTC + env->dataResponse[4] = 0; + // младший байт количества DTC + env->dataResponse[5] = GetCountUdsDTC_error(env->data.data[2]); + + response_size = 6; + } + + if (com->sub_function == UDS_dtc_reportDTCByStatusMask) { + + env->dataResponse[1] = env->data.data[1]; + + // доступные биты статусов + env->dataResponse[2] = 0xFF; + + response_size = 3; + + SetUdsDTC_error(env, env->data.data[2], &response_size); + } + + return response_size; } // конец --------------------------- Чтение ошибок --------------------------------------------------------- // конец --------------------------- Чтение ошибок --------------------------------------------------------- @@ -533,6 +607,7 @@ void CanSerialPortCanUds_Start(tCanUds *env) { void CanUds_Init( tCanUds *env, + tDiagnostic *Diagnostic, tSerialPortFrameIO *CanIO, tDeviceStorage *deviceStorage, tLoggerInterface *logger) { @@ -540,6 +615,7 @@ void CanUds_Init( env->logger = logger; env->CanIO = CanIO; env->deviceStorage = deviceStorage; + env->Diagnostic = Diagnostic; env->filterIdCount = 0; env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL); diff --git a/CanUds.h b/CanUds.h index 07f5861..7d00bb1 100644 --- a/CanUds.h +++ b/CanUds.h @@ -7,6 +7,7 @@ #include "CanSerialPortFrameTP.h" #include "DeviceStorage.h" +#include "DiagnosticTask.h" #define CAN_US_QUEUE_SIZE 3 @@ -37,38 +38,54 @@ typedef enum { typedef enum { UDS_error_incorrectMessageLengthOrInvalidFormat = 0x13, - UDS_error_responseTooLong= 0x14, - UDS_error_requestOutOfRange= 0x31, - UDS_error_securityAccessDenied= 0x33, - UDS_error_sub_functionNotSupported = 0x12 + UDS_error_responseTooLong = 0x14, + UDS_error_requestOutOfRange = 0x31, + UDS_error_securityAccessDenied = 0x33, + UDS_error_sub_functionNotSupported = 0x12, + UDS_error_conditionsNotCorrect = 0x22 } eUdsResponseError; typedef enum { UDS_session_defaultSession = 0x1, - UDS_session_programmingSession= 0x2, - UDS_session_extendedDiagnosticSession= 0x3 + UDS_session_programmingSession = 0x2, + UDS_session_extendedDiagnosticSession = 0x3 } eUdsSession; typedef enum { UDS_io_returnControlToECU = 0x0, - UDS_io_resetToDefault= 0x1, - UDS_io_shortTermAdjustment= 0x3 + UDS_io_shortTermAdjustment = 0x3 } eUdsIO; +typedef enum { + UDS_dtc_reportNumberOfDTCByStatusMask = 0x1, + UDS_dtc_reportDTCByStatusMask = 0x2 +} eUdsDtc; + +typedef enum { + UDS_reset_hardReset = 0x1, + UDS_reset_softReset = 0x3 +} eUdsReset; + + +typedef struct { + eUdsServices service; + uint8_t sub_function; + uint8_t *data; +} tUdsServiceCommand; typedef struct { tCanSerialPortFrameTp canSerialPortFrameTp; tLoggerInterface *logger; tSerialPortFrameIO *CanIO; tDeviceStorage *deviceStorage; - + tDiagnostic *Diagnostic; tCanTP_Ext_data canTP_Ext_data; osMessageQueueId_t queue; tCanTP_data data; - uint8_t dataResponse[256]; + uint8_t dataResponse[1024]; uint8_t filterIdCount; uint32_t filterReqId[16]; @@ -78,7 +95,7 @@ typedef struct { tStaticThreadBlock(512) T_can_Uds; } tCanUds; -typedef uint8_t (*uds_func_ptr)(tCanUds *env); +typedef uint16_t (*uds_func_ptr)(tCanUds *env); typedef struct { uds_func_ptr func; @@ -87,6 +104,7 @@ typedef struct { void CanUds_Init( tCanUds *env, + tDiagnostic *Diagnostic, tSerialPortFrameIO *CanIO, tDeviceStorage *deviceStorage, tLoggerInterface *logger);