Move most of the code from the constructor of the objects statically initialized in main() into Start()/Init() functions to avoid Static Initialization Order Fiasco (https://en.cppreference.com/w/cpp/language/siof). See https://github.com/JF002/InfiniTime/pull/415#issuecomment-859004238.

This commit is contained in:
Jean-François Milants 2021-06-12 10:58:28 +02:00
parent b1925ff286
commit 6d524ebea2
11 changed files with 30 additions and 12 deletions

View File

@ -77,12 +77,14 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
motorController {motorController}, motorController {motorController},
motionController {motionController}, motionController {motionController},
timerController {timerController} { timerController {timerController} {
msgQueue = xQueueCreate(queueSize, itemSize);
// Start clock when smartwatch boots
LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None);
} }
void DisplayApp::Start() { void DisplayApp::Start() {
msgQueue = xQueueCreate(queueSize, itemSize);
// Start clock when smartwatch boots
LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None);
if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) { if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) {
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
} }

View File

@ -21,10 +21,11 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::MotionController& motionController,
Pinetime::Controllers::TimerController& timerController) Pinetime::Controllers::TimerController& timerController)
: lcd {lcd}, bleController {bleController} { : lcd {lcd}, bleController {bleController} {
msgQueue = xQueueCreate(queueSize, itemSize);
} }
void DisplayApp::Start() { void DisplayApp::Start() {
msgQueue = xQueueCreate(queueSize, itemSize);
if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 512, this, 0, &taskHandle)) if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 512, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
} }

View File

@ -23,6 +23,10 @@ bool touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data) {
LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel)
: lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} { : lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} {
}
void LittleVgl::Init() {
lv_init(); lv_init();
InitTheme(); InitTheme();
InitDisplay(); InitDisplay();

View File

@ -19,6 +19,8 @@ namespace Pinetime {
LittleVgl(LittleVgl&&) = delete; LittleVgl(LittleVgl&&) = delete;
LittleVgl& operator=(LittleVgl&&) = delete; LittleVgl& operator=(LittleVgl&&) = delete;
void Init();
void FlushDisplay(const lv_area_t* area, lv_color_t* color_p); void FlushDisplay(const lv_area_t* area, lv_color_t* color_p);
bool GetTouchPadInfo(lv_indev_data_t* ptr); bool GetTouchPadInfo(lv_indev_data_t* ptr);
void SetFullRefresh(FullRefreshDirections direction); void SetFullRefresh(FullRefreshDirections direction);

View File

@ -7,11 +7,14 @@
using namespace Pinetime::Drivers; using namespace Pinetime::Drivers;
SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters& params) : spi {spi}, params {params} { SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters& params) : spi {spi}, params {params} {
mutex = xSemaphoreCreateBinary();
ASSERT(mutex != NULL);
} }
bool SpiMaster::Init() { bool SpiMaster::Init() {
if(mutex == nullptr) {
mutex = xSemaphoreCreateBinary();
ASSERT(mutex != nullptr);
}
/* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */ /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */
nrf_gpio_pin_set(params.pinSCK); nrf_gpio_pin_set(params.pinSCK);
nrf_gpio_cfg_output(params.pinSCK); nrf_gpio_cfg_output(params.pinSCK);

View File

@ -59,7 +59,7 @@ namespace Pinetime {
volatile uint32_t currentBufferAddr = 0; volatile uint32_t currentBufferAddr = 0;
volatile size_t currentBufferSize = 0; volatile size_t currentBufferSize = 0;
volatile TaskHandle_t taskToNotify; volatile TaskHandle_t taskToNotify;
SemaphoreHandle_t mutex; SemaphoreHandle_t mutex = nullptr;
}; };
} }
} }

View File

@ -9,10 +9,12 @@ using namespace Pinetime::Drivers;
// TODO use DMA/IRQ // TODO use DMA/IRQ
TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} { TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} {
mutex = xSemaphoreCreateBinary();
} }
void TwiMaster::Init() { void TwiMaster::Init() {
if(mutex == nullptr)
mutex = xSemaphoreCreateBinary();
NRF_GPIO->PIN_CNF[params.pinScl] = NRF_GPIO->PIN_CNF[params.pinScl] =
((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |

View File

@ -31,7 +31,7 @@ namespace Pinetime {
ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop);
void FixHwFreezed(); void FixHwFreezed();
NRF_TWIM_Type* twiBaseAddress; NRF_TWIM_Type* twiBaseAddress;
SemaphoreHandle_t mutex; SemaphoreHandle_t mutex = nullptr;
const Modules module; const Modules module;
const Parameters params; const Parameters params;
static constexpr uint8_t maxDataSize {16}; static constexpr uint8_t maxDataSize {16};

View File

@ -7,11 +7,12 @@ using namespace Pinetime::Applications;
HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller)
: heartRateSensor {heartRateSensor}, controller {controller}, ppg{} { : heartRateSensor {heartRateSensor}, controller {controller}, ppg{} {
messageQueue = xQueueCreate(10, 1);
controller.SetHeartRateTask(this);
} }
void HeartRateTask::Start() { void HeartRateTask::Start() {
messageQueue = xQueueCreate(10, 1);
controller.SetHeartRateTask(this);
if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle)) if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
} }

View File

@ -306,6 +306,8 @@ int main(void) {
debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback);
debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback);
lvgl.Init();
systemTask.Start(); systemTask.Start();
nimble_port_init(); nimble_port_init();

View File

@ -81,10 +81,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
motionController{motionController}, motionController{motionController},
displayApp{displayApp}, displayApp{displayApp},
heartRateApp(heartRateApp) { heartRateApp(heartRateApp) {
systemTasksMsgQueue = xQueueCreate(10, 1);
} }
void SystemTask::Start() { void SystemTask::Start() {
systemTasksMsgQueue = xQueueCreate(10, 1);
if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle)) if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle))
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
} }