This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

EEPROM layout any support?

I apologize for the maybe stupid question.
For the first time planning to use EEPROM for a larger number of calibration constants, saving operating modes (such as the number of starts) and logging errors.
Seeking examples or libraries for this purpose.
Pperhaps a graphical utility for assigning addresses and generating an address in EEPROM

Parents
  • Not sure why a graphical tool would be helpful.

    Enumerated addresses are normally handled with enum { ... }.

    Or you could create a struct:

    enum {
        NUM_UNITS = 4,
        NUM_ERRORS = 16,
    };
    struct error {
        uint32_t time;    // unix epoch of error - 0xffffffff if empty entry.
        uint32_t uptime;  // uptime in seconds when error detected
        uint8_t errcode;
        uint8_t subcode;
        uint16_t misc;
    };
    
    // Use this struct to retrieve the offset of individual fields in the EEPROM
    // Optionally make the structure packed, in case there is no need to also keep
    // a RAM copy of the data.
    struct eeprom { // <= optionally make structure packed
        uint16_t magic;                           // Magic value that EEPROM is initialized
        uint16_t version;                         // Version information of data.
        uint32_t num_reboots;                     // # of times program has booted
        uint32_t num_watchdog;                    // # of times program has had wd reset.
        uint32_t num_starts[NUM_UNITS];           // Total # of motor starts
        uint64_t num_seconds[NUM_UNITS];          // Total # of seconds of running time
        uint32_t num_startup_seconds[NUM_UNITS];  // Total # of seconds to nominal RPM
        uint32_t last_startup_seconds[NUM_UNITS]; // # of seconds to nominal RPM for last start
        ...
        // Last error codes in a circular buffer.
        struct error err_log[NUM_ERRORS];
    };
    
    bool read_eeprom_u8(unsigned offset,uint8 *val);
    bool read_eeprom_u16(unsigned offset,uint16 *val);
    bool read_eeprom_u32(unsigned offset,uint32 *val);
    bool read_eeprom_u64(unsigned offset,uint64 *val);
    bool read_eeprom_raw(unsigned offset,void *p,unsigned len);
    bool read_log_entry(unsigned seq,struct error *err);
    bool write_eeprom_u8(unsigned offset,uint8 val);
    bool write_eeprom_u16(unsigned offset,uint16 val);
    bool write_eeprom_u32(unsigned offset,uint32 val);
    bool write_eeprom_u64(unsigned offset,uint64 val);
    bool write_eeprom_raw(unsigned offset,const void *p,unsigned len);
    bool write_log_entry(const struct error *err);
    

    Next thing is if you have individual entries you will write so often, that you might need to rotate the writes over multiple cells for wear leveling - but that is often not needed since traditional EEPROM normally supports many times more writes than flash memory.

    Just remember that if you release a new firmware that changes the layout of the EEPROM data, you either need to erase all EEPROM data, or write code that either adapts to new/old layout or reads out the old information and then writes it back in the newer format. So it's good to have some version information in the EEPROM so you know the format of the current data.

Reply
  • Not sure why a graphical tool would be helpful.

    Enumerated addresses are normally handled with enum { ... }.

    Or you could create a struct:

    enum {
        NUM_UNITS = 4,
        NUM_ERRORS = 16,
    };
    struct error {
        uint32_t time;    // unix epoch of error - 0xffffffff if empty entry.
        uint32_t uptime;  // uptime in seconds when error detected
        uint8_t errcode;
        uint8_t subcode;
        uint16_t misc;
    };
    
    // Use this struct to retrieve the offset of individual fields in the EEPROM
    // Optionally make the structure packed, in case there is no need to also keep
    // a RAM copy of the data.
    struct eeprom { // <= optionally make structure packed
        uint16_t magic;                           // Magic value that EEPROM is initialized
        uint16_t version;                         // Version information of data.
        uint32_t num_reboots;                     // # of times program has booted
        uint32_t num_watchdog;                    // # of times program has had wd reset.
        uint32_t num_starts[NUM_UNITS];           // Total # of motor starts
        uint64_t num_seconds[NUM_UNITS];          // Total # of seconds of running time
        uint32_t num_startup_seconds[NUM_UNITS];  // Total # of seconds to nominal RPM
        uint32_t last_startup_seconds[NUM_UNITS]; // # of seconds to nominal RPM for last start
        ...
        // Last error codes in a circular buffer.
        struct error err_log[NUM_ERRORS];
    };
    
    bool read_eeprom_u8(unsigned offset,uint8 *val);
    bool read_eeprom_u16(unsigned offset,uint16 *val);
    bool read_eeprom_u32(unsigned offset,uint32 *val);
    bool read_eeprom_u64(unsigned offset,uint64 *val);
    bool read_eeprom_raw(unsigned offset,void *p,unsigned len);
    bool read_log_entry(unsigned seq,struct error *err);
    bool write_eeprom_u8(unsigned offset,uint8 val);
    bool write_eeprom_u16(unsigned offset,uint16 val);
    bool write_eeprom_u32(unsigned offset,uint32 val);
    bool write_eeprom_u64(unsigned offset,uint64 val);
    bool write_eeprom_raw(unsigned offset,const void *p,unsigned len);
    bool write_log_entry(const struct error *err);
    

    Next thing is if you have individual entries you will write so often, that you might need to rotate the writes over multiple cells for wear leveling - but that is often not needed since traditional EEPROM normally supports many times more writes than flash memory.

    Just remember that if you release a new firmware that changes the layout of the EEPROM data, you either need to erase all EEPROM data, or write code that either adapts to new/old layout or reads out the old information and then writes it back in the newer format. So it's good to have some version information in the EEPROM so you know the format of the current data.

Children