2012-04-21 03:24 PM
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!2012-04-21 06:34 PM
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.2012-04-21 07:35 PM
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.2012-04-21 09:40 PM
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 ( * )
}
}
2012-04-22 07:55 AM
2012-04-24 09:49 AM
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....2012-04-24 12:04 PM
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-M32012-04-24 03:40 PM
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......