Proper building for Flash

This commit is contained in:
Romain Goyet
2015-05-02 13:25:27 +02:00
commit 1b8d5201de
6 changed files with 142 additions and 0 deletions

2
INSTALL.txt Normal file
View File

@@ -0,0 +1,2 @@
- Download a toolchain from https://launchpad.net/gcc-arm-embedded/+download
- Install openocd (tested with 0.8.0)

30
Makefile Normal file
View File

@@ -0,0 +1,30 @@
CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld.bfd
GDB=arm-none-eabi-gdb
OBJCOPY=arm-none-eabi-objcopy
CFLAGS=-march=armv7e-m -mcpu=cortex-m4 -mthumb -std=c99 -g
objs := boot/crt0.o src/blinky.o
run: boot.elf
$(GDB) -x gdb_script.gdb boot.elf
boot.hex: boot.elf
@echo "OBJCOPY $@"
@$(OBJCOPY) -O ihex boot.elf boot.hex
boot.bin: boot.elf
@echo "OBJCOPY $@"
@$(OBJCOPY) -O binary boot.elf boot.bin
boot.elf: $(objs)
@echo "LD $@"
@$(LD) -T boot/stm32f429_flash.ld $(objs) -o $@
%.o: %.c
@echo "CC $@"
@$(CC) $(CFLAGS) -c $< -o $@
clean:
@echo "CLEAN"
@rm -f $(objs) boot.elf boot.bin boot.hex

52
boot/crt0.c Normal file
View File

@@ -0,0 +1,52 @@
typedef long uint32_t;
extern const void * _data_segment_start_flash;
extern const void * _data_segment_start_ram;
extern const void * _data_segment_end_ram;
void reset(void);
/* Interrupt Service Routines are void->void functions */
typedef void(*ISR)(void);
/* Notice: The Cortex-M4 expects all jumps to be made at an odd address when
* jumping to Thumb code. For example, if you want to execute Thumb code at
* address 0x100, you'll have to jump to 0x101. Luckily, this idiosyncrasy is
* properly handled by the C compiler that will generate proper addresses when
* using function pointers. */
#define INITIALISATION_VECTOR_SIZE 0x6B
ISR InitialisationVector[INITIALISATION_VECTOR_SIZE]
__attribute__((section(".isr_vector_table")))
= {
0x20010000, //FIXME: This is the stack pointer!
reset,
0,
0,
0
};
void blink(void);
void reset(void) {
// This is where execution start after reset.
// Many things are not initialized yet so the code here has to pay attention.
/* Copy data segment to RAM
* The data segment is R/W but its initialization value matters. It's stored
* in Flash, but linked as if it were in RAM. Now's our opportunity to copy
* it. Note that until then the data segment (e.g. global variables) contains
* garbage values and should not be used. */
// int dataSegmentSize = &_data_segment_end_ram - &_data_segment_start_ram;
uint32_t * ramPointer = (uint32_t *)&_data_segment_start_ram;
uint32_t * flashPointer = (uint32_t *)&_data_segment_start_flash;
while (ramPointer < (uint32_t *)&_data_segment_end_ram) {
*ramPointer++ = *flashPointer++;
}
blink();
}
/*
void _start(void) {
}*/

49
boot/stm32f429_flash.ld Normal file
View File

@@ -0,0 +1,49 @@
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 192K
CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K
}
SECTIONS {
.isr_vector_table ORIGIN(FLASH) : {
/* We're explicitly asking for the ISR vector table to be at the beginning
* of the Flash memory. This is what the STM32F42xx expects when booting.
* See ST/RM0090/p70 */
*(.isr_vector_table)
/*LONG(0x20010000);*/ /* Stack pointer */
/*LONG(0x00000201);*/ /* Reset vector */
/* CAUTION: The least significant bit of the reset
* vector should be set to indicate Thumb code */
} >FLASH
.text : {
. = ALIGN(4);
*(.text)
} >FLASH
.rodata : {
. = ALIGN(4);
*(.rodata)
} >FLASH
.data : {
/* The data section is written to Flash but linked as if it were in RAM.
* This is required because its initial value matters (so it has to be in
* persistant memory in the first place), but it is a R/W area of memory
* so it will have to live in RAM upon execution (in linker lingo, that
* translate to the data segment having a LMA in Flash and a VMA in RAM).
* This means we'll have to copy it from Flash to RAM on initialization.
* To do this, we'll need to know the source location of the data segment
* (in Flash), the target location (in RAM), and the size of the segment.
* That's why we're defining three symbols that we'll use in the initial-
* -ization routine. */
. = ALIGN(4);
_data_segment_start_flash = LOADADDR(.data);
_data_segment_start_ram = .;
*(.data)
_data_segment_end_ram = .;
} >RAM AT> FLASH
/*. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }*/
}

8
gdb_script.gdb Normal file
View File

@@ -0,0 +1,8 @@
# Let's connect to OpenOCD
target remote localhost:3333
# Load our executable
load boot.elf
# Tell OpenOCD to reset and halt
monitor reset halt

1
openocd.cfg Normal file
View File

@@ -0,0 +1 @@
source [find board/stm32f429discovery.cfg]