Advanced EasyC programming - Non Volatile parameters

There have been some discussions before about how to store data on the cortex which remains intact when power is removed. Some such threads are

https://vexforum.com/t/non-volatile-storage/19788/1&highlight=flash
https://vexforum.com/t/writing-to-text-files/21067/1

It’s been on my to do list for some to address this for EasyC, not much I can do about it for ROBOTC unfortunately as it’s too much of a closed system.

I have created a small library that allows storing user parameters, currently limited at 32 bytes, in an area of flash memory beyond that normally used for the EasyC firmware. The idea is to be able to store the robot’s configuration, for example, red or blue alliance, autonomous strategy and perhaps runtime error codes for post analysis, and not lose the data when power is removed. The library only has three functions, this is the header file.

#ifndef VEXFLASHLIB_H_
#define VEXFLASHLIB_H_

#define ERROR_WRITE         (-1)
#define ERROR_WRITE_LIMIT   (-2)
#define ERROR_ERASE         (-3)
#define ERROR_ERASE_LIMIT   (-4)

// Number of user parameter words
// Do not change !!
#define USER_PARAM_WORDS    8

// Structure to hold user parameters
typedef struct _user_param {
    // storage for the NV data
    unsigned char data[USER_PARAM_WORDS * 4];

    // useful debug data
    unsigned int  offset;
    void          *addr;
    } user_param;


// public functions
user_param *UserParamRead( void );
int         UserParamWrite( user_param *u );
int         UserParamInit( void );


#endif // VEXFLASHLIB_H_

The library uses one complete page of the flash memory for parameter storage even though only 32 bytes are available to the user. A flash page is 2048 bytes and is the smallest unit of flash memory that can be erased. The library implements some simple wear leveling and protection mechanisms.

  1. Each time the parameters are written, a new section of the flash page is used, 256 bytes are reserved at the beginning of the page as a type of index, the page only needs to be erased after 56 save operations.

  2. There is a hard limit of 32 save operations each time the cortex is powered.

  3. There is a hard limit of one erase operation each time the cortex is powered.

A typical use of these functions would be as follows.

The cortex is powered.
Parameters are read from flash and the firmware configuration set. This could be anything you want but would typically be perhaps the defaults for a LCD menu system.
The user interacts with the robot by using the LCD or other methods, the user initiates saving new default parameters to flash.

I have not yet decided if I’m going to release this as source code or a pre-compiled library, if I release the source then the built in safeguards could be bypassed, I’m just looking for some feedback at this point.

If a new EasyC program is downloaded to the cortex all the parameters are currently erased, there are ways around this but I’m not planning on implementing them. The best solution would be for the EasyC loader to only erase the necessary area of flash for the program rather than everything each time new code is downloaded.

1 Like

So it looks like EasyC actually has some of this type of functionality already in its runtime library, I did not try it yet but the code seems to write the 20 globals accessed through the “GlobalData©” function to the last page of flash, they are also read on startup. Flash is erased every time this function is called (which is why I’m not advertising its name here) so not as safe as the code I wrote yesterday.

Anyone from Intelitek care to comment ?

1 Like

So this writes to the Same ( kind of ) Flash Blocks the main Code in written into??

So this would also be effected by the ~10,000 write limitation.

The PIC 18F8520 might be more limited, but with the ~100,000 write cycles, the chance of reaching, End Of Life are extended…

This writes to the same flash as the program is stored in. A typical EasyC program uses less than half the available storage. My code is designed to move the location where the user bytes are stored so that an erase is only needed every 56 write operations. The write limitation is really an erase/program limitation so end of life would be reached after 560000 saves, not really a problem. This could be further improved by using more than one 2K page.

The code/compile/debug cycle which erases all flash each time the program is downloaded is more likely to have issues with the 10k cycle life.

There are also 84 bytes of battery backed SRAM available in the STM32, it’s a shame a small lithium backup battery was not used for this memory. I guess there is a very small chance the 9v backup battery is used but I need to test that (Oh to have a schematic :slight_smile: )

1 Like

So this does work as expected.

The 20 global variables (accessed through GlobalData© ) can be written to flash. If they were written to flash they are read from flash every time the code runs making the GlobalData array non volatile. Every call to the write function causes a page erase (although it looks like the code may check for the data being changed). There is a global variable that can tell you if the GlobalData array was read from flash or set to the default values of 0.

I will leave it up to Intelitek to decide if they want to make this undocumented feature available.

As expected the backup registers are cleared every time the cortex is powered, however, they could be used to maintain variables between downloads and potentially make it appear that the flash variables are maintained also by some clever code. This may be useful for PID constants or for code that has taught itself to correct for drive errors etc.

1 Like