Fix crash when flash is written too frequently (#18)

This commit is contained in:
J. Nick Koston 2023-06-25 10:45:37 -05:00 committed by GitHub
parent a38b18aa20
commit 385a89507b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 15 deletions

View File

@ -6,6 +6,9 @@ external_components:
url: https://github.com/esphome-ratgdo/esphome-ratgdo url: https://github.com/esphome-ratgdo/esphome-ratgdo
refresh: 1s refresh: 1s
preferences:
flash_write_interval: 5s
ratgdo: ratgdo:
id: ${id_prefix} id: ${id_prefix}
input_gdo_pin: ${uart_rx_pin} input_gdo_pin: ${uart_rx_pin}

View File

@ -22,7 +22,17 @@ namespace ratgdo {
static const char* const TAG = "ratgdo"; static const char* const TAG = "ratgdo";
static const int SYNC_DELAY = 2000; static const int SYNC_DELAY = 2000;
static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 3; //
// MAX_CODES_WITHOUT_FLASH_WRITE is a bit of a guess
// since we write the flash at most every every 5s
//
// We want the rolling counter to be high enough that the
// GDO will accept the command after an unexpected reboot
// that did not save the counter to flash in time which
// results in the rolling counter being behind what the GDO
// expects.
//
static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 5;
static const uint32_t FLASH_WRITE_INTERVAL = 10000; static const uint32_t FLASH_WRITE_INTERVAL = 10000;
void IRAM_ATTR HOT RATGDOStore::isrObstruction(RATGDOStore* arg) void IRAM_ATTR HOT RATGDOStore::isrObstruction(RATGDOStore* arg)
@ -55,9 +65,6 @@ namespace ratgdo {
this->input_obst_pin_->attach_interrupt(RATGDOStore::isrObstruction, &this->store_, gpio::INTERRUPT_ANY_EDGE); this->input_obst_pin_->attach_interrupt(RATGDOStore::isrObstruction, &this->store_, gpio::INTERRUPT_ANY_EDGE);
// save counter to flash every 10s if it changed
set_interval(FLASH_WRITE_INTERVAL, std::bind(&RATGDOComponent::saveCounter, this, 1));
ESP_LOGV(TAG, "Syncing rolling code counter after reboot..."); ESP_LOGV(TAG, "Syncing rolling code counter after reboot...");
// many things happening at startup, use some delay for sync // many things happening at startup, use some delay for sync
@ -447,7 +454,7 @@ namespace ratgdo {
delayMicroseconds(1260); // "LOW" pulse duration before the message start delayMicroseconds(1260); // "LOW" pulse duration before the message start
this->swSerial.write(this->txRollingCode, CODE_LENGTH); this->swSerial.write(this->txRollingCode, CODE_LENGTH);
saveCounter(MAX_CODES_WITHOUT_FLASH_WRITE); saveCounter();
} }
void RATGDOComponent::sync() void RATGDOComponent::sync()
@ -545,16 +552,12 @@ namespace ratgdo {
transmit(command::LOCK, data::TOGGLE); transmit(command::LOCK, data::TOGGLE);
} }
void RATGDOComponent::saveCounter(int threshold) void RATGDOComponent::saveCounter()
{ {
this->pref_.save(&this->rollingCodeCounter); this->pref_.save(&this->rollingCodeCounter);
if (!this->lastSyncedRollingCodeCounter || this->rollingCodeCounter - this->lastSyncedRollingCodeCounter >= threshold) { // Forcing a sync results in a soft reset if there are too many
// do flash write outside of the component loop // writes to flash in a short period of time. To avoid this,
defer([=] { // we have configured preferences to write every 5s
this->lastSyncedRollingCodeCounter = this->rollingCodeCounter;
global_preferences->sync();
});
}
} }
void RATGDOComponent::register_child(RATGDOClient* obj) void RATGDOComponent::register_child(RATGDOClient* obj)

View File

@ -160,7 +160,7 @@ namespace ratgdo {
void obstructionLoop(); void obstructionLoop();
void statusUpdateLoop(); void statusUpdateLoop();
void saveCounter(int threshold); void saveCounter();
void doorCommand(uint32_t data); void doorCommand(uint32_t data);