| Author |
Message |
|
|
Posted: Jun 11, 2012 - 06:58 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
Hello,
I am having some trouble wrapping my head around a particular type of function.
Here's what I'm looking to do:
-Download the code to the microcontroller
-The microcontroller will load variables from its memory
-The microcontroller will save the variables to EEPROM
-The variables will be changed through normal execution
-The updated variables will be saved to EEPROM
Now when power is cycled on the microcontroller, I want it to use the EEPROM variables rather than the ones programmed.
I feel like this is a chicken and egg type problem and I'm just looking for a pointer in the right direction. Any thoughts are greatly appreciated.
Thanks,
Matt |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 07:29 PM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
| How are what you just described and the thread title related? |
_________________
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 07:30 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
A function is called first run after flashing the chip. This function assigns values to variables. Following this first run, the function will never be called again as the variables will be loaded from EEPROM data.
Matt |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 07:40 PM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
OK think "cookies". A cookie is just a numerical value to say "I've been here before". Also consider that EEPROM, when erased and before first use will hold 0xFF in each location. So your program can do something like:
Code:
typedef struct {
uint8_t cookie;
int n;
char c;
} ee_layout;
ee_layout ee_data_in_flash = { 0x5A, 12345, 'A' };
ee_layout ee_data_in_eeprom EEMEM;
int main(void) {
if (eeprom_read_byte(&ee_data_in_eeprom) != 0x5A) {
eeprom_write_block(%ee_data_in_flash, &ee_data_in_eeprom, sizeof(ee_data_in_eeprom));
}
// update the variables...
eeprom_write_block(&updated_vars, &ee_data_in_eeprom, sizeof(ee_data_in_eeprom));
}
|
_________________
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 07:45 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
|
Quote:
EEPROM, when erased and before first use will hold 0xFF in each location
Thank you very much. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 08:30 PM |
|


Joined: Feb 19, 2001
Posts: 25921
Location: Wisconsin USA
|
|
|
Quote:
A function is called first run after flashing the chip. This function assigns values to variables. Following this first run, the function will never be called again as the variables will be loaded from EEPROM data.
Why not skip all that foo-fer-ah and simply assign EEPROM variables and initial value, and use that .EEP during the ISP process? It is, like, zero effort as you have described it.
That said, we have some apps where the controller is used for different target machine models. The customer has a set of .EEP values tailored for proper operation of each machine model. At ISP time, it is carried out with the latest flash image and the correct .EEP for that model.
There are several ways to create these app profiles, all of which (including combinations) we've used at various times:
-- Create separate source files with the initial values for that profile assigned, and rebuild the app
-- When the machine is tuned as desired, use ISP to read the EEPROM image and save that as the profile for similar machines of the same model
-- Construct a PC app that creates a proper "profile" .EEP from a set of parameter specifications
The latter is an extensive task, but is useful for complex apps with literally thousands of configurable parameters. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 08:43 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
|
Quote:
Why not skip all that foo-fer-ah and simply assign EEPROM variables and initial value, and use that .EEP during the ISP process?
I am skipping the foo-fer-ah as far as the struct is concerned, but a check for 0xFF is exactly what I needed.
Basically, I required initial data to get the device in the operative ballpark. However, this data is virtually guaranteed to change for correct operation, so I didn't want to keep writing the same general initializations on power-up. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 08:50 PM |
|


Joined: Feb 19, 2001
Posts: 25921
Location: Wisconsin USA
|
|
|
Quote:
I am skipping the foo-fer-ah as far as the struct is concerned, but a check for 0xFF is exactly what I needed.
Why do you need it? No function is needed, unless you have a "restore factory defaults" on your feature list. The "ff" becomes moot.
I don't think you are grasping the concept of the EEP file (or equivalent mechanism with your toolchain). The simple summary: ISP is a process that does:
-- Signature check
-- Chip erase
-- Flash download
-- EEPROM download
-- Flash verify
-- EEPROM verify
-- Fuse write
-- Fuse verify
-- Lockbit write
Now, it is up to you whether you do the full sequence or not; whether you add "Erasure check" or other steps. The point here is that any ISP sequence worth its salt can carry out all of the above steps. In particular to your query, the flash and corresponding EEPROM images are loaded during the same ISP session, so there is no need for your app to have any flags or routines or such.
[edit] I know from experience that the Restore Factory Defaults routine, equivalent to your initial load routine, is fraught with dangers as it is prone to be forgotten when the EEPROM map changes. |
Last edited by theusch on Jun 11, 2012 - 08:53 PM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 08:53 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
I should have mentioned it before, but this is external EEPROM.
That said, you just enlightened me a good deal. Thanks. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 08:58 PM |
|


