Add new screen that allows the user to manually validate the new firmware he's just OTA'ed.

Still need to find a way to display this screen when needed.
This commit is contained in:
JF 2020-08-11 17:50:00 +02:00
parent 27fa273d83
commit bbfc20c3ff
8 changed files with 179 additions and 9 deletions

View file

@ -337,6 +337,7 @@ list(APPEND SOURCE_FILES
DisplayApp/Screens/Label.cpp
DisplayApp/Screens/FirmwareUpdate.cpp
DisplayApp/Screens/Music.cpp
DisplayApp/Screens/FirmwareValidation.cpp
main.cpp
drivers/St7789.cpp
drivers/SpiNorFlash.cpp
@ -358,6 +359,7 @@ list(APPEND SOURCE_FILES
Components/Ble/CurrentTimeService.cpp
Components/Ble/AlertNotificationService.cpp
Components/Ble/MusicService.cpp
Components/FirmwareValidator/FirmwareValidator.cpp
drivers/Cst816s.cpp
FreeRTOS/port.c
FreeRTOS/port_cmsis_systick.c
@ -415,6 +417,7 @@ set(INCLUDE_FILES
DisplayApp/Screens/ScreenList.h
DisplayApp/Screens/Label.h
DisplayApp/Screens/FirmwareUpdate.h
DisplayApp/Screens/FirmwareValidation.h
drivers/St7789.h
drivers/SpiNorFlash.h
drivers/SpiMaster.h
@ -432,7 +435,8 @@ set(INCLUDE_FILES
Components/Ble/CurrentTimeClient.h
Components/Ble/AlertNotificationClient.h
Components/Ble/DfuService.h
drivers/Cst816s.h
Components/FirmwareValidator/FirmwareValidator.h
drivers/Cst816s.h
FreeRTOS/portmacro.h
FreeRTOS/portmacro_cmsis.h
libs/date/includes/date/tz.h

View file

@ -0,0 +1,20 @@
#include <drivers/InternalFlash.h>
#include <hal/nrf_rtc.h>
#include "FirmwareValidator.h"
using namespace Pinetime::Controllers;
bool FirmwareValidator::IsValidated() const {
auto* imageOkPtr = reinterpret_cast<uint32_t *>(validBitAdress);
return (*imageOkPtr) == validBitValue;
}
void FirmwareValidator::Validate() {
if(!IsValidated())
Pinetime::Drivers::InternalFlash::WriteWord(validBitAdress, validBitValue);
}
void FirmwareValidator::Reset() {
NVIC_SystemReset();
}

View file

@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
namespace Pinetime {
namespace Controllers {
class FirmwareValidator {
public:
void Validate();
bool IsValidated() const;
void Reset();
private:
static constexpr uint32_t validBitAdress {0x7BFE8};
static constexpr uint32_t validBitValue {1};
};
}
}

View file

@ -18,6 +18,7 @@
#include <DisplayApp/Screens/Music.h>
#include <Components/Ble/NotificationManager.h>
#include <DisplayApp/Screens/FirmwareUpdate.h>
#include <DisplayApp/Screens/FirmwareValidation.h>
#include "../SystemTask/SystemTask.h"
using namespace Pinetime::Applications;

View file

@ -17,6 +17,7 @@
#include <drivers/Watchdog.h>
#include <DisplayApp/Screens/Modal.h>
#include <Components/Ble/NotificationManager.h>
#include <Components/FirmwareValidator/FirmwareValidator.h>
#include "TouchEvents.h"
@ -80,6 +81,7 @@ namespace Pinetime {
Controllers::BrightnessController brightnessController;
std::unique_ptr<Screens::Modal> modal;
Pinetime::Controllers::NotificationManager& notificationManager;
Pinetime::Controllers::FirmwareValidator validator;
};
}
}

View file

@ -0,0 +1,91 @@
#include <libs/lvgl/lvgl.h>
#include "FirmwareValidation.h"
#include "../DisplayApp.h"
#include "../../Version.h"
#include "../../Components/FirmwareValidator/FirmwareValidator.h"
using namespace Pinetime::Applications::Screens;
extern lv_font_t jetbrains_mono_extrabold_compressed;
extern lv_font_t jetbrains_mono_bold_20;
namespace {
static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event)
{
FirmwareValidation* screen = static_cast<FirmwareValidation *>(obj->user_data);
screen->OnButtonEvent(obj, event);
}
}
FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app,
Pinetime::Controllers::FirmwareValidator &validator)
: Screen{app}, validator{validator} {
labelVersionInfo = lv_label_create(lv_scr_act(), NULL);
lv_obj_align(labelVersionInfo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);
lv_label_set_text(labelVersionInfo, "Version : ");
lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT);
labelVersionValue = lv_label_create(lv_scr_act(), NULL);
lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
lv_label_set_recolor(labelVersionValue, true);
sprintf(version, "%d.%d.%d", Version::Major(), Version::Minor(), Version::Patch());
lv_label_set_text(labelVersionValue, version);
labelIsValidated = lv_label_create(lv_scr_act(), NULL);
lv_obj_align(labelIsValidated, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50);
lv_label_set_recolor(labelIsValidated, true);
lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK);
lv_obj_set_width(labelIsValidated, 240);
if(validator.IsValidated())
lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#");
else {
lv_label_set_text(labelIsValidated,
"Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version.");
buttonValidate = lv_btn_create(lv_scr_act(), NULL);
lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
buttonValidate->user_data = this;
lv_obj_set_event_cb(buttonValidate, ButtonEventHandler);
labelButtonValidate = lv_label_create(buttonValidate, NULL);
lv_label_set_recolor(labelButtonValidate, true);
lv_label_set_text(labelButtonValidate, "#00ff00 Validate#");
buttonReset = lv_btn_create(lv_scr_act(), NULL);
buttonReset->user_data = this;
lv_obj_align(buttonReset, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
lv_obj_set_event_cb(buttonReset, ButtonEventHandler);
labelButtonReset = lv_label_create(buttonReset, NULL);
lv_label_set_recolor(labelButtonReset, true);
lv_label_set_text(labelButtonReset, "#ff0000 Reset#");
}
}
FirmwareValidation::~FirmwareValidation() {
lv_obj_clean(lv_scr_act());
}
bool FirmwareValidation::Refresh() {
return running;
}
bool FirmwareValidation::OnButtonPushed() {
running = false;
return true;
}
void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) {
if(object == buttonValidate && event == LV_EVENT_PRESSED) {
validator.Validate();
running = false;
} else if(object == buttonReset && event == LV_EVENT_PRESSED) {
validator.Reset();
}
}

