1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-20 06:45:10 +03:00

[simu] Refactor simu startup and shutdown handling (for 2.3 branch):

* Use pwrCheck() as primary control point for shutdown, centralizes thread control in simpgmspace module;
 * Remove main_thread_running in favor of separate variables for startup mode and shutdown flag;
 * Don't start a thread for ARM startup, just run simuMain() directly (the thread just exits anyway);
 * Refactor SIMU_SLEEP() macro, and remove all unnecessary uses of it, also remove SIMU_SLEEP_NORET;
 * Add startType param to opentxStart() to control splash and startup checks;
 * Fixes backlight never turning off in simulator with "SWITCH" power button type (pwrPressed() was always true);
 * Fixes simu shutdown when model checklist is displayed at startup;
 * Adds stubs to possibly simulate a "soft" power button in the future.
This commit is contained in:
Max Paperno 2018-09-07 14:46:28 -04:00
parent 942ae1847d
commit a2006940db
No known key found for this signature in database
GPG key ID: F5A9DFACA08DD174
12 changed files with 97 additions and 70 deletions

View file

@ -61,8 +61,7 @@
#define CONVERT_PTR_UINT(x) ((uint32_t)(uint64_t)(x)) #define CONVERT_PTR_UINT(x) ((uint32_t)(uint64_t)(x))
#define CONVERT_UINT_PTR(x) ((uint32_t*)(uint64_t)(x)) #define CONVERT_UINT_PTR(x) ((uint32_t*)(uint64_t)(x))
#else #else
#define SIMU_SLEEP(x) #define SIMU_SLEEP(x) true
#define SIMU_SLEEP_NORET(x)
#define CONVERT_PTR_UINT(x) ((uint32_t)(x)) #define CONVERT_PTR_UINT(x) ((uint32_t)(x))
#define CONVERT_UINT_PTR(x) ((uint32_t *)(x)) #define CONVERT_UINT_PTR(x) ((uint32_t *)(x))
#endif #endif

View file

@ -82,6 +82,7 @@ void runFatalErrorScreen(const char * message)
uint32_t pwr_check = pwrCheck(); uint32_t pwr_check = pwrCheck();
if (pwr_check == e_power_off) { if (pwr_check == e_power_off) {
boardOff(); boardOff();
return; // only happens in SIMU, required for proper shutdown
} }
else if (pwr_check == e_power_press) { else if (pwr_check == e_power_press) {
refresh = true; refresh = true;
@ -89,7 +90,6 @@ void runFatalErrorScreen(const char * message)
else if (pwr_check == e_power_on && refresh) { else if (pwr_check == e_power_on && refresh) {
break; break;
} }
SIMU_SLEEP_NORET(1);
} }
} }
} }

View file

