Merge pull request #367 from bobbycar-graz/crash-handler
This commit is contained in:
@ -128,6 +128,7 @@ set(headers
|
|||||||
displays/menus/networksettingsmenu.h
|
displays/menus/networksettingsmenu.h
|
||||||
displays/menus/otamenu.h
|
displays/menus/otamenu.h
|
||||||
displays/menus/profilesmenu.h
|
displays/menus/profilesmenu.h
|
||||||
|
displays/menus/recoverymenu.h
|
||||||
displays/menus/remotecontrolmodesettingsmenu.h
|
displays/menus/remotecontrolmodesettingsmenu.h
|
||||||
displays/menus/selectbuildserverbranch.h
|
displays/menus/selectbuildserverbranch.h
|
||||||
displays/menus/selectbuildservermenu.h
|
displays/menus/selectbuildservermenu.h
|
||||||
@ -376,6 +377,7 @@ set(sources
|
|||||||
displays/menus/networksettingsmenu.cpp
|
displays/menus/networksettingsmenu.cpp
|
||||||
displays/menus/otamenu.cpp
|
displays/menus/otamenu.cpp
|
||||||
displays/menus/profilesmenu.cpp
|
displays/menus/profilesmenu.cpp
|
||||||
|
displays/menus/recoverymenu.cpp
|
||||||
displays/menus/remotecontrolmodesettingsmenu.cpp
|
displays/menus/remotecontrolmodesettingsmenu.cpp
|
||||||
displays/menus/selectbuildserverbranch.cpp
|
displays/menus/selectbuildserverbranch.cpp
|
||||||
displays/menus/selectbuildservermenu.cpp
|
displays/menus/selectbuildservermenu.cpp
|
||||||
|
@ -3,11 +3,42 @@
|
|||||||
// 3rdparty lib includes
|
// 3rdparty lib includes
|
||||||
#include <schedulertask.h>
|
#include <schedulertask.h>
|
||||||
|
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
class BobbySchedulerTask : public espcpputils::SchedulerTask {
|
class BobbySchedulerTask : public espcpputils::SchedulerTask {
|
||||||
public:
|
public:
|
||||||
using SchedulerTask::SchedulerTask;
|
// using SchedulerTask::SchedulerTask; -> we need to add one more parameter
|
||||||
void setup() const { SchedulerTask::setup(); m_wasInitialized = true; }
|
BobbySchedulerTask(const char *name, void (&setupCallback)(), void (&loopCallback)(),
|
||||||
|
espchrono::millis_clock::duration loopInterval, bool use_in_recovery = false,
|
||||||
|
bool intervalImportant = false,
|
||||||
|
std::string (*perfInfo)() = nullptr) :
|
||||||
|
espcpputils::SchedulerTask(name, setupCallback, loopCallback, loopInterval, intervalImportant, perfInfo),
|
||||||
|
m_use_in_recovery{use_in_recovery}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void setup(bool in_recovery = false)
|
||||||
|
{
|
||||||
|
m_in_recovery = in_recovery;
|
||||||
|
if (in_recovery && !m_use_in_recovery)
|
||||||
|
{
|
||||||
|
ESP_LOGI("BobbySchedulerTask", "Skipping setup of %s (%s)", name(), m_use_in_recovery ? "use in recovery" : "no use in recovery");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SchedulerTask::setup();
|
||||||
|
m_wasInitialized = true;
|
||||||
|
ESP_LOGI("BobbySchedulerTask", "Task %s initialized", name());
|
||||||
|
}
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
if (!m_in_recovery || m_use_in_recovery)
|
||||||
|
{
|
||||||
|
// ESP_LOGI("BobbySchedulerTask", "Loop %s", name());
|
||||||
|
SchedulerTask::loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
bool isInitialized() const { return m_wasInitialized; }
|
bool isInitialized() const { return m_wasInitialized; }
|
||||||
private:
|
private:
|
||||||
mutable bool m_wasInitialized{false};
|
mutable bool m_wasInitialized{false};
|
||||||
|
const bool m_use_in_recovery;
|
||||||
|
bool m_in_recovery{false};
|
||||||
};
|
};
|
||||||
|
56
main/displays/menus/recoverymenu.cpp
Normal file
56
main/displays/menus/recoverymenu.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "recoverymenu.h"
|
||||||
|
|
||||||
|
// 3dparty lib includes
|
||||||
|
#include <menuitem.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "actions/rebootaction.h"
|
||||||
|
#include "bobbycheckbox.h"
|
||||||
|
#include "bobbyerrorhandler.h"
|
||||||
|
#include "icons/reboot.h"
|
||||||
|
#include "newsettings.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr char TEXT_REBOOT[] = "Reboot";
|
||||||
|
}
|
||||||
|
|
||||||
|
class BasicFeatureFlagMenuItem : public espgui::MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BasicFeatureFlagMenuItem(ConfiguredFeatureFlag &flag) :
|
||||||
|
m_flag{flag}
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string text() const override
|
||||||
|
{
|
||||||
|
return m_flag.isEnabled.nvsName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void triggered() override
|
||||||
|
{
|
||||||
|
if (auto result = m_flag.isEnabled.write(configs.nvs_handle_user, !m_flag.isEnabled.value()); !result)
|
||||||
|
BobbyErrorHandler{}.errorOccurred(std::move(result).error());
|
||||||
|
}
|
||||||
|
|
||||||
|
const espgui::MenuItemIcon *icon() const override
|
||||||
|
{
|
||||||
|
return m_flag.isEnabled.value() ? &espgui::icons::checked : &espgui::icons::unchecked;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
ConfiguredFeatureFlag &m_flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
RecoveryMenu::RecoveryMenu()
|
||||||
|
{
|
||||||
|
using namespace espgui;
|
||||||
|
|
||||||
|
configs.callForEveryFeature([&](ConfiguredFeatureFlag &feature){
|
||||||
|
constructMenuItem<BasicFeatureFlagMenuItem>(feature);
|
||||||
|
});
|
||||||
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RecoveryMenu::text() const
|
||||||
|
{
|
||||||
|
return "Recovery Menu";
|
||||||
|
}
|
16
main/displays/menus/recoverymenu.h
Normal file
16
main/displays/menus/recoverymenu.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "displays/bobbymenudisplay.h"
|
||||||
|
|
||||||
|
class RecoveryMenu : public BobbyMenuDisplay
|
||||||
|
{
|
||||||
|
using Base = BobbyMenuDisplay;
|
||||||
|
public:
|
||||||
|
RecoveryMenu();
|
||||||
|
|
||||||
|
std::string text() const override;
|
||||||
|
|
||||||
|
void back() override {}
|
||||||
|
|
||||||
|
};
|
@ -15,6 +15,8 @@ using namespace std::chrono_literals;
|
|||||||
#include <espwifistack.h>
|
#include <espwifistack.h>
|
||||||
#include <schedulertask.h>
|
#include <schedulertask.h>
|
||||||
#include <screenmanager.h>
|
#include <screenmanager.h>
|
||||||
|
#include <tickchrono.h>
|
||||||
|
#include <espstrutils.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "bobbycar-common.h"
|
#include "bobbycar-common.h"
|
||||||
@ -29,16 +31,18 @@ using namespace std::chrono_literals;
|
|||||||
#else
|
#else
|
||||||
#include "modes/defaultmode.h"
|
#include "modes/defaultmode.h"
|
||||||
#endif
|
#endif
|
||||||
#include "displays/statusdisplay.h"
|
|
||||||
#include "displays/lockscreen.h"
|
|
||||||
#include "displays/potiscalibratedisplay.h"
|
|
||||||
#include "displays/buttoncalibratedisplay.h"
|
#include "displays/buttoncalibratedisplay.h"
|
||||||
|
#include "displays/lockscreen.h"
|
||||||
|
#include "displays/menus/recoverymenu.h"
|
||||||
|
#include "displays/potiscalibratedisplay.h"
|
||||||
|
#include "displays/statusdisplay.h"
|
||||||
#include "newsettings.h"
|
#include "newsettings.h"
|
||||||
#include "taskmanager.h"
|
#include "taskmanager.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
espchrono::millis_clock::time_point lastStatsPush;
|
espchrono::millis_clock::time_point lastStatsPush;
|
||||||
std::optional<espchrono::millis_clock::time_point> lastStatsUpdate;
|
std::optional<espchrono::millis_clock::time_point> lastStatsUpdate;
|
||||||
|
RTC_NOINIT_ATTR bool recovery;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
extern "C" void app_main()
|
extern "C" void app_main()
|
||||||
@ -48,6 +52,48 @@ extern "C" void app_main()
|
|||||||
digitalWrite(PINS_LEDBACKLIGHT, ledBacklightInverted ? LOW : HIGH);
|
digitalWrite(PINS_LEDBACKLIGHT, ledBacklightInverted ? LOW : HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (const auto reset_reason = esp_reset_reason(); reset_reason == ESP_RST_POWERON)
|
||||||
|
{
|
||||||
|
recovery = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recovery)
|
||||||
|
{
|
||||||
|
initScreen();
|
||||||
|
|
||||||
|
ESP_LOGE(TAG, "Recovery mode (%s)", espcpputils::toString(esp_reset_reason()).c_str());
|
||||||
|
bootLabel.redraw("Entering recovery mode");
|
||||||
|
|
||||||
|
if (const auto result = configs.init("bobbycar"); result != ESP_OK)
|
||||||
|
ESP_LOGE(TAG, "config_init_settings() failed with %s", esp_err_to_name(result));
|
||||||
|
|
||||||
|
for (auto &task : schedulerTasks)
|
||||||
|
{
|
||||||
|
task.setup(recovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
espgui::switchScreen<RecoveryMenu>();
|
||||||
|
|
||||||
|
recovery = false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto now = espchrono::millis_clock::now();
|
||||||
|
|
||||||
|
for (auto &schedulerTask : schedulerTasks)
|
||||||
|
{
|
||||||
|
if (schedulerTask.isInitialized())
|
||||||
|
schedulerTask.loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
espcpputils::delay(1ms);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recovery = true;
|
||||||
|
}
|
||||||
|
|
||||||
initScreen();
|
initScreen();
|
||||||
|
|
||||||
bootLabel.redraw("settings");
|
bootLabel.redraw("settings");
|
||||||
@ -67,12 +113,12 @@ extern "C" void app_main()
|
|||||||
else
|
else
|
||||||
ESP_LOGE("BOBBY", "init() failed");
|
ESP_LOGE("BOBBY", "init() failed");
|
||||||
|
|
||||||
for (const auto &task : schedulerTasks)
|
for (auto &task : schedulerTasks)
|
||||||
{
|
{
|
||||||
if (checkEnabledByName(task.name()))
|
if (checkEnabledByName(task.name()))
|
||||||
{
|
{
|
||||||
bootLabel.redraw(task.name());
|
bootLabel.redraw(task.name());
|
||||||
task.setup();
|
task.setup(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +159,12 @@ extern "C" void app_main()
|
|||||||
{
|
{
|
||||||
const auto now = espchrono::millis_clock::now();
|
const auto now = espchrono::millis_clock::now();
|
||||||
|
|
||||||
|
if (recovery && now.time_since_epoch() > 5s)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "Booting successful, disabling recovery...");
|
||||||
|
recovery = false;
|
||||||
|
}
|
||||||
|
|
||||||
// if (!heap_caps_check_integrity_all(true))
|
// if (!heap_caps_check_integrity_all(true))
|
||||||
// ESP_LOGW(TAG, "OIS IM OARSCH!!!!!");
|
// ESP_LOGW(TAG, "OIS IM OARSCH!!!!!");
|
||||||
|
|
||||||
@ -150,5 +202,7 @@ extern "C" void app_main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
espcpputils::delay(1ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,11 +470,11 @@ public:
|
|||||||
ConfiguredFeatureFlag garage {"f_garage" };
|
ConfiguredFeatureFlag garage {"f_garage" };
|
||||||
ConfiguredFeatureFlag cloud {"f_cloud", false, false, "cloud"};
|
ConfiguredFeatureFlag cloud {"f_cloud", false, false, "cloud"};
|
||||||
ConfiguredFeatureFlag udpcloud {"f_udpcloud", false, false, "udpcloud"};
|
ConfiguredFeatureFlag udpcloud {"f_udpcloud", false, false, "udpcloud"};
|
||||||
ConfiguredFeatureFlag dnsannounce {"f_dnsannounce"};
|
ConfiguredFeatureFlag dnsannounce {"f_dnsannounce", false, false, "dnsannounce"};
|
||||||
ConfiguredFeatureFlag ntp {"f_ntp", false, false, "time"};
|
ConfiguredFeatureFlag ntp {"f_ntp", false, false, "time"};
|
||||||
ConfiguredFeatureFlag ble {"f_ble", false, false, "ble"};
|
ConfiguredFeatureFlag ble {"f_ble", false, false, "ble"};
|
||||||
ConfiguredFeatureFlag ota {"f_ota", false, false, "ota"};
|
ConfiguredFeatureFlag ota {"f_ota", false, false, "ota"};
|
||||||
ConfiguredFeatureFlag webserver {"featureWebserv", true};
|
ConfiguredFeatureFlag webserver {"featureWebserv", true, false, "webserver"};
|
||||||
ConfiguredFeatureFlag gschissene_diode {"featurDiodeHin"};
|
ConfiguredFeatureFlag gschissene_diode {"featurDiodeHin"};
|
||||||
ConfiguredFeatureFlag esp_now {"featureEspNow", false, false, "espnow"};
|
ConfiguredFeatureFlag esp_now {"featureEspNow", false, false, "espnow"};
|
||||||
} feature;
|
} feature;
|
||||||
|
@ -52,43 +52,43 @@ constexpr const char * const TAG = "TASKS";
|
|||||||
void not_needed() {}
|
void not_needed() {}
|
||||||
|
|
||||||
BobbySchedulerTask schedulerTasksArr[] {
|
BobbySchedulerTask schedulerTasksArr[] {
|
||||||
BobbySchedulerTask { "wifi", wifi_begin, wifi_update, 100ms },
|
BobbySchedulerTask { "wifi", wifi_begin, wifi_update, 100ms, false },
|
||||||
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined(FEATURE_DPAD_6WIRESW) || defined(DPAD_BOARDCOMPUTER_V2)
|
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined(FEATURE_DPAD_6WIRESW) || defined(DPAD_BOARDCOMPUTER_V2)
|
||||||
BobbySchedulerTask { bobbydpad::dpad_name, bobbydpad::dpad_init, bobbydpad::dpad_update, 20ms },
|
BobbySchedulerTask { bobbydpad::dpad_name, bobbydpad::dpad_init, bobbydpad::dpad_update, 20ms, true },
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEATURE_ROTARY
|
#ifdef FEATURE_ROTARY
|
||||||
BobbySchedulerTask { "rotary", initRotary, updateRotary, 20ms },
|
BobbySchedulerTask { "rotary", initRotary, updateRotary, 20ms, false },
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEATURE_MOSFETS
|
#ifdef FEATURE_MOSFETS
|
||||||
BobbySchedulerTask { "mosfets", init_mosfets, update_mosfets, 100ms },
|
BobbySchedulerTask { "mosfets", init_mosfets, update_mosfets, 100ms, false },
|
||||||
#endif
|
#endif
|
||||||
BobbySchedulerTask { "time", initTime, updateTime, 100ms },
|
BobbySchedulerTask { "time", initTime, updateTime, 100ms, false },
|
||||||
BobbySchedulerTask { "potis", initPotis, readPotis, 20ms },
|
BobbySchedulerTask { "potis", initPotis, readPotis, 20ms, false },
|
||||||
#ifdef FEATURE_BLUETOOTH
|
#ifdef FEATURE_BLUETOOTH
|
||||||
BobbySchedulerTask { "bluetooth", bluetooth_init, bluetooth_update, 100ms },
|
BobbySchedulerTask { "bluetooth", bluetooth_init, bluetooth_update, 100ms, false },
|
||||||
#ifdef FEATURE_BMS
|
#ifdef FEATURE_BMS
|
||||||
BobbySchedulerTask { "bms", bms::init, bms::update, 100ms },
|
BobbySchedulerTask { "bms", bms::init, bms::update, 100ms, false },
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEATURE_CAN
|
#ifdef FEATURE_CAN
|
||||||
BobbySchedulerTask { "can", can::initCan, can::updateCan, 10ms },
|
BobbySchedulerTask { "can", can::initCan, can::updateCan, 10ms, false },
|
||||||
#endif
|
#endif
|
||||||
BobbySchedulerTask { "debuginput", initDebugInput, handleDebugInput, 50ms },
|
BobbySchedulerTask { "debuginput", initDebugInput, handleDebugInput, 50ms, true },
|
||||||
#ifdef FEATURE_SERIAL
|
#ifdef FEATURE_SERIAL
|
||||||
BobbySchedulerTask { "serial", initSerial, updateSerial, 50ms },
|
BobbySchedulerTask { "serial", initSerial, updateSerial, 50ms, false },
|
||||||
#endif
|
#endif
|
||||||
BobbySchedulerTask { "ota", initOta, handleOta, 50ms },
|
BobbySchedulerTask { "ota", initOta, handleOta, 50ms, false },
|
||||||
BobbySchedulerTask { "ble", initBle, handleBle, 100ms },
|
BobbySchedulerTask { "ble", initBle, handleBle, 100ms, false },
|
||||||
BobbySchedulerTask { "webserver", initWebserver, handleWebserver, 100ms },
|
BobbySchedulerTask { "webserver", initWebserver, handleWebserver, 100ms, false },
|
||||||
BobbySchedulerTask { "ledstrip", initLedStrip, updateLedStrip, 30ms },
|
BobbySchedulerTask { "ledstrip", initLedStrip, updateLedStrip, 30ms, false },
|
||||||
BobbySchedulerTask { "espnow", espnow::initESPNow, espnow::handle, 100ms },
|
BobbySchedulerTask { "espnow", espnow::initESPNow, espnow::handle, 100ms, false },
|
||||||
BobbySchedulerTask { "cloud", initCloud, updateCloud, 50ms },
|
BobbySchedulerTask { "cloud", initCloud, updateCloud, 50ms, false },
|
||||||
BobbySchedulerTask { "udpcloud", udpCloudInit, udpCloudUpdate, 50ms },
|
BobbySchedulerTask { "udpcloud", udpCloudInit, udpCloudUpdate, 50ms, false },
|
||||||
BobbySchedulerTask { "drivingmode", initDrivingMode, updateDrivingMode, 20ms },
|
BobbySchedulerTask { "drivingmode", initDrivingMode, updateDrivingMode, 20ms, false },
|
||||||
BobbySchedulerTask { "drivingstatistics", initStatistics, calculateStatistics, 100ms },
|
BobbySchedulerTask { "drivingstatistics", initStatistics, calculateStatistics, 100ms, false },
|
||||||
BobbySchedulerTask { "dnsannounce", init_dns_announce, handle_dns_announce, 100ms },
|
BobbySchedulerTask { "dnsannounce", init_dns_announce, handle_dns_announce, 100ms, false },
|
||||||
BobbySchedulerTask { "updateDisp", not_needed, updateDisplay, 20ms },
|
BobbySchedulerTask { "updateDisp", not_needed, updateDisplay, 20ms, true },
|
||||||
BobbySchedulerTask { "redrawDisp", not_needed, redrawDisplay, 20ms },
|
BobbySchedulerTask { "redrawDisp", not_needed, redrawDisplay, 20ms, true },
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user