Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update settings.cpp with #if - saves memory #27000

Conversation

classicrocker883
Copy link
Contributor

Description

Adding #if/#endif to SettingsDataStruct and MarlinUI::save/_load.

what this basically does is save flash memory

Requirements

Benefits

depending what is disabled, a user can save hundreds of bytes or even over 1k.

Configurations

Related Issues

@sjasonsmith
Copy link
Contributor

I am quite sure that the current behavior is intentional, in order to lessen the chance of invalidating the EEPROM contents when they make minor changes to their configuration.

I don't really care about the size inside the EEPROM (or flash-based settings), unless we are hitting limits and causing issues.

Of more interest would be the impact on code size. If this makes a substantial difference it could enable small devices to stay relevant longer, although that would come at the cost of more frequent "Invalid EEPROM" messages for everyone that didn't need it.

@thisiskeithb
Copy link
Member

I am quite sure that the current behavior is intentional, in order to lessen the chance of invalidating the EEPROM contents when they make minor changes to their configuration.

Indeed: #26158 (comment)

@thinkyhead thinkyhead closed this Apr 23, 2024
@classicrocker883
Copy link
Contributor Author

classicrocker883 commented Apr 23, 2024

@thinkyhead you mention an example of this implementation. can we open somewhere so this can be discussed? for instance here is an example i was able to conjure up:

Example 1:

#include <EEPROM.h>

// Define a template class for feature-specific settings
template <typename T>
class MarlinSettings {
public:
    // Structure to hold feature settings
    struct Settings {
        char identifier[5]; // 4 char identifier (e.g., "ABCD")
        uint16_t version;   // Version number (2 bytes)
        uint16_t size;      // Size of data
        T data;             // Feature-specific data
        
        uint16_t crc;       // CRC for data integrity
    };

    // Read feature settings from EEPROM
    static void readSettings(Settings& settings, int address) {
        EEPROM.get(address, settings);
    }

    // Write feature settings to EEPROM
    static void writeSettings(const Settings& settings, int address) {
        EEPROM.put(address, settings);
    }

    // Reset feature settings
    static void resetSettings(Settings& settings) {
        // Implement reset logic here
    }

    // Report feature settings
    static void reportSettings(const Settings& settings) {
        // Implement reporting logic here
    }

    // Update feature settings from an older version
    static void updateSettings(Settings& settings, uint16_t oldVersion) {
        // Implement update logic here based on oldVersion
    }
};

// Example usage for MarlinSettings
struct MyFeatureData {
    int value1;
    float value2;
};

using SettingsData = MarlinSettings<MyFeatureData>;

// Refactored MarlinSettings class
class MarlinSettings {
public:
    static EEPROM_Error load() {
        EEPROM_Error eeprom_error = ERR_EEPROM_NOERR;

        if (!EEPROM_START(EEPROM_OFFSET)) return eeprom_error;

        char stored_ver[5];
        EEPROM_READ_ALWAYS(stored_ver);

        uint16_t stored_crc;

        do {
            #if ENABLED(EEPROM_INIT_NOW)
                uint32_t stored_hash;
                EEPROM_READ_ALWAYS(stored_hash);
                if (stored_hash != build_hash) {
                    eeprom_error = ERR_EEPROM_CORRUPT;
                    break;
                }
            #endif
        } while (0);

        return eeprom_error;
    }
};

void setup() {
    SettingsData::Settings settings;
    
    // Read feature settings from EEPROM using MarlinSettings
    SettingsData::readSettings(settings, 0);
    
    // Use feature settings
    Serial.begin(9600);
    Serial.print("Value 1: ");
    Serial.println(settings.data.value1);
    Serial.print("Value 2: ");
    Serial.println(settings.data.value2);
    
    // Update feature settings if needed
    SettingsData::updateSettings(settings, settings.version);
    
    // Write feature settings back to EEPROM using MarlinSettings
    SettingsData::writeSettings(settings, 0);
}

void loop() {
    // Main loop logic
}

Example 2:

#include <EEPROM.h>

// Define the structure for storing feature settings in EEPROM
struct FeatureSettings {
  char identifier[5]; // 4 char identifier + null terminator
  uint16_t version;
  uint16_t size;
  uint16_t crc;
  // Add other settings specific to the feature here
};

// Template class for handling EEPROM operations for individual features
template <class T>
class MarlinSettings {
public:
  void writeSettings(const T& settings, int address) {
    EEPROM.put(address, settings);
  }

  void readSettings(T& settings, int address) {
    EEPROM.get(address, settings);
  }

  void resetSettings(int address) {
    T defaultSettings;
    writeSettings(defaultSettings, address);
  }
};

// Example usage of MarlinSettings with FeatureSettings structure
MarlinSettings<FeatureSettings> marlinFeatureSettings;

// Example feature-specific settings
FeatureSettings feature1Settings = {"ABCD", 1, sizeof(FeatureSettings), 0};
FeatureSettings feature2Settings = {"EFGH", 1, sizeof(FeatureSettings), 0};

void setup() {
  // Initialize EEPROM
  EEPROM.begin(512);

  // Write feature settings to EEPROM
  marlinFeatureSettings.writeSettings(feature1Settings, 0);
  marlinFeatureSettings.writeSettings(feature2Settings, sizeof(FeatureSettings));

  // Read feature settings from EEPROM
  FeatureSettings readFeature1Settings;
  marlinFeatureSettings.readSettings(readFeature1Settings, 0);

  // Reset feature settings
  marlinFeatureSettings.resetSettings(sizeof(FeatureSettings));
}

void loop() {
  // Main program loop
}

@classicrocker883 classicrocker883 deleted the bugfix-2.1.x-April8 branch April 25, 2024 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants