Hi, I am new to Nano Matter. I have a user calibration data wanted to store in on board flash memory. I have googled about this. It gave me two answers with slightly different phrases. One is using FlashIAPBlockDevice library**,** one is using NVM3 driver. While the former seems not right, the later seems quite complicated and has no code example. Does anyone have experience on this? Please help out. it will be greatly appreciated if example code provided.
Just use the bog-standard EEPROM library. It's included in the core and has dozen of standard examples. The library is implemented using nvm3_writeData() and friends underneath.
Create a single struct for your calibration data and EEPROM.put() it to write, EEPROM.get() to read. That's literally it.
Simple solution get a copy of the Arduino Cookbook and If my memory is correct you will find schematics and code reading and writing this memory. Also note it has a write limit so if this is going to happen over 100K times during the life of the project consider using FRAM.
@maxgerhardt. Thank you very much for the library which looks great. I have written a test sketch and get what I expected.
#include <EEPROM.h>
#include <cmath>
//Define a constant to convert reading to voltage in millivolte
#define ReadingCV 0.805664 // For ADC, 3300/4096 = 0.805664
// Define a structure to hold the calibration data
struct myObject {
unsigned int myRefV;
};
void setup() {
Serial.begin(115200);
while (!Serial); // Wait for Serial monitor to open
Serial.println("Nano Matter Write Flash Now.");
// Initialize data with 500
myObject caldata = {
500
};
int address = 0;
// Write the new data to flash
EEPROM.put(address, caldata);
Serial.println("Data written successfully.");
}
myObject data = {
0
};
void loop() {
Serial.println("Running in the Loop.");
if (data.myRefV == 0) {
int myAdd = 0;
EEPROM.get(myAdd, data);
Serial.print("Read data object from Flash, myRefV=");
Serial.println(data.myRefV);
}
delay(5000);
}
at the terminal:
g in the Loop.
Read data object from Flash, myRefV=500
Running in the Loop.
Running in the Loop.
Running in the Loop.
Running in the Loop.
However, there are two things I am curious, first, I don’t see those write to flash text given by setup() code in terminal. Second, It seems this small sketch taken 58% of flash memory space, Also the global variable object with only a integer taken 53% of SRAM, Why?
Is it because I used address zero to write and read? I assume that the library will allocate a page after the sketch code in flash space, so zero address should be the first address of the page. Am I right?
Below is compilation information:
Sketch uses 913072 bytes (58%) of program storage space. Maximum is 1572864 bytes.
Global variables use 139512 bytes (53%) of dynamic memory, leaving 122632 bytes for local variables. Maximum is 262144 bytes.
Open On-Chip Debugger 0.12.0+dev-01514-g21fa2de70 (2024-02-07-19:18)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
debug_level: 0
efm32s2_dci_read_se_status
[efm32s2.cpu] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x08000170 msp: 0x20001008
[efm32s2.cpu] halted due to debug-request, current mode: Thread
xPSR: 0xf9000000 pc: 0x08000170 msp: 0x20001008
** Programming Started **
** Programming Finished **
Does not make the main chip on your Arduino Nano Matter wait for the serial monitor to open. This only works if the Serial is implemented directly on the main chip you upload to in native USB. That's not the case for the Arduino Nano Matter if you look at the schematic
Your PC connects via USB to the SAMD11 USB-to-UART converter.
while(!Serial); does not wait at all in the Arduino Nano Matter implementation, because it cannot detect whether the PC has connected -- it only has a UART connection to the USB-to-UART converter chip (the SAMD11).
On a native-USB board like an Arduino Leonardo, Arduino Due etc. Arduino Zero, that would have worked.
You need to use a more primitive method like just delay(4000); at the start of setup() and open the serial monitor quickly enough.
You're thinking like a webdeveloper. How "small" the sketch code it doesn't matter, because most of the size in the firmware comes from the Arduino core and the underlying SDK it's built upon. Even if you have an empty setup(){} and loop(){} function, all the code to boot up the chip and initialize the SDK (including an RTOS) and some peripherals will still be active, and this will take Flash and RAM. Just look at all dependencies of the main function. Even adding two lines to a sketch, like including a library and creating an object or calling into a function of the library, can blow up the size of the firmware because that library's code (and RAM usage) is now included in the firmware.
Again, see above, most of the memory usage comes from the Arduino core itself, not from your sketch. You're right that your structure only takes 4 bytes. But that's not the memory usage that is shown there in the log, it's the memory usage of the entire firmware.
@maxgerhardt. Thank you for explanation. I overlooked absence of Native USB on Nano Matter, regarding this topic, there is a thread having detailed discussion.
About memory space taken, I have tried to compile an empty setup() and loop(), it does take 58% of flash and 53% of SRAM like what you said. Well, This is very different from what I experienced with Seeeduino Xiao SAMD21 which only took 16% of flash with 800 lines of code sketch, that is about 41KB (256KB x 16%) with 800 lines of codes versus 870KB (1500KB x 58%) with zero code.
My understanding about compilation is that only necessary and involved/dependent codes to be included into binary and loaded to flash rather than entire core or library regardless of dependency.
What is necessity for SiliconLab to load whole core into the flash?
Whatever the reason might be, Silabs has decided to build their Arduino core on their GSDK (Gecko SDK) in the form of a precompiled library, some of which are linked in with -Wl,-whole-archive "{build.path}/{archive_file}" {compiler.silabs.precompiled_gsdk} , so the linker is forbidden to optimize out any unused function in the GSDK (source).
What also doesn't help that, depending on the "Protocol Stack" menu option, it pulls in another metric ton of libraries
So yeah, building this Arduino core as being layered upon a layer upon a layer on a layer of libraries and abstractions has blown up the binary size considerably. Others have noted that too.
Though with flash and RAM sizes this excessive (1.5 MB flash, 256KB RAM), there's little incentive to improve. Most Arduino sketches, used for prototyping stuff, will fit. The serious stuff uses the Gecko SDK directly anyways.