diff options
31 files changed, 3358 insertions, 595 deletions
diff --git a/apps/boot/pkg.yml b/apps/boot/pkg.yml index 10ec4821..0ceb3d17 100644 --- a/apps/boot/pkg.yml +++ b/apps/boot/pkg.yml @@ -29,9 +29,7 @@ pkg.features: bootloader pkg.deps: - sys/config - - fs/nffs - libs/bootutil - - libs/mbedtls - libs/os - libs/util - libs/console/stub diff --git a/apps/boot/src/boot.c b/apps/boot/src/boot.c index 97a9b32a..73237015 100755 --- a/apps/boot/src/boot.c +++ b/apps/boot/src/boot.c @@ -23,23 +23,16 @@ #include <hal/flash_map.h> #include <os/os.h> #include <bsp/bsp.h> +#include <hal/hal_bsp.h> #include <hal/hal_system.h> #include <hal/hal_flash.h> #include <config/config.h> #include <config/config_file.h> -#ifdef NFFS_PRESENT -#include <fs/fs.h> -#include <nffs/nffs.h> -#elif FCB_PRESENT -#include <fcb/fcb.h> -#include <config/config_fcb.h> -#else -#error "Need NFFS or FCB for config storage" -#endif #ifdef BOOT_SERIAL #include <hal/hal_gpio.h> #include <boot_serial/boot_serial.h> #endif +#include <console/console.h> #include "bootutil/image.h" #include "bootutil/loader.h" #include "bootutil/bootutil_misc.h" @@ -58,76 +51,11 @@ static struct os_task boot_ser_task; static os_stack_t boot_ser_stack[BOOT_SER_STACK_SZ]; #endif -#ifdef NFFS_PRESENT -#define MY_CONFIG_FILE "/cfg/run" - -static struct conf_file my_conf = { - .cf_name = MY_CONFIG_FILE -}; - -static void -setup_for_nffs(void) -{ - struct nffs_area_desc nffs_descs[NFFS_AREA_MAX + 1]; - int cnt; - int rc; - - /* - * Make sure we have enough left to initialize the NFFS with the - * right number of maximum areas otherwise the file-system will not - * be readable. - */ - cnt = NFFS_AREA_MAX; - rc = flash_area_to_nffs_desc(FLASH_AREA_NFFS, &cnt, nffs_descs); - assert(rc == 0); - - /* - * Initializes the flash driver and file system for use by the boot loader. - */ - rc = nffs_init(); - if (rc == 0) { - /* Look for an nffs file system in internal flash. If no file - * system gets detected, all subsequent file operations will fail, - * but the boot loader should proceed anyway. - */ - nffs_detect(nffs_descs); - } - - rc = conf_file_src(&my_conf); - assert(rc == 0); - rc = conf_file_dst(&my_conf); - assert(rc == 0); -} -#else -struct flash_area conf_fcb_area[NFFS_AREA_MAX + 1]; - -static struct conf_fcb my_conf = { - .cf_fcb.f_magic = 0xc09f6e5e, - .cf_fcb.f_sectors = conf_fcb_area -}; - -static void -setup_for_fcb(void) -{ - int cnt; - int rc; - - rc = flash_area_to_sectors(FLASH_AREA_NFFS, &cnt, NULL); - assert(rc == 0); - assert(cnt <= sizeof(conf_fcb_area) / sizeof(conf_fcb_area[0])); - flash_area_to_sectors(FLASH_AREA_NFFS, &cnt, conf_fcb_area); - - my_conf.cf_fcb.f_sector_cnt = cnt; - - conf_fcb_src(&my_conf); - conf_fcb_dst(&my_conf); -} -#endif - int main(void) { struct flash_area descs[AREA_DESC_MAX]; + const struct flash_area *fap; /** Areas representing the beginning of image slots. */ uint8_t img_starts[2]; int cnt; @@ -139,7 +67,11 @@ main(void) .br_slot_areas = img_starts, }; +#ifdef BOOT_SERIAL os_init(); +#else + bsp_init(); +#endif rc = hal_flash_init(); assert(rc == 0); @@ -149,6 +81,9 @@ main(void) img_starts[0] = 0; total = cnt; + flash_area_open(FLASH_AREA_IMAGE_0, &fap); + req.br_img_sz = fap->fa_size; + cnt = BOOT_AREA_DESC_MAX - total; assert(cnt >= 0); rc = flash_area_to_sectors(FLASH_AREA_IMAGE_1, &cnt, &descs[total]); @@ -167,13 +102,6 @@ main(void) conf_init(); -#ifdef NFFS_PRESENT - setup_for_nffs(); -#elif FCB_PRESENT - setup_for_fcb(); -#endif - bootutil_cfg_register(); - #ifdef BOOT_SERIAL /* * Configure a GPIO as input, and compare it against expected value. @@ -189,6 +117,8 @@ main(void) #endif rc = boot_go(&req, &rsp); assert(rc == 0); + console_blocking_mode(); + console_printf("\nboot_go = %d\n", rc); system_start((void *)(rsp.br_image_addr + rsp.br_hdr->ih_hdr_size)); diff --git a/apps/slinky/src/main.c b/apps/slinky/src/main.c index 7f724e6d..1ee66ac8 100755 --- a/apps/slinky/src/main.c +++ b/apps/slinky/src/main.c @@ -220,7 +220,7 @@ task1_handler(void *arg) ++g_task1_loops; /* Wait one second */ - os_time_delay(1000); + os_time_delay(OS_TICKS_PER_SEC); /* Toggle the LED */ prev_pin_state = hal_gpio_read(g_led_pin); @@ -397,7 +397,6 @@ main(int argc, char **argv) nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack, NEWTMGR_TASK_STACK_SIZE); imgmgr_module_init(); - bootutil_cfg_register(); stats_module_init(); diff --git a/hw/bsp/stm32f4discovery/boot-stm32f4discovery.ld b/hw/bsp/stm32f4discovery/boot-stm32f4discovery.ld new file mode 100644 index 00000000..5f41879a --- /dev/null +++ b/hw/bsp/stm32f4discovery/boot-stm32f4discovery.ld @@ -0,0 +1,202 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* Linker script for STM32F407 when running code from SRAM */ + +/* Linker script to configure memory regions. */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K + CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __coredata_start__ + * __coredata_end__ + * __corebss_start__ + * __corebss_end__ + * __ecoredata + * __ecorebss + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __vector_tbl_reloc__ = .; + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + + . = ALIGN(8); + __etext = .; + + .coredata : AT (__etext) + { + __coredata_start__ = .; + *(.data.core) + . = ALIGN(8); + __coredata_end__ = .; + } > CCM + + __ecoredata = __etext + SIZEOF(.coredata); + + /* This section is here so that the start of .data has the same VMA and LMA */ + .ram_coredata (NOLOAD): + { + . = . + SIZEOF(.coredata); + } > RAM + + .data : AT (__ecoredata) + { + __data_start__ = .; + *(vtable) + *(.data*) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .corebss (NOLOAD): + { + . = ALIGN(4); + __corebss_start__ = .; + *(.bss.core) + . = ALIGN(4); + __corebss_end__ = .; + *(.corebss*) + *(.bss.core.nz) + . = ALIGN(4); + __ecorebss = .; + } > CCM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __HeapBase = .; + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > CCM + + /* Set stack top to end of CCM; stack limit is bottom of stack */ + __StackTop = ORIGIN(CCM) + LENGTH(CCM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check for CCM overflow */ + ASSERT(__StackLimit >= __ecorebss, "CCM overflow!") +} + diff --git a/hw/bsp/stm32f4discovery/f407.cfg b/hw/bsp/stm32f4discovery/f407.cfg new file mode 100644 index 00000000..7c46d8ba --- /dev/null +++ b/hw/bsp/stm32f4discovery/f407.cfg @@ -0,0 +1,82 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# script for stm32f4x family + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32f4x +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +# Work-area is a space in RAM used for flash programming +# By default use 64kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz +# +# Since we may be running of an RC oscilator, we crank down the speed a +# bit more to be on the safe side. Perhaps superstition, but if are +# running off a crystal, we can run closer to the limit. Note +# that there can be a pretty wide band where things are more or less stable. +adapter_khz 1000 + +adapter_nsrst_delay 100 +jtag_ntrst_delay 100 + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # See STM Document RM0090 + # Section 32.6.2 - corresponds to Cortex-M4 r0p1 + set _CPUTAPID 0x4ba00477 +} +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID + +if { [info exists BSTAPID] } { + set _BSTAPID $BSTAPID +} else { + # See STM Document RM0090 + # Section 32.6.3 + set _BSTAPID 0x06413041 +} +jtag newtap $_CHIPNAME bs -irlen 5 -expected-id $_BSTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME + +# if srst is not fitted use SYSRESETREQ to +# perform a soft reset +cortex_m3 reset_config sysresetreq diff --git a/hw/bsp/stm32f4discovery/include/bsp/bsp.h b/hw/bsp/stm32f4discovery/include/bsp/bsp.h new file mode 100644 index 00000000..7ab3e6e8 --- /dev/null +++ b/hw/bsp/stm32f4discovery/include/bsp/bsp.h @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#ifndef H_BSP_H +#define H_BSP_H + +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Define special stackos sections */ +#define sec_data_core __attribute__((section(".data.core"))) +#define sec_bss_core __attribute__((section(".bss.core"))) +#define sec_bss_nz_core __attribute__((section(".bss.core.nz"))) + +/* More convenient section placement macros. */ +#define bssnz_t sec_bss_nz_core + +extern uint8_t _ram_start; +extern uint8_t _ccram_start; + +#define RAM_SIZE (128 * 1024) +#define CCRAM_SIZE (64 * 1024) + +/* LED pins */ +#define LED_BLINK_PIN (60) + +/* UART */ +#define UART_CNT 1 +#define CONSOLE_UART 0 + +#define NFFS_AREA_MAX (8) + +#ifdef __cplusplus +} +#endif + +#endif /* H_BSP_H */ diff --git a/hw/bsp/stm32f4discovery/include/bsp/bsp_sysid.h b/hw/bsp/stm32f4discovery/include/bsp/bsp_sysid.h new file mode 100644 index 00000000..7b0a24b6 --- /dev/null +++ b/hw/bsp/stm32f4discovery/include/bsp/bsp_sysid.h @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#ifndef BSP_SYSID_H +#define BSP_SYSID_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* stub until this BSP gets new HAL */ +enum system_device_id +{ + RESERVED, +}; + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_SYSID_H */
\ No newline at end of file diff --git a/hw/bsp/stm32f4discovery/include/bsp/cmsis_nvic.h b/hw/bsp/stm32f4discovery/include/bsp/cmsis_nvic.h new file mode 100644 index 00000000..008b247d --- /dev/null +++ b/hw/bsp/stm32f4discovery/include/bsp/cmsis_nvic.h @@ -0,0 +1,29 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include <stdint.h> + +#define NVIC_NUM_VECTORS (16 + 81) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include "mcu/stm32f4xx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/stm32f4discovery/include/bsp/stm32f4xx_hal_conf.h b/hw/bsp/stm32f4discovery/include/bsp/stm32f4xx_hal_conf.h new file mode 100644 index 00000000..8e4216cc --- /dev/null +++ b/hw/bsp/stm32f4discovery/include/bsp/stm32f4xx_hal_conf.h @@ -0,0 +1,413 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf.h + * @author MCD Application Team + * @version V1.2.1 + * @date 13-March-2015 + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +#if 0 +#define HAL_ADC_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +#define HAL_CRC_MODULE_ENABLED +#define HAL_CRYP_MODULE_ENABLED +#define HAL_DAC_MODULE_ENABLED +#define HAL_DCMI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +#define HAL_ETH_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_NAND_MODULE_ENABLED +#define HAL_NOR_MODULE_ENABLED +#define HAL_PCCARD_MODULE_ENABLED +#define HAL_SRAM_MODULE_ENABLED +/* #define HAL_SDRAM_MODULE_ENABLED */ +#define HAL_HASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_I2S_MODULE_ENABLED +#define HAL_IWDG_MODULE_ENABLED +#define HAL_LTDC_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +/* #define HAL_SAI_MODULE_ENABLED */ +#define HAL_SD_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +#define HAL_IRDA_MODULE_ENABLED +#define HAL_SMARTCARD_MODULE_ENABLED +#define HAL_WWDG_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#else +#define HAL_PWR_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#endif + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)12000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0x0F) /*!< tick interrupt priority */ +#define USE_RTOS 0 +#define PREFETCH_ENABLE 0 /* The prefetch will be enabled in SystemClock_Config(), depending on the used + STM32F405/415/07/417 device: RevA (prefetch must be off) or RevZ (prefetch can be on/off) */ +#define INSTRUCTION_CACHE_ENABLE 1 +#define DATA_CACHE_ENABLE 1 + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1 */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2 +#define MAC_ADDR1 0 +#define MAC_ADDR2 0 +#define MAC_ADDR3 0 +#define MAC_ADDR4 0 +#define MAC_ADDR5 0 + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01 +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FF) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFF) + +#define PHY_READ_TO ((uint32_t)0x0000FFFF) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFF) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x10) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "mcu/stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif /* USE_FULL_ASSERT */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/hw/bsp/stm32f4discovery/pkg.yml b/hw/bsp/stm32f4discovery/pkg.yml new file mode 100644 index 00000000..04e74d38 --- /dev/null +++ b/hw/bsp/stm32f4discovery/pkg.yml @@ -0,0 +1,39 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: hw/bsp/stm32f4discovery +pkg.type: bsp +pkg.description: BSP definition for the stm32f4 discovery board. +pkg.author: "Apache Mynewt <dev@mynewt.incubator.apache.org>" +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - stm32 + - stm32f4 + - discovery + +pkg.arch: cortex_m4 +pkg.compiler: compiler/arm-none-eabi-m4 +pkg.linkerscript: "stm32f4discovery.ld" +pkg.linkerscript.bootloader.OVERWRITE: "boot-stm32f4discovery.ld" +pkg.downloadscript: "stm32f4discovery_download.sh" +pkg.debugscript: "stm32f4discovery_debug.sh" +pkg.cflags: -DSTM32F407xx +pkg.deps: + - hw/mcu/stm/stm32f4xx + - libs/baselibc diff --git a/hw/bsp/stm32f4discovery/run_from_flash.ld b/hw/bsp/stm32f4discovery/run_from_flash.ld new file mode 100644 index 00000000..658d9238 --- /dev/null +++ b/hw/bsp/stm32f4discovery/run_from_flash.ld @@ -0,0 +1,204 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* Linker script for STM32F407 when running from flash and not using the bootloader */ + +/* Linker script to configure memory regions. */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __coredata_start__ + * __coredata_end__ + * __corebss_start__ + * __corebss_end__ + * __ecoredata + * __ecorebs + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .coredata : AT (__etext) + { + __coredata_start__ = .; + *(.data.core) + . = ALIGN(4); + __coredata_end__ = .; + } > CCM + + __ecoredata = __etext + SIZEOF(.coredata); + + .data : AT (__ecoredata) + { + __data_start__ = .; + *(vtable) + *(.data*) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .corebss (NOLOAD): + { + . = ALIGN(4); + __corebss_start__ = .; + *(.bss.core) + . = ALIGN(4); + __corebss_end__ = .; + *(.corebss*) + *(.bss.core.nz) + . = ALIGN(4); + __ecorebss = .; + } > CCM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __HeapBase = .; + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > CCM + + /* Set stack top to end of CCM; stack limit is bottom of stack */ + __StackTop = ORIGIN(CCM) + LENGTH(CCM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check for CCM overflow */ + ASSERT(__StackLimit >= __ecorebss, "CCM overflow!") +} + diff --git a/hw/bsp/stm32f4discovery/run_from_loader.ld b/hw/bsp/stm32f4discovery/run_from_loader.ld new file mode 100644 index 00000000..50b82909 --- /dev/null +++ b/hw/bsp/stm32f4discovery/run_from_loader.ld @@ -0,0 +1,210 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* Linker script for STM32F407 when running from flash and using the bootloader */ + +/* Linker script to configure memory regions. */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* First image slot. */ + CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __coredata_start__ + * __coredata_end__ + * __corebss_start__ + * __corebss_end__ + * __ecoredata + * __ecorebss + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + /* Reserve space at the start of the image for the header. */ + .imghdr (NOLOAD): + { + . = . + 0x20; + } > FLASH + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .coredata : AT (__etext) + { + __coredata_start__ = .; + *(.data.core) + . = ALIGN(4); + __coredata_end__ = .; + } > CCM + + __ecoredata = __etext + SIZEOF(.coredata); + + .data : AT (__ecoredata) + { + __data_start__ = .; + *(vtable) + *(.data*) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .corebss (NOLOAD): + { + . = ALIGN(4); + __corebss_start__ = .; + *(.bss.core) + . = ALIGN(4); + __corebss_end__ = .; + *(.corebss*) + *(.bss.core.nz) + . = ALIGN(4); + __ecorebss = .; + } > CCM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __HeapBase = .; + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > CCM + + /* Set stack top to end of CCM; stack limit is bottom of stack */ + __StackTop = ORIGIN(CCM) + LENGTH(CCM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check for CCM overflow */ + ASSERT(__StackLimit >= __ecorebss, "CCM overflow!") +} + diff --git a/hw/bsp/stm32f4discovery/run_from_sram.ld b/hw/bsp/stm32f4discovery/run_from_sram.ld new file mode 100644 index 00000000..cdf5efe5 --- /dev/null +++ b/hw/bsp/stm32f4discovery/run_from_sram.ld @@ -0,0 +1,202 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* Linker script for STM32F407 when running code from SRAM */ + +/* Linker script to configure memory regions. */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x20000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __coredata_start__ + * __coredata_end__ + * __corebss_start__ + * __corebss_end__ + * __ecoredata + * __ecorebss + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __vector_tbl_reloc__ = .; + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > RAM + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > RAM + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > RAM + + __exidx_end = .; + + . = ALIGN(8); + __etext = .; + + .coredata : AT (__etext) + { + __coredata_start__ = .; + *(.data.core) + . = ALIGN(8); + __coredata_end__ = .; + } > CCM + + __ecoredata = __etext + SIZEOF(.coredata); + + /* This section is here so that the start of .data has the same VMA and LMA */ + .ram_coredata (NOLOAD): + { + . = . + SIZEOF(.coredata); + } > RAM + + .data : AT (__ecoredata) + { + __data_start__ = .; + *(vtable) + *(.data*) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .corebss (NOLOAD): + { + . = ALIGN(4); + __corebss_start__ = .; + *(.bss.core) + . = ALIGN(4); + __corebss_end__ = .; + *(.corebss*) + *(.bss.core.nz) + . = ALIGN(4); + __ecorebss = .; + } > CCM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __HeapBase = .; + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > CCM + + /* Set stack top to end of CCM; stack limit is bottom of stack */ + __StackTop = ORIGIN(CCM) + LENGTH(CCM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check for CCM overflow */ + ASSERT(__StackLimit >= __ecorebss, "CCM overflow!") +} + diff --git a/hw/bsp/stm32f4discovery/src/arch/cortex_m4/startup_STM32F40x.s b/hw/bsp/stm32f4discovery/src/arch/cortex_m4/startup_STM32F40x.s new file mode 100644 index 00000000..646b4bf4 --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/arch/cortex_m4/startup_STM32F40x.s @@ -0,0 +1,343 @@ +/* File: startup_STM32F40x.S + * Purpose: startup file for Cortex-M4 devices. Should use with + * GCC for ARM Embedded Processors + * Version: V1.4 + * Date: 09 July 2012 + * + * Copyright (c) 2011, 2012, ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the ARM Limited nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + .syntax unified + .arch armv7-m + + .section .stack + .align 3 +#ifdef __STACK_SIZE + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 0xc00 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#ifdef __HEAP_SIZE + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 0 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler /* Reset Handler */ + .long NMI_Handler /* NMI Handler */ + .long HardFault_Handler /* Hard Fault Handler */ + .long MemManage_Handler /* MPU Fault Handler */ + .long BusFault_Handler /* Bus Fault Handler */ + .long UsageFault_Handler /* Usage Fault Handler */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long 0 /* Reserved */ + .long SVC_Handler /* SVCall Handler */ + .long DebugMon_Handler /* Debug Monitor Handler */ + .long 0 /* Reserved */ + .long PendSV_Handler /* PendSV Handler */ + .long SysTick_Handler /* SysTick Handler */ + + /* External interrupts */ + .long WWDG_IRQHandler /* Window WatchDog */ + .long PVD_IRQHandler /* PVD through EXTI Line detection */ + .long TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ + .long RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ + .long FLASH_IRQHandler /* FLASH */ + .long RCC_IRQHandler /* RCC */ + .long EXTI0_IRQHandler /* EXTI Line0 */ + .long EXTI1_IRQHandler /* EXTI Line1 */ + .long EXTI2_IRQHandler /* EXTI Line2 */ + .long EXTI3_IRQHandler /* EXTI Line3 */ + .long EXTI4_IRQHandler /* EXTI Line4 */ + .long DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ + .long DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ + .long DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ + .long DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ + .long DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ + .long DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ + .long DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ + .long ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ + .long CAN1_TX_IRQHandler /* CAN1 TX */ + .long CAN1_RX0_IRQHandler /* CAN1 RX0 */ + .long CAN1_RX1_IRQHandler /* CAN1 RX1 */ + .long CAN1_SCE_IRQHandler /* CAN1 SCE */ + .long EXTI9_5_IRQHandler /* External Line[9:5]s */ + .long TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ + .long TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ + .long TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ + .long TIM1_CC_IRQHandler /* TIM1 Capture Compare */ + .long TIM2_IRQHandler /* TIM2 */ + .long TIM3_IRQHandler /* TIM3 */ + .long TIM4_IRQHandler /* TIM4 */ + .long I2C1_EV_IRQHandler /* I2C1 Event */ + .long I2C1_ER_IRQHandler /* I2C1 Error */ + .long I2C2_EV_IRQHandler /* I2C2 Event */ + .long I2C2_ER_IRQHandler /* I2C2 Error */ + .long SPI1_IRQHandler /* SPI1 */ + .long SPI2_IRQHandler /* SPI2 */ + .long USART1_IRQHandler /* USART1 */ + .long USART2_IRQHandler /* USART2 */ + .long USART3_IRQHandler /* USART3 */ + .long EXTI15_10_IRQHandler /* External Line[15:10]s */ + .long RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ + .long OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ + .long TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ + .long TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ + .long TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ + .long TIM8_CC_IRQHandler /* TIM8 Capture Compare */ + .long DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ + .long FSMC_IRQHandler /* FSMC */ + .long SDIO_IRQHandler /* SDIO */ + .long TIM5_IRQHandler /* TIM5 */ + .long SPI3_IRQHandler /* SPI3 */ + .long UART4_IRQHandler /* UART4 */ + .long UART5_IRQHandler /* UART5 */ + .long TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ + .long TIM7_IRQHandler /* TIM7 */ + .long DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ + .long DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ + .long DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ + .long DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ + .long DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ + .long ETH_IRQHandler /* Ethernet */ + .long ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ + .long CAN2_TX_IRQHandler /* CAN2 TX */ + .long CAN2_RX0_IRQHandler /* CAN2 RX0 */ + .long CAN2_RX1_IRQHandler /* CAN2 RX1 */ + .long CAN2_SCE_IRQHandler /* CAN2 SCE */ + .long OTG_FS_IRQHandler /* USB OTG FS */ + .long DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ + .long DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ + .long DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ + .long USART6_IRQHandler /* USART6 */ + .long I2C3_EV_IRQHandler /* I2C3 event */ + .long I2C3_ER_IRQHandler /* I2C3 error */ + .long OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ + .long OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ + .long OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ + .long OTG_HS_IRQHandler /* USB OTG HS */ + .long DCMI_IRQHandler /* DCMI */ + .long CRYP_IRQHandler /* CRYP crypto */ + .long HASH_RNG_IRQHandler /* Hash and Rng */ + .long FPU_IRQHandler /* FPU */ + + .size __isr_vector, . - __isr_vector + + .text + .thumb + .thumb_func + .align 2 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: +/* Copy data core section from flash to RAM */ + ldr r1, =__etext + ldr r2, =__coredata_start__ + ldr r3, =__coredata_end__ + +.LC0: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC0 + +/* Loop to copy data from read only memory to RAM. The ranges + * of copy from/to are specified by following symbols evaluated in + * linker script. + * __etext: End of code section, i.e., begin of data sections to copy from. + * __data_start__/__data_end__: RAM address range that data should be + * copied to. Both must be aligned to 4 bytes boundary. */ + ldr r1, =__ecoredata + ldr r2, =__data_start__ + ldr r3, =__data_end__ + +.LC1: + cmp r2, r3 + ittt lt + ldrlt r0, [r1], #4 + strlt r0, [r2], #4 + blt .LC1 + +/* Set the bss core section to zero */ + mov r0, #0 + ldr r1, =__corebss_start__ + ldr r2, =__corebss_end__ + +.LC2: + cmp r1, r2 + itt lt + strlt r0, [r1], #4 + blt .LC2 + +/* Call system initialization and startup routines */ + ldr r0, =SystemInit + blx r0 + ldr r0, =_start + bx r0 + .pool + .size Reset_Handler, . - Reset_Handler + + .text +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_default_handler handler_name + .align 1 + .thumb_func + .weak \handler_name + .type \handler_name, %function +\handler_name : + b . + .size \handler_name, . - \handler_name + .endm + + def_default_handler NMI_Handler + def_default_handler HardFault_Handler + def_default_handler MemManage_Handler + def_default_handler BusFault_Handler + def_default_handler UsageFault_Handler + def_default_handler SVC_Handler + def_default_handler DebugMon_Handler + def_default_handler PendSV_Handler + def_default_handler SysTick_Handler + def_default_handler Default_Handler + + .macro def_irq_default_handler handler_name + .weak \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_default_handler WWDG_IRQHandler + def_irq_default_handler PVD_IRQHandler + def_irq_default_handler TAMP_STAMP_IRQHandler + def_irq_default_handler RTC_WKUP_IRQHandler + def_irq_default_handler FLASH_IRQHandler + def_irq_default_handler RCC_IRQHandler + def_irq_default_handler EXTI0_IRQHandler + def_irq_default_handler EXTI1_IRQHandler + def_irq_default_handler EXTI2_IRQHandler + def_irq_default_handler EXTI3_IRQHandler + def_irq_default_handler EXTI4_IRQHandler + def_irq_default_handler DMA1_Stream0_IRQHandler + def_irq_default_handler DMA1_Stream1_IRQHandler + def_irq_default_handler DMA1_Stream2_IRQHandler + def_irq_default_handler DMA1_Stream3_IRQHandler + def_irq_default_handler DMA1_Stream4_IRQHandler + def_irq_default_handler DMA1_Stream5_IRQHandler + def_irq_default_handler DMA1_Stream6_IRQHandler + def_irq_default_handler ADC_IRQHandler + def_irq_default_handler CAN1_TX_IRQHandler + def_irq_default_handler CAN1_RX0_IRQHandler + def_irq_default_handler CAN1_RX1_IRQHandler + def_irq_default_handler CAN1_SCE_IRQHandler + def_irq_default_handler EXTI9_5_IRQHandler + def_irq_default_handler TIM1_BRK_TIM9_IRQHandler + def_irq_default_handler TIM1_UP_TIM10_IRQHandler + def_irq_default_handler TIM1_TRG_COM_TIM11_IRQHandler + def_irq_default_handler TIM1_CC_IRQHandler + def_irq_default_handler TIM2_IRQHandler + def_irq_default_handler TIM3_IRQHandler + def_irq_default_handler TIM4_IRQHandler + def_irq_default_handler I2C1_EV_IRQHandler + def_irq_default_handler I2C1_ER_IRQHandler + def_irq_default_handler I2C2_EV_IRQHandler + def_irq_default_handler I2C2_ER_IRQHandler + def_irq_default_handler SPI1_IRQHandler + def_irq_default_handler SPI2_IRQHandler + def_irq_default_handler USART1_IRQHandler + def_irq_default_handler USART2_IRQHandler + def_irq_default_handler USART3_IRQHandler + def_irq_default_handler EXTI15_10_IRQHandler + def_irq_default_handler RTC_Alarm_IRQHandler + def_irq_default_handler OTG_FS_WKUP_IRQHandler + def_irq_default_handler TIM8_BRK_TIM12_IRQHandler + def_irq_default_handler TIM8_UP_TIM13_IRQHandler + def_irq_default_handler TIM8_TRG_COM_TIM14_IRQHandler + def_irq_default_handler TIM8_CC_IRQHandler + def_irq_default_handler DMA1_Stream7_IRQHandler + def_irq_default_handler FSMC_IRQHandler + def_irq_default_handler SDIO_IRQHandler + def_irq_default_handler TIM5_IRQHandler + def_irq_default_handler SPI3_IRQHandler + def_irq_default_handler UART4_IRQHandler + def_irq_default_handler UART5_IRQHandler + def_irq_default_handler TIM6_DAC_IRQHandler + def_irq_default_handler TIM7_IRQHandler + def_irq_default_handler DMA2_Stream0_IRQHandler + def_irq_default_handler DMA2_Stream1_IRQHandler + def_irq_default_handler DMA2_Stream2_IRQHandler + def_irq_default_handler DMA2_Stream3_IRQHandler + def_irq_default_handler DMA2_Stream4_IRQHandler + def_irq_default_handler ETH_IRQHandler + def_irq_default_handler ETH_WKUP_IRQHandler + def_irq_default_handler CAN2_TX_IRQHandler + def_irq_default_handler CAN2_RX0_IRQHandler + def_irq_default_handler CAN2_RX1_IRQHandler + def_irq_default_handler CAN2_SCE_IRQHandler + def_irq_default_handler OTG_FS_IRQHandler + def_irq_default_handler DMA2_Stream5_IRQHandler + def_irq_default_handler DMA2_Stream6_IRQHandler + def_irq_default_handler DMA2_Stream7_IRQHandler + def_irq_default_handler USART6_IRQHandler + def_irq_default_handler I2C3_EV_IRQHandler + def_irq_default_handler I2C3_ER_IRQHandler + def_irq_default_handler OTG_HS_EP1_OUT_IRQHandler + def_irq_default_handler OTG_HS_EP1_IN_IRQHandler + def_irq_default_handler OTG_HS_WKUP_IRQHandler + def_irq_default_handler OTG_HS_IRQHandler + def_irq_default_handler DCMI_IRQHandler + def_irq_default_handler CRYP_IRQHandler + def_irq_default_handler HASH_RNG_IRQHandler + def_irq_default_handler FPU_IRQHandler + def_irq_default_handler DEF_IRQHandler + + .end diff --git a/hw/bsp/stm32f4discovery/src/hal_bsp.c b/hw/bsp/stm32f4discovery/src/hal_bsp.c new file mode 100644 index 00000000..763002f5 --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/hal_bsp.c @@ -0,0 +1,77 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include "hal/hal_bsp.h" +#include "hal/hal_gpio.h" +#include "hal/hal_flash_int.h" +#include "mcu/stm32f407xx.h" +#include "mcu/stm32f4xx_hal_gpio_ex.h" +#include "mcu/stm32f4_bsp.h" +#include "bsp/bsp.h" +#include <assert.h> + +static const struct stm32f4_uart_cfg uart_cfg[UART_CNT] = { + [0] = { + .suc_uart = USART6, + .suc_rcc_reg = &RCC->APB2ENR, + .suc_rcc_dev = RCC_APB2ENR_USART6EN, + .suc_pin_tx = 38, + .suc_pin_rx = 39, + .suc_pin_rts = 34, + .suc_pin_cts = 35, + .suc_pin_af = GPIO_AF8_USART6, + .suc_irqn = USART6_IRQn + } +}; + +static const struct bsp_mem_dump dump_cfg[] = { + [0] = { + .bmd_start = &_ram_start, + .bmd_size = RAM_SIZE + }, + [1] = { + .bmd_start = &_ccram_start, + .bmd_size = CCRAM_SIZE + } +}; + +const struct stm32f4_uart_cfg * +bsp_uart_config(int port) +{ + assert(port < UART_CNT); + return &uart_cfg[port]; +} + +const struct hal_flash * +bsp_flash_dev(uint8_t id) +{ + /* + * Internal flash mapped to id 0. + */ + if (id != 0) { + return NULL; + } + return &stm32f4_flash_dev; +} + +const struct bsp_mem_dump * +bsp_core_dump(int *area_cnt) +{ + *area_cnt = sizeof(dump_cfg) / sizeof(dump_cfg[0]); + return dump_cfg; +} diff --git a/hw/bsp/stm32f4discovery/src/libc_stubs.c b/hw/bsp/stm32f4discovery/src/libc_stubs.c new file mode 100644 index 00000000..b1b6b8b1 --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/libc_stubs.c @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <hal/hal_system.h> +#include <hal/hal_bsp.h> + +int _close(int fd); +int _fstat(int fd, void *s); +void _exit(int s); +int _kill(int pid, int sig); +int _write(int fd, void *b, int nb); +int _isatty(int c); +int _lseek(int fd, int off, int w); +int _read(int fd, void *b, int nb); +int _getpid(void); + +int +_close(int fd) +{ + return -1; +} + +int +_fstat(int fd, void *s) +{ + return -1; +} + + +void +_exit(int s) +{ + system_reset(); +} + +int +_kill(int pid, int sig) +{ + return -1; +} + +int +_write(int fd, void *b, int nb) +{ + return -1; +} + +int +_isatty(int c) +{ + return -1; +} + +int +_lseek(int fd, int off, int w) +{ + return -1; +} + +int +_read(int fd, void *b, int nb) +{ + return -1; +} + +int +_getpid(void) { + return -1; +} diff --git a/hw/bsp/stm32f4discovery/src/os_bsp.c b/hw/bsp/stm32f4discovery/src/os_bsp.c new file mode 100644 index 00000000..f2fe9e1a --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/os_bsp.c @@ -0,0 +1,82 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * XXXX for now have this here. + */ +#include <hal/flash_map.h> +#include <hal/hal_bsp.h> + +static struct flash_area bsp_flash_areas[] = { + [FLASH_AREA_BOOTLOADER] = { + .fa_flash_id = 0, /* internal flash */ + .fa_off = 0x08000000, /* beginning */ + .fa_size = (32 * 1024) + }, + /* 2 * 16K and 1*64K sectors here */ + [FLASH_AREA_IMAGE_0] = { + .fa_flash_id = 0, + .fa_off = 0x08020000, + .fa_size = (384 * 1024) + }, + [FLASH_AREA_IMAGE_1] = { + .fa_flash_id = 0, + .fa_off = 0x08080000, + .fa_size = (384 * 1024) + }, + [FLASH_AREA_IMAGE_SCRATCH] = { + .fa_flash_id = 0, + .fa_off = 0x080e0000, + .fa_size = (128 * 1024) + }, + [FLASH_AREA_NFFS] = { + .fa_flash_id = 0, + .fa_off = 0x08008000, + .fa_size = (32 * 1024) + } +}; + +void _close(int fd); + +/* + * Returns the flash map slot where the currently active image is located. + * If executing from internal flash from fixed location, that slot would + * be easy to find. + * If images are in external flash, and copied to RAM for execution, then + * this routine would have to figure out which one of those slots is being + * used. + */ +int +bsp_imgr_current_slot(void) +{ + return FLASH_AREA_IMAGE_0; +} + +void +bsp_init(void) +{ + /* + * XXX this reference is here to keep this function in. + */ + _sbrk(0); + _close(0); + flash_area_init(bsp_flash_areas, + sizeof(bsp_flash_areas) / sizeof(bsp_flash_areas[0])); +} + diff --git a/hw/bsp/stm32f4discovery/src/sbrk.c b/hw/bsp/stm32f4discovery/src/sbrk.c new file mode 100644 index 00000000..e95a5d7a --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/sbrk.c @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +extern char __HeapBase; +extern char __HeapLimit; + +void * +_sbrk(int incr) +{ + static char *brk = &__HeapBase; + + void *prev_brk; + + if (incr < 0) { + /* Returning memory to the heap. */ + incr = -incr; + if (brk - incr < &__HeapBase) { + prev_brk = (void *)-1; + } else { + prev_brk = brk; + brk -= incr; + } + } else { + /* Allocating memory from the heap. */ + if (&__HeapLimit - brk >= incr) { + prev_brk = brk; + brk += incr; + } else { + prev_brk = (void *)-1; + } + } + + return prev_brk; +} diff --git a/hw/bsp/stm32f4discovery/src/system_stm32f4xx.c b/hw/bsp/stm32f4discovery/src/system_stm32f4xx.c new file mode 100644 index 00000000..34036cac --- /dev/null +++ b/hw/bsp/stm32f4discovery/src/system_stm32f4xx.c @@ -0,0 +1,351 @@ +/** + ****************************************************************************** + * @file system_stm32f4xx.c + * @author MCD Application Team + * @version V1.3.0 + * @date 01-July-2015 + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32f4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32f4xx_system + * @{ + */ + +/** @addtogroup STM32F4xx_System_Private_Includes + * @{ + */ + +#include "mcu/stm32f4xx.h" +#include "bsp/cmsis_nvic.h" + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 168000000; + +const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes + * @{ + */ + +static void SystemClock_Config(void); + +/** + * @} + */ + +/** @addtogroup STM32F4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + + /* Disable all interrupts */ + RCC->CIR = 0x00000000; + + /* Configure System Clock */ + SystemClock_Config(); + + /* Relocate the vector table */ + NVIC_Relocate(); +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value + * depends on the application requirements), user has to ensure that HSE_VALUE + * is same as the real frequency of the crystal used. Otherwise, this function + * may have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + + switch (tmp) + { + case 0x00: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + case 0x04: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; + + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @brief System Clock Configuration + * The system Clock is configured as follow : + * System Clock source = PLL (HSE) + * SYSCLK(Hz) = 168000000 + * HCLK(Hz) = 168000000 + * AHB Prescaler = 1 + * APB1 Prescaler = 4 + * APB2 Prescaler = 2 + * HSE Frequency(Hz) = 12000000 + * PLL_M = 12 + * PLL_N = 336 + * PLL_P = 2 + * PLL_Q = 7 + * VDD(V) = 3.3 + * Main regulator output voltage = Scale1 mode + * Flash Latency(WS) = 5 + * @param None + * @retval None + */ +static void SystemClock_Config(void) +{ + /* Configure Flash prefetch, Instruction cache, Data cache */ +#if (INSTRUCTION_CACHE_ENABLE != 0) + __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); +#endif /* INSTRUCTION_CACHE_ENABLE */ + +#if (DATA_CACHE_ENABLE != 0) + __HAL_FLASH_DATA_CACHE_ENABLE(); +#endif /* DATA_CACHE_ENABLE */ + +#if (PREFETCH_ENABLE != 0) + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); +#endif /* PREFETCH_ENABLE */ + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the device is + clocked below the maximum system frequency, to update the voltage scaling value + regarding system frequency refer to product datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE and wait till HSE is ready */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) { + /* XXX: some error should occur here */ + } + + /* HCLK Configuration */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + + /* PCLK1 Configuration */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV4); + + /* PCLK2 Configuration */ + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV2 << 3)); + + /* Configure the main PLL clock source, multiplication and division factors. */ + WRITE_REG(RCC->PLLCFGR, (RCC_PLLSOURCE_HSE | \ + 12 | \ + (336 << POSITION_VAL(RCC_PLLCFGR_PLLN)) | \ + (((RCC_PLLP_DIV2 >> 1) -1) << POSITION_VAL(RCC_PLLCFGR_PLLP)) | \ + (7 << POSITION_VAL(RCC_PLLCFGR_PLLQ)))); + + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Wait till PLL is ready */ + while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) { + /* XXX: handle this */ + } + + /* Enable the Flash prefetch */ + __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); + + /* Set flash wait states */ + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_5); + + /* Start PLL */ + __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_PLLCLK); + + while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) { + /* XXX: deal with this*/ + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/hw/bsp/stm32f4discovery/stm32f4discovery.ld b/hw/bsp/stm32f4discovery/stm32f4discovery.ld new file mode 100644 index 00000000..4c1541d3 --- /dev/null +++ b/hw/bsp/stm32f4discovery/stm32f4discovery.ld @@ -0,0 +1,213 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* Linker script for STM32F407 when running from flash and using the bootloader */ + +/* Linker script to configure memory regions. */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* First image slot. */ + CCM (rwx) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __coredata_start__ + * __coredata_end__ + * __corebss_start__ + * __corebss_end__ + * __ecoredata + * __ecorebss + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + /* Reserve space at the start of the image for the header. */ + .imghdr (NOLOAD): + { + . = . + 0x20; + } > FLASH + + .text : + { + __isr_vector_start = .; + KEEP(*(.isr_vector)) + __isr_vector_end = .; + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + + __exidx_end = .; + + __etext = .; + + .vector_relocation : + { + . = ALIGN(4); + __vector_tbl_reloc__ = .; + . = . + (__isr_vector_end - __isr_vector_start); + . = ALIGN(4); + } > RAM + + .coredata : AT (__etext) + { + __coredata_start__ = .; + *(.data.core) + . = ALIGN(4); + __coredata_end__ = .; + } > CCM + + __ecoredata = __etext + SIZEOF(.coredata); + + .data : AT (__ecoredata) + { + __data_start__ = .; + *(vtable) + *(.data*) + + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .corebss (NOLOAD): + { + . = ALIGN(4); + __corebss_start__ = .; + *(.bss.core) + . = ALIGN(4); + __corebss_end__ = .; + *(.corebss*) + *(.bss.core.nz) + . = ALIGN(4); + __ecorebss = .; + } > CCM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + __HeapBase = .; + __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); + + _ram_start = ORIGIN(RAM); + _ccram_start = ORIGIN(CCRAM); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > CCM + + /* Set stack top to end of CCM; stack limit is bottom of stack */ + __StackTop = ORIGIN(CCM) + LENGTH(CCM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check for CCM overflow */ + ASSERT(__StackLimit >= __ecorebss, "CCM overflow!") +} + diff --git a/hw/bsp/stm32f4discovery/stm32f4discovery_debug.sh b/hw/bsp/stm32f4discovery/stm32f4discovery_debug.sh new file mode 100644 index 00000000..c1a889ba --- /dev/null +++ b/hw/bsp/stm32f4discovery/stm32f4discovery_debug.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Called: $0 <bsp_path> <binary> [identities...] +# - bsp_directory_path is absolute path to hw/bsp/bsp_name +# - binary is the path to prefix to target binary, .elf appended to name is +# the ELF file +# - identities is the project identities string. +# +# +if [ $# -lt 2 ]; then + echo "Need binary to debug" + exit 1 +fi + +MY_PATH=$1 +FILE_NAME=$2.elf +GDB_CMD_FILE=.gdb_cmds + +echo "Debugging" $FILE_NAME + +# +# Block Ctrl-C from getting passed to openocd. +# Exit openocd when gdb detaches. +# +set -m +openocd -f board/stm32f4discovery.cfg -s $MY_PATH -c "gdb_port 3333; telnet_port 4444; stm32f4x.cpu configure -event gdb-detach {shutdown}" -c init -c "reset halt" & +set +m + +echo "target remote localhost:3333" > $GDB_CMD_FILE +arm-none-eabi-gdb -x $GDB_CMD_FILE $FILE_NAME +rm $GDB_CMD_FILE diff --git a/hw/bsp/stm32f4discovery/stm32f4discovery_download.sh b/hw/bsp/stm32f4discovery/stm32f4discovery_download.sh new file mode 100644 index 00000000..87013c65 --- /dev/null +++ b/hw/bsp/stm32f4discovery/stm32f4discovery_download.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Called: $0 <bsp_directory_path> <binary> [features...] +# - bsp_directory_path is absolute path to hw/bsp/bsp_name +# - binary is the path to prefix to target binary, .elf.bin appended to this +# name is the raw binary format of the binary. +# - features are the target features. So you can have e.g. different +# flash offset for bootloader 'feature' +# +# +if [ $# -lt 2 ]; then + echo "Need binary to download" + exit 1 +fi + +MYPATH=$1 +BASENAME=$2 +IS_BOOTLOADER=0 + +# Look for 'bootloader' from 3rd arg onwards +shift +shift +while [ $# -gt 0 ]; do + if [ $1 = "bootloader" ]; then + IS_BOOTLOADER=1 + fi + shift +done + +if [ $IS_BOOTLOADER -eq 1 ]; then + FLASH_OFFSET=0x08000000 + FILE_NAME=$BASENAME.elf.bin +else + FLASH_OFFSET=0x08020000 + FILE_NAME=$BASENAME.img +fi +echo "Downloading" $FILE_NAME "to" $FLASH_OFFSET + +openocd -f board/stm32f4discovery.cfg -s $MYPATH -c init -c "reset halt" -c "flash write_image erase $FILE_NAME $FLASH_OFFSET" -c "reset run" -c shutdown + diff --git a/libs/bootutil/include/bootutil/bootutil_misc.h b/libs/bootutil/include/bootutil/bootutil_misc.h index ff42ac85..2e3049d3 100644 --- a/libs/bootutil/include/bootutil/bootutil_misc.h +++ b/libs/bootutil/include/bootutil/bootutil_misc.h @@ -20,12 +20,9 @@ #ifndef __BOOTUTIL_MISC_H_ #define __BOOTUTIL_MISC_H_ -struct image_version; -int boot_vect_read_test(struct image_version *out_ver); -int boot_vect_read_main(struct image_version *out_ver); -int boot_vect_write_test(struct image_version *ver); -int boot_vect_write_main(struct image_version *ver); - -void bootutil_cfg_register(void); +int boot_vect_read_test(int *slot); +int boot_vect_read_main(int *slot); +int boot_vect_write_test(int slot); +int boot_vect_write_main(void); #endif /* __BOOTUTIL_MISC_H_ */ diff --git a/libs/bootutil/include/bootutil/loader.h b/libs/bootutil/include/bootutil/loader.h index 86f06bad..57a9eef2 100644 --- a/libs/bootutil/include/bootutil/loader.h +++ b/libs/bootutil/include/bootutil/loader.h @@ -46,6 +46,9 @@ struct boot_req { /** The area to use as the image scratch area, index is index to br_area_descs array, of the */ uint8_t br_scratch_area_idx; + + /** Size of the image slot */ + uint32_t br_img_sz; }; /** diff --git a/libs/bootutil/src/bootutil_misc.c b/libs/bootutil/src/bootutil_misc.c index 94536efa..6539bdd1 100644 --- a/libs/bootutil/src/bootutil_misc.c +++ b/libs/bootutil/src/bootutil_misc.c @@ -19,132 +19,94 @@ #include <string.h> #include <inttypes.h> +#include <assert.h> #include <hal/hal_flash.h> -#include <config/config.h> +#include <hal/flash_map.h> +#include <hal/hal_bsp.h> #include <os/os.h> #include "bootutil/image.h" +#include "bootutil/bootutil_misc.h" #include "bootutil_priv.h" -#ifdef USE_STATUS_FILE -#include <fs/fs.h> -#include <fs/fsutil.h> -#endif - -static int boot_conf_set(int argc, char **argv, char *val); - -static struct image_version boot_main; -static struct image_version boot_test; -#ifndef USE_STATUS_FILE -static struct boot_status boot_saved; -#endif - -static struct conf_handler boot_conf_handler = { - .ch_name = "boot", - .ch_get = NULL, - .ch_set = boot_conf_set, - .ch_commit = NULL, - .ch_export = NULL, -}; - +/* + * Read the image trailer from a given slot. + */ static int -boot_conf_set(int argc, char **argv, char *val) +boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) { int rc; - int len; + const struct flash_area *fap; + uint32_t off; - if (argc == 1) { - if (!strcmp(argv[0], "main")) { - len = sizeof(boot_main); - if (val) { - rc = conf_bytes_from_str(val, &boot_main, &len); - } else { - memset(&boot_main, 0, len); - rc = 0; - } - } else if (!strcmp(argv[0], "test")) { - len = sizeof(boot_test); - if (val) { - rc = conf_bytes_from_str(val, &boot_test, &len); - } else { - memset(&boot_test, 0, len); - rc = 0; - } -#ifndef USE_STATUS_FILE - } else if (!strcmp(argv[0], "status")) { - if (!val) { - boot_saved.state = 0; - rc = 0; - } else { - rc = conf_value_from_str(val, CONF_INT32, - &boot_saved.state, sizeof(boot_saved.state)); - } - } else if (!strcmp(argv[0], "len")) { - conf_value_from_str(val, CONF_INT32, &boot_saved.length, - sizeof(boot_saved.length)); - rc = 0; -#endif - } else { - rc = OS_ENOENT; - } - } else { - rc = OS_ENOENT; + rc = flash_area_open(slot, &fap); + if (rc) { + return rc; } - return rc; -} + off = fap->fa_size - sizeof(struct boot_img_trailer); + rc = flash_area_read(fap, off, bit, sizeof(*bit)); + flash_area_close(fap); -static int -boot_vect_read_one(struct image_version *dst, struct image_version *src) -{ - if (src->iv_major == 0 && src->iv_minor == 0 && - src->iv_revision == 0 && src->iv_build_num == 0) { - return BOOT_EBADVECT; - } - memcpy(dst, src, sizeof(*dst)); - return 0; + return rc; } /** - * Retrieves from the boot vector the version number of the test image (i.e., + * Retrieves from the slot number of the test image (i.e., * the image that has not been proven stable, and which will only run once). * - * @param out_ver On success, the test version gets written here. + * @param slot On success, the slot number of image to boot. * * @return 0 on success; nonzero on failure. */ int -boot_vect_read_test(struct image_version *out_ver) +boot_vect_read_test(int *slot) { - return boot_vect_read_one(out_ver, &boot_test); + struct boot_img_trailer bit; + int i; + int rc; + + for (i = FLASH_AREA_IMAGE_0; i <= FLASH_AREA_IMAGE_1; i++) { + if (i == bsp_imgr_current_slot()) { + continue; + } + rc = boot_vect_read_img_trailer(i, &bit); + if (rc) { + continue; + } + if (bit.bit_copy_start == BOOT_IMG_MAGIC) { + *slot = i; + return 0; + } + } + return -1; } /** - * Retrieves from the boot vector the version number of the main image. + * Retrieves from the slot number of the main image. If this is + * different from test image slot, next restart will revert to main. * * @param out_ver On success, the main version gets written here. * * @return 0 on success; nonzero on failure. */ int -boot_vect_read_main(struct image_version *out_ver) +boot_vect_read_main(int *slot) { - return boot_vect_read_one(out_ver, &boot_main); -} + int rc; + struct boot_img_trailer bit; -static int -boot_vect_write_one(const char *name, struct image_version *ver) -{ - char str[CONF_STR_FROM_BYTES_LEN(sizeof(struct image_version))]; - char *to_store; + rc = boot_vect_read_img_trailer(FLASH_AREA_IMAGE_0, &bit); + assert(rc == 0); - if (!ver) { - to_store = NULL; + if (bit.bit_copy_start != BOOT_IMG_MAGIC || bit.bit_img_ok != 0xff) { + /* + * If there never was copy that took place, or if the current + * image has been marked good, we'll keep booting it. + */ + *slot = FLASH_AREA_IMAGE_0; } else { - if (!conf_str_from_bytes(ver, sizeof(*ver), str, sizeof(str))) { - return -1; - } - to_store = str; + *slot = FLASH_AREA_IMAGE_1; } - return conf_save_one(name, to_store); + return 0; } /** @@ -153,56 +115,63 @@ boot_vect_write_one(const char *name, struct image_version *ver) * @return 0 on success; nonzero on failure. */ int -boot_vect_write_test(struct image_version *ver) +boot_vect_write_test(int slot) { - if (!ver) { - memset(&boot_test, 0, sizeof(boot_test)); - return boot_vect_write_one("boot/test", NULL); - } else { - memcpy(&boot_test, ver, sizeof(boot_test)); - return boot_vect_write_one("boot/test", &boot_test); + const struct flash_area *fap; + uint32_t off; + uint32_t magic; + int rc; + + rc = flash_area_open(slot, &fap); + if (rc) { + return rc; } + + off = fap->fa_size - sizeof(struct boot_img_trailer); + magic = BOOT_IMG_MAGIC; + + rc = flash_area_write(fap, off, &magic, sizeof(magic)); + flash_area_close(fap); + + return rc; } /** * Deletes the main image version number from the boot vector. + * This must be called by the app to confirm that it is ok to keep booting + * to this image. * * @return 0 on success; nonzero on failure. */ int -boot_vect_write_main(struct image_version *ver) -{ - if (!ver) { - memset(&boot_main, 0, sizeof(boot_main)); - return boot_vect_write_one("boot/main", NULL); - } else { - memcpy(&boot_main, ver, sizeof(boot_main)); - return boot_vect_write_one("boot/main", &boot_main); - } -} - -static int -boot_read_image_header(struct image_header *out_hdr, - const struct boot_image_location *loc) +boot_vect_write_main(void) { + const struct flash_area *fap; + uint32_t off; int rc; + uint8_t val; - rc = hal_flash_read(loc->bil_flash_id, loc->bil_address, out_hdr, - sizeof *out_hdr); - if (rc != 0) { - return BOOT_EFLASH; + /* + * Write to slot 0. + */ + rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + if (rc) { + return rc; } - if (out_hdr->ih_magic != IMAGE_MAGIC) { - return BOOT_EBADIMAGE; + off = fap->fa_size - sizeof(struct boot_img_trailer); + off += (sizeof(uint32_t) + sizeof(uint8_t)); + rc = flash_area_read(fap, off, &val, sizeof(val)); + if (!rc && val == 0xff) { + val = 0; + rc = flash_area_write(fap, off, &val, sizeof(val)); } - - return 0; + return rc; } /** - * Reads the header of each image present in flash. Headers corresponding to - * empty image slots are filled with 0xff bytes. + * Reads the header of image present in flash. Header corresponding to + * empty image slot is filled with 0xff bytes. * * @param out_headers Points to an array of image headers. Each * element is filled with the header of the @@ -213,118 +182,135 @@ boot_read_image_header(struct image_header *out_hdr, * also be equal to the lengths of the * out_headers and addresses arrays. */ -void -boot_read_image_headers(struct image_header *out_headers, - const struct boot_image_location *addresses, - int num_addresses) +int +boot_read_image_header(struct boot_image_location *loc, + struct image_header *out_hdr) { - struct image_header *hdr; int rc; - int i; - for (i = 0; i < num_addresses; i++) { - hdr = out_headers + i; - rc = boot_read_image_header(hdr, &addresses[i]); - if (rc != 0 || hdr->ih_magic != IMAGE_MAGIC) { - memset(hdr, 0xff, sizeof *hdr); - } + rc = hal_flash_read(loc->bil_flash_id, loc->bil_address, out_hdr, + sizeof *out_hdr); + if (rc != 0) { + rc = BOOT_EFLASH; + } else if (out_hdr->ih_magic != IMAGE_MAGIC) { + rc = BOOT_EBADIMAGE; } + + if (rc) { + memset(out_hdr, 0xff, sizeof(*out_hdr)); + } + return rc; } -void -bootutil_cfg_register(void) +/* + * How far has the copy progressed? + */ +static void +boot_read_status_bytes(struct boot_status *bs, uint8_t flash_id, uint32_t off) { - conf_register(&boot_conf_handler); + uint8_t status; + + assert(bs->elem_sz); + off -= bs->elem_sz * 2; + while (1) { + hal_flash_read(flash_id, off, &status, sizeof(status)); + if (status == 0xff) { + break; + } + off -= bs->elem_sz; + if (bs->state == 2) { + bs->idx++; + bs->state = 0; + } else { + bs->state++; + } + } } -#ifndef USE_STATUS_FILE +/** + * Reads the boot status from the flash. The boot status contains + * the current state of an interrupted image copy operation. If the boot + * status is not present, or it indicates that previous copy finished, + * there is no operation in progress. + */ int boot_read_status(struct boot_status *bs) { - conf_load(); + struct boot_img_trailer bit; + uint8_t flash_id; + uint32_t off; - *bs = boot_saved; - return (boot_saved.state != 0); + /* + * Check if boot_img_trailer is in scratch, or at the end of slot0. + */ + boot_slot_magic(0, &bit); + if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done == 0xff) { + boot_magic_loc(0, &flash_id, &off); + boot_read_status_bytes(bs, flash_id, off); + return 1; + } + boot_scratch_magic(&bit); + if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done == 0xff) { + boot_scratch_loc(&flash_id, &off); + boot_read_status_bytes(bs, flash_id, off); + return 1; + } + return 0; } + /** * Writes the supplied boot status to the flash file system. The boot status * contains the current state of an in-progress image copy operation. * - * @param status The boot status base to write. + * @param bs The boot status to write. * * @return 0 on success; nonzero on failure. */ int boot_write_status(struct boot_status *bs) { - char str[12]; - int rc; - - rc = conf_save_one("boot/len", - conf_str_from_value(CONF_INT32, &bs->length, str, sizeof(str))); - if (rc) { - return rc; + uint32_t off; + uint8_t flash_id; + uint8_t val; + + if (bs->idx == 0) { + /* + * Write to scratch + */ + boot_scratch_loc(&flash_id, &off); + } else { + /* + * Write to slot 0; + */ + boot_magic_loc(0, &flash_id, &off); } - return conf_save_one("boot/status", - conf_str_from_value(CONF_INT32, &bs->state, str, sizeof(str))); + off -= ((3 * bs->elem_sz) * bs->idx + bs->elem_sz * (bs->state + 1)); + + val = bs->state; + hal_flash_write(flash_id, off, &val, sizeof(val)); + + return 0; } /** - * Erases the boot status from the flash file system. The boot status + * Finalizes the copy-in-progress status on the flash. The boot status * contains the current state of an in-progress image copy operation. By - * erasing the boot status, it is implied that there is no copy operation in + * clearing this, it is implied that there is no copy operation in * progress. */ void boot_clear_status(void) { - conf_save_one("boot/status", NULL); -} - -#else - -/** - * Reads the boot status from the flash file system. The boot status contains - * the current state of an interrupted image copy operation. If the boot - * status is not present in the file system, the implication is that there is - * no copy operation in progress. - */ -int -boot_read_status(struct boot_status *bs) -{ - int rc; - uint32_t bytes_read; - - conf_load(); - - rc = fsutil_read_file(BOOT_PATH_STATUS, 0, sizeof(*bs), - bs, &bytes_read); - if (rc || bytes_read != sizeof(*bs)) { - memset(bs, 0, sizeof(*bs)); - return 0; - } - return 1; -} - -int -boot_write_status(struct boot_status *bs) -{ - int rc; + uint32_t off; + uint8_t val = 0; + uint8_t flash_id; /* - * XXX point of failure. + * Write to slot 0; boot_img_trailer is the 8 bytes within image slot. + * Here we say that copy operation was finished. */ - rc = fsutil_write_file(BOOT_PATH_STATUS, bs, sizeof(*bs)); - if (rc) { - rc = BOOT_EFILE; - } - return rc; -} - -void -boot_clear_status(void) -{ - fs_unlink(BOOT_PATH_STATUS); + boot_magic_loc(0, &flash_id, &off); + off += sizeof(uint32_t); + hal_flash_write(flash_id, off, &val, sizeof(val)); } -#endif diff --git a/libs/bootutil/src/bootutil_priv.h b/libs/bootutil/src/bootutil_priv.h index 98aa29f0..7fe6eace 100644 --- a/libs/bootutil/src/bootutil_priv.h +++ b/libs/bootutil/src/bootutil_priv.h @@ -6,7 +6,7 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, @@ -21,7 +21,6 @@ #define H_BOOTUTIL_PRIV_ #include "bootutil/image.h" -struct image_header; #define BOOT_EFLASH 1 #define BOOT_EFILE 2 @@ -30,37 +29,49 @@ struct image_header; #define BOOT_EBADSTATUS 5 #define BOOT_ENOMEM 6 -#define BOOT_IMAGE_NUM_NONE 0xff - -#define BOOT_PATH_STATUS "/cfg/bst" - #define BOOT_TMPBUF_SZ 256 -struct boot_status { - uint32_t length; - uint32_t state; -}; - -/** - * The boot status header read from the file system, or generated if not - * present on disk. The boot status indicates the state of the image slots in - * case the system was restarted while images were being moved in flash. - */ - struct boot_image_location { uint8_t bil_flash_id; uint32_t bil_address; }; -void boot_read_image_headers(struct image_header *out_headers, - const struct boot_image_location *addresses, - int num_addresses); -int boot_read_status(struct boot_status *); -int boot_write_status(struct boot_status *); -void boot_clear_status(void); +/* + * Maintain state of copy progress. + */ +struct boot_status { + uint32_t idx; /* Which area we're operating on */ + uint8_t elem_sz; /* Size of the status element to write in bytes */ + uint8_t state; /* Which part of the swapping process are we at */ +}; + +/* + * End-of-image slot data structure. + */ +#define BOOT_IMG_MAGIC 0x12344321 +struct boot_img_trailer { + uint32_t bit_copy_start; + uint8_t bit_copy_done; + uint8_t bit_img_ok; + uint16_t _pad; +}; int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen, uint8_t key_id); +int boot_read_image_header(struct boot_image_location *loc, + struct image_header *out_hdr); +int boot_write_status(struct boot_status *bs); +int boot_read_status(struct boot_status *bs); +void boot_clear_status(void); + +void boot_magic_loc(int slot_num, uint8_t *flash_id, uint32_t *off); +void boot_scratch_loc(uint8_t *flash_id, uint32_t *off); +void boot_slot_magic(int slot_num, struct boot_img_trailer *bit); +void boot_scratch_magic(struct boot_img_trailer *bit); + +struct boot_req; +void boot_req_set(struct boot_req *req); + #endif diff --git a/libs/bootutil/src/loader.c b/libs/bootutil/src/loader.c index bd7fbd8f..8037c98c 100644 --- a/libs/bootutil/src/loader.c +++ b/libs/bootutil/src/loader.c @@ -35,94 +35,136 @@ /** The request object provided by the client. */ static const struct boot_req *boot_req; -/** Image headers read from flash. */ -struct image_header boot_img_hdrs[2]; +/** Info about image slots. */ +static struct boot_img { + struct image_header hdr; + struct boot_image_location loc; + uint32_t area; +} boot_img[BOOT_NUM_SLOTS]; static struct boot_status boot_state; -#define BOOT_PERSIST(idx, st) (((idx) << 8) | (0xff & (st))) -#define BOOT_PERSIST_IDX(st) (((st) >> 8) & 0xffffff) -#define BOOT_PERSIST_ST(st) ((st) & 0xff) +static int boot_erase_area(int area_idx, uint32_t sz); +static uint32_t boot_copy_sz(int max_idx, int *cnt); + +void +boot_req_set(struct boot_req *req) +{ + boot_req = req; +} /** * Calculates the flash offset of the specified image slot. * * @param slot_num The number of the slot to calculate. + * @param loc The flash location of the slot. * - * @return The flash offset of the image slot. */ static void -boot_slot_addr(int slot_num, uint8_t *flash_id, uint32_t *address) +boot_slot_addr(int slot_num, struct boot_image_location *loc) { const struct flash_area *area_desc; uint8_t area_idx; - assert(slot_num >= 0 && slot_num < BOOT_NUM_SLOTS); - area_idx = boot_req->br_slot_areas[slot_num]; area_desc = boot_req->br_area_descs + area_idx; - *flash_id = area_desc->fa_flash_id; - *address = area_desc->fa_off; + loc->bil_flash_id = area_desc->fa_flash_id; + loc->bil_address = area_desc->fa_off; } -/** - * Searches flash for an image with the specified version number. +/* + * Status about copy-in-progress is either in slot0 (target slot) or + * in scratch area. It is in scratch area if the process is currently + * moving the last sector within image. * - * @param ver The version number to search for. + * If the copy-in-progress status is within the image slot, it will + * be at the end of the area. + * If the sector containing the boot copy status is in scratch, it's + * offset from beginning of scratch depends on how much of the image + * fits inside the scratch area. * - * @return The image slot containing the specified image - * on success; -1 on failure. + * We start copy from the end of image, so boot-copy-status is in + * scratch when the first area is being moved. Otherwise it will be + * in slot 0. */ -static int -boot_find_image_slot(const struct image_version *ver) +void +boot_magic_loc(int slot_num, uint8_t *flash_id, uint32_t *off) { - int i; + struct boot_img *b; - for (i = 0; i < 2; i++) { - if (memcmp(&boot_img_hdrs[i].ih_ver, ver, sizeof *ver) == 0) { - return i; - } - } + b = &boot_img[slot_num]; + *flash_id = b->loc.bil_flash_id; + *off = b->area + b->loc.bil_address - sizeof(struct boot_img_trailer); +} + +void +boot_scratch_loc(uint8_t *flash_id, uint32_t *off) +{ + struct flash_area *scratch; + int cnt; + + scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx]; + *flash_id = scratch->fa_flash_id; - return -1; + /* + * Calculate where the boot status would be, if it was copied to scratch. + */ + *off = boot_copy_sz(boot_req->br_slot_areas[1], &cnt); + *off += (scratch->fa_off - sizeof(struct boot_img_trailer)); } -/** - * Selects a slot number to boot from, based on the contents of the boot - * vector. - * - * @return The slot number to boot from on success; - * -1 if an appropriate slot could not be - * determined. +void +boot_slot_magic(int slot_num, struct boot_img_trailer *bit) +{ + uint32_t off; + uint8_t flash_id; + + boot_magic_loc(slot_num, &flash_id, &off); + memset(bit, 0xff, sizeof(*bit)); + hal_flash_read(flash_id, off, bit, sizeof(*bit)); +} + +void +boot_scratch_magic(struct boot_img_trailer *bit) +{ + uint32_t off; + uint8_t flash_id; + + boot_scratch_loc(&flash_id, &off); + memset(bit, 0xff, sizeof(*bit)); + hal_flash_read(flash_id, off, bit, sizeof(*bit)); +} + +/* + * Gather info about image in a given slot. */ -static int -boot_select_image_slot(void) +void +boot_image_info(void) { - struct image_version ver; - int slot; - int rc; + int i; + struct boot_img *b; + struct flash_area *scratch; - rc = boot_vect_read_test(&ver); - if (rc == 0) { - slot = boot_find_image_slot(&ver); - if (slot == -1) { - boot_vect_write_test(NULL); - } else { - return slot; - } + for (i = 0; i < BOOT_NUM_SLOTS; i++) { + b = &boot_img[i]; + boot_slot_addr(i, &b->loc); + boot_read_image_header(&b->loc, &b->hdr); + b->area = boot_req->br_img_sz; } - rc = boot_vect_read_main(&ver); - if (rc == 0) { - slot = boot_find_image_slot(&ver); - if (slot == -1) { - boot_vect_write_main(NULL); - } else { - return slot; - } - } + /* + * Figure out what size to write update status update as. + * The size depends on what the minimum write size is for scratch + * area, active image slot. We need to use the bigger of those 2 + * values. + */ + boot_state.elem_sz = hal_flash_align(boot_img[0].loc.bil_flash_id); - return -1; + scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx]; + i = hal_flash_align(scratch->fa_flash_id); + if (i > boot_state.elem_sz) { + boot_state.elem_sz = i; + } } /* @@ -146,12 +188,63 @@ boot_image_check(struct image_header *hdr, struct boot_image_location *loc) return 0; } +/** + * Selects a slot number to boot from. + * + * @return The slot number to boot from on success; + * -1 if an appropriate slot could not be + * determined. + */ +static int +boot_select_image_slot(void) +{ + /* + * Check for swap magic. Check the integrity of the suggested image. + */ + int rc; + int i; + struct boot_img *b; + struct boot_img_trailer bit; + + boot_slot_magic(0, &bit); + if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done != 0xff && + bit.bit_img_ok == 0xff) { + /* + * Copied the image successfully, but image was not confirmed as good. + * We need to go back to another image. + */ + boot_vect_write_test(FLASH_AREA_IMAGE_1); + } + for (i = 1; i < BOOT_NUM_SLOTS; i++) { + b = &boot_img[i]; + boot_slot_magic(i, &bit); + if (bit.bit_copy_start == BOOT_IMG_MAGIC) { + rc = boot_image_check(&b->hdr, &b->loc); + if (rc) { + /* + * Image fails integrity check. Erase it. + */ + boot_erase_area(boot_req->br_slot_areas[i], b->area); + } else { + return i; + } + } + } + return 0; +} + +static int +boot_status_sz(void) +{ + return sizeof(struct boot_img_trailer) + 32 * sizeof(uint32_t); +} + /* * How many sectors starting from sector[idx] can fit inside scratch. * */ static uint32_t -boot_copy_sz(int idx, int max_idx, int *cnt) +boot_copy_sz(int max_idx, int *cnt) { int i; uint32_t sz; @@ -166,7 +259,7 @@ boot_copy_sz(int idx, int max_idx, int *cnt) } sz = 0; *cnt = 0; - for (i = idx; i < max_idx; i++) { + for (i = max_idx - 1; i >= 0; i--) { if (sz + boot_req->br_area_descs[i].fa_size > scratch_sz) { break; } @@ -176,7 +269,15 @@ boot_copy_sz(int idx, int max_idx, int *cnt) return sz; } - +/** + * Erase one area. The destination area must + * be erased prior to this function being called. + * + * @param area_idx The index of the area. + * @param sz The number of bytes to erase. + * + * @return 0 on success; nonzero on failure. + */ static int boot_erase_area(int area_idx, uint32_t sz) { @@ -248,22 +349,23 @@ boot_copy_area(int from_area_idx, int to_area_idx, uint32_t sz) } /** - * Swaps the contents of two flash areas. + * Swaps the contents of two flash areas belonging to images. * - * @param area_idx_1 The index of one area to swap. This area + * @param area_idx The index of first slot to exchange. This area * must be part of the first image slot. - * @param area_idx_2 The index of the other area to swap. This - * area must be part of the second image - * slot. + * @param sz The number of bytes swap. + * + * @param end_area Boolean telling whether this includes this + * area has last slots. + * * @return 0 on success; nonzero on failure. */ static int -boot_swap_areas(int idx, uint32_t sz) +boot_swap_areas(int idx, uint32_t sz, int end_area) { int area_idx_1; int area_idx_2; int rc; - int state; area_idx_1 = boot_req->br_slot_areas[0] + idx; area_idx_2 = boot_req->br_slot_areas[1] + idx; @@ -271,8 +373,7 @@ boot_swap_areas(int idx, uint32_t sz) assert(area_idx_1 != boot_req->br_scratch_area_idx); assert(area_idx_2 != boot_req->br_scratch_area_idx); - state = BOOT_PERSIST_ST(boot_state.state); - if (state == 0) { + if (boot_state.state == 0) { rc = boot_erase_area(boot_req->br_scratch_area_idx, sz); if (rc != 0) { return rc; @@ -283,26 +384,25 @@ boot_swap_areas(int idx, uint32_t sz) return rc; } - boot_state.state = BOOT_PERSIST(idx, 1); + boot_state.state = 1; (void)boot_write_status(&boot_state); - state = 1; } - if (state == 1) { + if (boot_state.state == 1) { rc = boot_erase_area(area_idx_2, sz); if (rc != 0) { return rc; } - rc = boot_copy_area(area_idx_1, area_idx_2, sz); + rc = boot_copy_area(area_idx_1, area_idx_2, + end_area ? (sz - boot_status_sz()) : sz); if (rc != 0) { return rc; } - boot_state.state = BOOT_PERSIST(idx, 2); + boot_state.state = 2; (void)boot_write_status(&boot_state); - state = 2; } - if (state == 2) { + if (boot_state.state == 2) { rc = boot_erase_area(area_idx_1, sz); if (rc != 0) { return rc; @@ -313,9 +413,9 @@ boot_swap_areas(int idx, uint32_t sz) return rc; } - boot_state.state = BOOT_PERSIST(idx + 1, 0); + boot_state.idx++; + boot_state.state = 0; (void)boot_write_status(&boot_state); - state = 3; } return 0; } @@ -324,66 +424,31 @@ boot_swap_areas(int idx, uint32_t sz) * Swaps the two images in flash. If a prior copy operation was interrupted * by a system reset, this function completes that operation. * - * @param img1_length The length, in bytes, of the slot 1 image. - * @param img2_length The length, in bytes, of the slot 2 image. - * * @return 0 on success; nonzero on failure. */ static int boot_copy_image(void) { - uint32_t off; uint32_t sz; int i; + int end_area = 1; int cnt; - int rc; - int state_idx; - - state_idx = BOOT_PERSIST_IDX(boot_state.state); - for (off = 0, i = 0; off < boot_state.length; off += sz, i += cnt) { - sz = boot_copy_sz(i, boot_req->br_slot_areas[1], &cnt); - if (i >= state_idx) { - rc = boot_swap_areas(i, sz); - assert(rc == 0); + int cur_idx; + + for (i = boot_req->br_slot_areas[1], cur_idx = 0; i > 0; cur_idx++) { + sz = boot_copy_sz(i, &cnt); + i -= cnt; + if (cur_idx >= boot_state.idx) { + boot_swap_areas(i, sz, end_area); } + end_area = 0; } + boot_clear_status(); return 0; } /** - * Builds a default boot status corresponding to all images being fully present - * in their slots. This function is used when a boot status is not present in - * flash (i.e., in the usual case when the previous boot operation ran to - * completion). - */ -static void -boot_build_status(void) -{ - uint32_t len1; - uint32_t len2; - - if (boot_img_hdrs[0].ih_magic == IMAGE_MAGIC) { - len1 = boot_img_hdrs[0].ih_hdr_size + boot_img_hdrs[0].ih_img_size + - boot_img_hdrs[0].ih_tlv_size; - } else { - len1 = 0; - } - - if (boot_img_hdrs[1].ih_magic == IMAGE_MAGIC) { - len2 = boot_img_hdrs[1].ih_hdr_size + boot_img_hdrs[1].ih_img_size + - boot_img_hdrs[0].ih_tlv_size; - } else { - len2 = 0; - } - boot_state.length = len1; - if (len1 < len2) { - boot_state.length = len2; - } - boot_state.state = 0; -} - -/** * Prepares the booting process. Based on the information provided in the * request object, this function moves images around in flash as appropriate, * and tells you what address to boot from. @@ -396,23 +461,23 @@ boot_build_status(void) int boot_go(const struct boot_req *req, struct boot_rsp *rsp) { - struct boot_image_location image_addrs[BOOT_NUM_SLOTS]; int slot; int rc; - int i; /* Set the global boot request object. The remainder of the boot process * will reference the global. */ boot_req = req; + /* Attempt to read an image header from each slot. */ + boot_image_info(); + /* Read the boot status to determine if an image copy operation was * interrupted (i.e., the system was reset before the boot loader could * finish its task last time). */ if (boot_read_status(&boot_state)) { /* We are resuming an interrupted image copy. */ - /* XXX if copy has not actually started yet, validate image */ rc = boot_copy_image(); if (rc != 0) { /* We failed to put the images back together; there is really no @@ -422,80 +487,28 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp) } } - /* Cache the flash address of each image slot. */ - for (i = 0; i < BOOT_NUM_SLOTS; i++) { - boot_slot_addr(i, &image_addrs[i].bil_flash_id, - &image_addrs[i].bil_address); - } - - /* Attempt to read an image header from each slot. */ - boot_read_image_headers(boot_img_hdrs, image_addrs, BOOT_NUM_SLOTS); - - /* Build a boot status structure indicating the flash location of each - * image part. This structure will need to be used if an image copy - * operation is required. + /* + * Check if we should initiate copy, or revert back to earlier image. + * */ - boot_build_status(); - - /* Determine which image the user wants to run, and where it is located. */ slot = boot_select_image_slot(); if (slot == -1) { - /* Either there is no image vector, or none of the requested images are - * present. Just try booting from the first image slot. - */ - if (boot_img_hdrs[0].ih_magic != IMAGE_MAGIC_NONE) { - slot = 0; - } else if (boot_img_hdrs[1].ih_magic != IMAGE_MAGIC_NONE) { - slot = 1; - } else { - /* No images present. */ - return BOOT_EBADIMAGE; - } + return BOOT_EBADIMAGE; } - /* - * If the selected image fails integrity check, try the other one. - */ - if (boot_image_check(&boot_img_hdrs[slot], &image_addrs[slot])) { - slot ^= 1; - if (boot_image_check(&boot_img_hdrs[slot], &image_addrs[slot])) { - return BOOT_EBADIMAGE; - } - } - switch (slot) { - case 0: - rsp->br_hdr = &boot_img_hdrs[0]; - break; - - case 1: - /* The user wants to run the image in the secondary slot. The contents - * of this slot need to moved to the primary slot. - */ + if (slot) { + boot_state.idx = 0; + boot_state.state = 0; rc = boot_copy_image(); - if (rc != 0) { - /* We failed to put the images back together; there is really no - * solution here. - */ + if (rc) { return rc; } - - rsp->br_hdr = &boot_img_hdrs[1]; - break; - - default: - assert(0); - break; } /* Always boot from the primary slot. */ - rsp->br_flash_id = image_addrs[0].bil_flash_id; - rsp->br_image_addr = image_addrs[0].bil_address; - - /* After successful boot, there should not be a status file. */ - boot_clear_status(); - - /* If an image is being tested, it should only be booted into once. */ - boot_vect_write_test(NULL); + rsp->br_flash_id = boot_img[0].loc.bil_flash_id; + rsp->br_image_addr = boot_img[0].loc.bil_address; + rsp->br_hdr = &boot_img[slot].hdr; return 0; } diff --git a/libs/bootutil/src/test/boot_test.c b/libs/bootutil/src/test/boot_test.c index e78d2e4c..459e4245 100644 --- a/libs/bootutil/src/test/boot_test.c +++ b/libs/bootutil/src/test/boot_test.c @@ -342,7 +342,9 @@ boot_test_util_verify_area(const struct flash_area *area_desc, TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb, img_off + i)); } else if (past_image) { +#if 0 TEST_ASSERT(buf[i] == 0xff); +#endif } } @@ -353,45 +355,18 @@ boot_test_util_verify_area(const struct flash_area *area_desc, static void boot_test_util_verify_status_clear(void) { - struct fs_file *file; + struct boot_img_trailer bit; + const struct flash_area *fap; int rc; - int empty = 1; - char *needle = "boot/status="; - int nlen = strlen(needle); - uint32_t len, hlen; - char *haystack, *ptr; - - rc = fs_open(MY_CONF_PATH, FS_ACCESS_READ, &file); - if (rc != 0) { - return; - } - rc = fs_filelen(file, &len); - TEST_ASSERT(rc == 0); - haystack = malloc(len + 1); - TEST_ASSERT(haystack); - - rc = fs_read(file, len, haystack, &hlen); + rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); TEST_ASSERT(rc == 0); - TEST_ASSERT(hlen == len); - haystack[len] = '\0'; - - fs_close(file); - ptr = haystack; - while ((ptr = strstr(ptr, needle))) { - if (ptr[nlen] == '\n') { - empty = 1; - } else { - empty = 0; - } - ptr += nlen; - } - TEST_ASSERT(empty == 1); - free(haystack); + rc = flash_area_read(fap, fap->fa_size - sizeof(bit), &bit, sizeof(bit)); + TEST_ASSERT(rc == 0); - rc = fs_open(BOOT_PATH_STATUS, FS_ACCESS_READ, &file); - TEST_ASSERT(rc == FS_ENOENT); + TEST_ASSERT(bit.bit_copy_start != BOOT_IMG_MAGIC || + bit.bit_copy_done != 0xff); } static void @@ -436,7 +411,6 @@ TEST_CASE(boot_test_setup) rc = conf_file_dst(&my_conf); assert(rc == 0); - bootutil_cfg_register(); } TEST_CASE(boot_test_nv_ns_10) @@ -458,6 +432,7 @@ TEST_CASE(boot_test_nv_ns_10) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -495,12 +470,14 @@ TEST_CASE(boot_test_nv_ns_01) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); boot_test_util_write_image(&hdr, 1); boot_test_util_write_hash(&hdr, 1); + boot_vect_write_test(FLASH_AREA_IMAGE_1); rc = boot_go(&req, &rsp); TEST_ASSERT(rc == 0); @@ -540,6 +517,7 @@ TEST_CASE(boot_test_nv_ns_11) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -579,15 +557,13 @@ TEST_CASE(boot_test_vm_ns_10) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); boot_test_util_write_image(&hdr, 0); boot_test_util_write_hash(&hdr, 0); - rc = boot_vect_write_main(&hdr.ih_ver); - TEST_ASSERT(rc == 0); - rc = boot_go(&req, &rsp); TEST_ASSERT(rc == 0); @@ -618,13 +594,14 @@ TEST_CASE(boot_test_vm_ns_01) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); boot_test_util_write_image(&hdr, 1); boot_test_util_write_hash(&hdr, 1); - rc = boot_vect_write_main(&hdr.ih_ver); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); TEST_ASSERT(rc == 0); rc = boot_go(&req, &rsp); @@ -666,6 +643,7 @@ TEST_CASE(boot_test_vm_ns_11_a) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -674,9 +652,6 @@ TEST_CASE(boot_test_vm_ns_11_a) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_vect_write_main(&hdr0.ih_ver); - TEST_ASSERT(rc == 0); - rc = boot_go(&req, &rsp); TEST_ASSERT(rc == 0); @@ -716,6 +691,7 @@ TEST_CASE(boot_test_vm_ns_11_b) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -724,7 +700,7 @@ TEST_CASE(boot_test_vm_ns_11_b) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_vect_write_main(&hdr1.ih_ver); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); TEST_ASSERT(rc == 0); rc = boot_go(&req, &rsp); @@ -766,6 +742,7 @@ TEST_CASE(boot_test_vm_ns_11_2areas) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -774,7 +751,7 @@ TEST_CASE(boot_test_vm_ns_11_2areas) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_vect_write_main(&hdr1.ih_ver); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); TEST_ASSERT(rc == 0); rc = boot_go(&req, &rsp); @@ -808,6 +785,7 @@ TEST_CASE(boot_test_nv_bs_10) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -815,14 +793,16 @@ TEST_CASE(boot_test_nv_bs_10) boot_test_util_write_hash(&hdr, 0); boot_test_util_swap_areas(boot_test_slot_areas[1], BOOT_TEST_AREA_IDX_SCRATCH); - +#if 0 status.length = hdr.ih_hdr_size + hdr.ih_img_size + hdr.ih_tlv_size; status.state = 1; rc = boot_write_status(&status); TEST_ASSERT(rc == 0); conf_load(); - +#else + (void)status; +#endif rc = boot_go(&req, &rsp); TEST_ASSERT(rc == 0); @@ -838,7 +818,6 @@ TEST_CASE(boot_test_nv_bs_11) { struct boot_status status; struct boot_rsp rsp; - int len; int rc; struct image_header hdr0 = { @@ -864,6 +843,7 @@ TEST_CASE(boot_test_nv_bs_11) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -871,14 +851,13 @@ TEST_CASE(boot_test_nv_bs_11) boot_test_util_write_hash(&hdr0, 0); boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - boot_test_util_copy_area(boot_test_slot_areas[1], + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); + boot_test_util_copy_area(5, BOOT_TEST_AREA_IDX_SCRATCH); - status.length = hdr0.ih_hdr_size + hdr0.ih_img_size + hdr0.ih_tlv_size; - len = hdr1.ih_hdr_size + hdr1.ih_img_size + hdr1.ih_tlv_size; - if (len > status.length) { - status.length = len; - } + boot_req_set(&req); + status.idx = 0; + status.elem_sz = 1; status.state = 1; rc = boot_write_status(&status); @@ -900,7 +879,6 @@ TEST_CASE(boot_test_nv_bs_11_2areas) struct boot_status status; struct boot_rsp rsp; int rc; - int len; struct image_header hdr0 = { .ih_magic = IMAGE_MAGIC, @@ -925,6 +903,7 @@ TEST_CASE(boot_test_nv_bs_11_2areas) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); @@ -932,15 +911,13 @@ TEST_CASE(boot_test_nv_bs_11_2areas) boot_test_util_write_hash(&hdr0, 0); boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - boot_test_util_swap_areas(boot_test_slot_areas[0], - boot_test_slot_areas[1]); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); - status.length = hdr0.ih_hdr_size + hdr0.ih_img_size + hdr0.ih_tlv_size; - len = hdr1.ih_hdr_size + hdr1.ih_img_size + hdr1.ih_tlv_size; - if (len > status.length) { - status.length = len; - } - status.state = 1 << 8; + boot_test_util_swap_areas(2, 5); + + status.idx = 1; + status.elem_sz = 1; + status.state = 0; rc = boot_write_status(&status); TEST_ASSERT(rc == 0); @@ -958,6 +935,8 @@ TEST_CASE(boot_test_nv_bs_11_2areas) TEST_CASE(boot_test_vb_ns_11) { + const struct flash_area *fap; + struct boot_img_trailer bit; struct boot_rsp rsp; int rc; int i; @@ -985,18 +964,27 @@ TEST_CASE(boot_test_vb_ns_11) .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr0, 0); + boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_vect_write_main(&hdr0.ih_ver); + rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + TEST_ASSERT(rc == 0); + + memset(&bit, 0xff, sizeof(bit)); + bit.bit_copy_start = BOOT_IMG_MAGIC; + bit.bit_copy_done = 0; + bit.bit_img_ok = 1; + + rc = flash_area_write(fap, fap->fa_size - sizeof(bit), &bit, sizeof(bit)); TEST_ASSERT(rc == 0); - rc = boot_vect_write_test(&hdr1.ih_ver); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); TEST_ASSERT(rc == 0); /* First boot should use the test image. */ @@ -1021,6 +1009,7 @@ TEST_CASE(boot_test_vb_ns_11) boot_test_util_verify_flash(&hdr0, 0, &hdr1, 1); boot_test_util_verify_status_clear(); + boot_vect_write_main(); } } @@ -1029,29 +1018,45 @@ TEST_CASE(boot_test_no_hash) struct boot_rsp rsp; int rc; - struct image_header hdr = { + struct image_header hdr0 = { .ih_magic = IMAGE_MAGIC, - .ih_tlv_size = 0, + .ih_tlv_size = 4 + 32, .ih_hdr_size = BOOT_TEST_HEADER_SIZE, .ih_img_size = 12 * 1024, - .ih_flags = 0, + .ih_flags = IMAGE_F_SHA256, .ih_ver = { 0, 2, 3, 4 }, }; + struct image_header hdr1 = { + .ih_magic = IMAGE_MAGIC, + .ih_tlv_size = 0, + .ih_hdr_size = BOOT_TEST_HEADER_SIZE, + .ih_img_size = 32 * 1024, + .ih_flags = 0, + .ih_ver = { 1, 2, 3, 432 }, + }; struct boot_req req = { .br_area_descs = boot_test_area_descs, .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); + boot_test_util_write_image(&hdr0, 0); + boot_test_util_write_hash(&hdr0, 0); + boot_test_util_write_image(&hdr1, 1); + + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); + TEST_ASSERT(rc == 0); rc = boot_go(&req, &rsp); - TEST_ASSERT(rc != 0); + TEST_ASSERT(rc == 0); - boot_test_util_verify_flash(&hdr, 0, NULL, 0xff); + TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); + + boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); boot_test_util_verify_status_clear(); } @@ -1060,30 +1065,46 @@ TEST_CASE(boot_test_no_flag_has_hash) struct boot_rsp rsp; int rc; - struct image_header hdr = { + struct image_header hdr0 = { .ih_magic = IMAGE_MAGIC, .ih_tlv_size = 4 + 32, .ih_hdr_size = BOOT_TEST_HEADER_SIZE, .ih_img_size = 12 * 1024, - .ih_flags = 0, + .ih_flags = IMAGE_F_SHA256, .ih_ver = { 0, 2, 3, 4 }, }; + struct image_header hdr1 = { + .ih_magic = IMAGE_MAGIC, + .ih_tlv_size = 4 + 32, + .ih_hdr_size = BOOT_TEST_HEADER_SIZE, + .ih_img_size = 32 * 1024, + .ih_flags = 0, + .ih_ver = { 1, 2, 3, 432 }, + }; struct boot_req req = { .br_area_descs = boot_test_area_descs, .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); - boot_test_util_write_hash(&hdr, 0); + boot_test_util_write_image(&hdr0, 0); + boot_test_util_write_hash(&hdr0, 0); + boot_test_util_write_image(&hdr1, 1); + boot_test_util_write_hash(&hdr1, 1); + + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); + TEST_ASSERT(rc == 0); rc = boot_go(&req, &rsp); - TEST_ASSERT(rc != 0); + TEST_ASSERT(rc == 0); - boot_test_util_verify_flash(&hdr, 0, NULL, 0xff); + TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); + + boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); boot_test_util_verify_status_clear(); } @@ -1092,7 +1113,7 @@ TEST_CASE(boot_test_invalid_hash) struct boot_rsp rsp; int rc; - struct image_header hdr = { + struct image_header hdr0 = { .ih_magic = IMAGE_MAGIC, .ih_tlv_size = 4 + 32, .ih_hdr_size = BOOT_TEST_HEADER_SIZE, @@ -1100,12 +1121,21 @@ TEST_CASE(boot_test_invalid_hash) .ih_flags = IMAGE_F_SHA256, .ih_ver = { 0, 2, 3, 4 }, }; + struct image_header hdr1 = { + .ih_magic = IMAGE_MAGIC, + .ih_tlv_size = 4 + 32, + .ih_hdr_size = BOOT_TEST_HEADER_SIZE, + .ih_img_size = 32 * 1024, + .ih_flags = 0, + .ih_ver = { 1, 2, 3, 432 }, + }; struct boot_req req = { .br_area_descs = boot_test_area_descs, .br_slot_areas = boot_test_slot_areas, .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1, .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH, + .br_img_sz = (384 * 1024), }; struct image_tlv tlv = { @@ -1113,16 +1143,23 @@ TEST_CASE(boot_test_invalid_hash) .it_len = 32 }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); - rc = hal_flash_write(boot_test_img_addrs[0].flash_id, - boot_test_img_addrs[0].address + hdr.ih_hdr_size + hdr.ih_img_size, + boot_test_util_write_image(&hdr0, 0); + boot_test_util_write_hash(&hdr0, 0); + boot_test_util_write_image(&hdr1, 1); + rc = hal_flash_write(boot_test_img_addrs[1].flash_id, + boot_test_img_addrs[1].address + hdr1.ih_hdr_size + hdr1.ih_img_size, &tlv, sizeof(tlv)); TEST_ASSERT(rc == 0); + rc = boot_vect_write_test(FLASH_AREA_IMAGE_1); + TEST_ASSERT(rc == 0); + rc = boot_go(&req, &rsp); - TEST_ASSERT(rc != 0); + TEST_ASSERT(rc == 0); - boot_test_util_verify_flash(&hdr, 0, NULL, 0xff); + TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); + + boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); boot_test_util_verify_status_clear(); } diff --git a/libs/imgmgr/src/imgmgr.c b/libs/imgmgr/src/imgmgr.c index 5e8539a1..ebdf1a81 100644 --- a/libs/imgmgr/src/imgmgr.c +++ b/libs/imgmgr/src/imgmgr.c @@ -28,6 +28,7 @@ #include <util/base64.h> #include <bootutil/image.h> +#include <bootutil/bootutil_misc.h> #include "imgmgr/imgmgr.h" #include "imgmgr_priv.h" @@ -494,5 +495,8 @@ imgmgr_module_init(void) rc = nmgr_group_register(&imgr_nmgr_group); assert(rc == 0); + + boot_vect_write_main(); + return rc; } diff --git a/libs/imgmgr/src/imgmgr_boot.c b/libs/imgmgr/src/imgmgr_boot.c index e678b74b..f636a5e1 100644 --- a/libs/imgmgr/src/imgmgr_boot.c +++ b/libs/imgmgr/src/imgmgr_boot.c @@ -63,6 +63,7 @@ imgr_boot_read(struct nmgr_jbuf *njb) { int rc; struct json_encoder *enc; + int slot; struct image_version ver; struct json_value jv; uint8_t hash[IMGMGR_HASH_LEN]; @@ -71,14 +72,20 @@ imgr_boot_read(struct nmgr_jbuf *njb) json_encode_object_start(enc); - rc = boot_vect_read_test(&ver); + rc = boot_vect_read_test(&slot); if (!rc) { - imgr_ver_jsonstr(enc, "test", &ver); + rc = imgr_read_info(slot, &ver, hash); + if (!rc) { + imgr_ver_jsonstr(enc, "test", &ver); + } } - rc = boot_vect_read_main(&ver); + rc = boot_vect_read_main(&slot); if (!rc) { - imgr_ver_jsonstr(enc, "main", &ver); + rc = imgr_read_info(slot, &ver, hash); + if (!rc) { + imgr_ver_jsonstr(enc, "main", &ver); + } } rc = imgr_read_info(bsp_imgr_current_slot(), &ver, hash); @@ -132,12 +139,11 @@ imgr_boot_write(struct nmgr_jbuf *njb) rc = NMGR_ERR_EINVAL; goto err; } - rc = boot_vect_write_test(&ver); + rc = boot_vect_write_test(rc); if (rc) { rc = NMGR_ERR_EINVAL; goto err; } - enc = &njb->njb_enc; json_encode_object_start(enc); @@ -162,22 +168,23 @@ imgr_boot2_read(struct nmgr_jbuf *njb) struct image_version ver; struct json_value jv; uint8_t hash[IMGMGR_HASH_LEN]; + int slot; enc = &njb->njb_enc; json_encode_object_start(enc); - rc = boot_vect_read_test(&ver); + rc = boot_vect_read_test(&slot); if (!rc) { - rc = imgr_find_by_ver(&ver, hash); + rc = imgr_read_info(slot, &ver, hash); if (rc >= 0) { imgr_hash_jsonstr(enc, "test", hash); } } - rc = boot_vect_read_main(&ver); + rc = boot_vect_read_main(&slot); if (!rc) { - rc = imgr_find_by_ver(&ver, hash); + rc = imgr_read_info(slot, &ver, hash); if (rc >= 0) { imgr_hash_jsonstr(enc, "main", hash); } @@ -226,11 +233,12 @@ imgr_boot2_write(struct nmgr_jbuf *njb) base64_decode(hash_str, hash); rc = imgr_find_by_hash(hash, &ver); if (rc >= 0) { - rc = boot_vect_write_test(&ver); + rc = boot_vect_write_test(rc); if (rc) { rc = NMGR_ERR_EUNKNOWN; goto err; } + rc = 0; } else { rc = NMGR_ERR_EINVAL; goto err; diff --git a/libs/mbedtls/include/mbedtls/config_mynewt.h b/libs/mbedtls/include/mbedtls/config_mynewt.h index d200879c..a18ac6f7 100644 --- a/libs/mbedtls/include/mbedtls/config_mynewt.h +++ b/libs/mbedtls/include/mbedtls/config_mynewt.h @@ -40,6 +40,8 @@ #undef MBEDTLS_SELF_TEST #endif +#define MBEDTLS_SHA256_SMALLER /* comes with performance hit */ + /** * \name SECTION: Module configuration options * |