389 lines
16 KiB
C
389 lines
16 KiB
C
//
|
||
// Created by xemon on 30.10.22.
|
||
//
|
||
|
||
#include <AudioPlayerInterface.h>
|
||
#include <SystemDelayInterface.h>
|
||
#include "DeviceTesting.h"
|
||
#include "UserInput.h"
|
||
#include "DeviceTesting_TestsWithUser.h"
|
||
#include "Adc.h"
|
||
#include "EraGlonassMsd.h"
|
||
#include "EraGlonassUveos.h"
|
||
#include "Accel.h"
|
||
#include "GsmWithGnss.h"
|
||
#include "AsciiStringAssmeblingUtils.h"
|
||
|
||
#define LOGGER env->logger
|
||
#define LOG_SIGN "Тест."
|
||
|
||
bool DeviceTesting_Init(
|
||
tDeviceTesting *env,
|
||
|
||
tUserInputButtonWatcher *UserInputButtonWatcher,
|
||
tGpioPin *ignPin,
|
||
tAdcIO *gnssAntAdc,
|
||
tAdcIO *speakerAdc,
|
||
tAdcIO *batteryAdc,
|
||
tAccel *accel,
|
||
|
||
tGsmWithGnss *gsmWithGnss,
|
||
tAudioCodec *audioCodec,
|
||
tLoggerInterface *logger,
|
||
tAtCmd *gsm,
|
||
|
||
tAudioPlayerInterface *audioPlayer,
|
||
tAudioRecorderInterface *audioRecorder,
|
||
|
||
tUserButtonsInterface *input,
|
||
tUserIndication *indication,
|
||
|
||
tEraGlonassUveos *ErGlUv,
|
||
bool *antMode,
|
||
tGpioPin *ring
|
||
) {
|
||
env->UserInputButtonWatcher = UserInputButtonWatcher;
|
||
env->logger = logger;
|
||
env->audioPlayer = audioPlayer;
|
||
env->audioRecorder = audioRecorder;
|
||
env->input = input;
|
||
env->indication = indication;
|
||
env->ErGlUv = ErGlUv;
|
||
env->accelDFI = &accel->accelDataFlow;
|
||
env->pinIgnition = ignPin;
|
||
env->ringPin = ring;
|
||
env->antDiscript.externalAdc = gnssAntAdc;
|
||
env->antDiscript.gsmAt = gsm;
|
||
env->antDiscript.mode = antMode;
|
||
env->gsmWithGnss = gsmWithGnss;
|
||
DeviceTests_InitTestsTable(env, ignPin, speakerAdc, batteryAdc, gsm, audioCodec, accel, &env->antDiscript);
|
||
|
||
InitThreadAtrStatic(&env->threadTest.attr, "Thread_Test", env->threadTest.controlBlock,
|
||
env->threadTest.stack, osPriorityNormal);
|
||
|
||
env->flagAutoTestSucsess = false;
|
||
env->flagAcsessExitThread = (uint8_t)1;
|
||
return true;
|
||
}
|
||
|
||
|
||
void DeviceTesting_StartTestThread(tDeviceTesting *env) {
|
||
if (!env->threadTest.id) {
|
||
env->threadTest.id = osThreadNew(
|
||
(osThreadFunc_t) (DeviceTesting_ManualTestMode),
|
||
(void *) (env),
|
||
&env->threadTest.attr
|
||
);
|
||
}
|
||
}
|
||
|
||
bool DeviceTesting_ExitTestMode(tDeviceTesting *env) {
|
||
if (osThreadTerminate(env->threadTest.id) == osOK) {
|
||
osDelay(2000);
|
||
env->threadTest.id = NULL;
|
||
env->flagAcsessExitThread = (uint8_t)1;
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void DeviceTesting_ChekExit(tDeviceTesting *env) {
|
||
AtGsm_Gsnss_GetNMEA_Pack(env->gsmWithGnss, 1000);
|
||
SystemDelayMs(100);
|
||
EraGlonassUveos_DoNothingModeDistance(env->ErGlUv, false);
|
||
}
|
||
|
||
bool DeviceTesting_RunUserTests(tDeviceTesting *env) {
|
||
|
||
DeviceTesting_StartTestThread(env);
|
||
|
||
for (;;) {
|
||
|
||
if (EraGlonassUveos_IsAllowInCall(env->ErGlUv) && GpioPinGet(env->ringPin)) {
|
||
if (DeviceTesting_ExitTestMode(env)) {
|
||
EraGlonassUveos_DoNotingReset(env->ErGlUv);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
if (!GpioPinGet(env->pinIgnition) && (env->flagAcsessExitThread == 1)) {
|
||
if (DeviceTesting_ExitTestMode(env)) {
|
||
EraGlonassUveos_DoNotingReset(env->ErGlUv);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
if (env->flagAcsessExitThread == 2) {
|
||
if (DeviceTesting_ExitTestMode(env)) {
|
||
EraGlonassUveos_DoNotingReset(env->ErGlUv);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
if (env->ErGlUv->doNothing.mode == UVEOS_DO_NOTHING_DISABLED) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматический выход из режима пользовательского тестирования")
|
||
if (DeviceTesting_ExitTestMode(env)) {
|
||
EraGlonassUveos_DoNotingReset(env->ErGlUv);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
SystemDelayMs(500);
|
||
}
|
||
|
||
}
|
||
|
||
void DeviceTesting_ManualTestMode(tDeviceTesting *env) {
|
||
//запускаем режим тестирования с пользователем
|
||
DeviceTesting_MainTestingMode(env);
|
||
}
|
||
|
||
//возвращает true в случае ошибки
|
||
bool DeviceTesting_OnIgnitionWithoutGsm(tDeviceTesting *env) {
|
||
DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_IGNITION_WITHOUT_GSM, 0);
|
||
return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR);
|
||
}
|
||
|
||
//возвращает true в случае ошибки
|
||
bool DeviceTesting_OnIgnitionAfterGsm(tDeviceTesting *env) {
|
||
DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_IGNITION_AFTER_GSM, 0);
|
||
return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR);
|
||
}
|
||
|
||
//возвращает true в случае ошибки
|
||
bool DeviceTesting_Always(tDeviceTesting *env) {
|
||
DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_ALWAYS, 0);
|
||
//
|
||
if ((DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR)) ||
|
||
(DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_NOT_CONNECTED)) ||
|
||
(DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_SHORT_CIRCUIT))
|
||
) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
|
||
}
|
||
|
||
//возвращает true в случае ошибки
|
||
bool DeviceTesting_Main(tDeviceTesting *env) {
|
||
DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_MAIN, 0);
|
||
return DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR);
|
||
}
|
||
|
||
|
||
//возвращает true в случае ошибки
|
||
bool DeviceTesting_Periodical(tDeviceTesting *env) {
|
||
if (!env->testsTable.currentProcessIterationsLeft) {
|
||
return false;
|
||
}
|
||
--env->testsTable.currentProcessIterationsLeft;
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Режим самотестирования")
|
||
SystemDelayMs(5000);
|
||
DeviceTestsTable_TestInMode(&env->testsTable, DEVICE_TESTING_MODE_PERIODICAL, 1000);
|
||
bool errors = DeviceTestsTable_AnyTestHasCode(&env->testsTable, DEVICE_TESTING_CODE_ERROR);
|
||
|
||
if (errors) {
|
||
for (uint16_t testIdx = 0; testIdx < env->testsTable.count; ++testIdx) {
|
||
tTestDescriptor *test = env->testsTable.items + testIdx;
|
||
|
||
if (test->result == DEVICE_TESTING_CODE_ERROR) {
|
||
LoggerCnErrorStatic(LOGGER, LOG_SIGN, "Тест ")
|
||
LoggerCnError(LOGGER, LOG_SIGN, test->name.str, test->name.length)
|
||
LoggerErrorStatic(LOGGER, LOG_SIGN, " не пройден")
|
||
}
|
||
}
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Все тесты пройдены")
|
||
}
|
||
|
||
return errors;
|
||
}
|
||
|
||
bool DeviceTesting_UserTests(tDeviceTesting *env) {
|
||
DeviceTesting_ChekExit(env);
|
||
EraGlonassMsd_ClearDiagnostic(&env->tmsdDiagRes);
|
||
//задаем режим и обновляем индикторы
|
||
UserIndication_SetMode(env->indication, DEVICE_MODE_TESTING);
|
||
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.speakersFailure, DeviceTesting_TestAudioSpeaker(env));
|
||
DeviceTesting_ChekExit(env);
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.ignitionLineFailure, DeviceTesting_Ignition(env));
|
||
DeviceTesting_ChekExit(env);
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.micFailure, DeviceTesting_TestMic(env));
|
||
DeviceTesting_ChekExit(env);
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.uimFailure, DeviceTesting_Buttons(env));
|
||
DeviceTesting_ChekExit(env);
|
||
//выключаем индикацию
|
||
UserIndication_StopThread(env->indication);
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.statusIndicatorFailure, DeviceTesting_Indication(env));
|
||
DeviceTesting_ChekExit(env);
|
||
//включаем индикацию
|
||
UserIndication_StartThread(env->indication);
|
||
return DeviceTesting_UserGetResult(env);
|
||
}
|
||
|
||
|
||
void DeviceTesting_AudioSysTestOk(tDeviceTesting *env) {
|
||
SystemDelayMs(100);
|
||
DEVTST_PLAY_SAMPLE("func")
|
||
DEVTST_PLAY_SAMPLE("regularly")
|
||
if (!env->flagAutoTestSucsess) {
|
||
env->flagAutoTestSucsess = true;
|
||
}
|
||
}
|
||
|
||
void DeviceTesting_AudioSysTestErr(tDeviceTesting *env) {
|
||
SystemDelayMs(100);
|
||
DEVTST_PLAY_SAMPLE("func")
|
||
DEVTST_PLAY_SAMPLE("no")
|
||
DEVTST_PLAY_SAMPLE("regularly")
|
||
}
|
||
|
||
|
||
void DeviceTesting_GetSystemTest(tDeviceTesting *env) {
|
||
if (DeviceTestsTable_MakeTest(env->namedTests.firmware) == DEVICE_TESTING_CODE_PASSED) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование целостности ПО, вызванное пользователем прошло успешно")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.firmwareImageCorruption, false);
|
||
DEVTST_PLAY_SAMPLE("ks_right")
|
||
// DEVTST_PLAY_SAMPLE("po")
|
||
// DEVTST_PLAY_SAMPLE("no")
|
||
// DEVTST_PLAY_SAMPLE("violated")
|
||
if (!env->flagAutoTestSucsess) {
|
||
env->flagAutoTestSucsess = true;
|
||
}
|
||
// } else {
|
||
// LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка при автоматическом тестировании целостности ПО")
|
||
// DEVTST_PLAY_SAMPLE("ks_mistake")
|
||
// DEVTST_PLAY_SAMPLE("integrity")
|
||
// DEVTST_PLAY_SAMPLE("po")
|
||
// DEVTST_PLAY_SAMPLE("no")
|
||
// DEVTST_PLAY_SAMPLE("violated")
|
||
|
||
}
|
||
|
||
if (DeviceTestsTable_MakeTest(env->namedTests.gsm) != DEVICE_TESTING_CODE_PASSED) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка модема при автоматическом тестировании пользователем")
|
||
DEVTST_PLAY_SAMPLE("modem")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.commModuleFailure, true);
|
||
DeviceTesting_AudioSysTestErr(env);
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование модема, вызванное пользователем прошло успешно")
|
||
DEVTST_PLAY_SAMPLE("modem")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.commModuleFailure, false);
|
||
DeviceTesting_AudioSysTestOk(env);
|
||
}
|
||
|
||
if (DeviceTestsTable_MakeTest(env->namedTests.accel) == DEVICE_TESTING_CODE_PASSED) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование акселеромерта, вызванное пользователем прошло успешно")
|
||
DEVTST_PLAY_SAMPLE("axel")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.crashSensorFailure, false);
|
||
DeviceTesting_AudioSysTestOk(env);
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка акселеромерта при автоматическом тестировании пользователем")
|
||
DEVTST_PLAY_SAMPLE("axel")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.crashSensorFailure, true);
|
||
DeviceTesting_AudioSysTestErr(env);
|
||
}
|
||
|
||
if (DeviceTestsTable_MakeTest(env->namedTests.batteryCharge) != DEVICE_TESTING_CODE_ERROR) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование АКБ, вызванное пользователем прошло успешно")
|
||
DEVTST_PLAY_SAMPLE("akb")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.batteryFailure, false);
|
||
DeviceTesting_AudioSysTestOk(env);
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка АКБ при автоматическом тестировании пользователем")
|
||
DEVTST_PLAY_SAMPLE("akb")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.batteryFailure, true);
|
||
DeviceTesting_AudioSysTestErr(env);
|
||
}
|
||
|
||
if (
|
||
(DeviceTestsTable_MakeTest(env->namedTests.gnssAnt) == DEVICE_TESTING_CODE_CONNECTED)||
|
||
(DeviceTestsTable_MakeTest(env->namedTests.gnssAnt) == DEVICE_TESTING_CODE_INPUT_ANTENA_OK)
|
||
) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование антены, вызванное пользователем прошло успешно")
|
||
DEVTST_PLAY_SAMPLE("antenna")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.gnssAntennaFailure, false);
|
||
DeviceTesting_AudioSysTestOk(env);
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка антены при автоматическом тестировании пользователем")
|
||
DEVTST_PLAY_SAMPLE("antenna")
|
||
EraGlonassMsd_OptionalFlagSet(env->tmsdDiagRes.gnssAntennaFailure, true);
|
||
DeviceTesting_AudioSysTestErr(env);
|
||
}
|
||
|
||
if (DeviceTestsTable_MakeTest(env->namedTests.audioCodec) == DEVICE_TESTING_CODE_PASSED) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Автоматическое тестирование аудиотракта, вызванное пользователем прошло успешно")
|
||
DEVTST_PLAY_SAMPLE("auditract")
|
||
DeviceTesting_AudioSysTestOk(env);
|
||
} else {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка аудиотракта при автоматическом тестировании пользователем")
|
||
DEVTST_PLAY_SAMPLE("auditract")
|
||
DeviceTesting_AudioSysTestErr(env);
|
||
}
|
||
|
||
}
|
||
|
||
//возвращает true в случае ошибки
|
||
void DeviceTesting_MainTestingMode(tDeviceTesting *env) {
|
||
UserIndication_Uiu(env->indication, UIU_OFF);
|
||
|
||
UserButtons_Clear(env->input);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Начало пользовательского тестирования")
|
||
|
||
DEVTST_PLAY_SAMPLE("switching-to")
|
||
DEVTST_PLAY_SAMPLE("mode")
|
||
DEVTST_PLAY_SAMPLE("testing")
|
||
|
||
bool userTestsOk = DeviceTesting_UserTests(env);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполняются внутренние тесты")
|
||
DeviceTesting_GetSystemTest(env);
|
||
if (env->flagAutoTestSucsess) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Внутренние тесты завершены успешно")
|
||
}
|
||
DeviceTesting_ChekExit(env);
|
||
if (userTestsOk && !env->flagAutoTestSucsess) {
|
||
SystemDelayMs(500);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка внутреннего теста")
|
||
DEVTST_PLAY_SAMPLE("bug_internal_testing")
|
||
}
|
||
DeviceTesting_ChekExit(env);
|
||
if (userTestsOk && env->flagAutoTestSucsess) {
|
||
if (!DeviceTesting_Main(env)) {
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Все тесты пройдены успешно")
|
||
SystemDelayMs(500);
|
||
DEVTST_PLAY_SAMPLE("testing")
|
||
DEVTST_PLAY_SAMPLE("exit_good")
|
||
}
|
||
}
|
||
DeviceTesting_ChekExit(env);
|
||
UserInputButtonWatcher_Clear(env->UserInputButtonWatcher);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Начало тестирования вызова с передачей данных с результатами проверки")
|
||
|
||
SystemDelayMs(2000);
|
||
DeviceTesting_Ecall(env);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Тестовый вызов пройден")
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Формируется голосовой отчёт по тестовому вызову")
|
||
DeviceTesting_ChekExit(env);
|
||
DeviceTesting_GetEcalRes(env);
|
||
|
||
if(env->ecallAddStatusRes == 1){
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Выполняются вызов оператору 112")
|
||
env->ErGlUv->currentMsd->msd.MSD_Data.msgId = 1;
|
||
EraGlonassUveos_ManualEmergencyCall(env->ErGlUv, false);
|
||
}
|
||
DeviceTesting_ChekExit(env);
|
||
LoggerInfoStatic(LOGGER, LOG_SIGN, "Голосовой отчёт по тестовому вызову выполнен")
|
||
|
||
env->flagAcsessExitThread = (uint8_t) 2;
|
||
uint32_t time = SystemGetMs() + 20000;
|
||
while (1) {
|
||
if(time < SystemGetMs()){
|
||
return ;
|
||
}
|
||
SystemDelayMs(20);
|
||
}
|
||
|
||
} |