// // Created by cfif on 23.01.2026. // #include "DiagnosticTask.h" #include "CmsisRtosThreadUtils.h" #include "StatusData.h" #include "StatusError.h" void Diagnostic_Init(tDiagnostic *env, tLoggerInterface *logger) { env->logger = logger; env->queue = osMessageQueueNew(DIAGNOSTIC_QUEUE_SIZE, 1, NULL); env->access = osMutexNew(NULL); for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { // Тест DTC не был выполнен в текущем цикле работы dtc_state_error[i] = UDS_dtc_mask_testNotCompletedThisOperationCycle; } InitThreadAtrStatic(&env->thread.attr, "Diagnostic", env->thread.controlBlock, env->thread.stack, osPriorityNormal); } static uint32_t diagnostic_ClearDiagnosticInformation_14(tDiagnostic *env, void *extEnv) { for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { // Тест DTC не был выполнен в текущем цикле работы dtc_state_error[i] = UDS_dtc_mask_testNotCompletedThisOperationCycle; // Тест DTC не был выполнен с момента последней очистки dtc_state_error[i] |= UDS_dtc_mask_testNotCompletedSinceLastClear; } return 0; } static uint32_t diagnostic_UDS_ReadDTCInformation_19_1(tDiagnostic *env, void *extEnv) { tDiagnosticDTC *diagnosticDTC = (tDiagnosticDTC *) extEnv; uint32_t countDTC = 0; for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { if (dtc_state_error[i] & (~diagnosticDTC->mask)) { ++countDTC; } } return countDTC; } static uint32_t diagnostic_UDS_ReadDTCInformation_19_2(tDiagnostic *env, void *extEnv) { tDiagnosticDTC *diagnosticDTC = (tDiagnosticDTC *) extEnv; uint32_t size = 0; for (uint8_t i = 0; i < COUNT_DTC_CODE_ERROR; ++i) { if (dtc_state_error[i] & (~diagnosticDTC->mask)) { diagnosticDTC->dataResponse[size] = dtc_codes[i].DTCHighByte; diagnosticDTC->dataResponse[size + 1] = dtc_codes[i].DTCMiddleByte; diagnosticDTC->dataResponse[size + 2] = dtc_codes[i].DTCLowByte; diagnosticDTC->dataResponse[size + 3] = dtc_state_error[i] & (~diagnosticDTC->mask); size += 4; } } return size; } const eDiagnosticState diagnostic_com[] = { {diagnostic_ClearDiagnosticInformation_14, "diagnostic_ClearDiagnosticInformation_14"}, {diagnostic_UDS_ReadDTCInformation_19_1, "diagnostic_UDS_ReadDTCInformation_19_1"}, {diagnostic_UDS_ReadDTCInformation_19_2, "diagnostic_UDS_ReadDTCInformation_19_2"}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""}, {NULL, ""} }; uint32_t SetGetDiagnosticData(tDiagnostic *env, eDiagnosticType diagnosticType, void *extEnv) { uint32_t ret = 0; if (diagnostic_com[diagnosticType].func != NULL) { if (osMutexAcquire(env->access, 1000) == osOK) { ret = diagnostic_com[diagnosticType].func(env, extEnv); osMutexRelease(env->access); } } return ret; } static _Noreturn void Diagnostic_Thread(tDiagnostic *env) { for (;;) { osStatus_t status = osMessageQueueGet(env->queue, &env->diagnosticType, 0, 1000); if (status == osOK) { if (osMutexAcquire(env->access, 1000) == osOK) { osMutexRelease(env->access); } } } } void Diagnostic_StartThread(tDiagnostic *env) { if (!env->thread.id) { env->thread.id = osThreadNew((osThreadFunc_t) (Diagnostic_Thread), (void *) (env), &env->thread.attr); } }