OPT=-Os -Wl,-Map=$(PROGNAME)-$(VERSION).map
-NEWLIB_PRINTF_CFLAGS = -DNEWLIB_INTEGER_PRINTF_SCANF
+PICOLIBC_PRINTF_CFLAGS = -DPICOLIBC_INTEGER_PRINTF_SCANF
-NEWLIB_CFLAGS= \
- -ffreestanding -nostdlib \
- -isystem $(NEWLIB_NANO)/arm-none-eabi/include \
- $(NEWLIB_PRINTF_CFLAGS)
+PICOLIBC_CFLAGS= \
+ -specs=picolibc.specs \
+ $(PICOLIBC_PRINTF_CFLAGS)
AO_CFLAGS=\
-std=gnu99 \
#define TOTAL_LENGTH (HEADER_LEN + AO_USB_HAS_INT * CONTROL_CLASS_LEN + DATA_LEN)
#define NUM_INTERFACES (AO_USB_HAS_INT + 1)
+#ifndef AO_USBCONFIG_SYMBOL
+#define AO_USBCONFIG_SYMBOL AO_ROMCONFIG_SYMBOL
+#endif
+
/* USB descriptors in one giant block of bytes */
-AO_ROMCONFIG_SYMBOL uint8_t ao_usb_descriptors [] =
+AO_USBCONFIG_SYMBOL uint8_t ao_usb_descriptors [] =
{
/* Device descriptor */
0x12,
CFLAGS = $(PRODUCT_DEF) $(LPC_CFLAGS)
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/lpc -Wl,-Taltos-loader.ld
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos-loader.ld
PROGNAME=altos-flash
PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
CC=$(ARM_CC)
-LIBS=-L$(NEWLIB_NANO)/arm-none-eabi/lib/thumb/v6-m -lc -lm -lgcc
+LIBS=-lm
LPC_CFLAGS=-mlittle-endian -mcpu=cortex-m0 -mthumb\
- -I$(TOPDIR)/lpc $(AO_CFLAGS) $(NEWLIB_CFLAGS)
+ -I$(TOPDIR)/lpc $(AO_CFLAGS) $(PICOLIBC_CFLAGS)
include $(TOPDIR)/lpc/Makefile-lpc.defs
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/lpc -Wl,-Taltos.ld -n
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/lpc -Taltos.ld -n
ao_serial_lpc.h: $(TOPDIR)/lpc/baud_rate ao_pins.h
nickle $(TOPDIR)/lpc/baud_rate `awk '/AO_LPC_CLKOUT/{print $$3}' ao_pins.h` > $@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom : ORIGIN = 0x00000000, LENGTH = 4K
- ram : ORIGIN = 0x10000000, LENGTH = 4k - 128 - 32
- usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256
- stack (!w) : ORIGIN = 0x10000000 + 4K - 128 - 32, LENGTH = 128
-}
+__flash = 0x0;
+__flash_size = 4K;
+__ram = 0x10000000;
+__ram_size = 4k;
+__stack_size = 128;
INCLUDE registers.ld
-
-EXTERN (lpc_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .interrupt : {
- __text_start__ = .;
- *(.interrupt) /* Interrupt vectors */
-
- } > rom
-
- .text ORIGIN(rom) + 0x100 : {
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
-
- *(.text*) /* Executable code */
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- *(.rodata*) /* Constants */
- __text_end__ = .;
- } > rom
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot ORIGIN(ram) + SIZEOF(.interrupt) (NOLOAD) : {
- __boot_start__ = .;
- *(.boot*)
- __boot_end__ = .;
- } >ram
-
- /* Data -- relocated to RAM, but written to ROM
- */
- .data : {
- _start__ = .;
- *(.data*) /* initialized data */
- _end__ = .;
- } >ram AT>rom
-
-
- .bss : {
- __bss_start__ = .;
- *(.bss*)
- *(COMMON*)
- __bss_end__ = .;
- } >ram
-
- PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram));
- PROVIDE(end = .);
-}
-
-ENTRY(start);
+INCLUDE picolibc.ld
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom (rx) : ORIGIN = 0x00001000, LENGTH = 28K
- ram (!w) : ORIGIN = 0x10000000, LENGTH = 4K - 128
- usb (!x) : ORIGIN = 0x20004000 + 2K - 256, LENGTH = 256
- stack (!w) : ORIGIN = 0x10000000 + 4K - 128, LENGTH = 128
-}
+__flash = 0x1000;
+__flash_size = 28K;
+__ram = 0x10000000;
+__ram_size = 4k;
+__stack_size = 128;
INCLUDE registers.ld
-
-EXTERN (lpc_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) {
- __interrupt_start__ = .;
- __interrupt_rom__ = ORIGIN(rom);
- *(.interrupt) /* Interrupt vectors */
- __interrupt_end__ = .;
- } > ram
-
- .text ORIGIN(rom) + 0x100 : {
- __text_start__ = .;
-
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
-
- *(.text*) /* Executable code */
- *(.rodata*) /* Constants */
-
- } > rom
-
- .ARM.exidx : {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- __text_end__ = .;
- } > rom
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot : {
- __boot_start__ = .;
- *(.boot)
- . = ALIGN(4);
- __boot_end__ = .;
- } >ram
-
- /* Data -- relocated to RAM, but written to ROM
- */
- .data : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) {
- _start__ = .;
- *(.data) /* initialized data */
- _end__ = .;
- __bss_start__ = .;
- } >ram
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- __bss_end__ = .;
- } >ram
- PROVIDE(end = .);
-
- PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
* ao_romconfig.c
*/
-#define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
+#define AO_ROMCONFIG_SYMBOL __attribute__((section(".init.1"))) const
+#define AO_USBCONFIG_SYMBOL __attribute__((section(".init.2"))) const
#define ao_arch_block_interrupts() asm("cpsid i")
#define ao_arch_release_interrupts() asm("cpsie i")
uint32_t check;
};
-static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
+struct ao_boot ao_boot __attribute__((section(".preserve.2")));
int
ao_boot_check_chain(void)
#define RELOCATE_INTERRUPT 1
#endif
-extern void main(void);
-extern char __stack__;
-extern char __text_start__, __text_end__;
-extern char _start__, _end__;
-extern char __bss_start__, __bss_end__;
-#if RELOCATE_INTERRUPT
-extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__;
-#endif
-
/* Interrupt functions */
void lpc_halt_isr(void)
{
}
-void start(void) {
-#ifdef AO_BOOT_CHAIN
- if (ao_boot_check_chain()) {
-#ifdef AO_BOOT_PIN
- if (ao_boot_check_pin())
-#endif
- {
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
- }
- }
-#endif
-#if RELOCATE_INTERRUPT
- memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
- lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
-#endif
- memcpy(&_start__, &__text_end__, &_end__ - &_start__);
- memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
- main();
-}
-
#define STRINGIFY(x) #x
#define isr(name) \
#define i(addr,name) [(addr)/4] = lpc_ ## name ## _isr
#define c(addr,value) [(addr)/4] = (value)
-__attribute__ ((section(".interrupt")))
-const void *lpc_interrupt_vector[] = {
- [0] = &__stack__,
- [1] = start,
+extern char __stack[];
+void _start(void) __attribute__((__noreturn__));
+
+__attribute__ ((section(".init")))
+const void *const __interrupt_vector[0x30] = {
+ [0] = __stack,
+ [1] = _start,
i(0x08, nmi),
i(0x0c, hardfault),
c(0x10, 0),
i(0xb8, usb_wakeup),
i(0xbc, hardfault),
};
+
+/*
+ * Previous versions of this code had a 256 byte interupt vector. Add
+ * some padding to make sure the other low ROM variables land at the
+ * same address
+ */
+
+__attribute__ ((section(".init.0")))
+const void *const __interrupt_pad[0x10];
+
+void main(void) __attribute__((__noreturn__));
+
+void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute((section(".preserve.1")));
+
+extern char __data_source[];
+extern char __data_start[];
+extern char __data_size[];
+extern char __bss_start[];
+extern char __bss_size[];
+
+void _start(void) {
+ memcpy(__data_start, __data_source, (uintptr_t) __data_size);
+ memset(__bss_start, '\0', (uintptr_t) __bss_size);
+
+#ifdef AO_BOOT_CHAIN
+ if (ao_boot_check_chain()) {
+#ifdef AO_BOOT_PIN
+ if (ao_boot_check_pin())
+#endif
+ {
+ ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ }
+ }
+#endif
+#if RELOCATE_INTERRUPT
+ memcpy(__interrupt_ram, __interrupt_vector, sizeof(__interrupt_ram));
+ lpc_scb.sysmemremap = LPC_SCB_SYSMEMREMAP_MAP_RAM << LPC_SCB_SYSMEMREMAP_MAP;
+#endif
+ main();
+}
all: $(PROG) $(HEX)
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Tmicropeak.ld -n
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stmf0 -Tmicropeak.ld -n
$(PROG): Makefile $(OBJ) micropeak.ld
- $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
distclean: clean
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom (rx) : ORIGIN = 0x08001000, LENGTH = 20K
- flash(rx) : ORIGIN = 0x08006000, LENGTH = 8K
- ram (!w) : ORIGIN = 0x20000000, LENGTH = 6k - 512
- stack (!w) : ORIGIN = 0x20000000 + 6k - 512, LENGTH = 512
-}
+__flash = 0x08001000;
+__flash_size = 22K;
+__flash__ = __flash + __flash_size;
+__flash_end__ = __flash__ + 6K;
+__ram = 0x20000000;
+__ram_size = 6K;
+__stack_size = 512;
INCLUDE registers.ld
-
-EXTERN (stm_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) {
- __interrupt_start__ = .;
- __interrupt_rom__ = ORIGIN(rom);
- *(.interrupt) /* Interrupt vectors */
- __interrupt_end__ = .;
- } > ram
-
- .text ORIGIN(rom) + 0x100 : {
- __text_start__ = .;
-
- /* Ick. What I want is to specify the
- * addresses of some global constants so
- * that I can find them across versions
- * of the application. I can't figure out
- * how to make gnu ld do that, so instead
- * we just load the two files that include
- * these defines in the right order here and
- * expect things to 'just work'. Don't change
- * the contents of those files, ok?
- */
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
-
- *(.text*) /* Executable code */
- } > rom
-
- .ARM.exidx : {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } > rom
-
- .rodata : {
- *(.rodata*) /* Constants */
- } > rom
-
- __text_end__ = .;
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot (NOLOAD) : {
- __boot_start__ = .;
- *(.boot)
- . = ALIGN(4);
- __boot_end__ = .;
- } >ram
-
- /* Functions placed in RAM (required for flashing)
- *
- * Align to 8 bytes as that's what the ARM likes text
- * segment alignments to be, and if we don't, then
- * we end up with a mismatch between the location in
- * ROM and the desired location in RAM. I don't
- * entirely understand this, but at least this appears
- * to work...
- */
-
- .textram BLOCK(8): {
- _start__ = .;
- *(.ramtext)
- } >ram AT>rom
-
- /* Data -- relocated to RAM, but written to ROM,
- * also aligned to 8 bytes to agree with textram
- */
- .data BLOCK(8): {
- *(.data) /* initialized data */
- _end__ = .;
- } >ram AT>rom
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- . = ALIGN(4);
- __bss_end__ = .;
- } >ram
-
- PROVIDE(end = .);
-
- PROVIDE(__flash__ = ORIGIN(flash));
- PROVIDE(__flash_end__ = ORIGIN(flash) + LENGTH(flash));
-
- PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
.textram BLOCK(8): {
_start__ = .;
__text_ram_start__ = .;
- *(.ramtext)
+ *(.srodata)
__text_ram_end = .;
} >ram AT>rom
CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS)
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm -Wl,-Taltos-loader.ld -n
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stm -Taltos-loader.ld -n
PROGNAME=altos-flash
PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
$(PROG): Makefile $(OBJ) altos-loader.ld
- $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
$(OBJ): $(INC)
vpath % $(TOPDIR)/stm:$(AO_VPATH)
CC=$(ARM_CC)
-LIBS=-L$(NEWLIB_NANO)/arm-none-eabi/lib/thumb/v7-m -lm -lc -lgcc
+LIBS=-lm
STM_CFLAGS=-mlittle-endian -mcpu=cortex-m3 -mthumb \
- -I$(TOPDIR)/stm $(AO_CFLAGS) $(NEWLIB_CFLAGS)
+ -I$(TOPDIR)/stm $(AO_CFLAGS) $(PICOLIBC_CFLAGS)
include $(TOPDIR)/stm/Makefile-stm.defs
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stm -Wl,-Taltos.ld -n
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stm -Taltos.ld -n
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom : ORIGIN = 0x08000000, LENGTH = 4K
- ram : ORIGIN = 0x20000000, LENGTH = 16K
-}
+__flash = 0x08000000;
+__flash_size = 4K;
+__ram = 0x20000000;
+__ram_size = 16K;
+__stack_size = 512;
INCLUDE registers.ld
-
-EXTERN (stm_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .text : {
- __text_start__ = .;
- *(.interrupt) /* Interrupt vectors */
-
- . = ORIGIN(rom) + 0x100;
-
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
- *(.text*) /* Executable code */
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- *(.rodata*) /* Constants */
- } > rom
- __text_end__ = .;
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot (NOLOAD) : {
- __boot_start__ = .;
- *(.boot)
- __boot_end__ = .;
- } >ram
-
- /* Functions placed in RAM (required for flashing)
- *
- * Align to 8 bytes as that's what the ARM likes text
- * segment alignments to be, and if we don't, then
- * we end up with a mismatch between the location in
- * ROM and the desired location in RAM. I don't
- * entirely understand this, but at least this appears
- * to work...
- */
-
- .textram BLOCK(8): {
- _start__ = .;
- __text_ram_start__ = .;
- *(.ramtext)
- __text_ram_end = .;
- } >ram AT>rom
-
- /* Data -- relocated to RAM, but written to ROM
- * Also aligned to 8 bytes to agree with textram
- */
- .data BLOCK(8): {
- *(.data) /* initialized data */
- _end__ = .;
- } >ram AT>rom
-
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- __bss_end__ = .;
- } >ram
-
- PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram));
- PROVIDE(end = .);
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom (rx) : ORIGIN = 0x08001000, LENGTH = 124K
- ram (!w) : ORIGIN = 0x20000000, LENGTH = 15872
- stack (!w) : ORIGIN = 0x20003e00, LENGTH = 512
-}
+__flash = 0x08001000;
+__flash_size = 124K;
+__ram = 0x20000000;
+__ram_size = 16k;
+__stack_size = 512;
INCLUDE registers.ld
-
-EXTERN (stm_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .text ORIGIN(rom) : {
- __text_start__ = .;
- *(.interrupt) /* Interrupt vectors */
-
- . = ORIGIN(rom) + 0x100;
-
-
- /* Ick. What I want is to specify the
- * addresses of some global constants so
- * that I can find them across versions
- * of the application. I can't figure out
- * how to make gnu ld do that, so instead
- * we just load the two files that include
- * these defines in the right order here and
- * expect things to 'just work'. Don't change
- * the contents of those files, ok?
- */
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
- *(.text*) /* Executable code */
- *(.rodata*) /* Constants */
-
- } > rom
-
- .ARM.exidx : {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } > rom
- __text_end__ = .;
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot (NOLOAD) : {
- __boot_start__ = .;
- *(.boot)
- . = ALIGN(4);
- __boot_end__ = .;
- } >ram
-
- /* Data -- relocated to RAM, but written to ROM
- */
- .data : {
- _start__ = .;
- *(.data) /* initialized data */
- . = ALIGN(4);
- _end__ = .;
- } >ram AT>rom
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- . = ALIGN(4);
- __bss_end__ = .;
- } >ram
-
- PROVIDE(end = .);
-
- PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
* ao_romconfig.c
*/
-#define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
+#define AO_ROMCONFIG_SYMBOL __attribute__((section(".init.1"))) const
+#define AO_USBCONFIG_SYMBOL __attribute__((section(".init.2"))) const
/*
* For now, we're running at a weird frequency
uint32_t check;
};
-static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
-
+struct ao_boot ao_boot __attribute__((section(".preserve.2")));
+
int
ao_boot_check_chain(void)
{
;
}
-static void __attribute__ ((section(".ramtext"),noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_erase_page(uint32_t *page)
{
stm_flash.pecr |= (1 << STM_FLASH_PECR_ERASE) | (1 << STM_FLASH_PECR_PROG);
ao_arch_release_interrupts();
}
-static void __attribute__ ((section(".ramtext"), noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_half_page(uint32_t *dst, uint32_t *src)
{
uint8_t i;
#include <ao_boot.h>
extern void main(void);
-extern char __stack__;
-extern char __text_start__, __text_end__;
-extern char _start__, _end__;
-extern char __bss_start__, __bss_end__;
/* Interrupt functions */
{
}
-const void *stm_interrupt_vector[];
+void *const __interrupt_vector[];
uint32_t
stm_flash_size(void) {
return (uint32_t) kbytes * 1024;
}
-void start(void)
-{
-#ifdef AO_BOOT_CHAIN
- if (ao_boot_check_chain()) {
-#ifdef AO_BOOT_PIN
- if (ao_boot_check_pin())
-#endif
- {
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
- }
- }
-#endif
- /* Set interrupt vector table offset */
- stm_nvic.vto = (uint32_t) &stm_interrupt_vector;
- memcpy(&_start__, &__text_end__, &_end__ - &_start__);
- memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
- main();
-}
-
#define STRINGIFY(x) #x
#define isr(name) \
#define i(addr,name) [(addr)/4] = stm_ ## name ## _isr
-__attribute__ ((section(".interrupt")))
-const void *stm_interrupt_vector[] = {
- [0] = &__stack__,
- [1] = start,
+extern char __stack[];
+void _start(void) __attribute__((__noreturn__));
+void main(void) __attribute__((__noreturn__));
+
+/* This must be exactly 256 bytes long so that the configuration data
+ * gets loaded at the right place
+ */
+
+__attribute__ ((section(".init")))
+void * const __interrupt_vector[64] = {
+ [0] = &__stack,
+ [1] = _start,
i(0x08, nmi),
i(0x0c, hardfault),
i(0x10, memmanage),
i(0xec, tim6),
i(0xf0, tim7),
};
+
+extern char __data_source[];
+extern char __data_start[];
+extern char __data_size[];
+extern char __bss_start[];
+extern char __bss_size[];
+
+void _start(void) {
+ memcpy(__data_start, __data_source, (uintptr_t) __data_size);
+ memset(__bss_start, '\0', (uintptr_t) __bss_size);
+
+#ifdef AO_BOOT_CHAIN
+ if (ao_boot_check_chain()) {
+#ifdef AO_BOOT_PIN
+ if (ao_boot_check_pin())
+#endif
+ {
+ ao_boot_chain(AO_BOOT_APPLICATION_BASE);
+ }
+ }
+#endif
+ /* Set interrupt vector table offset */
+ stm_nvic.vto = (uint32_t) &__interrupt_vector;
+ main();
+}
.textram BLOCK(8): {
_start__ = .;
__text_ram_start__ = .;
- *(.ramtext)
+ *(.srodata)
__text_ram_end = .;
} >ram AT>rom
CFLAGS = $(PRODUCT_DEF) $(STMF0_CFLAGS)
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Taltos-loader.ld
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stmf0 -Taltos-loader.ld
PROGNAME=altos-flash
PROG=$(HARDWARE)-$(PROGNAME)-$(VERSION).elf
all: $(PROG) $(BIN)
$(PROG): Makefile $(OBJ) altos-loader.ld
- $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
$(BIN): $(PROG)
$(MAKEBIN) --output=$@ --base=$(FLASH_ADDR) $(PROG)
CC=$(ARM_CC)
STMF0_CFLAGS=-mlittle-endian -mcpu=cortex-m0 -mthumb\
- -I$(TOPDIR)/stmf0 $(AO_CFLAGS) $(NEWLIB_CFLAGS)
+ -I$(TOPDIR)/stmf0 $(AO_CFLAGS) $(PICOLIBC_CFLAGS)
-LIBS=-L$(NEWLIB_NANO)/arm-none-eabi/lib/thumb/v6-m -lc -lm -lgcc
+LIBS=-lm
include $(TOPDIR)/stmf0/Makefile-stmf0.defs
-LDFLAGS=$(CFLAGS) -L$(TOPDIR)/stmf0 -Wl,-Taltos.ld -n
+LDFLAGS=-nostartfiles $(CFLAGS) -L$(TOPDIR)/stmf0 -Taltos.ld -n
LOADER=flash-loader/$(PROGNAME)-altos-flash-$(VERSION).elf
MAKEBIN=$(TOPDIR)/../ao-tools/ao-makebin/ao-makebin
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom : ORIGIN = 0x08000000, LENGTH = 4K
- ram : ORIGIN = 0x20000000, LENGTH = 6K
-}
+__flash = 0x08000000;
+__flash_size = 4K;
+__ram = 0x20000000;
+__ram_size = 6k;
+__stack_size = 128;
INCLUDE registers.ld
-
-EXTERN (stm_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .interrupt : {
- __text_start__ = .;
- *(.interrupt) /* Interrupt vectors */
- } > rom
-
- .text ORIGIN(rom) + 0x100 : {
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
-
- *(.text*) /* Executable code */
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- *(.rodata*) /* Constants */
- } > rom
- __text_end__ = .;
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot ORIGIN(ram) + SIZEOF(.interrupt) (NOLOAD) : {
- __boot_start__ = .;
- *(.boot)
- __boot_end__ = .;
- } >ram
-
- /* Functions placed in RAM (required for flashing)
- *
- * Align to 8 bytes as that's what the ARM likes text
- * segment alignments to be, and if we don't, then
- * we end up with a mismatch between the location in
- * ROM and the desired location in RAM. I don't
- * entirely understand this, but at least this appears
- * to work...
- */
-
- .textram BLOCK(8): {
- _start__ = .;
- __text_ram_start__ = .;
- *(.ramtext)
- __text_ram_end = .;
- } >ram AT>rom
-
- /* Data -- relocated to RAM, but written to ROM.
- * also aligned to 8 bytes in case textram is empty
- */
- .data BLOCK(8): {
- *(.data) /* initialized data */
- _end__ = .;
- } >ram AT>rom
-
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- __bss_end__ = .;
- } >ram
-
- PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram));
- PROVIDE(end = .);
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-MEMORY {
- rom (rx) : ORIGIN = 0x08001000, LENGTH = 28K
- ram (!w) : ORIGIN = 0x20000000, LENGTH = 6k - 128
- stack (!w) : ORIGIN = 0x20000000 + 6k - 128, LENGTH = 128
-}
+__flash = 0x08001000;
+__flash_size = 28K;
+__ram = 0x20000000;
+__ram_size = 6k;
+__stack_size = 128;
INCLUDE registers.ld
-
-EXTERN (stm_interrupt_vector)
-
-SECTIONS {
- /*
- * Rom contents
- */
-
- .interrupt ORIGIN(ram) : AT (ORIGIN(rom)) {
- __interrupt_start__ = .;
- __interrupt_rom__ = ORIGIN(rom);
- *(.interrupt) /* Interrupt vectors */
- __interrupt_end__ = .;
- } > ram
-
- .text ORIGIN(rom) + 0x100 : {
- __text_start__ = .;
-
- /* Ick. What I want is to specify the
- * addresses of some global constants so
- * that I can find them across versions
- * of the application. I can't figure out
- * how to make gnu ld do that, so instead
- * we just load the two files that include
- * these defines in the right order here and
- * expect things to 'just work'. Don't change
- * the contents of those files, ok?
- */
- ao_romconfig.o(.romconfig*)
- ao_product.o(.romconfig*)
-
- *(.text*) /* Executable code */
- } > rom
-
- .ARM.exidx : {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } > rom
-
- .rodata : {
- *(.rodata*) /* Constants */
- } > rom
-
- __text_end__ = .;
-
- /* Boot data which must live at the start of ram so that
- * the application and bootloader share the same addresses.
- * This must be all uninitialized data
- */
- .boot (NOLOAD) : {
- __boot_start__ = .;
- *(.boot)
- . = ALIGN(4);
- __boot_end__ = .;
- } >ram
-
- /* Data -- relocated to RAM, but written to ROM
- */
- .data : {
- _start__ = .;
- *(.data) /* initialized data */
- . = ALIGN(4);
- _end__ = .;
- } >ram AT>rom
-
- .bss : {
- __bss_start__ = .;
- *(.bss)
- *(COMMON)
- . = ALIGN(4);
- __bss_end__ = .;
- } >ram
-
- PROVIDE(end = .);
-
- PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack));
-}
-
-ENTRY(start);
-
-
+INCLUDE picolibc.ld
* ao_romconfig.c
*/
-#define AO_ROMCONFIG_SYMBOL __attribute__((section(".romconfig"))) const
+#define AO_ROMCONFIG_SYMBOL __attribute__((section(".init.1"))) const
+#define AO_USBCONFIG_SYMBOL __attribute__((section(".init.2"))) const
extern const uint16_t ao_romconfig_version;
extern const uint16_t ao_romconfig_check;
uint32_t check;
};
-static struct ao_boot __attribute__ ((section(".boot"))) ao_boot;
+struct ao_boot ao_boot __attribute__((section(".preserve.2")));
int
ao_boot_check_chain(void)
#define ao_flash_wait_bsy() do { while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)); } while (0)
-static void __attribute__ ((section(".ramtext"),noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_erase_page(uint32_t *page)
{
stm_flash.cr |= (1 << STM_FLASH_CR_PER);
ao_arch_release_interrupts();
}
-static void __attribute__ ((section(".ramtext"), noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_page(uint16_t *dst, uint16_t *src)
{
uint8_t i;
#endif
#endif
-extern void main(void);
-extern char __stack__;
-extern char __text_start__, __text_end__;
-extern char _start__, _end__;
-extern char __bss_start__, __bss_end__;
-#if RELOCATE_INTERRUPT
-extern char __interrupt_rom__, __interrupt_start__, __interrupt_end__;
-#endif
-
/* Interrupt functions */
void stm_halt_isr(void)
{
}
-const void *stm_interrupt_vector[];
-
uint32_t
stm_flash_size(void) {
uint16_t dev_id = stm_dev_id();
return (uint32_t) kbytes * 1024;
}
-void start(void)
-{
-#if AO_BOOT_CHAIN
- if (ao_boot_check_chain()) {
-#if AO_BOOT_PIN
- if (ao_boot_check_pin())
-#endif
- {
- ao_boot_chain(AO_BOOT_APPLICATION_BASE);
- }
- }
-#endif
- /* Turn on syscfg */
- stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN);
-
-#if RELOCATE_INTERRUPT
- memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__);
- stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
- (STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE);
-#else
- /* Switch to Main Flash mode (DFU loader leaves us in System mode) */
- stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
- (STM_SYSCFG_CFGR1_MEM_MODE_MAIN_FLASH << STM_SYSCFG_CFGR1_MEM_MODE);
-#endif
- memcpy(&_start__, &__text_end__, &_end__ - &_start__);
- memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__);
- main();
-}
-
#define STRINGIFY(x) #x
#define isr(name) \
#define i(addr,name) [(addr)/4] = stm_ ## name ## _isr
-__attribute__ ((section(".interrupt")))
-const void *stm_interrupt_vector[] = {
- [0] = &__stack__,
- [1] = start,
+extern char __stack[];
+void _start(void) __attribute__((__noreturn__));
+void main(void) __attribute__((__noreturn__));
+
+__attribute__ ((section(".init")))
+const void * const __interrupt_vector[0x30] = {
+ [0] = __stack,
+ [1] = _start,
i(0x08, nmi),
i(0x0c, hardfault),
i(0x2c, svc),
i(0xb8, cec_can),
i(0xbc, usb),
};
+
+/*
+ * Previous versions of this code had a 256 byte interupt vector. Add
+ * some padding to make sure the other low ROM variables land at the
+ * same address
+ */
+
+__attribute__ ((section(".init.0")))
+const void *const __interrupt_pad[0x10];
+
+void *__interrupt_ram[sizeof(__interrupt_vector)/sizeof(__interrupt_vector[0])] __attribute__((section(".preserve.1")));
+
+extern char __data_source[];
+extern char __data_start[];
+extern char __data_size[];
+extern char __bss_start[];
+extern char __bss_size[];
+
+void _start(void)
+{
+ memcpy(__data_start, __data_source, (uintptr_t) __data_size);
+ memset(__bss_start, '\0', (uintptr_t) __bss_size);
+
+#if AO_BOOT_CHAIN
+ if (ao_boot_check_chain()) {
+#if AO_BOOT_PIN
+ ao_boot_check_pin();
+#endif
+ }
+#endif
+ /* Turn on syscfg */
+ stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN);
+
+#if RELOCATE_INTERRUPT
+ memcpy(__interrupt_ram, __interrupt_vector, sizeof(__interrupt_ram));
+ stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
+ (STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE);
+#else
+ /* Switch to Main Flash mode (DFU loader leaves us in System mode) */
+ stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) |
+ (STM_SYSCFG_CFGR1_MEM_MODE_MAIN_FLASH << STM_SYSCFG_CFGR1_MEM_MODE);
+#endif
+ main();
+}
#define ao_flash_wait_bsy() do { while (stm_flash.sr & (1 << STM_FLASH_SR_BSY)); } while (0)
-static void __attribute__ ((section(".ramtext"),noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_erase_page(uint16_t *page)
{
stm_flash.cr |= (1 << STM_FLASH_CR_PER);
#define _ao_flash_addr(pos) ((uint16_t *) (void *) ((uint8_t *) __flash__ + (pos)))
-static void __attribute ((section(".ramtext"), noinline)) _ao_flash_byte(uint32_t pos, uint8_t b)
+static void __attribute__ ((section(".sdata2.flash"), noinline))
+_ao_flash_byte(uint32_t pos, uint8_t b)
{
uint16_t v;
uint16_t *a = _ao_flash_addr(pos & ~1);
ao_flash_wait_bsy();
}
-static void __attribute__ ((section(".ramtext"), noinline))
+static void __attribute__ ((section(".sdata2.flash"), noinline))
_ao_flash_write(uint32_t pos, void *sv, uint16_t len)
{
uint8_t *s = sv;
all: $(PROG) $(HEX)
$(PROG): Makefile $(OBJ) altos.ld
- $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
$(OBJ): $(INC)
all: $(PROG) $(HEX)
$(PROG): Makefile $(OBJ) altos.ld
- $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
$(OBJ): $(INC)
all: $(PROG) $(HEX)
$(PROG): Makefile $(OBJ) altos.ld
- $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS)
+ $(call quiet,CC) $(LDFLAGS) -o $(PROG) $(OBJ) $(LIBS) -Wl,-Map=$(PROGNAME)-$(VERSION).map
$(OBJ): $(INC)