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:
1 | ... |
2 | _idata = . ; |
3 | .data : AT(_idata) |
4 | { |
5 | _data = .; |
6 | *(.data) |
7 | *(.data.*) |
8 | } >RAM |
9 | ... |
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 :-).
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
Log in with Google account
No account? Register here.