Hi,
I need to load an unsigned int array of a few hundreds values to flash, and read it back.
I looked into many examples, but only found such that describe loading of manually prepared arrays of few elements.
Arduino / AVR is new to me, thus I tried all kinds of C options, but the received data is different from the saved one, so something is wrong, either in saving, reading or both.
What is the correct way to do the job?
The ready full array to save is timedata[360].
The array to save in the flash and read back is ftimedata.
Here is what I have tried, which compiles OK:
void flashSave(unsigned int timedata[], unsigned int length)
{
PROGMEM prog_uint16_t* ftimedata = timedata;
Serial.println("flash saved");
}
void readFlash(unsigned int index)
{
int i;
for (i=0; i < index; i++)
{
Serial.println(pgm_read_word_near(ftimedata*));*
It may compile OK, but it will never work. You can't just write to flash like it's RAM - if you could there'd be no need for RAM
Writing to flash is considerably more involved that just sending a byte to a memory location. You should take a look at the bootloader source code to see how it does it.
In general the basic principal:
Erase a page of data (size depends on the microcontroller)
Write a page / row / word of data (again, sizes depend on microcontroller).
The operations to perform those generally involve interacting with SFRs to set your write addresses, operation codes, data values, etc.
Majenko,
Yes, you are right - Generally, writing to flash in low-level code requires some registers manipulation, erasing, etc.
I am fully aware of it, and have the necessary experience.
(Why did you right "if you could there'd be no need for RAM"? Its a whole other issue. Flash is non-volatile and slow and limited in performance, RAM is RAM. You can not mix their use).
As I am new to AVR and Arduino, (but very old programmer), I looked into the Arduino staff, and found out that there is a high level command(s) that enable to treat the flash as RAM.
Please see PROGMEM - Arduino Reference, which is detailed in the pgmspace.h
The only problem is that it does not clearly show how to load an array using that library and command.
found out that there is a high level command(s) that enable to treat the flash as RAM
That contradicts the Atmel documentation which says that only code running from the bootload space can write into Flash memory.
If you want something stored into flash, I believe you need to have the data all documented in an array at compile time, and the compiler will put into flash as read-only data when the sketch is put into flash.
I think this article covers it pretty well. http://deans-avr-tutorials.googlecode.com/svn/trunk/Progmem/Output/Progmem.pdf
This book goes into Arduino software in depth. I have a copy, and really have only used for 2 things, PROGMEM arrays being one of them. It can be a frustrating book to look things up in; if you don't know what you are looking for is called to start with, it can be difficult to find it. Once you find it, the info is good.
samtal:
Majenko,
Yes, you are right - Generally, writing to flash in low-level code requires some registers manipulation, erasing, etc.
I am fully aware of it, and have the necessary experience.
(Why did you right "if you could there'd be no need for RAM"? Its a whole other issue. Flash is non-volatile and slow and limited in performance, RAM is RAM. You can not mix their use).
As Flash speeds up, and/or gets replaced with other technologies, like MRAM, then traditional RAM has less and less meaning.
As I am new to AVR and Arduino, (but very old programmer), I looked into the Arduino staff, and found out that there is a high level command(s) that enable to treat the flash as RAM.
Please see http://www.arduino.cc/en/Reference/PROGMEM, which is detailed in the pgmspace.h
The only problem is that it does not clearly show how to load an array using that library and command.
The whole PROGMEM is purely for reading of pre-compiled data from flash. It has nothing at all to do with writing to flash. You can only place data into flash at compile time, not run time, using that system.
Hi CrossRoad,
As I wrote, I came to the Arduino, Atmel and AVR from Maple that is 32 bit ARM based.
In all my Maple IDE (that are 90%) copy of Arduino) I regularly write and read to \ from flash by basic registers bit manipulations. Its cumbersome to begin with, but after some time it becomes a habit.
I assume I can do the same with the Atmel AVR, but that will necessitate learning all that stuff that is different.
When you write "That contradicts the Atmel documentation" are you saying the whole PROGMEM is untrue?
In general, writing to flash is a regular run-time operation in every device, and must be that way. I am writing about the user flash, not the Atmel firmware region.
samtal
After reading your replies and looking into some additional material, and running a test program I probably will have to return to the ST32 ARM based Maple.
I am used to it, but more than that, I can easily program any flash page or address in run time, which is what I need.
The nice thing about it is that one can approach the flash as if it was any memory location, and all memory features (pointers etc.) are the same for ram and flash.
The only major difference is that one must erase the flash before writing to it, but this is a simple one line command.
I still have difficult to believe that the Atmel flash can not do the same. It makes no sense to me.
I will therefor keep digging until I will better understand how it works.
If anyone have a real solution - Please let me know.
thanks again
samtal
If you want your sketch to be able to write to flash, you will need to create some code that can call a function that runs from the bootload area of memory. See the '328P datasheet:
27.3 Application and Boot Loader Flash Sections
The Flash memory is organized in two main sections, the Application section and the Boot Loader section (see Figure 27-2). The size of the different sections is configured by the BOOTSZ Fuses as shown in Table 27-7 on page 280 and Figure 27-2. These two sections can have different level of protection since they have different sets of Lock bits.
27.3.1 Application Section
The Application section is the section of the Flash that is used for storing the application code. The protection level for the Application section can be selected by the application Boot Lock bits (Boot Lock bits 0), see Table 27-2 on page 273. The Application section can never store any Boot Loader code since the SPM instruction is disabled when executed from the Application section.
27.3.2 BLS – Boot Loader Section
While the Application section is used for storing the application code, the The Boot Loader software must be located in the BLS since the SPM instruction can initiate a programming when executing from the BLS only. The SPM instruction can access the entire Flash, including the BLS itself. The protection level for the Boot Loader section
can be selected by the Boot Loader Lock bits (Boot Lock bits 1), see Table 27-3 on page 273.