I was reading up on the flash eeprom and best I can tell for the stm32f chips this is needed. micromouseusa.com/
Has Keil mdk5 not provided a simple function?
So, if you have a chip without it, you're either going to have to add it externally or emulate it in Flash.
Or is battery backup an option for you?
ST have an App Note on emulating EEPROM in STM32 Flash - but note that their supplied linker script is fundamentally flawed (it doesn't tell the linker that some flash is being used for the EEPROM emulation).
Yes, it gets complicated because of wear-levelling and coping with erasing & re-writing the data in Flash.
Other manufacturers have similar App Notes - you might also be able to get ideas from them...
Sorry I was not clear on that.
I have a st32f205 with eeprom on the chip, I simply just want to write and read form it. This "emulating EEPROM" is confusing me. Is there no easy way to write/read to eeprom on the chip. All the info I find talks about this "emulating EEPROM" when searching for how to use the eeprom.
Again, what firmware library are you using? CLEARLY (at least to me) you are not using the STM32F2xx_StdPeriph_Lib. Your examples that you have posted are expecting you to be using that firmware library. The reason you are getting errors EVERY TIME you build your example code is because it is making references to the STM32F2xx_StdPeriph_Lib and you are not actually using that library.
The library is stm32f2xx_hal
After destruction with the team and considering nvram/i2c, eeprom, flash. We decided to go with flash. Eeprom emulation or may what "Clive One" suggested. Can anyone suggest a way to see the flash after I do a test write? A visual debug would be essential in troubleshooting.
oops / discussion - but sometimes does feel like destruction.
That's what the debugger is for!
Please read the manual: http://www.keil.com/support/man/docs/uv4/uv4_db_dbg_memwin.htm
I found a project of some help.
github.com/.../eepromConfig.h
It compiles all but he flash erase.
flashErase.NbPages=1;//error no member flashErase.Banks = FLASH_BANK_1; flashErase.PageAddress = _EEPROM_FLASH_PAGE_ADDRESS; //error no member flashErase.TypeErase = FLASH_TYPEERASE_PAGES;
and FLASH_TYPEERASE_PAGES does no exist.
flashErase has; voltageRange nbSectors sector
guesssing nbSectors/sectors and nbPages/PageAddress interchangeable? and how can I find the missing define FLASH_TYPEERASE_PAGES what would I use for a voltageRange?
ok got it all flashErase.NbSectors=1; flashErase.Banks = FLASH_BANK_1; flashErase.Sector = _EEPROM_FLASH_PAGE_ADDRESS; flashErase.TypeErase = FLASH_TYPEERASE_SECTORS;
Right I forgot this Keil had a rather useful debugger, thx.
Thank you. The Flash solution is a very good choice (as Clive suggested very early). Even better than the EEPROM. Good Luck.
forget all you heard about EEPROM. although not always true EEPROM has become to mean "serial storage" the flash is accessible parallel.
remember you can tot set a bit in flash, only clear it
bad code but shows the principle
struct flashthinh unsigned char mark = o unsigned char unsigned char
to write scan the structures till you find mark =0xff write there
to read scan the structures till you find mark =0xff back up one and read
The STM32 Flash arrays have parity/haming bits associated with them, they are write-once, so you can't really incrementally knock one bits down.
The L family parts supposedly use "EEPROM", the erased state is zero (0x00), but this could just be FLASH with an inverter on the data bus. The block diagrams and slide decks really don't given much fabrication detail.
Typically NAND FLASH accesses like a block storage device. NOR FLASH accesses like random-access memory, and you can execute from it.
thx for all the advice but I'll have to start somewhere. Thus far that eeprom emulation code in my github link above helps. but few this confusing me yet.
flashErase.VoltageRange = FLASH_VOLTAGE_RANGE_4;//1,2,3,4.. Where do I look this up. I'm not finding this in the data sheet.
I can read in words (ffffffff=4294967295) so for so good and reading from my data area I do see the correct values as shown in the debugger.
writing I can not do. Per the code I sampled from no data is written. Also in the debug I can not change the memory outside my data area, I get an error. Cannot access Memory Internal command error
Do I need to enable something in the RTE?
thx for all the advice but I'll have to start somewhere. Thus far that eeprom emulation code in my github link above helps. but few this confusing me yet.>/i>
You also need to know how to move forward. I thought you did. You said you were going to go with the approach Clive proposed and use the Flash. I thought that was a very appropriate idea which started with him stating "I would avoid the idea of EEPROM emulation completely". The whole concept of the EEPROM emulation was making it very difficult for you to move forward. It was clear that it was not helping you to move forward. It was keeping you stuck on something that was just not appropriate for you to be spending time on. It was fairly clear that what Clive suggested was most likely a very good way for you to go forward. You finally said that you wanted to go with what Clive presented (NO EEPROM) which seemed like progress. Now you are back to saying that starting from EEPROM emulation code as a starting point is helping you!
Moving forward is a few steps a way. As I said I need to start with a few things to understand how all this works. This example I found shows things pretty well and got me a little further. I still "think" Clive has a good idea but what do I know? This is all new to me, so whatever works out of the box is going to fundamentally assist in learning the basics. Like the debugger.
I believe I now understand things a bit better. After studding and playing with the emulated eeprom it is becoming clear this needs to be organized upfront. So I can not just add these functions in my existing code and the code area needs to be managed. Since I plan to use a DFU bootlaoder this is only going to make thing a lot more confusing.
So in looking at this I think the flash emulation needs to be loaded in to the first sector. Kind of like a bootloader? If so that is more then I need and just going to complicate things.
Normally when I write my application it starts writing at 0x08000000, and I would only assume it will write and grow till I hit the top flash area. I'm would not expect it to skip any sectors (i.e. 0x0800C000), maybe I'm wrong?
Using Clive's method I could just write wherever I like. Dangerous yes but not if I plan everything out well.
Am I on there right track or doing more harm then good?
You can't control where the processor boots into FLASH, so the boot loader needs to be in the first sector to control where it goes next, the emulation or whatever can use the second two.
That is what I figure but this is what is currently confusing me. The first few sectors are written to when I view the memory in debug.
0x08000000 to 0x080083df all have data.
So this must be the bootloader + app I see. If my app grows it will start writing in to the next sector. So I'm a bit confused on how I can use any of the sectors for eeprom? When writing the app location to the device, is it not going to just continue til it hits the top flash area? So at this time it is unclear to me how I can reserve an area for flash unless I reserve the last sector and prevent the application from getting too big.
Thx for taking the time to help.
Go into the Target menu, or edit the scatter file (linker script), and split the IROM into multiple sections leaving a hole where *you* want to control what happens rather than the linker.
The boot loader and the app should frankly be two separate entities (projects), the loader being free standing and capable of updating and validating the app.
I get that part, but now that will cause an issue for the users to upgrade the device. There will be one, more then one, or many that will not know to specify the start memory location (or ignorantly not read the warning) and brick the device.
I plan to use the default built in bootloader DFU not make my own.
Is wring flash to sector 10 or 11 bad, not possible? If so then we will deal with it.
What Clive said.
I think NOT doing your own bootloader is fine (at least for now where you are in your development). Put the configuration at the end of flash. limit the application so that it does not overwrite the config area. As long as you don't do a complete erase when you load new code, your old configuration will remain.
Adding you own bootloader can be done later if you need too. You configuration data will still be at the end of flash.
Ok that was my intention, so using Clive's suggestion above and using the correct sector should in theory work out for now.
Just a quite little derail here, will the built in boot loaded work with a usb design? http://www.keil.com/forum/62872/#/msg206441
I'll get to this soon but since the topic was reintroduced here, i figure i'd ask.
thank you both.
The standard DFU loader can scatter load memory, it describes addresses and blocks of data, and they can be throughout memory.
If you want to control stupidity you need to provide tools that enforce things to prevent it.
With serial connectivity your own code could accept .HEX file data, or X-MODEM in binary data and *control* what get's written where. You can secure the device from bricking by having a loader which validates the app before transferring control. This doesn't have to replace the ROM based DFU loader, it just adds levels of idiot proofing.
You can write you firmware to do anything you want. The High order 128KB sectors are certainly usable, the erase time is significant.
Ok I see the advantage to the example Clive demonstrated. Though I'm not sure it will work in the end as we do need to write to flash during execution as well as an init structure. I have yet to try it because I can not make any flash write functions work. Very difficult to get an idea of how all of this works if you can not see any real examples.
The EEprom emulation is starting to sound like an over kill.
"The application requires two Flash memory sectors of identical size allocated to non-volatile data:one that is initially erased, and offers byte-by-byte programmability; the other that is ready to take over when the former sector needs to be garbage-collected. A header field that occupies the first half word (16-bit) of each sector indicates the sector status. Each of these sectors is considered as a page."
Did that not just cut of 32k of my available space? I still hope to avoid this as best I can.
The way we intend to use EEPROM is wring an init structure and saving tokens.
line one (16 bytes) contains the structure the next few lines (16 bytes each) hold token data. Each use will store a token. This needs to be available for consecutive uses. Wait times for storing and read are not an importance. Using any type of battery or external eeprom will allow this to be erased/copied cheating the intention.
If I understand the eeprom emulation correctly it will need to be at sector 0 first 6k. then it takes 2 more sectors for eeprom. Still unclear but somehow the actual code will use an API to write to the manager in sector 0 and work as EEPORM. Assuming not via i2c to itself?
I'd like something more like what Clive has shown that would allow writing directly from the code itself. After unlocking the flash I can read very easily with read = *((uint16_t *) FLASH_PAGE); I understand writing is more complicated but none of the examples or functions work. The executed code in sector 0, should be able able to write to sector 2 with the needed unlocks in place with first an erase function. if(HAL_FLASH_Unlock()!=HAL_OK) FLASH_PageErase(0x0800C000); FLASH->CR = 0; if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, 0x0800C000, 0x01010101) != HAL_OK) //error
Ok I have it working now, much clearer picture. I see now I'll need some type of shadow array to hold the writes as I progress thru the code as I can only write a page at a time. Using my last sector would be far to wasteful and using the first has that bootloader issue that can be addressed but is a pain to deal with at first.
I just want to rule out the hole in the middle possibility?
code fake eeprom or nvram code code code...
Is there anyway possibly of using IROM so that the code can be split up to have a hole in the middle for this fake nvram.
Use a scatter file that puts the vector/reset stuff low in flash, leaves space for your configuration flash area and add a section for everything else past the configuration flash area you want to use.
Along these lines?
LR_IROM1 0x08000000 0x00804000 { ; vector/reset ER_IROM1 0x08000000 0x08004000 { ; *.o (RESET, +First) *(InRoot$Sections) .ANY (+RO) } RW_IRAM1 0x08004000 0x08008000 { ; eeprom area .ANY (+RW +ZI) } }
LR_IROM2 0x08008000 0x08100000 { ER_IROM2 0x08008000 0x08100000 { ; remaining of code.. .ANY (+RO) } }
Hope this is more readable.
LR_IROM1 0x08000000 0x00804000 { ; vector/reset
ER_IROM1 0x08000000 0x08004000 { ;
*.o (RESET, +First)
*(InRoot$Sections)
.ANY (+RO)
}
RW_IRAM1 0x08004000 0x08004000 { ; eeprom area
.ANY (+RW +ZI)
LR_IROM2 0x08004000 0x08100000 {
ER_IROM2 0x08004000 0x08100000 { ; remaing of code..
"You can write you firmware to do anything you want. The High order 128KB sectors are certainly usable, the erase time is significant."
The stm32f207 has a flash size of 128k. From what I know this is sectors 0-4 for firmware. Can I access and use the upper memory sector 5 for my NVRAM area? My thinking is if I use that, there is no way the firmware will ever grow past the fake eeprom area.
This is something that you will understand best if you do it yourself. You should try to build with that scatter file and see what fails. You have a general idea of how to use the scatter file to do what you want to do, but have a few errors that you will go "why was I thinking that would work" once you figure them out.
One hint: +RW variables cannot go into flash. // this is actually more than 1 hint
To post source use PRE tags
1MB Flash on Die (all parts) Sec# 0 16K 0x08000000 1 16K 0x08004000 2 16K 0x08008000 3 16K 0x0800C000 4 64K 0x08010000 5 128K 0x08020000 6 128K 0x08040000 7 128K 0x08060000 8 128K 0x08080000 9 128K 0x080A0000 10 128K 0x080C0000 11 128K 0x080E0000
See Data Sheet and Reference Manual
The value of using the small sectors is that they don't eat into the code space budget as much, and erase faster. Think the erase time is mentioned in DS, but depends on age and voltage.
The use of journalling is strongly recommended to reduce wear. Erase only needs to occur after sector completely consumed, many examples will ping-pong between two sectors to reduce window for data loss.
View all questions in Keil forum