@ -61,7 +61,8 @@ void bootloaderFlash(const char * filename)
flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS+i+j), (uint32_t *)(buffer+j)); flashWrite(CONVERT_UINT_PTR(FIRMWARE_ADDRESS+i+j), (uint32_t *)(buffer+j));
} }
drawProgressBar(STR_WRITING, i, BOOTLOADER_SIZE); drawProgressBar(STR_WRITING, i, BOOTLOADER_SIZE);
SIMU_SLEEP(30/*ms*/); if (!SIMU_SLEEP(30/*ms*/))
break;
} }
if (unlocked) { if (unlocked) {

View file

@ -123,7 +123,7 @@ void sportProcessUpdatePacket(uint8_t * packet)
bool sportWaitState(SportUpdateState state, int timeout) bool sportWaitState(SportUpdateState state, int timeout)
{ {
#if defined(SIMU) #if defined(SIMU)
SIMU_SLEEP_NORET(1); SIMU_SLEEP(1);
return true; return true;
#else #else
watchdogSuspend(timeout / 10); watchdogSuspend(timeout / 10);

View file

@ -188,12 +188,7 @@ bool clearKeyEvents()
#endif #endif
while (keyDown()) { while (keyDown()) {
#if defined(SIMU)
SIMU_SLEEP_NORET(1/*ms*/);
#else
wdt_reset(); wdt_reset();
#endif
#if !defined(BOOT) #if !defined(BOOT)
if ((get_tmr10ms() - start) >= 300) { // wait no more than 3 seconds if ((get_tmr10ms() - start) >= 300) { // wait no more than 3 seconds

View file

@ -1019,18 +1019,20 @@ void alert(const char * title, const char * msg , uint8_t sound)
while (1) { while (1) {
RTOS_WAIT_MS(10); RTOS_WAIT_MS(10);
if (keyDown()) break; // wait for key release if (keyDown()) // wait for key release
break;
doLoopCommonActions(); doLoopCommonActions();
wdt_reset(); wdt_reset();
#if defined(PWR_BUTTON_PRESS) const uint32_t pwr_check = pwrCheck();
uint32_t pwr_check = pwrCheck();
if (pwr_check == e_power_off) { if (pwr_check == e_power_off) {
drawSleepBitmap(); drawSleepBitmap();
boardOff(); boardOff();
return; // only happens in SIMU, required for proper shutdown
} }
#if defined(PWR_BUTTON_PRESS)
else if (pwr_check == e_power_press) { else if (pwr_check == e_power_press) {
refresh = true; refresh = true;
} }
@ -1038,11 +1040,6 @@ void alert(const char * title, const char * msg , uint8_t sound)
RAISE_ALERT(title, msg, STR_PRESSANYKEY, AU_NONE); RAISE_ALERT(title, msg, STR_PRESSANYKEY, AU_NONE);
refresh = false; refresh = false;
} }
#else
if (pwrCheck() == e_power_off) {
drawSleepBitmap();
boardOff(); // turn power off now
}
#endif #endif
} }
@ -1506,20 +1503,26 @@ void doMixerCalculations()
s_mixer_first_run_done = true; s_mixer_first_run_done = true;
} }
void opentxStart(uint8_t splash=true)
{
TRACE("opentxStart");
#if defined(SIMU) #define OPENTX_START_NO_SPLASH 0x01
if (main_thread_running == 2) { #define OPENTX_START_NO_CHECKS 0x02
#if !defined(OPENTX_START_DEFAULT_ARGS)
#define OPENTX_START_DEFAULT_ARGS 0
#endif
void opentxStart(const uint8_t startType = OPENTX_START_DEFAULT_ARGS)
{
TRACE("opentxStart(%u)", startType);
if (startType & OPENTX_START_NO_CHECKS) {
return; return;
} }
#endif
uint8_t calibration_needed = (g_eeGeneral.chkSum != evalChkSum()); uint8_t calibration_needed = (g_eeGeneral.chkSum != evalChkSum());
#if defined(GUI) #if defined(GUI)
if (!calibration_needed && splash) { if (!calibration_needed && !(startType & OPENTX_START_NO_SPLASH)) {
doSplash(); doSplash();
} }
#endif #endif
@ -1621,7 +1624,7 @@ void opentxResume()
loadFontCache(); loadFontCache();
#endif #endif
opentxStart(false); opentxStart(OPENTX_START_NO_SPLASH);
referenceSystemAudioFiles(); referenceSystemAudioFiles();
@ -1907,7 +1910,7 @@ void opentxInit(OPENTX_INIT_ARGS)
} }
#if defined(SIMU) #if defined(SIMU)
void * simuMain(void *) void simuMain()
#else #else
int main() int main()
#endif #endif
@ -1931,7 +1934,7 @@ int main()
loadFonts(); loadFonts();
#endif #endif
#if defined(GUI) && !defined(PCBTARANIS) && !defined(PCBHORUS) #if defined(GUI) && !defined(PCBTARANIS) && !defined(PCBHORUS)
// TODO remove this // TODO remove this
lcdInit(); lcdInit();
@ -1970,13 +1973,9 @@ int main()
#endif #endif
tasksStart(); tasksStart();
#if defined(SIMU)
return NULL;
#endif
} }
#if !defined(SIMU)
#if defined(PWR_BUTTON_PRESS) #if defined(PWR_BUTTON_PRESS)
uint32_t pwr_press_time = 0; uint32_t pwr_press_time = 0;
@ -2102,4 +2101,5 @@ uint32_t pwrCheck()
return e_power_off; return e_power_off;
} }
#endif #endif // defined(PWR_BUTTON_PRESS)
#endif // !defined(SIMU)

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX * Copyright (C) OpenTX
* *
* Based on code named * Based on code named
* th9x - http://code.google.com/p/th9x * th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x * er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x * gruvin9x - http://code.google.com/p/gruvin9x
* *
@ -63,16 +63,12 @@ uint8_t eepromWriteBuffer[EEPROM_BUFFER_SIZE] __DMA;
void eepromWaitReadStatus() void eepromWaitReadStatus()
{ {
while (eepromReadStatus() == 0) { while (eepromReadStatus() == 0 && SIMU_SLEEP(5/*ms*/)) { }
SIMU_SLEEP(5/*ms*/);
}
} }
void eepromWaitTransferComplete() void eepromWaitTransferComplete()
{ {
while (!eepromIsTransferComplete()) { while (!eepromIsTransferComplete() && SIMU_SLEEP(5/*ms*/)) { }
SIMU_SLEEP(5/*ms*/);
}
} }
void eepromEraseBlock(uint32_t address, bool blocking=true) void eepromEraseBlock(uint32_t address, bool blocking=true)