View file

@ -0,0 +1,42 @@
#pragma once
#include <cstdint>
#include "Screen.h"
#include <bits/unique_ptr.h>
#include <libs/lvgl/src/lv_core/lv_style.h>
#include <libs/lvgl/src/lv_core/lv_obj.h>
namespace Pinetime {
namespace Controllers {
class FirmwareValidator;
}
namespace Applications {
namespace Screens {
class FirmwareValidation : public Screen{
public:
FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator);
~FirmwareValidation() override;
bool Refresh() override;
bool OnButtonPushed() override;
void OnButtonEvent(lv_obj_t *object, lv_event_t event);
private:
Pinetime::Controllers::FirmwareValidator& validator;
lv_obj_t* labelVersionInfo;
lv_obj_t* labelVersionValue;
char version[9];
lv_obj_t* labelIsValidated;
lv_obj_t* buttonValidate;
lv_obj_t* labelButtonValidate;
lv_obj_t* buttonReset;
lv_obj_t* labelButtonReset;
bool running = true;
};
}
}
}

View file

@ -58,14 +58,6 @@ void SystemTask::Work() {
spi.Init();
spiNorFlash.Init();
// Write the 'image OK' flag if it's not already done
// TODO implement a better verification mecanism for the image (ask for user confirmation via UI/BLE ?)
uint32_t* imageOkPtr = reinterpret_cast<uint32_t *>(0x7BFE8);
uint32_t imageOk = *imageOkPtr;
if(imageOk != 1)
Pinetime::Drivers::InternalFlash::WriteWord(0x7BFE8, 1);
nimbleController.Init();
nimbleController.StartAdvertising();
lcd.Init();