EmbDev.net

Forum: ARM programming with GCC/GNU tools arm-none-eabi-ld problem (resulting main.bin is 400MB)


von Ar L. (al2757)


Rate this post
useful
not useful
Hi everyone,

  I got another problem. When I compile my code and link it to be 
downloaded in the RAM memory(for debuging purposes) everything is ok,the 
main.bin file is 36k large,no problems here.
  When I want to move the code into the flash memory I get a main.bin 
file that is aproximatley 400MB large.

These are my options in the make file:
CC      = arm-none-eabi-gcc
LD      = arm-none-eabi-ld -v
AR      = arm-none-eabi-ar
AS      = arm-none-eabi-as
CP      = arm-none-eabi-objcopy
OD    = arm-none-eabi-objdump


INCLUDE_DIRS = -I. -I./ -I toollib/lib_st/Utilities/STM32_EVAL -I 
toollib/lib_st/Libraries/CMSIS/Core/CM3 -I 
toollib/lib_st/Libraries/STM32F10x_StdPeriph_Driver/inc -I 
toollib/lib_st/Utilities/STM32_EVAL -I 
toollib/lib_st/Utilities/STM32_EVAL/STM3210E_EVAL
STARTUP_PATH =
CFLAGS  =  $(INCLUDE_DIRS) -c -fno-common -fno-reorder-functions 
-finline -mno-long-calls -O0 -g -mcpu=cortex-m3 -mthumb -L stm32.a
AFLAGS  = -ahls -o $(STARTUP_FILE).o
LFLAGS  = -Map main.map -T$(CMDFILE) -cref -u Reset_Handler
CPFLAGS = -Obinary
ODFLAGS  = -S --syms
APPOBJECTS = main.o SysInit.o SysTimers.o PowerMod.o MeasureMod.o 
I2CCom.o USARTCom.o stm32f10x_it.o stm32.a
LIBOBJECTS = core_cm3.o stm32f10x_adc.o stm32f10x_dma.o stm32f10x_i2c.o 
stm32f10x_iwdg.o stm32f10x_pwr.o stm32f10x_tim.o stm32f10x_exti.o 
stm32f10x_gpio.o misc.o stm32f10x_rcc.o stm32f10x_usart.o stm32_eval.o 
system_stm32f10x.o
LIBPATH = C:/gccfd/CodeSourcery/arm-none-eabi/lib/thumb
CMDFILE = stm3210e_eval_flash.cmd
STARTUP_FILE = startup_stm32f10x_ld-Mod

> And here is the linker file:
ENTRY(Reset_Handler)

MEMORY
{
  ram (rwx) : ORIGIN = 0x20005000, LENGTH = 32K
  flash (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}

_estack = 0x20004FFF;   /* end of stack set in the middle of the SRAM */

SECTIONS
  {
    .text :
    {
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
      *(.isr_vector)  /* Vector table */
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
      *(.text)        /* Program code */
      *(.rodata)            /* all .rodata sections (constants, strings, 
etc.)  */
    *(.rodata*)            /* all .rodata* sections (constants, strings, 
etc.)  */
      _sidata = .;
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
    } > flash

    .data :
    {
      _sdata = .;    /* create a global symbol marking the start of the 
.data section */
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
      *(.data)        /* Data memory */
      . = ALIGN(4);  /* advance location counter to the next 32-bit 
boundary */
      _edata = .;   /* define a global symbol marking the end of the 
.data section */
    } > ram

    .bss :
    {
      _sbss = .;     /* define a global symbol marking the start of the 
.bss section */
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
      *(.bss)         /* Zero-filled run time allocate data memory */
      . = ALIGN(4);   /* advance location counter to the next 32-bit 
boundary */
    } > ram

  _ebss = . ;   /* define a global symbol marking the end of the .bss 
section */
 }
  _end = .; /* define a global symbol marking the end of application RAM 
*/
/*========== end of file ==========*/

> Any sugestions?

P.S. Forgot to say that when I set the RAM address to 0x10000000 the 
main.bin is significantly smaller,still big but smaller then 400MB, it's 
around 135MB.

von (prx) A. K. (prx)


Rate this post
useful
not useful
I'd guess you requested the bin file to contain both RAM and FLASH area.

Likely RAM does not start at 20005000 but you reserve much of it for the 
stack. It's up to you to do it that way, but you should not fool the 
linker to believe there are 32KB starting at 20005000.

ARMs have a descending full stack, so the initial address should be 
20005000 and must never be unaligned.

von Ar L. (al2757)


Rate this post
useful
not useful
The ram is actually starting from 0x20000000 and is 64K large. I just 
used a setting for the stack(32K) I will make it smaller pretty soon. 
But this problem with using 2 memories in the linker always ends up into 
this problem with a file being 400MB long,which is not really ok ;-).

  So I'm not fooling nobody. For example if I set the stack at the end 
of the RAM memory it will do the same thing,even if I make the stack 
smaller.

von (prx) A. K. (prx)


