Skip to content

Commit

Permalink
Support eeprom update notification. (#499)
Browse files Browse the repository at this point in the history
Adds a weak callback to the eepromemulation driver, triggered
after each write is completed.

Shows with an example how to use this to automatically apply changes
that happened from JMRI configuration UI.
  • Loading branch information
balazsracz authored Jan 1, 2021
1 parent 3e486ff commit b476403
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ openlcb::ConfiguredProducer producer_sw2(
openlcb::RefreshLoop loop(
stack.node(), {producer_sw1.polling(), producer_sw2.polling()});

/// This timer checks the eeprom once a second and if the user has written
/// something, executes a reload of the configuration via the OpenLCB config
/// service.
class AutoUpdateTimer : public ::Timer
{
public:
AutoUpdateTimer()
: ::Timer(stack.executor()->active_timers())
{
start(SEC_TO_NSEC(1));
}

long long timeout() override
{
extern uint8_t eeprom_updated;
if (eeprom_updated)
{
needUpdate_ = true;
eeprom_updated = 0;
}
else
{
if (needUpdate_)
{
stack.config_service()->trigger_update();
needUpdate_ = false;
}
}
return RESTART;
}

bool needUpdate_ {false};
} update_timer;

/** Entry point to application.
* @param argc number of command line arguments
* @param argv array of command line arguments
Expand Down
9 changes: 9 additions & 0 deletions boards/ti-ek-tm4c123gxl-launchpad/HwInit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ StoredBitSet* g_gpio_stored_bit_set = nullptr;
constexpr unsigned EEPROM_BIT_COUNT = 84;
constexpr unsigned EEPROM_BITS_PER_CELL = 28;

/// This variable will be set to 1 when a write arrives to the eeprom.
uint8_t eeprom_updated = 0;

// Overridesthe default behavior to keep track of eeprom writes.
void EEPROMEmulation::updated_notification()
{
eeprom_updated = 1;
}

extern "C" {
void hw_set_to_safe(void);

Expand Down
2 changes: 2 additions & 0 deletions src/freertos_drivers/common/EEPROMEmulation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ void EEPROMEmulation::write(unsigned int index, const void *buf, size_t len)
{
memcpy(shadow_ + shadow_index, shadow_data, shadow_len);
}

updated_notification();
}

/** Write to the EEPROM on a native block boundary.
Expand Down
6 changes: 6 additions & 0 deletions src/freertos_drivers/common/EEPROMEmulation.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ protected:
static const size_t BLOCK_SIZE;

private:
/** This function will be called after every write. The default
* implementation is a weak symbol with an empty function. It is intended
* to be overridden in the application to get callbacks for eeprom writes
* that can trigger a reload. */
void updated_notification();

/** Write to the EEPROM. NOTE!!! This is not necessarily atomic across
* byte boundaries in the case of power loss. The user should take this
* into account as it relates to data integrity of a whole block.
Expand Down
8 changes: 8 additions & 0 deletions src/freertos_drivers/common/EEPROMEmulation_weak.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@
// emulation implementation to prevent GCC from mistakenly optimizing away the
// constant into a linker reference.
const bool __attribute__((weak)) EEPROMEmulation::SHADOW_IN_RAM = false;

/// This function will be called after every write. The default
/// implementation is a weak symbol with an empty function. It is intended
/// to be overridden in the application to get callbacks for eeprom writes
/// that can trigger a reload.
void __attribute__((weak)) EEPROMEmulation::updated_notification()
{
}

0 comments on commit b476403

Please sign in to comment.