cancel
Showing results for 
Search instead for 
Did you mean: 

EEPROM Emulation

jihlein
Associate II
Posted on April 22, 2012 at 00:24

The EEPROM emulation demo uses Flash pages 2 and 3 (16 Kbyte pages).  Flash pages 0 and 1 are also 16 Kbyte pages.

WHat happens when your program is longer than 32 K?  Is the linker smart enough to skip Flash pages 2 and 3, or does the linker file need to be changed?

I've tried, with no success, in moving the emulated EEPROM to pages 1 and 2, telling the linker to put the startup code and int vectors in page 0, and have the rest of the code start in page 3.  The debugger shows some rrandom start location in this configuration.

If I don't do this, leaving the linker file alone and leaving EEPROM in pages 3 and 3, the code will run under the debugger, but is totally unresponsive when the debugger is disconnected.

Obviously, there is something going on I don't understand, any ideas?

FWIW, I'm using Atollic TrueStudio 2.3,

Thanks!
7 REPLIES 7
Posted on April 22, 2012 at 03:34

You could have a boot loader in Page 0 (0x0000), upper end could hold things like serial numbers.

EEPROM at Pages 1 & 2 (0x4000, 0x8000)

Application code a Page 3 and above (0xC000)

Have the linker script start FLASH at 0x0800C000, and shrink the size bye 48KB

The boot load checks the integrity of the application, then vectors to 0x0800C000, the app the sets the vector address for the core to point to this address.

You could probably also tailor the linker script to define two ROM/FLASH areas, say a 32KB area at 0x08000000, and a second area at 0x08010000, this would leave a hole of 32KB at 0x08008000. I can't find a quick cite, but having multiple ROMs at dislocated addresses is quite common.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jihlein
Associate II
Posted on April 22, 2012 at 04:35

I tried both those methods you mentioned, without success.  I'm probably not modifying the linker script correctly.  I think for now, I'll disable the EEPROM emulation and get the code running again.  Then I'll try to mod the linker script with a ''hole'' for flash EEPROM at pages 1 and 2.  Once that works, I'll see if I can get the EEPROM emulation running again.

Am I making a mistake moving EEPROM emulation to pages 1 and 2? 

Thanks for the reply!

BTW - I'm working with the STM32F04 Discovery board FWIW.

Posted on April 22, 2012 at 06:40

In Keil it would just be a matter of setting some ROM areas in the GUI. For GCC I think you'd need to make two MEMORY regions, and then play with the SECTION assignments. I have to tinker. A simple method might be to just put the vectors in the first 16KB, and park all the code/text sections in

The problem with the STM32F4 would be the upper flash pages (128KB) can take of a second or more to erase, I'm not sure a real time system can take a hit like that. On the plus side the parts do have 1MB of flash on them. Perhaps something on the lines of this

/*
* STM32F4 Discovery Linker Script, 512KB FLASH, 128KB RAM
*/
_estack = 0x20020000; /* Assuming 128KB part */ 
_minimum_stack_size = 0x1000; /* 4096 bytes miniumum stack size */
ENTRY(Reset_Handler)
MEMORY
{
rom0 (rx) : ORIGIN = 0x08000000, LENGTH = 16K
rom1 (rx) : ORIGIN = 0x08010000, LENGTH = 448K
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS
{
.text0 :
{
KEEP(*(.isr_vector))
} >rom0
.text :
{
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} >rom1
/* .ARM.exidx is sorted, so has to go in its own output section.*/
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >rom1
_sidata = .; /* global needed for startup_stm3210x_md_vl.S */ 
/*now start ram area with initialized data section */
.data :
{ 
_sdata = .; /* global needed for startup_stm3210x_md_vl.S */
*(.data) 
*(.data*) 
. = ALIGN(4);
_edata = .; /* global needed for startup_stm3210x_md_vl.S */
} >ram AT>rom1
/* uninitialized data section bss*/
.bss :
{
. = ALIGN(4);
_sbss = .; /* global needed for startup_stm3210x_md_vl.S */
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* global needed for startup_stm3210x_md_vl.S */
} >ram
/* Generates an error if minimum stack size is not left in ram */
._check_stack_space :
{
. = ALIGN(4);
. = . + _minimum_stack_size;
. = ALIGN(4);
} >ram
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
/* Remove debug information from the standard libraries */
/DISCARD/ : {
*(.note.GNU-stack)
libc.a ( * )
libgcc.a ( * )
libm.a ( * )
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jihlein
Associate II
Posted on April 22, 2012 at 16:55

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6kt&d=%2Fa%2F0X0000000bug%2FNxBqYklDomkjahyRChPEoKp6.tfYDXDkQHdGyxXhMks&asPdf=false
jihlein
Associate II
Posted on April 24, 2012 at 18:49

Spent some time analyzing the .hex and .map files for the two different flash configurations.

For the standard contiguous flash load, the map file shows RESET_HANDLER at address 08000758.  The line from the .hex file is:

:10 0758 00 19 48 1A 49 02 68 00 60 8A 42 19 D0 00 21 03 E0 4A and the address in the vector table is 08000759.  Not sure why 0759 vs 0758, but this is the code that works correctly.  When the debugger comes up, the first assembly line in RESET_HANDLER is set to execute.

When I use the modified flash load, the map file shows RESET_HANDLER at address 0800C5D1, definitely in Flash sector 3.  The corresponding line from the .hex file is:

:10 C5D0 00 19 48 1A 49 02 68 00 60 8A 42 19 D0 00 21 03 E0 14 and the address in the vector table is 0800C5D1.  C5D1 vs C5D0.  All looks identical (except for the address and checksum, as expected).  But when the debugger comes up, it is showing that the first line to be executed is the second, not the first line of assembly code in RESET_HANDLER.

It appears that the program counter is not getting initialized correctly, but why?  Very confused....

Posted on April 24, 2012 at 21:04

I can't speak to the effectiveness of the debugger, or where it can stop things. Are you stepping there?

The ODD address is a flag indicating the code is 16-bit THUMB(2) code, rather than 32-bit ARM code, which doesn't run on the Cortex-M3
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jihlein
Associate II
Posted on April 25, 2012 at 00:40

Thanks for the odd address expalnation.  I'm not stepping there, it's where the debugger ''lands'' after loading the program.  In one case it's correct, in one, it's not.  Wonder if I found some kind of bug/limitation in the ''Lite'' version of TrueStudio......