Browse Source

Basic example of autogeneration of blinkies

for the purpose of running a mini blink, there's no actual different in
ld scripts needed at all, we just need one that supports our standard
startup, and declares enough ram/flash to be functional, but small
enough that it should cover just about any of the boards we can find.

Makefile's not ideal, but it _does_ correctly allow parallel builds at
least.
master
Karl Palsson 3 years ago
parent
commit
b167913883
4 changed files with 191 additions and 0 deletions
  1. 40
      Makefile
  2. 113
      cortex-m-generic.ld
  3. 16
      ld.stm32.basic
  4. 22
      template_stm32.c

40
Makefile

@ -0,0 +1,40 @@
CC=arm-none-eabi-gcc
STM32L1_BOARDS=stm32l-discovery nucleo-l152re
STM32F4_BOARDS=stm32f4discovery
BOARDS_L1=$(STM32L1_BOARDS:=.all)
BOARDS_F4=$(STM32F4_BOARDS:=.all)
SFLAGS= --static -nostartfiles -std=c11 -g3 -Os
SFLAGS+= -fno-common -ffunction-sections -fdata-sections
SFLAGS+= -I./libopencm3/include -L./libopencm3/lib
LFLAGS+=-Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
LFLAGS+= template_stm32.c -T ld.stm32.basic
M3_FLAGS= $(SFLAGS) -mcpu=cortex-m3 -mthumb -msoft-float
M4FH_FLAGS= $(SFLAGS) -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
# STM32L1 starts up with MSI at 4MHz
STM32L1_CFLAGS=$(M3_FLAGS) -DSTM32L1 -DLITTLE_BIT=100000 $(LFLAGS) -lopencm3_stm32l1
# STM32F4 starts up with HSI at 16MHz
STM32F4_CFLAGS=$(M4FH_FLAGS) -DSTM32F4 -DLITTLE_BIT=800000 $(LFLAGS) -lopencm3_stm32f4
all: $(BOARDS_L1) $(BOARDS_F4)
# New product code for original l1 discovery
32l152cdiscovery.all: stm32l-discovery.all
stm32l-discovery.all:
$(CC) -DRCC_LED1=RCC_GPIOB -DPORT_LED1=GPIOB -DPIN_LED1=GPIO6 $(STM32L1_CFLAGS) -o $@.elf
nucleo-l152re.all:
$(CC) -DRCC_LED1=RCC_GPIOA -DPORT_LED1=GPIOA -DPIN_LED1=GPIO5 $(STM32L1_CFLAGS) -o $@.elf
# New product code for original f4 discovery board.
stm32f407g-disc1.all: stm32f4discovery.all
stm32f4discovery.all:
$(CC) -DRCC_LED1=RCC_GPIOD -DPORT_LED1=GPIOD -DPIN_LED1=GPIO12 $(STM32F4_CFLAGS) -o $@.elf
clean:
# eh, I'm sure we can do this better, but this is ok for now.
$(RM) *.elf

113
cortex-m-generic.ld

@ -0,0 +1,113 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/* Generic linker script for pretty much any cortex-m targets using libopencm3. */
/* Memory regions MUST be defined in the ld script which includes this one. */
/* Enforce emmition of the vector table. */
EXTERN (vector_table)
/* Define the entry point of the output file. */
ENTRY(reset_handler)
/* Define sections. */
SECTIONS
{
.text : {
*(.vectors) /* Vector table */
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
} >rom
/* C++ Static constructors/destructors, also used for __attribute__
* ((constructor)) and the likes */
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom
/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom
. = ALIGN(4);
_etext = .;
/* ram, but not cleared on reset. eg: boot/app comms */
.noinit (NOLOAD) : {
*(.noinit)
} >ram
. = ALIGN(4);
.data : {
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
*(.ramfunctions) /* functions we need/want to run from ram */
_edata = .;
} >ram AT >rom
_data_loadaddr = LOADADDR(.data);
.bss : {
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram
/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }
. = ALIGN(4);
end = .;
}
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));

16
ld.stm32.basic

@ -0,0 +1,16 @@
/*
* Generic linker script that works for ~all STM32 devices
* ~all STM32 devices have flash at 0x08000000 and at least 8K
* ~all STM32 devices have ram at 0x200000000 and at least 4K
*
* This is enough for miniblink, but if you try and copy this to your own
* projects, "You're gonna have a bad day"
*/
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 4K
}
INCLUDE ./cortex-m-generic.ld

22
template_stm32.c

@ -0,0 +1,22 @@
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
int main(void) {
rcc_periph_clock_enable(RCC_LED1);
gpio_mode_setup(PORT_LED1, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED1);
gpio_set(PORT_LED1, PIN_LED1);
#if defined(RCC_LED2)
rcc_periph_clock_enable(RCC_LED2);
gpio_mode_setup(PORT_LED2, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, PIN_LED2);
#endif
while(1) {
/* wait a little bit */
for (int i = 0; i < LITTLE_BIT; i++) {
__asm__("nop");
}
gpio_toggle(PORT_LED1, PIN_LED1);
#if defined(RCC_LED2)
gpio_toggle(PORT_LED2, PIN_LED2);
#endif
}
}
Loading…
Cancel
Save