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.
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.
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.
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.
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.
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 ;-).
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.
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! :-)
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 :-).
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:
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
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.
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.
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
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.
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 :-).
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 :-).