Rate this post
useful
not useful
Did you write the linker file yourself basically from scratch? It should 
be a great deal easier if you do it based on working samples, since in 
the ROM case, data placement is a bit tricky. Because initialized data 
must get allocated twice, once in RAM for the addresses and once in ROM 
for the data to be initialized with. Also there is no need for contents 
in case of bss, there is a NOLOAD option for this.

von (prx) A. K. (prx)


Rate this post
useful
not useful
Ar Lc wrote:

>   So I'm not fooling nobody. For example if I set the stack at the end
> of the RAM memory it will do the same thing,even if I make the stack
> smaller.

Of course. It was just a side note, not related to your question.

von Ar L. (al2757)


Rate this post
useful
not useful
I used some examples,unfortunatley this script works only if I change 
everything to " > ram " then it goes to the right size and everything 
seems to be working just fine.
  I will try to place the NOLOAD option and maybe " flash AT> ram",not 
sure if this will actually help.


  Thank you!

  Lucian

LE: Same problem :),don't know what happens here ;-).

von (prx) A. K. (prx)


Rate this post
useful
not useful
If your linker script is based on examples, then maybe you tried to 
modify a working RAM based linker script for the ROM case. Won't work. 
Look at working examples for the ROM case instead, the details look 
quite a bit different.

The NOLOAD is once again a side note and not directly related to you 
problem.

von Ar L. (al2757)


Rate this post
useful
not useful
Ok, I will take a look on a flash example,although I started from a 
flash example and changed the file to fit my code into RAM for debugging 
purposes. I knew about this issue for something like 2 weeks.
  I will try another ld file.

  Thank you! :-)

von Ar L. (al2757)


Rate this post
useful
not useful
Modified it to this from a ROM example:

ENTRY(Reset_Handler)

MEMORY
{
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
  flash (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}

_estack = 0x2000FFFF;   /* end of stack set in the middle of the SRAM */
STACK_SIZE = 256;

SECTIONS
  {
    .text :
    {
      *(.isr_vector)  /* Vector table */
      *(.text)        /* Program code */
      *(.rodata)    /* all .rodata sections (constants, strings, etc.) 
*/
    *(.rodata*)   /* all .rodata* sections (constants, strings, etc.) 
*/
      _sidata = .;
    } > flash
      . = ALIGN(4);
    .data :
    {
      _sdata = .;    /* create a global symbol marking the start of the 
.data section */
      *(.data)        /* Data memory */
    } > ram

  . = ALIGN(4);
  _edata = . ;
  PROVIDE (edata = .);

    .bss (NOLOAD):
    {
      _sbss = .;     /* define a global symbol marking the start of the 
.bss section */
      *(.bss)         /* Zero-filled run time allocate data memory */
      *(COMMON)
    } > ram

  . = ALIGN(4);
  _ebss = . ;
  PROVIDE (ebss = .);

  .stack ALIGN(256) :
  {
    . += STACK_SIZE;
    PROVIDE (_stack = .);
  } > ram

  _ebss = . ;   /* define a global symbol marking the end of the .bss 
section */
  PROVIDE (end = .);
 }
  _end = .; /* define a global symbol marking the end of application RAM 
*/
/*========== end of file ==========*/

> Problem persists unfortunatley for me :-).

von (prx) A. K. (prx)


Rate this post
useful
not useful
I have no idea where you get your examples from, but judging from the 
apparent lack of the data section handling I mentioned it looks like you 
picked the wrong source.

The one I used for a STR9 some time ago looks different:
1
...
2
  _idata = . ;
3
  .data : AT(_idata)
4
  {
5
    _data = .;
6
    *(.data)
7
    *(.data.*)
8
  } >RAM
9
...

von Ar L. (al2757)


Rate this post
useful
not useful
Well...I just use the examples I find on the internet and just adapt my 
files.
  Seems that was the problem: ".data : AT(_idata)".
  It's good that I learned new things :-),now I can write linker files 
of my own without these issues.

  Thanks alot!

  Lucian

von Ar L. (al2757)


Rate this post
useful
not useful
Now it's not working anymore :-)). This is funny,not haha but still.

LE: Seems there are some issues with the startup code provided by ST(*.s 
files). I'm starting to dislike STM's Standard Pheripheral Library.

von (prx) A. K. (prx)


Rate this post
useful
not useful
Actually I would have been a bit surprised if it did ;-).

The startup code depends on the linker script. If you just copied my 
AT(_idata), your startup code probably does not initialize your data.

IMHO the road you've chosen is the hard one. Starting basically from 
scratch, copying a bit from here, another bit from there, hoping it 
magically fits together. It's not magic however, but works best when you 
understand what you are doing. The better part is, once you do, you end 
up with good knowledge. The worse part is the one visible here, coming 
up every 10 minutes with some question.

The easier road is to find startup code and linker script which are 
meant to be used together and which really work, and not to touch them 
until you know what you are doing. Should not be too hard though, as the 
STM32 is getting popular these days. Don't ask me though, as I started 
to use Rowley for STM32, so I could only provide samples for LPC2000 or 
STR9.

von Ar L. (al2757)


