This code is most useful for implementing non-volatile arrays,
...
...
@@ -49,7 +51,7 @@ value = arrayInFlash[index];
or
Serial.print(arrayInFlash[index]);
Declare arrays in flash is a two-step process.
Declaring arrays in flash is a two-step process.
The first step is to declare the array data type, and specify its scope.
This is done with a statement with a format of
NANO33BLE_DECLARE(\<datatype\>,\<arrayName\>);
...
...
@@ -57,7 +59,7 @@ such as
NANO33BLE_DECLARE(double,arrayInFlash);
to declare an array of doubles named "arrayInFlash".
The scope of the array is determined by where the declaration is made.
If outside of any function, the scope is global (all functions can see the array), while if it is inside a function, it will be seen only within that function, and others to which it is passed in function argument lists.
If outside of every function, the scope is global (all functions can see the array), while if it is inside a function, it will be seen only within that function, and others to which it is passed in function argument lists.
The second step is to specify where and how big the array is.
This is done using a macro:
...
...
@@ -73,7 +75,7 @@ to make a same-sized array of doubles in RAM.
The array macro NANO33BLE_PUT_ARRAY_IN_FLASH must be inside a function, because it makes calculations as to where the array will fit in flash. It should be called only once for each array, and prior to using that array. It makes the most sense to put it into the function setup(). The declaration must preceed the macro call, but can be in the same function (for a local array) or before all the functions (for a global array).
The array macro NANO33BLE_PUT_ARRAY_IN_FLASH does not initialize or otherwise modify the contents of the array. It just makes the sketch look in the correct place in flash memory when it encounters future references to the array.
The array macro NANO33BLE_PUT_ARRAY_IN_FLASH does not initialize or otherwise modify the contents of the array. It just enables the sketch look in the correct place in flash memory when it encounters future references to the array.
The macro sequentially packs the arrays in from the top of the available flash memory, reaching down as far as it needs to go.
It does not check for any collisions with the sketch or bootloader, which start at the bottom of flash, but it'd have to be a pretty big array and/or sketch for a collision to occur. Simply locating an array over the sketch or in the bootloader is not damaging, fortunately. The flashErasePage() function does check if the page number is too low, to prevent bricking of your Arduino.
...
...
@@ -87,7 +89,23 @@ for (page=NANO33BLE_FLASH_LOWEST_PAGE;page<flashNumberOfPages;page++){
flashMode(FLASH_READONLY);
}
You do not necessarily want to always erase the flash memory on start up,
as doing so defeats the non-volatility property of flash.
as doing so defeats the non-volatile property of flash.
The function flashEraseAll() executes the code snippet above.
Normally, pages in flash do not hold more than one array.
This facilitates the erasure of each array separately, by calling the macro
NANO33BLE_FLASH_ERASE(\<arrayName\>)
(bug/feature note: the macro has the same scope as the array.
ie. if the arrays are declared in setup(),
the sketch cannot call NANO33BLE_FLASH_ERASE()
from anywhere outside of setup(), too).
On the other hand, if space is really precious and you want to pack as much into flash as possible, do
#define FLASH_TIGHT
prior to the #include for this library.
Since with FLASH_TIGHT mulitple arrays might share parts of a flash page,
this disables the ability to erase individual arrays,
'tho erasing all of it with flashEraseAll() is still available.
Valid datatypes for arrays in flash using this library include structs and typedefs, in addition to the predefined C datatypes. Structs appear to default to multiples of flash words, so the programmer's attention to alignment issues does not appear to be neccessary.
...
...
@@ -122,4 +140,5 @@ watch the colored text as it uploads (hit the Arduino reset button to abort).
Or, compile and take the number of bytes
in "Sketch uses NNNN bytes (X%) of program storage space..."
and divide by 4096, rounding up.
I have not yet figured out how to determine from within a sketch what is the last page in flash that the sketch occupies.