// // Created by cfif on 15.10.2024. // #include "CanMain.h" #include "EgtsOutputCommands.h" #include "SystemDelayInterface.h" #include "math.h" #include "Rtc.h" #include "DiagnosticSessionControl_10.h" #include "EgtsEbu.h" #include "ReadDataByIdentifier_22i.h" #include "ClearDiagnosticInformation_14.h" #define LOG_SIGN "UDS_ADD" #define LOGGER &env->slog->logger #define ADD_TO_DATA_CHAR_SHORT(DATA) *(uint8_t *) (out + offset) = DATA; *(uint8_t *) (out + offset + 1) = 0; offset+=2; #define ADD_TO_DATA_SHORT(DATA) *(uint8_t *) (out + offset) = (uint8_t)DATA; *(uint8_t *) (out + offset + 1) = (uint8_t)(DATA >> 8); offset+=2; #define ADD_TO_DATA_BYTE(DATA) *(uint8_t *) (out + offset) = (uint8_t)DATA; offset+=1; #define ADD_TO_DATA(DATA, LEN) memcpy(out + offset, (uint8_t * ) & DATA, LEN); offset+=LEN; extern const tEgtsEbuName egtsEbuName[EBU_COUNT_TABLE_ITEMS]; void calc_driver_scoring(tCanMainAdditional *env, float new_speed) { if (!env->gnss_config.acc_calc_time) return; if ((env->EngineSpeed > 100) && (new_speed >= (float) env->gnss_config.gnss_course_speed) && (env->calc_scoring.old_speed >= (float) env->gnss_config.gnss_course_speed)) { float acc_sum = 0; float coef_acc = 1.0f; if (env->gnss_config.reference_speed && new_speed > ((float) env->gnss_config.reference_speed)) coef_acc = (float) sqrt((double) new_speed / ((double) env->gnss_config.reference_speed)); env->calc_scoring.acc_last[env->calc_scoring.index] = ((new_speed - env->calc_scoring.old_speed) * coef_acc); for (uint32_t i = 0; i < env->gnss_config.acc_calc_time; i++) { acc_sum += env->calc_scoring.acc_last[i]; } if ((float) env->gnss_config.diff_speed_up > 0.0f && acc_sum >= (float) env->gnss_config.diff_speed_up) { env->state_get.trip_acceleration++; env->bc_get.total_acceleration++; env->bc_get.acceleration++; for (int i = 0; i < NUM_ACC_COUNT_MAX; i++) { env->calc_scoring.acc_last[i] = 0.0f; } } else if ((float) env->gnss_config.diff_speed_down > 0.0f && acc_sum <= ((-1.0f) * (float) env->gnss_config.diff_speed_down)) { env->state_get.trip_braking++; env->bc_get.total_braking++; env->bc_get.braking++; for (int i = 0; i < NUM_ACC_COUNT_MAX; i++) { env->calc_scoring.acc_last[i] = 0.0f; } } if ((++env->calc_scoring.index) > (env->gnss_config.acc_calc_time - 1)) env->calc_scoring.index = 0; env->calc_scoring.data_erase = false; } else if (!env->calc_scoring.data_erase) { for (int i = 0; i < NUM_ACC_COUNT_MAX; i++) { env->calc_scoring.acc_last[i] = 0.0f; } env->calc_scoring.index = 0; env->calc_scoring.data_erase = true; } env->calc_scoring.old_speed = new_speed; } // fuel_lvl - current fuel level in 0.5L // raw_fuel - fuel level from CAN in 0.5L // ignition_on - ignition on or off (true/false) // esp_speed - speed from ABS/ESP in 0.01km/h // msg_cycle_time - message cycle time im milliseconds (for UAZ = 100) // fuel_tank_capacity - fuel tank capacity in milliliters (for UAZ = 60000) #define INIT_CALC_PERIOD (2000u) //fuel calculation period in ms uint32_t fuel_lvl_filtered(tCanMainAdditional *env, uint32_t fuel_lvl, uint32_t raw_fuel, bool ignition_on, uint32_t esp_speed, uint32_t msg_cycle_time, uint32_t fuel_tank_capacity) { uint32_t fuel_calc_period = 100; //fuel calculation period in ms if (!ignition_on) { env->calc_fuel_lvl.ign_on = false; env->calc_fuel_lvl.skip_fuel_frames = 0; env->calc_fuel_lvl.pre_filtered_fuel = 0; env->calc_fuel_lvl.mem_fuel_diff = 0; return fuel_lvl; } env->calc_fuel_lvl.pre_filtered_fuel += raw_fuel; if (!env->calc_fuel_lvl.ign_on && (++env->calc_fuel_lvl.skip_fuel_frames >= (INIT_CALC_PERIOD / msg_cycle_time))) { fuel_lvl = env->calc_fuel_lvl.pre_filtered_fuel / env->calc_fuel_lvl.skip_fuel_frames; env->calc_fuel_lvl.skip_fuel_frames = 0; env->calc_fuel_lvl.pre_filtered_fuel = 0; env->calc_fuel_lvl.mem_fuel_diff = 0; env->calc_fuel_lvl.ign_on = ignition_on; return fuel_lvl; } if (msg_cycle_time > fuel_calc_period) { fuel_calc_period = msg_cycle_time; } if (env->calc_fuel_lvl.ign_on && (++env->calc_fuel_lvl.skip_fuel_frames >= (fuel_calc_period / msg_cycle_time))) { uint32_t calc_lvl; calc_lvl = env->calc_fuel_lvl.pre_filtered_fuel / env->calc_fuel_lvl.skip_fuel_frames; env->calc_fuel_lvl.skip_fuel_frames = 0; env->calc_fuel_lvl.pre_filtered_fuel = 0; if (fuel_lvl == 0) { fuel_lvl = calc_lvl; env->calc_fuel_lvl.mem_fuel_diff = 0; return fuel_lvl; } if (esp_speed == 0) { if ((calc_lvl + 9 * 2) <= fuel_lvl) { // env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) // / 6u); //Diff >= 9L E->F RunTime: 6s env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) / (10u * 60u)); //Diff >= 9L E->F RunTime: 10min } else if (calc_lvl < fuel_lvl) { env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) / (240u * 60u)); //E->F RunTime: 240min } else if (calc_lvl >= fuel_lvl + 9 * 2) { // env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / // 6u); //Diff >= 9L E->F RunTime: 6s env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / (2u * 60u)); //Diff >= 9L E->F RunTime: 2min } else if (calc_lvl > fuel_lvl) { env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / (240u * 60u)); // E->F RunTime: 240min } else { env->calc_fuel_lvl.mem_fuel_diff = 0; } } else { if (calc_lvl < fuel_lvl) { if (esp_speed <= (80u * 100u)) // Diff < 0, speed < 80km/h: E->F RunTime: 90min { env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) / (90u * 60u)); } else if (esp_speed < (240u * 100u)) // Diff < 0, 80km/h < speed < 240km/h: E->F RunTime: 432000s/speed { env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) / ((432000u * 100u) / esp_speed)); } else { env->calc_fuel_lvl.mem_fuel_diff -= ((fuel_calc_period * fuel_tank_capacity) / (30u * 60u)); } } else if (calc_lvl > (fuel_lvl + 3 * 2)) // 3L < Diff E->F RunTime: 300min { env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / (300u * 60u)); } else if (calc_lvl > (fuel_lvl + 1 * 2)) // 1L < Diff <= 3L E->F RunTime: 300min { env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / (600u * 60u)); } else if (calc_lvl > fuel_lvl) // 0L < Diff <= 1L E->F RunTime: 300min { env->calc_fuel_lvl.mem_fuel_diff += ((fuel_calc_period * fuel_tank_capacity) / (900u * 60u)); } else { env->calc_fuel_lvl.mem_fuel_diff = 0; } } if (env->calc_fuel_lvl.mem_fuel_diff >= 1000000) { fuel_lvl += 2; env->calc_fuel_lvl.mem_fuel_diff = 0; } else if (env->calc_fuel_lvl.mem_fuel_diff >= 500000) { fuel_lvl += 1; env->calc_fuel_lvl.mem_fuel_diff = 0; } else if (env->calc_fuel_lvl.mem_fuel_diff <= -1000000 && fuel_lvl > 1) { fuel_lvl -= 2; env->calc_fuel_lvl.mem_fuel_diff = 0; } else if (env->calc_fuel_lvl.mem_fuel_diff <= -500000) { fuel_lvl -= 1; env->calc_fuel_lvl.mem_fuel_diff = 0; } } return fuel_lvl; } bool ReceivedCan_Additional_func(void *arg, can_rx_message_type *canFrame) { tCanMainAdditional *env = arg; if (EXT_ENV_TELE.store.device->factoryMode) { if (canFrame->standard_id == 0x88) { if ((canFrame->dlc == 8) && memcmp(canFrame->data, canTestData, 8) == 0) { env->canMainMute->isPassedTestCan = true; } } } if (canFrame->standard_id == 0x66) { for (uint8_t i = 0; i < canFrame->dlc; ++i) { osStatus_t status = osMessageQueuePut(env->serialPortCanComInt->queue, &canFrame->data[i], 0x0, 0U); if (status != osOK) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь serialPortCanComInt") } } } env->isTimeSENSORS_DIG_BodyCanBusStatus = SystemGetMs(); // if (env->timeCan < SystemGetMs()) { // env->timeCan = SystemGetMs() + 1000; // LoggerStrFormatInfo(LOGGER, LOG_SIGN, "CAN > [%02x:%02x] %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", // (canFrame->standard_id >> 8) & 0xff, canFrame->standard_id & 0xff, // canFrame->data[0], canFrame->data[1], canFrame->data[2], canFrame->data[3], // canFrame->data[4], canFrame->data[5], canFrame->data[6], canFrame->data[7]) // } // Поднят пин зажигания bool isIgnition = GpioPinGet(EXT_ENV_TELE.ignition); // IPC_General if (canFrame->standard_id == 0x3E8) { // внешняя температура // Factor = 1.0 Offset = -40 Factor = 0.5 Offset = -40 if (isIgnition) { uint8_t CanRaw_ExternalTemperature = canFrame->data[1]; if (CanRaw_ExternalTemperature != 0xFF) { double ExternalTemperature = CanRaw_ExternalTemperature * 1.0 - 40; /* if (env->time3E8_1 < SystemGetMs()) { env->time3E8_1 = SystemGetMs() + 1000; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Внешняя температура = %d", (uint8_t) ExternalTemperature) } */ env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ExternalTemperature].value = (uint16_t) ( (ExternalTemperature + 40) / 0.5); } } // уровень топлива // Factor = 0.5 Offset = 0 Factor = 0.5 Offset = 0 uint8_t CanRaw_FuelLevel = canFrame->data[3]; if ((CanRaw_FuelLevel != 0) && (CanRaw_FuelLevel != 0xFF)) { double FuelLevel = CanRaw_FuelLevel * 0.5; /* if (env->time3E8_2 < SystemGetMs()) { env->time3E8_2 = SystemGetMs() + 1000; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Уровень топлива = %d", (uint8_t)FuelLevel) } */ // env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_FuelLevel].value = (uint8_t) (FuelLevel / // 0.5); env->fuel_lvlFiltered = fuel_lvl_filtered(env, env->fuel_lvlFiltered, CanRaw_FuelLevel, isIgnition, env->ABS_VehicleSpeed, 100, 60000); env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_FuelLevel].value = env->fuel_lvlFiltered; } } // ECM_Status if ((isIgnition) && (canFrame->standard_id == 0x560)) { uint32_t mil = canFrame->data[4] & 3; env->egtsTeledata->egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS3].state = mil; } // ECM_Dashboard if ((isIgnition) && (canFrame->standard_id == 0x380)) { uint32_t mil = (canFrame->data[2] >> 3) & 1; env->egtsTeledata->egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS2].state = mil; // температура двигателя // Factor = 0.75 Offset = -48 Factor = 0.5 Offset = -40 uint8_t CanRaw_EngineOXTemperature = canFrame->data[0]; double EngineOXTemperature = CanRaw_EngineOXTemperature * 0.75 - 48; if (EngineOXTemperature < -39.5) { env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOXTemperature].value = 0; } else { env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_EngineOXTemperature].value = (uint16_t) ( (EngineOXTemperature + 40) / 0.5); } uint16_t ECM_VolumetricFuelFlow = (canFrame->data[3] << 8) | canFrame->data[4]; //там данные идут в литрах в час, что бы получить литры в час по их матрице надо помножить на 0,002146, нам нужны микролитры в 100 миллисекунд, для этого мы ECM_VolumetricFuelFlow*0.002146 умножаем на 1000000(перевод литры в микролитры) и делим на 36000 (перевод часа в сотки миллисекунд) env->Counter_SENSORS_AN_TripMileage_MICRO_L += (uint32_t) (((float) ECM_VolumetricFuelFlow * 0.05961f) + 0.5f); // топливо делим на 100, env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TripSpentFuel].value = env->Counter_SENSORS_AN_TripMileage_MICRO_L / 100; /* if (env->time380_1 < SystemGetMs()) { env->time380_1 = SystemGetMs() + 1000; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Температура двигателя = %d", (uint8_t) EngineOXTemperature) } */ // обороты двигателя env->EngineSpeed = canFrame->data[1] * 40; /* if (env->time380_2 < SystemGetMs()) { env->time380_2 = SystemGetMs() + 1000; LoggerStrFormatInfo(LOGGER, LOG_SIGN, "Обороты двигателя = %d", env->EngineSpeed) } */ } // ABS_Speed if ((isIgnition) && (canFrame->standard_id == 0x27D)) { env->egtsTeledata->egtsSensorsDigArgs.sensorsDigState[SENSORS_DIG_ANS1].state = 1; env->ABS_VehicleSpeed = (canFrame->data[4] << 8) | canFrame->data[5]; if ((env->timeAbsSpeed) && (env->ABS_VehicleSpeed >= 10) && (SystemGetMs() > env->timeAbsSpeed) && ((SystemGetMs() - env->timeAbsSpeed) < 1000)) { env->Counter_SENSORS_AN_TripMileage_MM += (uint32_t) ( (((float) env->ABS_VehicleSpeed * 10.0f * (float) (SystemGetMs() - env->timeAbsSpeed)) / (3600.0f)) + 0.5f); } env->timeAbsSpeed = SystemGetMs(); // в итоге, пробег в миллиметрах мы приводим к стометровкам, т.е. делим на 100000 env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_TripMileage].value = env->Counter_SENSORS_AN_TripMileage_MM / 100000; if (env->timeAbsSpeedOnSecond < SystemGetMs()) { env->timeAbsSpeedOnSecond = SystemGetMs() + 1000; float realSpeed = (float) env->ABS_VehicleSpeed * 0.01f; calc_driver_scoring(env, realSpeed); env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_ANS5].value = (uint32_t) realSpeed; env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberAccelerations].value = env->state_get.trip_acceleration; env->egtsTeledata->egtsSensorsAnArgs.sensorsAnState[SENSORS_AN_NumberBraking].value = env->state_get.trip_braking; } } return false; } char *sendLogCanHex(tCanSerialPortFrameTp *env, uint8_t *data, size_t size); void ReceivedTP_Additional_func(void *arg, tCanTP_data *data) { // tCanMainAdditional *env = arg; // LoggerStrInfoStatic(LOGGER, LOG_SIGN, "Приняты данные: "); // sendLogCanHex(&env->canSerialPortFrameTp, data->data, data->len); // osStatus_t status = osMessageQueuePut(env->queue, data, 0, 0U); // if (status != osOK) { // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка добавления в очередь addCommandQueue") // } } void CanMainAdditional_Init( tCanMainAdditional *env, tSerialPortFrameIO *CanIO, tSerialPortCanComInt *serialPortCanComInt, tCanMainMute *canMainMute, SystemMutexCmsis txAccessQueue, tDeviceTestsTable *testsTable, tLoggerToSerialPort *slog, volatile tRawAccel *rawAccel, tEgtsTeledata *egtsTeledata, tEgtsEbuState *ebuState, SystemMutexCmsis accessEbu, tCanMain *canMain, void *envEgtsProcessing, bool *isEnableTelematicaSendPoints ) { env->CanIO = CanIO; env->serialPortCanComInt = serialPortCanComInt; env->txAccessQueue = txAccessQueue; env->slog = slog; env->rawAccel = rawAccel; env->testsTable = testsTable; env->egtsTeledata = egtsTeledata; env->canMainMute = canMainMute; env->canMain = canMain; env->ebuState = ebuState; env->accessEbu = accessEbu; env->envEgtsProcessing = envEgtsProcessing; env->isEnableTelematicaSendPoints = isEnableTelematicaSendPoints; // env->queue = osMessageQueueNew(CAN_US_QUEUE_SIZE, sizeof(tCanTP_data), NULL); env->egtsEbuUdsReady.step = STATUS_STEP_NONE; env->egtsEbuUdsReady.isUdsBufReady = false; env->egtsEbuUdsReady.ebuIndex = 0; env->EngineSpeed = 0; env->timeAbsSpeed = 0; env->timeAbsSpeedOnSecond = 0; env->Counter_SENSORS_AN_TripMileage_MM = 0; env->Counter_SENSORS_AN_TripMileage_MICRO_L = 0; // расход топлива env->calc_scoring.index = 0; env->calc_scoring.old_speed = 0; env->calc_scoring.data_erase = true; env->calc_fuel_lvl.skip_fuel_frames = 0; env->calc_fuel_lvl.pre_filtered_fuel = 0; env->calc_fuel_lvl.mem_fuel_diff = 0; env->calc_fuel_lvl.ign_on = false; env->fuel_lvlFiltered = 0; env->ABS_VehicleSpeed = 0; env->gnss_config.acc_calc_time = egtsProcessing.deviceTeledataStorageData->telematica.EGTS_DRV_SCORE_ACC_CALC_TIME; env->gnss_config.gnss_course_speed = egtsProcessing.deviceTeledataStorageData->telematica.EGTS_GNSS_COURSE_SPEED; env->gnss_config.reference_speed = egtsProcessing.deviceTeledataStorageData->telematica.EGTS_DRV_SCORE_RFR_SPEED; if (env->gnss_config.reference_speed == 0) env->gnss_config.reference_speed = 50; env->gnss_config.diff_speed_up = egtsProcessing.deviceTeledataStorageData->telematica.EGTS_DRV_SCORE_DIFF_SPD_UP; env->gnss_config.diff_speed_down = egtsProcessing.deviceTeledataStorageData->telematica.EGTS_DRV_SCORE_DIFF_SPD_DOWN; memset(&env->state_get, 0, sizeof(env->state_get)); memset(&env->bc_get, 0, sizeof(env->bc_get)); env->invalidKey = true; env->invalidKeyAttempts = 3; env->invalidKeyIsDelay = 0; env->isTimeSENSORS_DIG_BodyCanBusStatus = 0; env->filterIdCount = 0; CanSerialPortFrameTpInit( &env->canSerialPortFrameTp, 1, env->txAccessQueue, ReceivedCan_Additional_func, env, ReceivedTP_Additional_func, env, env->CanIO, (tCanTP_data *) &env->canTP_data, sizeof(env->canTP_data.data), slog, env->filterIdCount, env->filterReqId, env->filterRespId, env->filterDirReq ); InitThreadBlock(env->T_can_MainAdditional, "CanMainAdditional", osPriorityNormal); } eEgtsEbu getEbuStateClearDTC(tCanMainAdditional *env) { if (osMutexAcquire(env->accessEbu, 2000) == osOK) { for (uint16_t i = 1; i < env->ebuState->count; ++i) { if (env->ebuState->ebuItemState[i].clearDTC == true) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Зафиксирован запрос очистки ошибок блоков") osMutexRelease(env->accessEbu); return env->ebuState->ebuItemState[i].ebu; } } osMutexRelease(env->accessEbu); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа getEbuStateClearDTC") } return EBU_UNKNOWN; } eEgtsEbu getEbuState(tCanMainAdditional *env, uint32_t timestamp) { if (osMutexAcquire(env->accessEbu, 2000) == osOK) { for (uint16_t i = 1; i < env->ebuState->count; ++i) { uint32_t deltaTime; if (env->ebuState->ebuItemState[i].timestamp > timestamp) { deltaTime = env->ebuState->ebuItemState[i].timestamp - timestamp; } else { deltaTime = timestamp - env->ebuState->ebuItemState[i].timestamp; } if ((env->ebuState->ebuItemState[i].timestamp == 0) || (env->ebuState->ebuItemState[i].timestamp < timestamp) || (deltaTime > (86400 + 86400))) { LoggerInfoStatic(LOGGER, LOG_SIGN, "Зафиксирован запрос данных блоков") osMutexRelease(env->accessEbu); return env->ebuState->ebuItemState[i].ebu; } } osMutexRelease(env->accessEbu); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка доступа getEbuState") } return EBU_UNKNOWN; } uint8_t getEgtsNameEbuIndex(tCanMainAdditional *env, eEgtsEbu ebu, uint8_t indexStart) { for (uint8_t i = indexStart; i < EBU_COUNT_TABLE_ITEMS; ++i) { if (egtsEbuName[i].ebu == ebu) { return i; } } return 0; } void clearQueueAdditional(tCanMainAdditional *env) { uint32_t count = osMessageQueueGetCount(env->canMain->queueAdditional); if (count > 0) { osMessageQueueReset(env->canMain->queueAdditional); } } //#define DEBUG_LOG_CAN_ADDITIONAL 1 void CanMainTaskAdditional(tCanMainAdditional *env) { tCanTP_data data; time_t timestamp = 0; uint32_t timeTeleOff = 0; uint32_t timeDiagnostTwo = 0; bool isTimestamp = true; bool oneOn = true; bool oneOff = true; uint8_t *out = (uint8_t *) env->egtsEbuUdsReady.buf; uint16_t offset = 0; for (;;) { if (onOffTelematica(env->envEgtsProcessing, &oneOn, &oneOff, "Задача CAN (опрос блоков)")) continue; if (*env->isEnableTelematicaSendPoints == false) { if (timeTeleOff < SystemGetMs()) { timeTeleOff = SystemGetMs() + 10000; LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание разрешения телематики") } SystemDelayMs(1000); continue; } RtcGet(env->canMainMute->gsm->Rtc, ×tamp); if (timestamp < 1718359909) { // LoggerInfoStatic(LOGGER, LOG_SIGN, "Ожидание получения временной метки") clearQueueAdditional(env); SystemDelayMs(40); continue; } else { if (isTimestamp) { isTimestamp = false; LoggerInfoStatic(LOGGER, LOG_SIGN, "Временная метка получена") clearQueueAdditional(env); } } if ((env->canMain->isTimeTESTER_REQUEST + 5000) > SystemGetMs()) { if (env->egtsEbuUdsReady.isUdsBufReady == false) { env->egtsEbuUdsReady.ebuIndex = 0; } env->egtsEbuUdsReady.step = STATUS_STEP_NONE; clearQueueAdditional(env); if (timeDiagnostTwo < SystemGetMs()) { timeDiagnostTwo = SystemGetMs() + 10000; LoggerInfoStatic(LOGGER, LOG_SIGN, "Зафиксирован второй диагност") } SystemDelayMs(40); continue; } // Если UDS опросов нет и готовых данных для отправки нет if ((env->egtsEbuUdsReady.step == STATUS_STEP_NONE) && (env->egtsEbuUdsReady.isUdsBufReady == false)) { eEgtsEbu ebu = getEbuStateClearDTC(env); if (ebu != EBU_UNKNOWN) { uint8_t ebuIndex = 0; ebuIndex = getEgtsNameEbuIndex(env, ebu, 1); if (ebuIndex == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s не найден тип блока", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) setUpdateEbuClearDTC(&egtsProcessing, env->ebuState, ebu, false); env->egtsEbuUdsReady.ebuIndex = 0; } else { offset = 0; env->egtsEbuUdsReady.step = STATUS_STEP_DTC_CLEAR; env->egtsEbuUdsReady.attempts = 2; env->egtsEbuUdsReady.counterDID = 0; env->egtsEbuUdsReady.ebuIndex = ebuIndex; env->egtsEbuUdsReady.isUdsBufReady = false; env->egtsEbuUdsReady.bufLen = 0; } } else { ebu = getEbuState(env, timestamp); if (ebu != EBU_UNKNOWN) { uint8_t ebuIndex = 0; if ((env->egtsEbuUdsReady.ebuIndex + 1) < EBU_COUNT_TABLE_ITEMS) { ebuIndex = getEgtsNameEbuIndex(env, ebu, env->egtsEbuUdsReady.ebuIndex + 1); } if (ebuIndex == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s не найден тип блока", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) setUpdateEbu(&egtsProcessing, env->ebuState, ebu, timestamp + 86400); env->egtsEbuUdsReady.ebuIndex = 0; } else { offset = 0; env->egtsEbuUdsReady.step = STATUS_STEP_DIAGNOSTIC; env->egtsEbuUdsReady.attempts = 2; env->egtsEbuUdsReady.counterDID = 0; env->egtsEbuUdsReady.ebuIndex = ebuIndex; env->egtsEbuUdsReady.isUdsBufReady = false; env->egtsEbuUdsReady.bufLen = 0; } } else { SystemDelayMs(1000); continue; } } } //начало ------------------------------------Отправка UDS_ClearDiagnosticInformation------------------------------ if (env->egtsEbuUdsReady.step == STATUS_STEP_DTC_CLEAR) { if (env->egtsEbuUdsReady.attempts > 0) { --env->egtsEbuUdsReady.attempts; tClearDiagnosticInformationRequest clearDiagnosticInformationRequest; clearDiagnosticInformationRequest.ServiceId = UDS_ClearDiagnosticInformation; clearDiagnosticInformationRequest.groupOfDTCHighByte = 0xFF; clearDiagnosticInformationRequest.groupOfDTCMiddleByte = 0xFF; clearDiagnosticInformationRequest.groupOfDTCLowByte = 0xFF; CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, (uint8_t *) &clearDiagnosticInformationRequest, sizeof(tClearDiagnosticInformationRequest), egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_req, WAIT_FRAME_WRITE); } else { if (env->egtsEbuUdsReady.attempts == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s не найден", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s найден", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; } setUpdateEbuClearDTC(&egtsProcessing, env->ebuState, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebu, false); env->egtsEbuUdsReady.ebuIndex = 0; continue; } } //конец ------------------------------------Отправка UDS_ClearDiagnosticInformation------------------------------ //начало ------------------------------------Отправка UDS_DiagnosticSessionControl------------------------------ if (env->egtsEbuUdsReady.step == STATUS_STEP_DIAGNOSTIC) { if (env->egtsEbuUdsReady.attempts > 0) { --env->egtsEbuUdsReady.attempts; tDiagnosticSessionControlRequest diagnosticSessionControlRequest; diagnosticSessionControlRequest.ServiceId = UDS_DiagnosticSessionControl; diagnosticSessionControlRequest.diagnosticSessionType = 1; // Default session #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Отправка запроса открытия сессии", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) #endif CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, (uint8_t *) &diagnosticSessionControlRequest, sizeof(tDiagnosticSessionControlRequest), egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_req, WAIT_FRAME_WRITE); } else { if (env->egtsEbuUdsReady.attempts == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s не найден", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; continue; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s найден", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.attempts = 2; env->egtsEbuUdsReady.step = STATUS_STEP_READ_TEST_IDENTIFIER; } } } //конец ------------------------------------Отправка UDS_DiagnosticSessionControl------------------------------ //начало ------------------------------------Отправка UDS_ReadDataByIdentifier TEST-------------------------- if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_TEST_IDENTIFIER) { if (egtsEbuName[env->egtsEbuUdsReady.ebuIndex].test_did == 0) { env->egtsEbuUdsReady.step = STATUS_STEP_READ_DTC; } else { if (env->egtsEbuUdsReady.attempts > 0) { --env->egtsEbuUdsReady.attempts; tReadDataByIdentifierRequest readDataByIdentifierRequest; readDataByIdentifierRequest.ServiceId = UDS_ReadDataByIdentifier; readDataByIdentifierRequest.dataIdentifierByte1 = egtsEbuName[env->egtsEbuUdsReady.ebuIndex].test_did >> 8; readDataByIdentifierRequest.dataIdentifierByte2 = egtsEbuName[env->egtsEbuUdsReady.ebuIndex].test_did; #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Отправка запроса чтения ТЕСТОВОГО идентификатора: 0x%x", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].test_did) #endif CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, (uint8_t *) &readDataByIdentifierRequest, sizeof(tReadDataByIdentifierRequest), egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_req, WAIT_FRAME_WRITE); } else { if (env->egtsEbuUdsReady.attempts == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Тестовый идентификатор: 0x%x не получен", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].test_did) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Тестовый идентификатор получен", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.attempts = 2; env->egtsEbuUdsReady.step = STATUS_STEP_READ_DTC; } } } } //конец ------------------------------------Отправка UDS_ReadDataByIdentifier TEST----------------------------- //начало ------------------------------------Отправка UDS_ReadDTCInformation---------------------------------- if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_DTC) { if (env->egtsEbuUdsReady.attempts > 0) { --env->egtsEbuUdsReady.attempts; tReadDTCInformationRequest readDTCInformationRequest; readDTCInformationRequest.ServiceId = UDS_ReadDTCInformation; readDTCInformationRequest.reportDTCByStatusMask = 2; readDTCInformationRequest.DTCStatusMask = 0x0D; #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Отправка запроса состояния ошибок", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) #endif CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, (uint8_t *) &readDTCInformationRequest, sizeof(tReadDTCInformationRequest), egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_req, WAIT_FRAME_WRITE); } else { if (env->egtsEbuUdsReady.attempts == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Информация о состоянии ошибок не получена", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Получена информация о состоянии ошибок", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) } env->egtsEbuUdsReady.attempts = 2; env->egtsEbuUdsReady.step = STATUS_STEP_READ_IDENTIFIER; } } //конец ------------------------------------Отправка UDS_ReadDTCInformation---------------------------------- //начало ------------------------------------Отправка UDS_ReadDataByIdentifier---------------------------------- if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_IDENTIFIER) { if (env->egtsEbuUdsReady.attempts > 0) { if ((env->egtsEbuUdsReady.counterDID >= EBU_COUNT_DID_LIST_ITEMS) || (egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID] == 0)) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Все запросы идентификаторов отправлены", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; env->egtsEbuUdsReady.bufLen = offset; env->egtsEbuUdsReady.isUdsBufReady = true; } else { --env->egtsEbuUdsReady.attempts; tReadDataByIdentifierRequest readDataByIdentifierRequest; readDataByIdentifierRequest.ServiceId = UDS_ReadDataByIdentifier; readDataByIdentifierRequest.dataIdentifierByte1 = egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID] >> 8; readDataByIdentifierRequest.dataIdentifierByte2 = egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]; #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Отправка запроса чтения идентификатора: 0x%x", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]) #endif CanSerialPortFrameTpTransmit(&env->canSerialPortFrameTp, (uint8_t *) &readDataByIdentifierRequest, sizeof(tReadDataByIdentifierRequest), egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_req, WAIT_FRAME_WRITE); } } else { if (env->egtsEbuUdsReady.attempts == 0) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Идентификатор: 0x%x не получен", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]) ADD_TO_DATA_SHORT( egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]); ADD_TO_DATA_CHAR_SHORT(0x0000); } else { #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Идентификатор: 0x%x получен", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]) #endif } if ((env->egtsEbuUdsReady.counterDID >= EBU_COUNT_DID_LIST_ITEMS) || (egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID] == 0)) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Все запросы идентификаторов отправлены", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName) env->egtsEbuUdsReady.step = STATUS_STEP_NONE; env->egtsEbuUdsReady.bufLen = offset; env->egtsEbuUdsReady.isUdsBufReady = true; } else { env->egtsEbuUdsReady.attempts = 2; ++env->egtsEbuUdsReady.counterDID; continue; } } } //конец ------------------------------------Отправка UDS_ReadDataByIdentifier---------------------------------- #ifdef DEBUG_LOG_CAN_ADDITIONAL if (env->egtsEbuUdsReady.step != STATUS_STEP_NONE) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Этап: 0x%x, Попыток осталось: 0x%x", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, env->egtsEbuUdsReady.step, env->egtsEbuUdsReady.attempts) } #endif // SystemDelayMs(1000); for (uint8_t i = 0; i < 2; ++i) { osStatus_t status = osMessageQueueGet(env->canMain->queueAdditional, &data, 0, 1200); if (status == osOK) { if (env->egtsEbuUdsReady.step == STATUS_STEP_NONE) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Неверный номер этапа: 0x%x Нет запроса !!!!", env->egtsEbuUdsReady.step) break; } if (data.adrCan == egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_resp) { // начало --------------------------- Ошибка ---------------------------------------------------------- // начало --------------------------- Ошибка ---------------------------------------------------------- // начало --------------------------- Ошибка ---------------------------------------------------------- // Отрицательный ответ if (data.data[0] == 0x7F) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен негативный ответ от сервиса: 0x%x ,код ошибки: 0x%x", data.data[1], data.data[2]) break; } // конец ---------------------------- Ошибка ---------------------------------------------- // конец ---------------------------- Ошибка ---------------------------------------------- // конец ---------------------------- Ошибка ---------------------------------------------- // начало --------------------------- Запрос очистки ошибок ---------------------------------------------- // начало --------------------------- Запрос очистки ошибок --------------------------------------------- // начало --------------------------- Запрос очистки ошибок --------------------------------------------- // Положительный ответ if (data.data[0] == (UDS_ClearDiagnosticInformation | 0b1000000)) { if (env->egtsEbuUdsReady.step == STATUS_STEP_DTC_CLEAR) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен положительный ответ от сервиса: 0x%x", data.data[0] & (~(0b1000000))) env->egtsEbuUdsReady.attempts = -1; break; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Неверный номер этапа, текущий: 0x%x получен: 0x%x", env->egtsEbuUdsReady.step, STATUS_STEP_DTC_CLEAR) } } // конец ---------------------------- Запрос очистки ошибок ---------------------------------------------- // конец ---------------------------- Запрос очистки ошибок --------------------------------------------- // конец ---------------------------- Запрос очистки ошибок --------------------------------------------- // начало --------------------------- Запрос открытия сессии ---------------------------------------------- // начало --------------------------- Запрос открытия сессии --------------------------------------------- // начало --------------------------- Запрос открытия сессии --------------------------------------------- // Положительный ответ if (data.data[0] == (UDS_DiagnosticSessionControl | 0b1000000)) { if (env->egtsEbuUdsReady.step == STATUS_STEP_DIAGNOSTIC) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен положительный ответ от сервиса: 0x%x ,код сессии: 0x%x", data.data[0] & (~(0b1000000)), data.data[1]) env->egtsEbuUdsReady.attempts = -1; break; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Неверный номер этапа, текущий: 0x%x получен: 0x%x", env->egtsEbuUdsReady.step, STATUS_STEP_DIAGNOSTIC) } } // конец ---------------------------- Запрос открытия сессии ---------------------------------------------- // конец ---------------------------- Запрос открытия сессии --------------------------------------------- // конец ---------------------------- Запрос открытия сессии --------------------------------------------- // начало --------------------------- Запрос состояния ошибок ---------------------------------------------- // начало --------------------------- Запрос состояния ошибок --------------------------------------------- // начало --------------------------- Запрос состояния ошибок --------------------------------------------- // Положительный ответ if (data.data[0] == (UDS_ReadDTCInformation | 0b1000000)) { if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_DTC) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен положительный ответ от сервиса: 0x%x ,код маски: 0x%x, код доступной маски: 0x%x", data.data[0] & (~(0b1000000)), data.data[1], data.data[2]) ADD_TO_DATA_SHORT(0x1902) // ReadDTCInformation + reportDTCByStatusMask ADD_TO_DATA_SHORT(0x0004) // Размер общих данных вместе с ошибками ADD_TO_DATA_BYTE(0x00) // DTCStatusAvailabilityMask ADD_TO_DATA_BYTE(0x00) // Всегда 0 ADD_TO_DATA_BYTE(0x00) // Всегда 0 ADD_TO_DATA_BYTE(0xE0) // E0 — нет ошибок. 00 - ошибки if (data.len > 3) { //ADD_TO_DATA(data.data[3], data.len - 3) ADD_TO_DATA(env->canMain->canTP_Ext_data.data[3], data.len - 3) } uint8_t *DTCStatusAvailabilityMask = (uint8_t *) &out[4]; *DTCStatusAvailabilityMask = data.data[2]; // Если есть ошибки if (offset > 8) { uint16_t *len = (uint16_t *) &out[2]; uint8_t *err = (uint8_t *) &out[7]; *len = offset - 4; *err = 0; asm("nop"); } env->egtsEbuUdsReady.attempts = -1; break; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Неверный номер этапа, текущий: 0x%x получен: 0x%x", env->egtsEbuUdsReady.step, STATUS_STEP_DIAGNOSTIC) } } // конец ---------------------------- Запрос состояния ошибок ---------------------------------------------- // конец ---------------------------- Запрос состояния ошибок --------------------------------------------- // конец ---------------------------- Запрос состояния ошибок --------------------------------------------- // начало --------------------------- Запрос идентификаторов ---------------------------------------------- // начало --------------------------- Запрос идентификаторов --------------------------------------------- // начало --------------------------- Запрос идентификаторов --------------------------------------------- // Положительный ответ if (data.data[0] == (UDS_ReadDataByIdentifier | 0b1000000)) { #ifdef DEBUG_LOG_CAN_ADDITIONAL LoggerFormatInfo(LOGGER, LOG_SIGN, "Получен положительный ответ от сервиса: 0x%x ,код идентификатора: 0x%x", data.data[0] & (~(0b1000000)), (data.data[1] << 8) | data.data[2]) #endif if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_TEST_IDENTIFIER) { env->egtsEbuUdsReady.attempts = -1; break; } else { if (env->egtsEbuUdsReady.step == STATUS_STEP_READ_IDENTIFIER) { if (data.len > 3) { ADD_TO_DATA_SHORT( egtsEbuName[env->egtsEbuUdsReady.ebuIndex].did_list[env->egtsEbuUdsReady.counterDID]); ADD_TO_DATA_CHAR_SHORT(data.len - 3); ADD_TO_DATA(data.data[3], data.len - 3) } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Не верная длина данных: 0x%x", data.len) } env->egtsEbuUdsReady.attempts = -1; break; } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Неверный номер этапа, текущий: 0x%x получен: 0x%x или 0x%x", env->egtsEbuUdsReady.step, STATUS_STEP_DIAGNOSTIC, STATUS_STEP_READ_IDENTIFIER) } } } // конец ---------------------------- Запрос идентификаторов ---------------------------------------------- // конец ---------------------------- Запрос идентификаторов --------------------------------------------- // конец ---------------------------- Запрос идентификаторов --------------------------------------------- } else { LoggerFormatInfo(LOGGER, LOG_SIGN, "Ответ не от того устройства. Адрес ожидаемый: 0x%x ,адрес принятый: 0x%x", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ecu_resp, data.adrCan) break; } } else { if (env->egtsEbuUdsReady.step != STATUS_STEP_NONE) { LoggerFormatInfo(LOGGER, LOG_SIGN, "Блок: %s Таймаут получения ответа на шаге: 0x%x", egtsEbuName[env->egtsEbuUdsReady.ebuIndex].ebuName, env->egtsEbuUdsReady.step) break; } } } // for } } void CanMainAdditional_Start(tCanMainAdditional *env) { CanSerialPortFrameTp_Start(&env->canSerialPortFrameTp, 1); ThreadBlock_Start(env->T_can_MainAdditional, env, CanMainTaskAdditional); }