Joined: Feb 19, 2001
Posts: 25921
Location: Wisconsin USA
|
|
|
Quote:
I should have mentioned it before, but this is external EEPROM.
OK, now I'll bite: When I started working with AVRs at the end of the last millennium, one of the exciting features was the internal EEPROM enabling high integration (no external EEPROM needed) along with very fast parameter read time (can be done "inline" whenever a parameter value is needed) and byte-addressable writing. We haven't attached an external EEPROM in 10 years. Now, I won't say that we would never again do it, but why? Sure, the modest-sized external EEPROM chips are cheap, but so is moving to a larger AVR model to gain a bit more EEPROM space. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 09:11 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
You're going to hate my response...
This is for a PIC processor, no internal EEPROM.
I had nothing to do with the part selection process, and this project has increased my appreciation for AVRs tenfold.
I came here first because I love how knowledgeable and helpful everyone is. Also, since I originally learned microcontrollers and embedded C with AVRs, I thought any example code would be easiest to understand here.
Thank you again for your help, and I do apologize for the blasphemy.
Matt |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 09:38 PM |
|


Joined: Jul 18, 2005
Posts: 62324
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
This is for a PIC processor, no internal EEPROM.
As such I've moved the thread from the avr-gcc forum. Clearly it has nothing to do with the AVR8 version of GCC and my responses above about eeprom_write_*() are completely irrelevant. |
_________________
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 09:50 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
|
Quote:
my responses above about eeprom_write_*() are completely irrelevant.
While they were to me, surely anyone attempting to do the same thing with avr-gcc would be glad to read Lee and your posts. |
|
|
| |
|
|
|
|
|
Posted: Jun 11, 2012 - 10:45 PM |
|

Joined: Nov 02, 2009
Posts: 3239
Location: Zelenograd, Russia
|
|
|
mquantz wrote:
This is for a PIC processor, no internal EEPROM
Just out of curiosity - which particular PIC? |
_________________ Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.
|
| |
|
|
|
|
|
Posted: Jun 12, 2012 - 08:08 PM |
|


Joined: May 26, 2004
Posts: 2538
Location: Las Vegas, Nevada
|
|
|
mquantz wrote:
You're going to hate my response...
You were brave! But we're in General Electronics now, where it's family-agnostic.
I handle this sort of thing by looking for a specific pair of bytes, usually AA-55, that I write to the EEPROM on first run. FF is what you read from an open-circuit bus so it's a bit ambiguous for my liking.
You posed a slightly different problem, though. You want the initialization to run on every reflash, but the reflash doesn't erase an external EEPROM. In that case I would incorporate some unique number in the compiled code - the time-date of the build is usually good - and save this to EEPROM. Then if it doesn't match, you initialize and make it match.
Lee, I use external EEPROMs from time to time where I have values, like the state of a counter or machine, that needs preserving through a power cycle and has to be saved so often that the endurance of the internal EEPROM would be used up in a few months. I used to use the RAM on a DS1307 chip for this, but providing a battery was a nuisance, so now I use a Ramtron FM24C16 FRAM. It looks and behaves exactly like a 24 series EEPROM except that its endurance is effectively infinite and its write delay is zero. |
|
|
| |
|
|
|
|
|
Posted: Jun 12, 2012 - 09:21 PM |
|


Joined: Jan 22, 2009
Posts: 180
Location: TX, NY
|
|
|
Quote:
which particular PIC?
PIC16F1519. yuck. |
|
|
| |
|
|
|
|
|