From c9c35b100c3fcae661501d2bf89eedc7fceb2e1c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 10 Mar 2013 21:02:59 -0700 Subject: [PATCH] altos: Make stm-flash capable of switching to application This shrinks the base OS load down a bit as well so that stm-flash fits comfortably in the first 8kB of memory. Signed-off-by: Keith Packard --- src/core/ao_cmd.c | 11 ++++++ src/core/ao_task.c | 2 + src/core/ao_task.h | 4 ++ src/stm-demo/Makefile | 2 +- src/stm-flash/ao_pins.h | 13 ++++--- src/stm-flash/ao_stm_flash.c | 28 +------------- src/stm/altos-application.ld | 72 ++++++++++++++++++++++++++++++++++++ src/stm/altos-loader.ld | 72 ++++++++++++++++++++++++++++++++++++ src/stm/ao_boot.h | 24 ++++++++++++ src/stm/ao_interrupt.c | 44 +++++++++++++++++----- 10 files changed, 229 insertions(+), 43 deletions(-) create mode 100644 src/stm/altos-application.ld create mode 100644 src/stm/altos-loader.ld create mode 100644 src/stm/ao_boot.h diff --git a/src/core/ao_cmd.c b/src/core/ao_cmd.c index 6eed08d9..7da2384f 100644 --- a/src/core/ao_cmd.c +++ b/src/core/ao_cmd.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_task.h" __pdata uint16_t ao_cmd_lex_i; __pdata uint32_t ao_cmd_lex_u32; @@ -262,6 +263,11 @@ ao_reboot(void) ao_panic(AO_PANIC_REBOOT); } +#ifndef HAS_VERSION +#define HAS_VERSION 1 +#endif + +#if HAS_VERSION static void version(void) { @@ -289,6 +295,7 @@ version(void) #endif printf("software-version %s\n", ao_version); } +#endif #ifndef NUM_CMDS #define NUM_CMDS 11 @@ -382,10 +389,14 @@ __xdata struct ao_task ao_cmd_task; __code struct ao_cmds ao_base_cmds[] = { { help, "?\0Help" }, +#if HAS_TASK_INFO { ao_task_info, "T\0Tasks" }, +#endif { echo, "E <0 off, 1 on>\0Echo" }, { ao_reboot, "r eboot\0Reboot" }, +#if HAS_VERSION { version, "v\0Version" }, +#endif { 0, NULL }, }; diff --git a/src/core/ao_task.c b/src/core/ao_task.c index c24c9929..0aad6508 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -512,6 +512,7 @@ ao_exit(void) /* we'll never get back here */ } +#if HAS_TASK_INFO void ao_task_info(void) { @@ -528,6 +529,7 @@ ao_task_info(void) ao_task_validate(); #endif } +#endif void ao_start_scheduler(void) diff --git a/src/core/ao_task.h b/src/core/ao_task.h index 50bfb220..1a4b5b6b 100644 --- a/src/core/ao_task.h +++ b/src/core/ao_task.h @@ -21,6 +21,10 @@ #include #endif +#ifndef HAS_TASK_INFO +#define HAS_TASK_INFO 1 +#endif + /* An AltOS task */ struct ao_task { __xdata void *wchan; /* current wait channel (NULL if running) */ diff --git a/src/stm-demo/Makefile b/src/stm-demo/Makefile index 3b1b671b..ab12f47b 100644 --- a/src/stm-demo/Makefile +++ b/src/stm-demo/Makefile @@ -53,7 +53,7 @@ OBJ=$(SRC:.c=.o) all: $(PROG) -LDFLAGS=-L../stm -Wl,-Taltos.ld +LDFLAGS=-L../stm -Wl,-Taltos-application.ld $(PROG): Makefile $(OBJ) $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(SAT_CLIB) -lgcc diff --git a/src/stm-flash/ao_pins.h b/src/stm-flash/ao_pins.h index b232f373..ca53d844 100644 --- a/src/stm-flash/ao_pins.h +++ b/src/stm-flash/ao_pins.h @@ -20,7 +20,9 @@ #define HAS_TASK_QUEUE 0 -#define AO_HSE 8000000 +/* Bridge SB17 on the board and use the MCO from the other chip */ +#define AO_HSE 8000000 +#define AO_HSE_BYPASS 1 /* PLLVCO = 96MHz (so that USB will work) */ #define AO_PLLMUL 12 @@ -61,11 +63,12 @@ #define AO_TICK_SIGNED int32_t #define HAS_TASK_INFO 0 +#define HAS_VERSION 0 -#define AO_BOOT_APPLICATION_GPIO stm_gpiob -#define AO_BOOT_APPLICATION_PIN 5 -#define AO_BOOT_APPLICATION_VALUE 0 -#define AO_BOOT_APPLICATION_MODE AO_EXTI_MODE_PULL_UP +#define AO_BOOT_APPLICATION_GPIO stm_gpioa +#define AO_BOOT_APPLICATION_PIN 0 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE 0 #define AO_BOOT_APPLICATION_BASE 0x2000 #endif /* _AO_PINS_H_ */ diff --git a/src/stm-flash/ao_stm_flash.c b/src/stm-flash/ao_stm_flash.c index 81ae86df..e2d7ec65 100644 --- a/src/stm-flash/ao_stm_flash.c +++ b/src/stm-flash/ao_stm_flash.c @@ -17,7 +17,6 @@ #include "ao.h" #include -<<<<<<< HEAD #include #include @@ -118,48 +117,23 @@ __code struct ao_cmds ao_flash_cmds[] = { { ao_block_read, "R \0Read block. Returns 256 bytes" }, { 0, NULL }, }; -======= -void -ao_panic(uint8_t c) -{ -} - -void -ao_test(void) -{ - char c; - - for (;;) { - c = ao_usb_getchar(); - ao_usb_putchar(c); - ao_usb_flush(); - } -} - -struct ao_task ao_test_task; ->>>>>>> 5187bb4... Add STM self-flashing loader int main(void) { ao_clock_init(); -<<<<<<< HEAD ao_task_init(); -======= ->>>>>>> 5187bb4... Add STM self-flashing loader ao_timer_init(); // ao_dma_init(); ao_cmd_init(); // ao_exti_init(); ao_usb_init(); -<<<<<<< HEAD ao_cmd_register(&ao_flash_cmds[0]); -======= ->>>>>>> 5187bb4... Add STM self-flashing loader + ao_cmd_register(&ao_flash_cmds[0]); ao_start_scheduler(); return 0; } diff --git a/src/stm/altos-application.ld b/src/stm/altos-application.ld new file mode 100644 index 00000000..63a3be00 --- /dev/null +++ b/src/stm/altos-application.ld @@ -0,0 +1,72 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +MEMORY { + rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K + ram (!w) : ORIGIN = 0x20000000, LENGTH = 16K +} + +INCLUDE registers.ld + +EXTERN (stm_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .text ORIGIN(rom) : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.rodata*) /* Constants */ + + } > rom + + .ARM.exidx : { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __text_end__ = .; + } > rom + + /* Data -- relocated to RAM, but written to ROM + */ + .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + __bss_start__ = .; + } >ram + + .bss : { + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + + PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(end = .); +} + +ENTRY(start); + + diff --git a/src/stm/altos-loader.ld b/src/stm/altos-loader.ld new file mode 100644 index 00000000..2d71b4ee --- /dev/null +++ b/src/stm/altos-loader.ld @@ -0,0 +1,72 @@ +/* + * Copyright © 2012 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +MEMORY { + rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K + ram (!w) : ORIGIN = 0x20000000, LENGTH = 16K +} + +INCLUDE registers.ld + +EXTERN (stm_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .text ORIGIN(rom) : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + + *(.text*) /* Executable code */ + *(.rodata*) /* Constants */ + + } > rom + + .ARM.exidx : { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __text_end__ = .; + } > rom + + /* Data -- relocated to RAM, but written to ROM + */ + .data ORIGIN(ram) : AT (ADDR(.ARM.exidx) + SIZEOF (.ARM.exidx)) { + __data_start__ = .; + *(.data) /* initialized data */ + __data_end__ = .; + __bss_start__ = .; + } >ram + + .bss : { + *(.bss) + *(COMMON) + __bss_end__ = .; + } >ram + + PROVIDE(__stack__ = ORIGIN(ram) + LENGTH(ram)); + PROVIDE(end = .); +} + +ENTRY(start); + + diff --git a/src/stm/ao_boot.h b/src/stm/ao_boot.h new file mode 100644 index 00000000..863d8e05 --- /dev/null +++ b/src/stm/ao_boot.h @@ -0,0 +1,24 @@ +/* + * Copyright © 2013 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_BOOT_H_ +#define _AO_BOOT_H_ + +void +ao_reboot_application(void); + +#endif /* _AO_BOOT_H_ */ diff --git a/src/stm/ao_interrupt.c b/src/stm/ao_interrupt.c index 12763a30..9e756219 100644 --- a/src/stm/ao_interrupt.c +++ b/src/stm/ao_interrupt.c @@ -42,12 +42,45 @@ const void *stm_interrupt_vector[]; #ifdef AO_BOOT_APPLICATION_PIN #include + +#define AO_BOOT_APPLICATION 0x5a5aa5a5 +#define AO_BOOT_APPLICATION_CHECK 0xc3c33c3c + +static uint32_t ao_boot_application; +static uint32_t ao_boot_application_check; + +static void +ao_boot_chain(void) { + uint32_t sp; + uint32_t pc; + + sp = BOOT_FETCH(0); + pc = BOOT_FETCH(4); + asm ("mov sp, %0" : : "r" (sp)); + asm ("mov lr, %0" : : "r" (pc)); + asm ("bx lr"); +} + +void +ao_reboot_application(void) +{ + ao_boot_application = AO_BOOT_APPLICATION; + ao_boot_application_check = AO_BOOT_APPLICATION_CHECK; + ao_arch_reboot(); +} + #endif void start(void) { #ifdef AO_BOOT_APPLICATION_PIN uint16_t v; + if (ao_boot_application == AO_BOOT_APPLICATION && + ao_boot_application_check == AO_BOOT_APPLICATION_CHECK) { + ao_boot_application = 0; + ao_boot_application_check = 0; + ao_boot_chain(); + } /* Enable power interface clock */ stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_PWREN); @@ -63,16 +96,7 @@ void start(void) { ao_disable_port(&AO_BOOT_APPLICATION_GPIO); stm_rcc.apb1enr &= ~(1 << STM_RCC_APB1ENR_PWREN); if (v == AO_BOOT_APPLICATION_VALUE) - { - uint32_t sp; - uint32_t pc; - - sp = BOOT_FETCH(0); - pc = BOOT_FETCH(4); - asm ("mov sp, %0" : : "r" (sp)); - asm ("mov lr, %0" : : "r" (pc)); - asm ("bx lr"); - } + ao_boot_chain(); #endif /* Set interrupt vector table offset */ -- 2.30.2