I have been working with an STM32F2 (specifically, the STM32F217IGH6 on a development board) for about two months. By far my biggest problem had to do with the "setup", which includes makefile, linker script and start-up file.
In particular, I have been unable to properly set up my interrupt vector table and have interrupt handlers called. ST does provide examples tailored to commercial IDEs. Instead, I am using the free Yagarto recompilation of the GCC toolchain (and OpenOCD to load the image via JTAG).
Are there example projects for my board (or a close cousin of it) which contain the appropriate makefile, linker script and start-up file combination for non-commercial IDEs that are set up for interrupt handlers to be called?
Best Answer
http://github.com/dwelch67
stm32f4 and stm32vld in particular, but the others may be useful to you as well. mbed and the mzero directory under mbed (cortex-m0).
I like the keep it simple stupid approach, minimal linker scripts, minimal startup code, etc. The work is done by the code not by any particular toolchain.
Most forms of gcc and binutils (capable of thumb) will work somewhat with these examples as I use the compiler to compile not as a resource for library calls, I dont use the stock linker scripts, etc. Older gcc and binutils will not know about the newer thumb2 parts so some changes may be required.
I build my own gcc, binutils and llvm/clang as well as use codesourcery for example (now mentor graphics but you can still get the free/lite version).
Esp when starting out putting together a project for a new target you need to do some disassembly. In particular to make sure the items are where you want them, the vector table for example.
Look at stm32f4d/blinker02 for example. It starts with vectors.s the exception/vector table plus some asm support routines:
No interrupts on this example, but the other things you need are here.
blinker02.c contains the main body of C code with the C entrypoint that I call notmain() to avoid calling it main (some compilers add junk to your binary when you have a main()).
will spare you a cut and paste. the makefile tells the story about compiling and linking. Note that a number of my examples compile two or more binaries from the same code. gcc compiler, llvm's clang compiler, thumb only and thumb2, different optimizations, etc.
Start by making object files from the source files.
the linker, ld, uses a linker script which I call memmap, these can be extremely painful, sometimes for a good reason, sometimes not. I prefer the less is more approach to the one size fits all, everything but the kitchen sink approach.
I dont use .data typically (well almost never) and this example doesnt have a need for .bss so here is the linker script, just enough to place the program (.text) where it needs to be for this processor they way I am using it.
I have a memory region to define that, there is nothing special about the name ram you can call it foo or bar or bob or ted it doesnt matter it just links the memory items to sections. The sections define things like .text, .data, .bss, .rodata and where they go in the memory map.
when you build this, you see I disassemble everything (objdump -D) you see this
The key thing to note is the address on the left is where we wanted it, the vectors.s code is first in the binary (Because it is first on the ld command line, unless you do something in the linker script the items will show up in the binary in the order they are on the ld command line). For booting properly you must insure your vector table is in the right place. The first item is my stack address, that is fine. The second item is the address to _start and it should be an odd number. the use of .thumb_func before a label causes this to happen so you dont have to do other ugly looking things.
so the 0x08000051 and 0x08000057 are the proper vector entries for _start and hang. start calls notmain()
That looks good (They dont show the odd numbered address in the disassembly).
All is well.
Skip to the example blinker05, this one does support interrupts. and needs some ram, so .bss is defined.
remember ram and rom are arbitrary names, bob and ted, foo and bar all work just fine.
Not going to show the whole vectors.s because the cortex-m3 has a zillion entries in the vector table if you make a complete one (varies from core to core and maybe within the same core depending on the options chosen by the chip vendor) The relevant portions are here after disassembly:
takes some trial and error to place that handler exactly at the right spot, check with your chip where it needs to be it isnt necessarily at the same place as this one, and with so many interrupts you may be looking for a different interrupt anyway. the cortex-m processors, unlike normal arms, make it so you dont NEED trampoline code for interrupts, they preserve a certain number of registers and manage switching of processor modes through the link register contents. so long as the hardware and the abi for the compiler are close enough it all works. In this case I did the handler in C, unlike other platforms and the past you dont need to do anything special with the compiler/syntax just make a function (but dont do stupid things in the function/handler)
The makefile for blinker05 should resemble the blinker02 example, mostly cut and paste for most of these. turn the individual source files into objects then link. I do build for thumb, thumb2 using gcc and clang. you can change the all: line at the time to only include the gcc items if you dont have/want clang (llvm) involved. I use binutils to assemble and link the clang output btw.
All of these projects use free, off the shelf, open source, tools. no IDE's, command line only. Yes I only mess with Linux and not Windows, but these tools are available to windows users as well, change things like rm -f something to del something in the makefile, things like that when building on windows. That or run linux on vmware or virtualbox or qemu. Not using an IDE means you pick your text editor as well, I wont get into that, I have my favorite(s). Note that an extremely annoying feature of the gnu make program is that it requires actual tabs in the makefile, I hate invisible tabs with a passion. So one text editor for makefiles that leaves tabs, the other for source code that makes spaces. I dont know about windows, I normally used borland make or microsoft make instead of gnu when developing there (even when using gcc and binutils).
I hope this helps, it is not the exact chip/board but a cortex-m4 well m4 not m3, close enough for this discussion. see the mbed or stm32vld dir for an actual cortex-m3 (not enough differences from the m4 for makefiles and boot code, etc), but not made by st. The cortex-m3 core's should be the same across vendors, the cortex-m3 and cortex-m4 are both ARMv7m and are closer rather than different. The cortex-m0 is an ARMv6m, hardly has thumb2 instructions enough to bother with, the compilers have not caught up with it so just use thumb only (pretend you are building for an ARMv4T (thumb only) if need be). My thumbulator simulator is thumb only, no thumb2, it might be useful to you as well, I think I made it perform interrupts in some form or fashion.