Обновление

This commit is contained in:
cfif 2026-04-17 15:11:14 +03:00
parent bc2d4c4f74
commit 1320d99700
3 changed files with 277 additions and 86 deletions

300
CanUds.c
View File

@ -12,6 +12,7 @@
#include "candb.h" #include "candb.h"
#include "stdio.h" #include "stdio.h"
#include "fc7xxx_driver_flash.h" #include "fc7xxx_driver_flash.h"
#include "DownloadFile.h"
#define LOG_SIGN "CAN_UDS" #define LOG_SIGN "CAN_UDS"
#define LOGGER env->logger #define LOGGER env->logger
@ -203,6 +204,7 @@ bool ReceivedCan_func(void *arg, can_rx_message_type *canFrame) {
return false; return false;
} }
/*
void ReceivedTP_func(void *arg, tCanTP_data *data) { void ReceivedTP_func(void *arg, tCanTP_data *data) {
tCanUds *env = arg; tCanUds *env = arg;
@ -217,6 +219,7 @@ void ReceivedTP_func(void *arg, tCanTP_data *data) {
} }
} }
*/
static void setDefaultSecurityAccess(tCanUds *env) { static void setDefaultSecurityAccess(tCanUds *env) {
env->SA.requestSequenceRequestSeed = false; env->SA.requestSequenceRequestSeed = false;
@ -239,9 +242,9 @@ uint16_t setResponseError(tCanUds *env, eUdsServices service, eUdsResponseError
static uint16_t TesterPresent_3E(tCanUds *env) { static uint16_t TesterPresent_3E(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 2) { if (env->data->len < 2) {
return setResponseError(env, UDS_TesterPresent, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_TesterPresent, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -261,9 +264,9 @@ static uint16_t TesterPresent_3E(tCanUds *env) {
// начало ----------------------------- Сессия ------------------------------------------------------------- // начало ----------------------------- Сессия -------------------------------------------------------------
// начало ----------------------------- Сессия ------------------------------------------------------------- // начало ----------------------------- Сессия -------------------------------------------------------------
static uint16_t DiagnosticSessionControl_10(tCanUds *env) { static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 2) { if (env->data->len < 2) {
return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_DiagnosticSessionControl, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -289,7 +292,7 @@ static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
tDiagnosticSessionsType *diagnosticSessionsType = (tDiagnosticSessionsType *) env->dataResponse; tDiagnosticSessionsType *diagnosticSessionsType = (tDiagnosticSessionsType *) env->dataResponse;
diagnosticSessionsType->ServiceId = UDS_DiagnosticSessionControl | 0b1000000; diagnosticSessionsType->ServiceId = UDS_DiagnosticSessionControl | 0b1000000;
diagnosticSessionsType->diagnosticSessionType = env->data.data[1]; diagnosticSessionsType->diagnosticSessionType = env->data->data[1];
// Нормальный таймаут. Важно: Клиент может отправлять TesterPresent для поддержания сессии до истечения этого таймаута // Нормальный таймаут. Важно: Клиент может отправлять TesterPresent для поддержания сессии до истечения этого таймаута
diagnosticSessionsType->sessionParameterRecord[0] = 0; diagnosticSessionsType->sessionParameterRecord[0] = 0;
@ -311,12 +314,12 @@ static uint16_t DiagnosticSessionControl_10(tCanUds *env) {
// начало --------------------------- Чтение --------------------------------------------------------- // начало --------------------------- Чтение ---------------------------------------------------------
static uint16_t ReadDataByIdentifier_22(tCanUds *env) { static uint16_t ReadDataByIdentifier_22(tCanUds *env) {
if (env->data.len < 3) { if (env->data->len < 3) {
return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_ReadDataByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
uint8_t dataIdentifier_hi = env->data.data[1]; uint8_t dataIdentifier_hi = env->data->data[1];
uint8_t dataIdentifier_lo = env->data.data[2]; uint8_t dataIdentifier_lo = env->data->data[2];
// uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo; // uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo;
if (dataIdentifier_hi == 0xCF) { if (dataIdentifier_hi == 0xCF) {
@ -384,12 +387,12 @@ static uint16_t ReadDataByIdentifier_22(tCanUds *env) {
static uint16_t WriteDataByIdentifier_2E(tCanUds *env) { static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
if (env->data.len < 3) { if (env->data->len < 3) {
return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_WriteDataByIdentifier, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
uint8_t dataIdentifier_hi = env->data.data[1]; uint8_t dataIdentifier_hi = env->data->data[1];
uint8_t dataIdentifier_lo = env->data.data[2]; uint8_t dataIdentifier_lo = env->data->data[2];
// uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo; // uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo;
if (dataIdentifier_hi == 0xCF) { if (dataIdentifier_hi == 0xCF) {
@ -409,7 +412,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
uint16_t size = uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].size; uint16_t size = uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].size;
if (env->data.len != size + 3) { if (env->data->len != size + 3) {
return setResponseError(env, UDS_WriteDataByIdentifier, return setResponseError(env, UDS_WriteDataByIdentifier,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -420,7 +423,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
// CCU_Configuration // CCU_Configuration
if (dataIdentifier_lo == 0) { if (dataIdentifier_lo == 0) {
tStatus_CCU_Configuration *CCU_Configuration = (tStatus_CCU_Configuration *) &env->data.data[3]; tStatus_CCU_Configuration *CCU_Configuration = (tStatus_CCU_Configuration *) &env->data->data[3];
if ((CCU_Configuration->AromaConfiguration > 1) || (CCU_Configuration->AlgorithmConfiguration > 1) || if ((CCU_Configuration->AromaConfiguration > 1) || (CCU_Configuration->AlgorithmConfiguration > 1) ||
(CCU_Configuration->RearHVACConfiguration > 1)) { (CCU_Configuration->RearHVACConfiguration > 1)) {
return setResponseError(env, UDS_WriteDataByIdentifier, return setResponseError(env, UDS_WriteDataByIdentifier,
@ -428,7 +431,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
} }
} }
memcpy(uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].data, &env->data.data[3], size); memcpy(uds_WriteDataByIdentifier_2E_com_CF[dataIdentifier_lo].data, &env->data->data[3], size);
SaveToStorageFromStatusData(env->deviceStorage, &statusData.ecu); SaveToStorageFromStatusData(env->deviceStorage, &statusData.ecu);
return 3; return 3;
@ -452,7 +455,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
uint16_t size = uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].size; uint16_t size = uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].size;
if (env->data.len != size + 3) { if (env->data->len != size + 3) {
return setResponseError(env, UDS_WriteDataByIdentifier, return setResponseError(env, UDS_WriteDataByIdentifier,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -464,7 +467,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
// Tester_Fingerprint // Tester_Fingerprint
if (dataIdentifier_lo == 0x5A) { if (dataIdentifier_lo == 0x5A) {
tFingerprint *fingerprint = (tFingerprint *) &env->data.data[3]; tFingerprint *fingerprint = (tFingerprint *) &env->data->data[3];
if (is_valid_day(fingerprint->year, fingerprint->month, fingerprint->day) == false) { if (is_valid_day(fingerprint->year, fingerprint->month, fingerprint->day) == false) {
return setResponseError(env, UDS_WriteDataByIdentifier, return setResponseError(env, UDS_WriteDataByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -472,7 +475,7 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
} }
memcpy(uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].data, &env->data.data[3], size); memcpy(uds_WriteDataByIdentifier_2E_com_F1[dataIdentifier_lo].data, &env->data->data[3], size);
SaveToStorageFromStatusData(env->deviceStorage, &statusData.ecu); SaveToStorageFromStatusData(env->deviceStorage, &statusData.ecu);
return 3; return 3;
@ -495,17 +498,17 @@ static uint16_t WriteDataByIdentifier_2E(tCanUds *env) {
static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) { static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
if (env->data.len < 4) { if (env->data->len < 4) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
uint8_t dataIdentifier_hi = env->data.data[1]; uint8_t dataIdentifier_hi = env->data->data[1];
uint8_t dataIdentifier_lo = env->data.data[2]; uint8_t dataIdentifier_lo = env->data->data[2];
// uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo; // uint16_t dataIdentifier = (dataIdentifier_hi << 8) | dataIdentifier_lo;
if ((env->data.data[3] != UDS_io_returnControlToECU) && if ((env->data->data[3] != UDS_io_returnControlToECU) &&
(env->data.data[3] != UDS_io_shortTermAdjustment)) { (env->data->data[3] != UDS_io_shortTermAdjustment)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_sub_functionNotSupported); return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_sub_functionNotSupported);
} }
@ -523,7 +526,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
uint16_t size = uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].size; uint16_t size = uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].size;
if ((env->data.data[3] == UDS_io_shortTermAdjustment) && (env->data.len != size + 4)) { if ((env->data->data[3] == UDS_io_shortTermAdjustment) && (env->data->len != size + 4)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -531,19 +534,19 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
env->dataResponse[0] = UDS_InputOutputControlByIdentifier | 0b1000000; env->dataResponse[0] = UDS_InputOutputControlByIdentifier | 0b1000000;
env->dataResponse[1] = dataIdentifier_hi; env->dataResponse[1] = dataIdentifier_hi;
env->dataResponse[2] = dataIdentifier_lo; env->dataResponse[2] = dataIdentifier_lo;
env->dataResponse[3] = env->data.data[3]; env->dataResponse[3] = env->data->data[3];
if (env->data.data[3] == UDS_io_shortTermAdjustment) { if (env->data->data[3] == UDS_io_shortTermAdjustment) {
// Motor_Def...MotorSealingValve (percent) // Motor_Def...MotorSealingValve (percent)
if ((dataIdentifier_lo >= 0x60) && (dataIdentifier_lo <= 0x78)) { if ((dataIdentifier_lo >= 0x60) && (dataIdentifier_lo <= 0x78)) {
uint16_t percent = (env->data.data[4] << 8) | env->data.data[5]; uint16_t percent = (env->data->data[4] << 8) | env->data->data[5];
if (percent > 1000) { if (percent > 1000) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_requestOutOfRange); return setResponseError(env, UDS_InputOutputControlByIdentifier, UDS_error_requestOutOfRange);
} }
memcpy(uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data, &env->data.data[4], size); memcpy(uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data, &env->data->data[4], size);
return size + 4; return size + 4;
} else { } else {
@ -552,7 +555,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// Doors Actuator // Doors Actuator
case 0x50: { case 0x50: {
for (uint8_t i = 0; i < 24; i += 2) { for (uint8_t i = 0; i < 24; i += 2) {
uint16_t percent = (env->data.data[4 + i] << 8) | env->data.data[5 + 1 + i]; uint16_t percent = (env->data->data[4 + i] << 8) | env->data->data[5 + 1 + i];
if (percent > 1000) { if (percent > 1000) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -564,7 +567,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// IO // IO
case 0x51: { case 0x51: {
for (uint8_t i = 0; i < 8; ++i) { for (uint8_t i = 0; i < 8; ++i) {
uint8_t on_off = env->data.data[4 + i]; uint8_t on_off = env->data->data[4 + i];
if (on_off > 1) { if (on_off > 1) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -576,7 +579,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// PWM // PWM
case 0x52: { case 0x52: {
tStatus_Pwm *pwm = (tStatus_Pwm *) &env->data.data[4]; tStatus_Pwm *pwm = (tStatus_Pwm *) &env->data->data[4];
if ((pwm->Pwm_Front > 1000) || (pwm->Pwm_Rear > 1000)) { if ((pwm->Pwm_Front > 1000) || (pwm->Pwm_Rear > 1000)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -588,7 +591,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// eComp // eComp
case 0x53: { case 0x53: {
tStatus_eComp *eComp = (tStatus_eComp *) &env->data.data[4]; tStatus_eComp *eComp = (tStatus_eComp *) &env->data->data[4];
if ((eComp->eComp_Statue_Request > 1) || (eComp->LowTempValve > 1)) { if ((eComp->eComp_Statue_Request > 1) || (eComp->LowTempValve > 1)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -600,7 +603,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// External // External
case 0x54: { case 0x54: {
tStatus_External *external = (tStatus_External *) &env->data.data[4]; tStatus_External *external = (tStatus_External *) &env->data->data[4];
if (external->CoolingFan > 1000) { if (external->CoolingFan > 1000) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -612,7 +615,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// EMS // EMS
case 0x55: { case 0x55: {
tStatus_EMS *ems = (tStatus_EMS *) &env->data.data[4]; tStatus_EMS *ems = (tStatus_EMS *) &env->data->data[4];
if (ems->EMS_Chiller_Req > 1) { if (ems->EMS_Chiller_Req > 1) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -624,7 +627,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// Ionizer_Aroma // Ionizer_Aroma
case 0x56: { case 0x56: {
tStatus_Ionizer_Aroma *ionizer_Aroma = (tStatus_Ionizer_Aroma *) &env->data.data[4]; tStatus_Ionizer_Aroma *ionizer_Aroma = (tStatus_Ionizer_Aroma *) &env->data->data[4];
if ((ionizer_Aroma->Ionizer > 1) || (ionizer_Aroma->AromatizationIntensivity > 3)) { if ((ionizer_Aroma->Ionizer > 1) || (ionizer_Aroma->AromatizationIntensivity > 3)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_requestOutOfRange); UDS_error_requestOutOfRange);
@ -636,7 +639,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// Duct Select // Duct Select
case 0x79: { case 0x79: {
tStatus_Duct_Select *duct_Select = (tStatus_Duct_Select *) &env->data.data[4]; tStatus_Duct_Select *duct_Select = (tStatus_Duct_Select *) &env->data->data[4];
if ((duct_Select->Duct_FL > 1) || (duct_Select->Duct_FR > 1) || if ((duct_Select->Duct_FL > 1) || (duct_Select->Duct_FR > 1) ||
(duct_Select->Duct_RL > 1) || (duct_Select->Duct_RR > 1)) { (duct_Select->Duct_RL > 1) || (duct_Select->Duct_RR > 1)) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
@ -650,7 +653,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
} }
memcpy(uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data, &env->data.data[4], size); memcpy(uds_IoDataByIdentifier_2F_com_CF[dataIdentifier_lo].data, &env->data->data[4], size);
return size + 4; return size + 4;
} }
@ -676,7 +679,7 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
uint16_t size = uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].size; uint16_t size = uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].size;
if (env->data.len != size + 4) { if (env->data->len != size + 4) {
return setResponseError(env, UDS_InputOutputControlByIdentifier, return setResponseError(env, UDS_InputOutputControlByIdentifier,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -684,8 +687,8 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
env->dataResponse[0] = UDS_InputOutputControlByIdentifier | 0b1000000; env->dataResponse[0] = UDS_InputOutputControlByIdentifier | 0b1000000;
env->dataResponse[1] = dataIdentifier_hi; env->dataResponse[1] = dataIdentifier_hi;
env->dataResponse[2] = dataIdentifier_lo; env->dataResponse[2] = dataIdentifier_lo;
env->dataResponse[3] = env->data.data[3]; env->dataResponse[3] = env->data->data[3];
//memcpy(uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].data, &env->data.data[3], size); //memcpy(uds_IoDataByIdentifier_2F_com_F1[dataIdentifier_lo].data, &env->data->data[3], size);
return 4; return 4;
} }
@ -704,9 +707,9 @@ static uint16_t InputOutputControlByIdentifier_2F(tCanUds *env) {
// начало --------------------------- Перезагрузка --------------------------------------------------------- // начало --------------------------- Перезагрузка ---------------------------------------------------------
static uint16_t ECUReset_11(tCanUds *env) { static uint16_t ECUReset_11(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 2) { if (env->data->len < 2) {
return setResponseError(env, UDS_ECUResetService, return setResponseError(env, UDS_ECUResetService,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -723,7 +726,7 @@ static uint16_t ECUReset_11(tCanUds *env) {
} }
env->dataResponse[0] = UDS_ECUResetService | 0b1000000;; env->dataResponse[0] = UDS_ECUResetService | 0b1000000;;
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
return 2; return 2;
} }
@ -738,7 +741,7 @@ static uint16_t ECUReset_11(tCanUds *env) {
static uint16_t UDS_ClearDiagnosticInformation_14(tCanUds *env) { static uint16_t UDS_ClearDiagnosticInformation_14(tCanUds *env) {
if (env->data.len < 4) { if (env->data->len < 4) {
return setResponseError(env, UDS_ClearDiagnosticInformation, return setResponseError(env, UDS_ClearDiagnosticInformation,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -763,9 +766,9 @@ static uint16_t UDS_ClearDiagnosticInformation_14(tCanUds *env) {
static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) { static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 3) { if (env->data->len < 3) {
return setResponseError(env, UDS_ReadDTCInformation, UDS_error_incorrectMessageLengthOrInvalidFormat); return setResponseError(env, UDS_ReadDTCInformation, UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -784,7 +787,7 @@ static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
if (com->sub_function == UDS_dtc_reportNumberOfDTCByStatusMask) { if (com->sub_function == UDS_dtc_reportNumberOfDTCByStatusMask) {
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
// доступные биты статусов // доступные биты статусов
env->dataResponse[2] = 0xFF; env->dataResponse[2] = 0xFF;
@ -793,7 +796,7 @@ static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
// старший байт количества DTC // старший байт количества DTC
env->dataResponse[4] = 0; env->dataResponse[4] = 0;
tDiagnosticDTC diagnosticDTC = {env->data.data[2], NULL}; tDiagnosticDTC diagnosticDTC = {env->data->data[2], NULL};
// младший байт количества DTC // младший байт количества DTC
env->dataResponse[5] = SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ReadDTCInformation_19_1, env->dataResponse[5] = SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ReadDTCInformation_19_1,
&diagnosticDTC); &diagnosticDTC);
@ -803,14 +806,14 @@ static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
if (com->sub_function == UDS_dtc_reportDTCByStatusMask) { if (com->sub_function == UDS_dtc_reportDTCByStatusMask) {
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
// доступные биты статусов // доступные биты статусов
env->dataResponse[2] = 0xFF; env->dataResponse[2] = 0xFF;
response_size = 3; response_size = 3;
tDiagnosticDTC diagnosticDTC = {env->data.data[2], &env->dataResponse[response_size]}; tDiagnosticDTC diagnosticDTC = {env->data->data[2], &env->dataResponse[response_size]};
response_size += SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ReadDTCInformation_19_2, &diagnosticDTC); response_size += SetGetDiagnosticData(env->Diagnostic, DIAGNOSTIC_UDS_ReadDTCInformation_19_2, &diagnosticDTC);
} }
@ -826,9 +829,9 @@ static uint16_t UDS_ReadDTCInformation_19(tCanUds *env) {
static uint16_t CommunicationControl_28(tCanUds *env) { static uint16_t CommunicationControl_28(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 3) { if (env->data->len < 3) {
return setResponseError(env, UDS_Communication_Control, return setResponseError(env, UDS_Communication_Control,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -852,7 +855,7 @@ static uint16_t CommunicationControl_28(tCanUds *env) {
} }
env->dataResponse[0] = UDS_Communication_Control | 0b1000000; env->dataResponse[0] = UDS_Communication_Control | 0b1000000;
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
return 2; return 2;
} }
@ -868,9 +871,9 @@ static uint16_t CommunicationControl_28(tCanUds *env) {
static uint16_t ControlDTCSetting_85(tCanUds *env) { static uint16_t ControlDTCSetting_85(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 2) { if (env->data->len < 2) {
return setResponseError(env, UDS_ControlDTCSetting, return setResponseError(env, UDS_ControlDTCSetting,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -892,7 +895,7 @@ static uint16_t ControlDTCSetting_85(tCanUds *env) {
} }
env->dataResponse[0] = UDS_ControlDTCSetting | 0b1000000; env->dataResponse[0] = UDS_ControlDTCSetting | 0b1000000;
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
return 2; return 2;
} }
@ -964,7 +967,6 @@ static uint16_t vUDS_routine_Erase_Memory(tCanUds *env, eUdsRoutineControlType u
bool result = env->clear_flash_func(0x01100000, 512 * 1024); bool result = env->clear_flash_func(0x01100000, 512 * 1024);
// bool result = FLASHDRIVER_FlashEraseBlock(FLASH_BLOCK_SELECT1); // bool result = FLASHDRIVER_FlashEraseBlock(FLASH_BLOCK_SELECT1);
if (result) { if (result) {
@ -1017,16 +1019,16 @@ static uint16_t vUDS_routine_eComp_Initialize(tCanUds *env, eUdsRoutineControlTy
static uint16_t Routine_Control_31(tCanUds *env) { static uint16_t Routine_Control_31(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 4) { if (env->data->len < 4) {
return setResponseError(env, UDS_Communication_Control, return setResponseError(env, UDS_Communication_Control,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
eUdsRoutineControlType udsRoutineControlType = env->data.data[1]; eUdsRoutineControlType udsRoutineControlType = env->data->data[1];
uint8_t routineIdentifier_hi = env->data.data[2]; uint8_t routineIdentifier_hi = env->data->data[2];
uint8_t routineIdentifier_lo = env->data.data[3]; uint8_t routineIdentifier_lo = env->data->data[3];
uint16_t routineIdentifier = (routineIdentifier_hi << 8) | routineIdentifier_lo; uint16_t routineIdentifier = (routineIdentifier_hi << 8) | routineIdentifier_lo;
if ((udsRoutineControlType != UDS_routine_StartRoutine) && (udsRoutineControlType != UDS_routine_StopRoutine) && if ((udsRoutineControlType != UDS_routine_StartRoutine) && (udsRoutineControlType != UDS_routine_StopRoutine) &&
@ -1035,7 +1037,7 @@ static uint16_t Routine_Control_31(tCanUds *env) {
} }
env->dataResponse[0] = UDS_RoutineControl | 0b1000000; env->dataResponse[0] = UDS_RoutineControl | 0b1000000;
env->dataResponse[1] = env->data.data[1]; // eUdsRoutineControlType env->dataResponse[1] = env->data->data[1]; // eUdsRoutineControlType
env->dataResponse[2] = routineIdentifier_hi; env->dataResponse[2] = routineIdentifier_hi;
env->dataResponse[3] = routineIdentifier_lo; env->dataResponse[3] = routineIdentifier_lo;
@ -1133,9 +1135,9 @@ static uint16_t Routine_Control_31(tCanUds *env) {
static uint16_t SecurityAccess_27(tCanUds *env) { static uint16_t SecurityAccess_27(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data.data; tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data.len < 2) { if (env->data->len < 2) {
return setResponseError(env, UDS_SecurityAccess, return setResponseError(env, UDS_SecurityAccess,
UDS_error_incorrectMessageLengthOrInvalidFormat); UDS_error_incorrectMessageLengthOrInvalidFormat);
} }
@ -1160,7 +1162,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
env->SA.requestSequenceRequestSeed = true; env->SA.requestSequenceRequestSeed = true;
env->dataResponse[0] = UDS_SecurityAccess | 0b1000000; env->dataResponse[0] = UDS_SecurityAccess | 0b1000000;
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
// Доступ уже получен // Доступ уже получен
if (env->SA.stateSecurityAccess) { if (env->SA.stateSecurityAccess) {
@ -1186,7 +1188,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
if (com->sub_function == UDS_sub_sendKey) { if (com->sub_function == UDS_sub_sendKey) {
if (env->data.len < 6) { if (env->data->len < 6) {
return setResponseError(env, UDS_SecurityAccess, UDS_error_requestOutOfRange); return setResponseError(env, UDS_SecurityAccess, UDS_error_requestOutOfRange);
} }
@ -1208,7 +1210,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
} }
uint32_t securitySeedFromServer = uint32_t securitySeedFromServer =
(env->data.data[2] << 24) | (env->data.data[3] << 16) | (env->data.data[4] << 8) | env->data.data[5]; (env->data->data[2] << 24) | (env->data->data[3] << 16) | (env->data->data[4] << 8) | env->data->data[5];
uint32_t securitySeedMy = generate_key(env->randomSecuritySeed); uint32_t securitySeedMy = generate_key(env->randomSecuritySeed);
@ -1220,7 +1222,7 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
env->SA.stateSecurityAccess = true; env->SA.stateSecurityAccess = true;
env->dataResponse[0] = UDS_SecurityAccess | 0b1000000; env->dataResponse[0] = UDS_SecurityAccess | 0b1000000;
env->dataResponse[1] = env->data.data[1] & 0b01111111; // sub-function env->dataResponse[1] = env->data->data[1] & 0b01111111; // sub-function
return 2; return 2;
} }
@ -1231,6 +1233,101 @@ static uint16_t SecurityAccess_27(tCanUds *env) {
// конец --------------------------- Security Access ------------------------------------------------------------- // конец --------------------------- Security Access -------------------------------------------------------------
// конец --------------------------- Security Access ------------------------------------------------------------- // конец --------------------------- Security Access -------------------------------------------------------------
// начало --------------------------- RequestDownload ---------------------------------------------------------
// начало --------------------------- RequestDownload ---------------------------------------------------------
// начало --------------------------- RequestDownload ---------------------------------------------------------
static uint16_t RequestDownload_34(tCanUds *env) {
tRequestDownload_Request *com = (tRequestDownload_Request *) env->data->data;
if (env->data->len < 11) {
return setResponseError(env, UDS_RequestDownload, UDS_error_incorrectMessageLengthOrInvalidFormat);
}
if (com->dataFormatIdentifier != 0) {
return setResponseError(env, UDS_RequestDownload, UDS_error_requestOutOfRange);
}
if (com->memoryAddress != 0x01100000) {
return setResponseError(env, UDS_RequestDownload, UDS_error_requestOutOfRange);
}
if (com->memorySize != 0x80000) {
return setResponseError(env, UDS_RequestDownload, UDS_error_requestOutOfRange);
}
tRequestDownload_Response *requestDownload_Response = (tRequestDownload_Response *) env->dataResponse;
requestDownload_Response->ServiceId = UDS_RequestDownload | 0b1000000;
requestDownload_Response->lengthFormatIdentifier = 0x20; // 2 байта - длина поля maxNumberOfBlockLength
uint8_t countBlock = 1;
requestDownload_Response->maxNumberOfBlockLength = countBlock * 128 + 2;
env->AdrFlash = 0x1100000;
env->SizeWriteFlash = 0;
return 4;
}
// конец --------------------------- RequestDownload ---------------------------------------------------------
// конец --------------------------- RequestDownload ---------------------------------------------------------
// конец --------------------------- RequestDownload ---------------------------------------------------------
// начало --------------------------- TransferData ---------------------------------------------------------
// начало --------------------------- TransferData ---------------------------------------------------------
// начало --------------------------- TransferData ---------------------------------------------------------
static uint16_t TransferData_36(tCanUds *env) {
tTransferData_Request *com = (tTransferData_Request *) env->data->data;
if (env->data->len <= 2) {
return setResponseError(env, UDS_TransferData, UDS_error_incorrectMessageLengthOrInvalidFormat);
}
bool result = env->write_flash_func(env->AdrFlash, &env->data->data[2], env->data->len - 2);
if (result == false) {
return setResponseError(env, UDS_TransferData, UDS_error_generalProgrammingFailure);
}
env->AdrFlash += env->data->len - 2;
env->SizeWriteFlash += env->data->len - 2;
LoggerFormatInfo(LOGGER, LOG_SIGN, "Size Write Flash = %d", env->SizeWriteFlash)
tTransferData_Response *transferData_Response = (tTransferData_Response *) env->dataResponse;
transferData_Response->ServiceId = UDS_TransferData | 0b1000000;
transferData_Response->blockSequenceCounter = com->blockSequenceCounter;
return 2;
}
// конец --------------------------- TransferData ---------------------------------------------------------
// конец --------------------------- TransferData ---------------------------------------------------------
// конец --------------------------- TransferData ---------------------------------------------------------
// начало --------------------------- RequestTransferExit ---------------------------------------------------------
// начало --------------------------- RequestTransferExit ---------------------------------------------------------
// начало --------------------------- RequestTransferExit ---------------------------------------------------------
static uint16_t RequestTransferExit_37(tCanUds *env) {
tUdsServiceCommand *com = (tUdsServiceCommand *) env->data->data;
if (env->data->len < 2) {
return setResponseError(env, UDS_RequestTransferExit, UDS_error_incorrectMessageLengthOrInvalidFormat);
}
return 2;
}
// конец --------------------------- RequestTransferExit ---------------------------------------------------------
// конец --------------------------- RequestTransferExit ---------------------------------------------------------
// конец --------------------------- RequestTransferExit ---------------------------------------------------------
const eUds_com uds_com[256] = { const eUds_com uds_com[256] = {
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
@ -1284,10 +1381,10 @@ const eUds_com uds_com[256] = {
{Routine_Control_31, "Routine_Control_31"}, {Routine_Control_31, "Routine_Control_31"},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
{RequestDownload_34, "RequestDownload_34"},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {TransferData_36, "TransferData_36"},
{NULL, ""}, {RequestTransferExit_37, "RequestTransferExit_37"},
{NULL, ""},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
{NULL, ""}, {NULL, ""},
@ -1491,6 +1588,53 @@ const eUds_com uds_com[256] = {
}; };
void ReceivedTP_func(void *arg, tCanTP_data *data) {
tCanUds *env = arg;
env->data = data;
// Контроль TesterPresent
if ((env->currentSessionTesterPresentTimeout > 0) &&
(env->currentSessionTesterPresentTimeout < SystemGetMs())) {
env->currentSessionTesterPresentTimeout = 0;
#if (LOG_UDS == 1)
LoggerFormatInfo(LOGGER, LOG_SIGN, "Resetting the session to default: %d", UDS_session_defaultSession)
#endif
setDefaultSecurityAccess(env);
set_CCU_Mute(env->canSpamTransmitter, false);
setNoBitsDTC(env->Diagnostic, false);
env->currentSession = UDS_session_defaultSession;
statusData.Status_Active_Diagnostic_Session.Active_Diagnostic_Session = env->currentSession;
}
uint8_t com = env->data->data[0];
if (uds_com[com].func != NULL) {
#if (LOG_UDS == 1)
sendLogCanUdsHex(env, env->data->data, env->data->len);
LoggerFormatInfo(LOGGER, LOG_SIGN, "> %s [%d] %s", uds_com[com].desc, env->data->len, env->hexString)
#endif
uint8_t response_size = uds_com[com].func(env);
if (response_size) {
#if (LOG_UDS == 1)
sendLogCanUdsHex(env, env->dataResponse, response_size);
LoggerFormatInfo(LOGGER, LOG_SIGN, "< %s [%d] %s", uds_com[com].desc, response_size, env->hexString)
#endif
CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, env->dataResponse,
response_size, PROTOCOL_CAN_ADR_UDS, WAIT_FRAME_WRITE);
}
} else {
asm("nop");
}
}
/*
void CanUds(tCanUds *env) { void CanUds(tCanUds *env) {
for (;;) { for (;;) {
@ -1514,13 +1658,13 @@ void CanUds(tCanUds *env) {
if (status == osOK) { if (status == osOK) {
uint8_t com = env->data.data[0]; uint8_t com = env->data->data[0];
if (uds_com[com].func != NULL) { if (uds_com[com].func != NULL) {
#if (LOG_UDS == 1) #if (LOG_UDS == 1)
sendLogCanUdsHex(env, env->data.data, env->data.len); sendLogCanUdsHex(env, env->data->data, env->data->len);
LoggerFormatInfo(LOGGER, LOG_SIGN, "> %s [%d] %s", uds_com[com].desc, env->data.len, env->hexString) LoggerFormatInfo(LOGGER, LOG_SIGN, "> %s [%d] %s", uds_com[com].desc, env->data->len, env->hexString)
#endif #endif
uint8_t response_size = uds_com[com].func(env); uint8_t response_size = uds_com[com].func(env);
@ -1544,10 +1688,10 @@ void CanUds(tCanUds *env) {
} }
} }
*/
void CanSerialPortCanUds_Start(tCanUds *env) { void CanSerialPortCanUds_Start(tCanUds *env) {
ThreadBlock_Start(env->T_can_Uds, env, CanUds); // ThreadBlock_Start(env->T_can_Uds, env, CanUds);
CanSerialPortFrameTp_Start(&env->canSerialPortFrameTp); CanSerialPortFrameTp_Start(&env->canSerialPortFrameTp);
} }
@ -1571,7 +1715,7 @@ void CanUds_Init(
env->canSpamTransmitter = canSpamTransmitter; env->canSpamTransmitter = canSpamTransmitter;
env->clear_flash_func = clear_flash_func; env->clear_flash_func = clear_flash_func;
env->write_flash_func = write_flash_func; env->write_flash_func = write_flash_func;
env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL); // env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL);
setDefaultStatus(); setDefaultStatus();
@ -1625,5 +1769,5 @@ void CanUds_Init(
env->currentSession = UDS_session_defaultSession; env->currentSession = UDS_session_defaultSession;
statusData.Status_Active_Diagnostic_Session.Active_Diagnostic_Session = UDS_session_defaultSession; statusData.Status_Active_Diagnostic_Session.Active_Diagnostic_Session = UDS_session_defaultSession;
InitThreadBlock(env->T_can_Uds, "CanUds", osPriorityNormal); // InitThreadBlock(env->T_can_Uds, "CanUds", osPriorityNormal);
}; };

View File

@ -11,9 +11,9 @@
#include "CanSpamTransmitter.h" #include "CanSpamTransmitter.h"
#include "AdcTasks.h" #include "AdcTasks.h"
#define LOG_UDS 1 #define LOG_UDS 0
#define CAN_US_QUEUE_SIZE 3 //#define CAN_US_QUEUE_SIZE 1
#define MAX_ATTEMPTS_DEFAULT 3 #define MAX_ATTEMPTS_DEFAULT 3
#define BLOCK_TIME_DEFAULT 60000 #define BLOCK_TIME_DEFAULT 60000
@ -47,7 +47,11 @@ typedef enum {
UDS_InputOutputControlByIdentifier = 0x2F, UDS_InputOutputControlByIdentifier = 0x2F,
UDS_SecurityAccess = 0x27, UDS_SecurityAccess = 0x27,
UDS_Communication_Control = 0x28, UDS_Communication_Control = 0x28,
UDS_ControlDTCSetting = 0x85 UDS_ControlDTCSetting = 0x85,
UDS_RequestDownload = 0x34,
UDS_TransferData = 0x36,
UDS_RequestTransferExit = 0x37
} eUdsServices; } eUdsServices;
typedef enum { typedef enum {
@ -60,7 +64,8 @@ typedef enum {
UDS_error_conditionsNotCorrect = 0x22, UDS_error_conditionsNotCorrect = 0x22,
UDS_error_requestSequenceError = 0x24, UDS_error_requestSequenceError = 0x24,
UDS_error_exceededNumberOfAttempts = 0x36, UDS_error_exceededNumberOfAttempts = 0x36,
UDS_error_requiredTimeDelayNotExpired = 0x37 UDS_error_requiredTimeDelayNotExpired = 0x37,
UDS_error_generalProgrammingFailure = 0x72
} eUdsResponseError; } eUdsResponseError;
@ -144,13 +149,13 @@ typedef struct {
tSerialPortFrameIO *CanIO; tSerialPortFrameIO *CanIO;
tDeviceStorage *deviceStorage; tDeviceStorage *deviceStorage;
tDiagnostic *Diagnostic; tDiagnostic *Diagnostic;
tCanTP_Ext_data canTP_Ext_data; tCanTP_data canTP_Ext_data;
osMessageQueueId_t queue; // osMessageQueueId_t queue;
tAdcTask *adcTask0; tAdcTask *adcTask0;
tCanTP_data data; tCanTP_data *data;
uint8_t dataResponse[1024]; uint8_t dataResponse[1024];
uint8_t filterIdCount; uint8_t filterIdCount;
@ -177,7 +182,11 @@ typedef struct {
uds_clear_flash_func *clear_flash_func; uds_clear_flash_func *clear_flash_func;
uds_write_flash_func *write_flash_func; uds_write_flash_func *write_flash_func;
tStaticThreadBlock(384) T_can_Uds; uint32_t AdrFlash;
uint32_t SizeWriteFlash;
uint8_t blockSequenceCounter;
// tStaticThreadBlock(384) T_can_Uds;
} tCanUds; } tCanUds;
typedef uint16_t (*uds_func_ptr)(tCanUds *env); typedef uint16_t (*uds_func_ptr)(tCanUds *env);

38
DownloadFile.h Normal file
View File

@ -0,0 +1,38 @@
//
// Created by cfif on 17.04.2026.
//
#ifndef HVAC_M7_DOWNLOADFILE_H
#define HVAC_M7_DOWNLOADFILE_H
#include "stdint.h"
#pragma scalar_storage_order big-endian
typedef struct __attribute__ ((packed)) {
uint8_t ServiceId;
uint8_t dataFormatIdentifier;
uint8_t addressAndLengthFormatIdentifier;
uint32_t memoryAddress;
uint32_t memorySize;
} tRequestDownload_Request;
typedef struct __attribute__ ((packed)) {
uint8_t ServiceId;
uint8_t lengthFormatIdentifier;
uint16_t maxNumberOfBlockLength;
} tRequestDownload_Response;
typedef struct __attribute__ ((packed)) {
uint8_t ServiceId;
uint8_t blockSequenceCounter;
} tTransferData_Request;
typedef struct __attribute__ ((packed)) {
uint8_t ServiceId;
uint8_t blockSequenceCounter;
} tTransferData_Response;
#pragma scalar_storage_order little-endian
#endif //HVAC_M7_DOWNLOADFILE_H