Rate this post
useful
not useful
It worked because I've been working on the .s file from ST(I had a hunch 
since it happend before when I tried to load everything in the RAM,the 
problem is that I'm using a different micro now,I did the same thing for 
a STM32 High Density and now I have to do everything for a Low 
Density),I altered it since the official one doesn't work with or 
without that AT(_sidata), it seems that there are some issues in that .s 
file provided with the Standard Pheripheral library 3.0 for arm gcc.

   With the altered file works every time,except if I remove that 
AT(_sidata), then it goes back to the same thing. So it was a little bit 
of both s and ld file. That's why I hate to work with new micros and new 
toolchains, but in this case I had no choice. Now I have to work on the 
reset handler to copy the initialization data where it's suposed to.

   I know it doesn't initialize my data, I still have to write the 
initialization code(no biggie, some small loads and stores ;-) and 
compares, assembler is not really an issue, this linker problem was).

   Don't worry about the startup files ;-), I usually write my own (did 
it for my EP-9302,also wrote the linker scripts and all fits, even the 
flash version without this AT(_sidata), but there I'm using arm-elf and 
here the Codesourcery Lite 2009q1 ).

   Seems that I still had some issues open with the flash script,since 
it is actually my first one. I usually work in RAM cause I never got 
that far with my ARM9,I'm still coding on that one,but until I find time 
to code some more on that one I have to work with this STM32. It's not 
that easy as I would have expected,since I managed to initialize the 
DDRAM using openOCD on the EP-9302 (board is an Olimex CS-9302) and for 
me that ARM9 seems to be more robust than the STM32, I don't get so 
often into Hardfaults or Busfults with it.

   The road I chose might be hard as you say :-), but not impossible. My 
only open issue with my code was this script for the flash, since I had 
some other issues with the gdb which was sending an extra read memory 
from an unmapped location,that one seems to be solved using the gdb frim 
devKit as Martin suggested.

  Thanks for the support, hope one day I can do the same for you or 
others!

  Lucian

von (prx) A. K. (prx)


Rate this post
useful
not useful
PS: Do not expect samples written for the ST lib V2 to be useful for V3 
too, regarding startup code, interrupt handler definitions and the like. 
It's a confusing subject, even Rowley adds its own layer of confusion as 
it has two different incompatible versions of STM32 support code. Latest 
CMSIS appears to have turned things a bit it seems, ST followed with V3 
lib and Rowley with V2 of its support code, but others like LM/TI still 
do not.

von Ar L. (al2757)


Rate this post
useful
not useful
I already finished the work on Interrupt handlers, thanks for the 
heads-up. The application works fine in the RAM code with all the 
interrupt vectors located there starting from address 0x20000000. The 
NVIC is a major pain in the ass(pardon my french), there are some things 
that are really weird about it.

  A small example: The SysTick in it is defined as an exception, nothing 
special so far,if you configure the SysTick and set a new priority and 
by mistake you say NVIC_EnableIRQ(SysTick_IRQn); than you got a problem. 
The only outcome from this operation is that the target starts and runs 
until that point where it just goes into HardFault and gdb connection is 
dropped.
  Doesn't seems natural to me, maybe I don't undestand the way that NVIC 
works. After trail and error you get it to work, but it takes time and 
the documentation on it is pretty vague. There is not a really good 
support for debugging such situations.
  I know it's an exception and I shouldn't tell NVIC to enable it,but 
still...it shouldn't drop everything.

  Another problem that I encountered is by using 2 USARTs(1 and 2) 
together with a null-modem cable(twisted RX-TX and ground). On USART1 I 
use DMA on send and receive byte with byte, but on USART2 I want to use 
DMA on send and receive in order to test my code. I doesn't really 
work,it works from time to time,sometimes I need to drop one DMA channel 
from USART2. The problem is the same...it just jumps into BusFault and 
I don't really know why. Not to say that the DMA didn't actually sent my 
data in the right order and ended up having extra characters in my 
received buffer on USART1. There are some issues here.
  When I connect with a terminal and a serial cable on USART1 everything 
seems ok, I will see tomorrow how it goes with USART1.
  Features that I liked and work flawles on it is the I2C which worked 
nice with a temperature sensor and the ADCs, I used it by converting 8 
channels in scan regular mode with DMA and circular mode for DMA,that 
thing does it's job really nice. Again on circular and normal mode for 
DMA, the ST documentation is really vague here.

   I used only V3 samples,but still it was a handfull. :-)

   These are my experiences so far with the STM32,unfortunatley next 
project is also by using the same STM32,this time I hope it will be 
better. I'll have to see,I think I'll have to use USB on the next 
one,I'll have to see how that goes :-).

von Ar L. (al2757)


Rate this post
useful
not useful
LE: Forgot about this issue. When you stop debugging do some coding and 
restart debuggin with the openOCD connected to the target you might get 
into problems with the interrupts. It seems that although I tray to 
reset the target using gdb it's actually not reseting the NVIC or 
something like that,the problem is that the interrupts will not work 
anymore unles I restart everything openOCD + gdb.
 It just happens, oh well ... I have to live with it :-).

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.