View file

@ -911,7 +911,8 @@ void eepromBackup()
eepromReadBlock(buffer, i, 1024); eepromReadBlock(buffer, i, 1024);
f_write(&file, buffer, 1024, &count); f_write(&file, buffer, 1024, &count);
drawProgressBar(STR_WRITING, i, EEPROM_SIZE); drawProgressBar(STR_WRITING, i, EEPROM_SIZE);
SIMU_SLEEP(100/*ms*/); if (!SIMU_SLEEP(100/*ms*/))
break;
} }
f_close(&file); f_close(&file);

View file

@ -86,7 +86,7 @@ QString OpenTxSimulator::name()
bool OpenTxSimulator::isRunning() bool OpenTxSimulator::isRunning()
{ {
QMutexLocker lckr(&m_mtxSimuMain); QMutexLocker lckr(&m_mtxSimuMain);
return (bool)main_thread_running; return simuIsRunning();
} }
void OpenTxSimulator::init() void OpenTxSimulator::init()

View file

@ -40,10 +40,12 @@ uint8_t portb, portc, porth=0, dummyport;
uint16_t dummyport16; uint16_t dummyport16;
int g_snapshot_idx = 0; int g_snapshot_idx = 0;
pthread_t main_thread_pid; uint8_t simu_start_mode = 0;
uint8_t main_thread_running = 0;
char * main_thread_error = NULL; char * main_thread_error = NULL;
bool simu_shutdown = false;
bool simu_running = false;
#if defined(STM32) #if defined(STM32)
uint32_t Peri1_frequency, Peri2_frequency; uint32_t Peri1_frequency, Peri2_frequency;
GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpioi, gpioj; GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpioi, gpioj;
@ -132,6 +134,13 @@ void simuInit()
RCC->CSR = 0; RCC->CSR = 0;
#endif #endif
// set power button to "not pressed"
#if defined(PWR_SWITCH_GPIO) // STM32
GPIO_SetBits(PWR_SWITCH_GPIO, PWR_SWITCH_GPIO_PIN);
#elif defined(PIO_PC17) // AT91SAM3
PIOC->PIO_PDSR &= ~PIO_PC17;
#endif
for (int i = 0; i <= 17; i++) { for (int i = 0; i <= 17; i++) {
simuSetSwitch(i, 0); simuSetSwitch(i, 0);
simuSetKey(i, false); // a little dirty, but setting keys that don't exist is perfectly OK here simuSetKey(i, false); // a little dirty, but setting keys that don't exist is perfectly OK here
@ -315,13 +324,14 @@ void simuSetSwitch(uint8_t swtch, int8_t state)
void StartSimu(bool tests, const char * sdPath, const char * settingsPath) void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
{ {
if (main_thread_running) if (simu_running)
return; return;
s_current_protocol[0] = 255; s_current_protocol[0] = 255;
menuLevel = 0; menuLevel = 0;
main_thread_running = (tests ? 1 : 2); // TODO rename to simu_run_mode with #define simu_start_mode = (tests ? 0 : 0x02 /* OPENTX_START_NO_CHECKS */);
simu_shutdown = false;
simuFatfsSetPaths(sdPath, settingsPath); simuFatfsSetPaths(sdPath, settingsPath);
@ -350,7 +360,9 @@ void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
try { try {
#endif #endif
pthread_create(&main_thread_pid, NULL, &simuMain, NULL); simuMain();
simu_running = true;
#if defined(SIMU_EXCEPTIONS) #if defined(SIMU_EXCEPTIONS)
} }
@ -361,14 +373,15 @@ void StartSimu(bool tests, const char * sdPath, const char * settingsPath)
void StopSimu() void StopSimu()
{ {
if (!main_thread_running) if (!simu_running)
return; return;
main_thread_running = 0; simu_shutdown = true;
pthread_join(mixerTaskId, NULL); pthread_join(mixerTaskId, NULL);
pthread_join(menusTaskId, NULL); pthread_join(menusTaskId, NULL);
pthread_join(main_thread_pid, NULL);
simu_running = false;
} }
struct SimulatorAudio { struct SimulatorAudio {
@ -380,6 +393,21 @@ struct SimulatorAudio {
pthread_t threadPid; pthread_t threadPid;
} simuAudio; } simuAudio;
bool simuIsRunning()
{
return simu_running;
}
bool simuSleep(uint32_t ms)
{
for (uint32_t i = 0; i < ms; ++i){
if (simu_shutdown || !simu_running)
return false;
sleep(1);
}
return true;
}
void audioConsumeCurrentBuffer() void audioConsumeCurrentBuffer()
{ {
} }
@ -572,16 +600,25 @@ int lcdRestoreBackupBuffer()
return 1; return 1;
} }
uint32_t pwrCheck()
{
// TODO: ability to simulate shutdown warning for a "soft" simulator restart
return simu_shutdown ? e_power_off : e_power_on;
}
void pwrOff() void pwrOff()
{ {
} }
uint32_t pwrPressed() uint32_t pwrPressed()
{ {
#if defined(PWR_BUTTON_PRESS) // TODO: simulate power button
return false; #if defined(PWR_SWITCH_GPIO) // STM32
return GPIO_ReadInputDataBit(PWR_SWITCH_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET;
#elif defined(PIO_PC17) // AT91SAM3
return PIOC->PIO_PDSR & PIO_PC17;
#else #else
return true; return false;
#endif #endif
} }
@ -648,9 +685,9 @@ FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG) { return SET; }
ErrorStatus RTC_WaitForSynchro(void) { return SUCCESS; } ErrorStatus RTC_WaitForSynchro(void) { return SUCCESS; }
void unlockFlash() { } void unlockFlash() { }
void lockFlash() { } void lockFlash() { }
void flashWrite(uint32_t *address, uint32_t *buffer) { SIMU_SLEEP(100); } void flashWrite(uint32_t *address, uint32_t *buffer) { simuSleep(100); }
uint32_t isBootloaderStart(const uint8_t * block) { return 1; } uint32_t isBootloaderStart(const uint8_t * block) { return 1; }
#endif // defined(PCBTARANIS) #endif // defined(STM32)
#if defined(PCBHORUS) #if defined(PCBHORUS)
void LCD_ControlLight(uint16_t dutyCycle) { } void LCD_ControlLight(uint16_t dutyCycle) { }

View file

@ -227,21 +227,24 @@ extern uint32_t Master_frequency;
#define __disable_irq() #define __disable_irq()
#define __enable_irq() #define __enable_irq()
extern uint8_t main_thread_running; extern uint8_t simu_start_mode;
extern char * main_thread_error; extern char * main_thread_error;
#define OPENTX_START_DEFAULT_ARGS simu_start_mode
static inline void getADC() static inline void getADC()
{ {
} }
#define SIMU_SLEEP(x) do { if (!main_thread_running) return; sleep(x/*ms*/); } while (0) #define SIMU_SLEEP(x) simuSleep(x)
#define SIMU_SLEEP_NORET(x) do { sleep(x/*ms*/); } while (0)
uint64_t simuTimerMicros(void); uint64_t simuTimerMicros(void);
void simuInit(); void simuInit();
void StartSimu(bool tests=true, const char * sdPath = 0, const char * settingsPath = 0); void StartSimu(bool tests=true, const char * sdPath = 0, const char * settingsPath = 0);
void StopSimu(); void StopSimu();
bool simuIsRunning();
bool simuSleep(uint32_t ms);
void simuSetKey(uint8_t key, bool state); void simuSetKey(uint8_t key, bool state);
void simuSetTrim(uint8_t trim, bool state); void simuSetTrim(uint8_t trim, bool state);
@ -257,7 +260,7 @@ void StopEepromThread();
#define StopAudioThread() #define StopAudioThread()
#endif #endif
void * simuMain(void * args = NULL); void simuMain();
#define UART_Stop(...) #define UART_Stop(...)
#define UART3_Stop(...) #define UART3_Stop(...)

View file

@ -82,20 +82,20 @@ TASK_FUNCTION(mixerTask)
while(1) { while(1) {
#if defined(SIMU)
if (main_thread_running == 0)
TASK_RETURN();
#endif
#if defined(SBUS) #if defined(SBUS)
processSbusInput(); processSbusInput();
#endif #endif
RTOS_WAIT_TICKS(1); RTOS_WAIT_TICKS(1);
#if defined(SIMU)
if (pwrCheck() == e_power_off)
TASK_RETURN();
#else
if (isForcePowerOffRequested()) { if (isForcePowerOffRequested()) {
pwrOff(); pwrOff();
} }
#endif
uint32_t now = RTOS_GET_TIME(); uint32_t now = RTOS_GET_TIME();
bool run = false; bool run = false;
@ -208,11 +208,6 @@ TASK_FUNCTION(menusTask)
} }
resetForcePowerOffRequest(); resetForcePowerOffRequest();
#if defined(SIMU)
if (main_thread_running == 0)
break;
#endif
} }
#if defined(PCBX9E) #if defined(PCBX9E)