As part of another project I needed to read/write EEPROM (UNO, 1K). Two of the functions used were memcmp() and EEPROM.get(). Rummaging through the AVR library functions I saw memcmp_P(), for comparing *n *bytes of RAM with flash memory but found no memcmp_E() counterpart dealing with EEPROM. Yes, there is EEPROM.read/write but I figured since these are likely built on the underlying avr/eeprom.h library they add abstraction overhead.
So, using Arduino IDE 1.8.2 and <avr/eeprom.h> I put together memcmp_E() which mimics memcmp_P() – having the form: memcmp_P(arg1(ram), arg2(flash), len) – except mine just returns true/false. Then I got the bright idea of extending the functionality to handle 16-bit arguments by adding to the function call argument list a number which is used to compute how many bytes are to be tested. I’d like to get rid of this and somehow have the compiler select a correct function for me.
What I have currently:
.ino
/*
Attempt to duplicate memcmp_P but for EEPROM
V1.6 accomodate 1-byte & 2-byte arguments and
is converted to library format
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include "memcmp_E.h"
void setup() {
Serial.begin(9600);
// ram_data[] based on combo lock code starting at 0020h 12/6/18
byte ram_data[] = {1, 7, 3, 1, 9, 5};
// EEPROM data = 1, 7, 3, 1, 9, 0
int EEPROM_addr = 20;
byte dLen = sizeof(ram_data) / sizeof(ram_data[0]);
// compare bytes
if ((memcmp_E(ram_data, EEPROM_addr, dLen, 1))) Serial.print("Data mismatch \n");
else Serial.print("Data matches \n");
//
if ((memcmp_E(ram_data, EEPROM_addr, 5, 1))) Serial.print("Data mismatch \n");
else Serial.print("Data matches \n");
// compare words
Serial.print("\n\n");
if (memcmp_E(ram_data, EEPROM_addr, 2, 2)) Serial.println("word mismatch");
else Serial.print("word match\n");
if (memcmp_E(ram_data, EEPROM_addr, 3, 2)) Serial.println("word mismatch");
else Serial.print("word match");
}
void loop() {}
.cpp
/*
Operates like memcmp_P but works in the EEPROM
space, with an additional argument to select
size of the compared values.
V1.6
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include "memcmp_E.h"
#include <avr/eeprom.h>
bool memcmp_E(uint8_t* ramAddr, uint16_t EE_addr, uint8_t len, uint8_t elementSize) {
// Compares n bytes of EEPROM with RAM variable.
// Caller provides:
// RAM address, EEPROM address, number of elements, size (1 or 2 bytes)
// of data to be compared. Function exits on first mismatch.
// Returns false if all bytes match, true if any mismatch detected.
//
if (elementSize > 2 or elementSize == 0)return;
len *= elementSize; // set number of bytes to test
for (int i = 0; i < len; i++) {
uint8_t EE_data = eeprom_read_byte((uint8_t*)EE_addr++);
if (*ramAddr++ - EE_data != 0)
return true;
}
return false;
}
.h
/*
Attempt to duplicate memcmp_P but for EEPROM
V1.5 accomodate 1-byte & 2-byte arguments
Next iteration: convert to void pointers and so
eliminate the need for the size argument?
https://www.avrfreaks.net/forum/tut-c-using-eeprom-memory-avr-gcc
*/
#include <avr/eeprom.h>
#ifndef memcmp_E_h
#define memcmp_E_h
class memcmp_E {
public:
memcmp_E(); //constructor
uint8_t* ramAddr;
uint16_t EE_addr;
uint8_t EE_data;
uint8_t len;
uint8_t elementSize;
uint16_t i;
};
bool memcmp_E(uint8_t*, uint16_t, uint8_t, uint8_t);
#endif
The goal: I want to be able to compare *n *8-bit, 16-bit, and 32-bit arguments against like size arguments, with one universal function call and not have to specify argument size.
Questions I’ve asked on previous threads have raised templates and the use of ‘traits’ (an extension?) to achieve certain ends. Could these things be a part of a solution? I believe something like this is possible because Serial.print() does it.
Where should I start reading?