Merge pull request #28 from dgarske/stm32h7

Thanks David!
pull/29/head
Daniele Lacamera 2019-12-17 08:36:40 +01:00 committed by GitHub
commit dc4ea1975d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 692 additions and 3 deletions

View File

@ -32,8 +32,10 @@ ifeq ($(ARCH),ARM)
ifeq ($(TARGET),stm32f7)
ARCH_FLASH_OFFSET=0x08000000
else
ARCH_FLASH_OFFSET=0x0
endif
ifeq ($(TARGET),stm32h7)
ARCH_FLASH_OFFSET=0x08000000
endif
## Cortex-M CPU

View File

@ -0,0 +1,22 @@
ARCH?=ARM
TARGET?=stm32h7
SIGN?=ECC256
DEBUG?=0
VTOR?=1
CORTEX_M0?=0
NO_ASM?=0
EXT_FLASH?=0
SPI_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=0
WOLFBOOT_VERSION?=1
V?=0
SPMATH?=1
RAM_CODE?=1
DUALBANK_SWAP?=0
IMAGE_HEADER_SIZE?=256
WOLFBOOT_PARTITION_SIZE?=0xD0000
WOLFBOOT_SECTOR_SIZE?=0x20000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8020000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x80F0000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81C0000

View File

@ -263,7 +263,7 @@ halt
OpenOCD can be either run in background (to allow remote GDB and monitor terminal connections), or
directly from command line, to execute terminal scripts.
If OpenOCD is running, local TCP port 4444 can be used to access an interactive terminal prompt.
If OpenOCD is running, local TCP port 4444 can be used to access an interactive terminal prompt. `telnet localhost 4444`
Using the following openocd commands, the initial images for wolfBoot and the test application
are loaded to flash in bank 0:
@ -309,3 +309,95 @@ From another console, connect using gdb, e.g.:
arm-none-eabi-gdb
(gdb) target remote:3333
```
## STM32H7
The STM32H7 flash geometry must be defined beforehand.
Use the "make config" operation to generate a .config file or copy the template
using `cp ./config/examples/stm32h7.config .config`.
Example 2MB partitioning on STM32-H753:
```
WOLFBOOT_SECTOR_SIZE?=0x20000
WOLFBOOT_PARTITION_SIZE?=0xD0000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8020000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x80F0000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81C0000
```
### Build Options
The STM32H7 build can be built using:
```
make TARGET=stm32h7 SIGN=ECC256
```
### Loading the firmware
OpenOCD configuration for flashing/debugging, can be copied into `openocd.cfg` in your working directory:
Note: May require OpenOCD 0.10.0 or greater for the STM32H7x support.
```
source [find interface/stlink.cfg]
source [find target/stm32h7x.cfg]
$_CHIPNAME.cpu0 configure -event reset-init {
mmw 0xe0042004 0x7 0x0
}
init
reset
halt
```
OpenOCD can be either run in background (to allow remote GDB and monitor terminal connections), or
directly from command line, to execute terminal scripts.
If OpenOCD is running, local TCP port 4444 can be used to access an interactive terminal prompt.
Using the following openocd commands, the initial images for wolfBoot and the test application
are loaded to flash in bank 0:
```
telnet localhost 4444
flash write_image unlock erase wolfboot.bin 0x08000000
flash verify_bank 0 wolfboot.bin
flash write_image unlock erase test-app/image_v1_signed.bin 0x08020000
flash verify_bank 0 test-app/image_v1_signed.bin 0x20000
reset
resume 0x08000000
```
To sign the same application image as new version (2), use the python script `sign.py` provided:
```
tools/keytools/sign.py test-app/image.bin ecc256.der 2
```
From OpenOCD, the updated image (version 2) can be flashed to the second bank:
```
flash write_image unlock erase test-app/image_v2_signed.bin 0x08120000
flash verify_bank 0 test-app/image_v1_signed.bin 0x20000
```
Upon reboot, wolfboot will elect the best candidate (version 2 in this case) and authenticate the image.
If the accepted candidate image resides on BANK B (like in this case), wolfBoot will perform one bank swap before
booting.
### Debugging
Debugging with OpenOCD:
Use the OpenOCD configuration from the previous section to run OpenOCD.
From another console, connect using gdb, e.g.:
```
arm-none-eabi-gdb
(gdb) target remote:3333
(gdb) add-symbol-file test-app/image.elf 0x08020000
(gdb) add-symbol-file wolfboot.elf 0x08000000
```

429
hal/stm32h7.c 100644
View File

@ -0,0 +1,429 @@
/* stm32h7.c
*
* Copyright (C) 2019 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdint.h>
#include <image.h>
/* Assembly helpers */
#define DMB() __asm__ volatile ("dmb")
#define ISB() __asm__ volatile ("isb")
#define DSB() __asm__ volatile ("dsb")
/* STM32 H7 register configuration */
/*** RCC ***/
#define RCC_BASE (0x58024400) //RM0433 - Table 8
#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) //RM0433 - 7.7.2
#define RCC_PLLCKSELR (*(volatile uint32_t *)(RCC_BASE + 0x28)) //RM0433 - 7.7.11
#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x2C)) //RM0433 - 7.7.12
#define RCC_PLL1DIVR (*(volatile uint32_t *)(RCC_BASE + 0x30)) //RM0433 - 7.7.13
#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x10)) //RM0433 - 7.7.7
#define RCC_D1CFGR (*(volatile uint32_t *)(RCC_BASE + 0x18)) //RM0433 - 7.7.8
#define RCC_D2CFGR (*(volatile uint32_t *)(RCC_BASE + 0x1C)) //RM0433 - 7.7.8
#define RCC_D3CFGR (*(volatile uint32_t *)(RCC_BASE + 0x20)) //RM0433 - 7.7.9
#define APB1_CLOCK_LER (*(volatile uint32_t *)(RCC_BASE + 0xE8)) //RM0433 - 7.7.45
#define APB1_CLOCK_HER (*(volatile uint32_t *)(RCC_BASE + 0xEC)) //RM0433 - 7.7.46
#define APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xF0)) //RM0433 - 7.7.47
#define RCC_CR_PLL1RDY (1 << 25)
#define RCC_CR_PLL1ON (1 << 24)
#define RCC_CR_HSEBYP (1 << 18)
#define RCC_CR_HSERDY (1 << 17)
#define RCC_CR_HSEON (1 << 16)
#define RCC_CR_HSIRDY (1 << 2)
#define RCC_CR_HSION (1 << 0)
#define RCC_CFGR_SW_HSISYS 0x0
#define RCC_CFGR_SW_PLL 0x3
#define RCC_PLLCFGR_DIVR1EN (1 << 18)
#define RCC_PLLCFGR_DIVQ1EN (1 << 17)
#define RCC_PLLCFGR_DIVP1EN (1 << 16)
#define RCC_PLLCFGR_PLL1VCOSEL (1 << 1)
#define RCC_PLLCFGR_PLL1RGE_2_4 0x1
#define RCC_PLLCFGR_PLL1RGE_SHIFT 0x2
#define RCC_PLLCKSELR_DIVM1 (1 << 4)
#define RCC_PLLCKSELR_PLLSRC_HSI 0x0
#define RCC_PLLCKSELR_PLLSRC_HSE 0x2
#define RCC_PLLCKSELR_DIVM1_NONE 0x1
/*** PWR ***/
#define PWR_BASE (0x58024800) //RM0433 - Table 8
#define PWR_CSR1 (*(volatile uint32_t *)(PWR_BASE + 0x04)) //RM0433 - 5.8.x
#define PWR_CSR1_ACTVOSRDY (1 << 13)
#define PWR_CR3 (*(volatile uint32_t *)(PWR_BASE + 0x0C)) //RM0433 - 5.8.4
#define PWR_CR3_SCUEN (1 << 2)
#define PWR_CR3_LDOEN (1 << 1)
#define PWR_D3CR (*(volatile uint32_t *)(PWR_BASE + 0x18)) //RM0433 - 5.8.6
#define PWR_D3CR_VOSRDY (1 << 13)
#define PWR_D3CR_VOS_SHIFT (14)
#define PWR_D3CR_VOS_SCALE_1 (3)
#define SYSCFG_BASE (0x58000400) //RM0433 - Table 8
#define SYSCFG_PWRCR (*(volatile uint32_t *)(SYSCFG_BASE + 0x04)) //RM0433 - 5.8.4
#define SYSCFG_PWRCR_ODEN (1 << 0)
/*** APB PRESCALER ***/
#define RCC_PRESCALER_DIV_NONE 0
#define RCC_PRESCALER_DIV_2 8
/*** FLASH ***/
#define SYSCFG_APB4_CLOCK_ER_VAL (1 << 0) //RM0433 - 7.7.48 - RCC_APB4ENR - SYSCFGEN
#define FLASH_BASE (0x52002000) //RM0433 - Table 8
#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) //RM0433 - 3.9.1 - FLASH_ACR
/*bank 1 */
#define FLASH_KEYR1 (*(volatile uint32_t *)(FLASH_BASE + 0x04)) //RM0433 - 3.9.2 - FLASH_KEYR 1
#define FLASH_SR1 (*(volatile uint32_t *)(FLASH_BASE + 0x10)) //RM0433 - 3.9.5 - FLASH_SR 1
#define FLASH_CR1 (*(volatile uint32_t *)(FLASH_BASE + 0x0C)) //RM0433 - 3.9.4 - FLASH_CR 1
/*bank 2 */
#define FLASH_KEYR2 (*(volatile uint32_t *)(FLASH_BASE + 0x104)) //RM0433 - 3.9.24 - FLASH_KEYR 2
#define FLASH_SR2 (*(volatile uint32_t *)(FLASH_BASE + 0x110)) //RM0433 - 3.9.26 - FLASH_SR 2
#define FLASH_CR2 (*(volatile uint32_t *)(FLASH_BASE + 0x10C)) //RM0433 - 3.9.25 - FLASH_CR 2
#define FLASHMEM_ADDRESS_SPACE (0x08000000)
#define FLASH_PAGE_SIZE (0x20000) /* 128KB */
#define FLASH_BANK2_BASE (0x08100000UL) /*!< Base address of : (up to 1 MB) Flash Bank2 accessible over AXI */
#define FLASH_TOP (0x081FFFFFUL) /*!< FLASH end address */
/* Register values */
#define FLASH_ACR_LATENCY_MASK (0x07)
#define FLASH_SR_BSY (1 << 0)
#define FLASH_SR_WBNE (1 << 1)
#define FLASH_SR_QW (1 << 2)
#define FLASH_SR_WRPERR (1 << 17)
#define FLASH_SR_PGSERR (1 << 18)
#define FLASH_SR_STRBERR (1 << 19)
#define FLASH_SR_INCERR (1 << 21)
#define FLASH_SR_OPERR (1 << 22)
#define FLASH_SR_RDPERR (1 << 23)
#define FLASH_SR_RDSERR (1 << 24)
#define FLASH_SR_SNECCERR (1 << 25)
#define FLASH_SR_DBECCERR (1 << 26)
#define FLASH_SR_EOP (1 << 16)
#define FLASH_CR_LOCK (1 << 0) //RM0433 - 3.7.5 - FLASH_CR
#define FLASH_CR_STRT (1 << 7)
#define FLASH_CR_PSIZE (1 << 4)
#define FLASH_CR_BER (1 << 3)
#define FLASH_CR_SER (1 << 2)
#define FLASH_CR_PG (1 << 1)
#define FLASH_CR2_SPSS2 (1 << 14)
#define FLASH_CR_SNB_SHIFT 8 //SNB bits 10:8
#define FLASH_CR_SNB_MASK 0x7 //SNB bits 10:8 - 3 bits
#define FLASH_KEY1 (0x45670123)
#define FLASH_KEY2 (0xCDEF89AB)
static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
{
uint32_t reg = FLASH_ACR;
if ((reg & FLASH_ACR_LATENCY_MASK) != waitstates)
FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates ;
}
static RAMFUNCTION void flash_wait_complete(uint8_t bank)
{
if(bank==0)
while ((FLASH_SR1 & FLASH_SR_QW) == FLASH_SR_QW);
if(bank==1)
while ((FLASH_SR2 & FLASH_SR_QW) == FLASH_SR_QW);
}
static void RAMFUNCTION flash_clear_errors(uint8_t bank)
{
if(bank==0)
FLASH_SR1 |= ( FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR | FLASH_SR_INCERR | FLASH_SR_OPERR |FLASH_SR_RDPERR | FLASH_SR_RDSERR | FLASH_SR_SNECCERR|FLASH_SR_DBECCERR ) ;
if(bank==1)
FLASH_SR2 |= ( FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR | FLASH_SR_INCERR | FLASH_SR_OPERR |FLASH_SR_RDPERR | FLASH_SR_RDSERR | FLASH_SR_SNECCERR|FLASH_SR_DBECCERR ) ;
}
int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
{
int i = 0, ii =0;
uint32_t *src, *dst, reg;
uint8_t bank=0;
flash_clear_errors(0);
flash_clear_errors(1);
src = (uint32_t *)data;
dst = (uint32_t *)(address + FLASHMEM_ADDRESS_SPACE);
while (i < len) {
if (dst < (uint32_t *)(FLASH_BANK2_BASE) )
{
bank=0;
FLASH_CR1 |= FLASH_CR_PG;
}
if( dst>=((uint32_t *)(FLASH_BANK2_BASE)) && dst <= ((uint32_t *)(FLASH_TOP)))
{
bank=1;
FLASH_CR2 |= FLASH_CR_PG;
}
ISB();
DSB();
for(ii=0; ii<8;ii++)
{
*dst=*src;
dst++;
src++;
}
ISB();
DSB();
flash_wait_complete(bank);
if(bank==0)
FLASH_CR1 &= ~FLASH_CR_PG;
if(bank==1)
FLASH_CR2 &= ~FLASH_CR_PG;
i+=32;
}
return 0;
}
void RAMFUNCTION hal_flash_unlock(void)
{
flash_wait_complete(1);
if ((FLASH_CR1 & FLASH_CR_LOCK) != 0) {
FLASH_KEYR1 = FLASH_KEY1;
DMB();
FLASH_KEYR1 = FLASH_KEY2;
DMB();
while ((FLASH_CR1 & FLASH_CR_LOCK) != 0)
;
}
flash_wait_complete(2);
if ((FLASH_CR2 & FLASH_CR_LOCK) != 0) {
FLASH_KEYR2 = FLASH_KEY1;
DMB();
FLASH_KEYR2 = FLASH_KEY2;
DMB();
while ((FLASH_CR2 & FLASH_CR_LOCK) != 0)
;
}
}
void RAMFUNCTION hal_flash_lock(void)
{
flash_wait_complete(1);
if ((FLASH_CR1 & FLASH_CR_LOCK) == 0)
FLASH_CR1 |= FLASH_CR_LOCK;
flash_wait_complete(2);
if ((FLASH_CR2 & FLASH_CR_LOCK) == 0)
FLASH_CR2 |= FLASH_CR_LOCK;
}
int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
{
uint32_t end_address;
uint32_t p;
if (len == 0)
return -1;
end_address = address + len - 1;
for (p = address; p < end_address; p += FLASH_PAGE_SIZE) {
if (p < (FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) )
{
uint32_t reg = FLASH_CR1 & (~((FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT)|FLASH_CR_PSIZE));
FLASH_CR1 = reg | (((p >> 17) << FLASH_CR_SNB_SHIFT) | FLASH_CR_SER | 0x00);
DMB();
FLASH_CR1 |= FLASH_CR_STRT;
flash_wait_complete(1);
}
if(p>=(FLASH_BANK2_BASE -FLASHMEM_ADDRESS_SPACE) && (p <= (FLASH_TOP -FLASHMEM_ADDRESS_SPACE) ))
{
uint32_t reg = FLASH_CR2 & (~((FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT)|FLASH_CR_PSIZE));
FLASH_CR2 = reg | (((p >> 17) << FLASH_CR_SNB_SHIFT) | FLASH_CR_SER | 0x00);
DMB();
FLASH_CR2 |= FLASH_CR_STRT;
flash_wait_complete(2);
}
}
return 0;
}
static void clock_pll_off(void)
{
uint32_t reg32;
/* Select HSI as SYSCLK source. */
reg32 = RCC_CFGR;
reg32 &= ~((1 << 2) |(1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS);
DMB();
/* Turn off PLL */
RCC_CR &= ~RCC_CR_PLL1ON;
DMB();
}
/*This implementation will setup HSI RC 16 MHz as PLL Source Mux, PLLCLK as System Clock Source*/
static void clock_pll_on(int powersave)
{
uint32_t reg32;
uint32_t cpu_freq, plln, pllm, pllq, pllp, pllr, hpre, d1cpre, d1ppre,d2ppre1,d2ppre2, d3ppre , flash_waitstates;
PWR_CR3 |= PWR_CR3_LDOEN;
while ((PWR_CSR1 & PWR_CSR1_ACTVOSRDY) == 0) {};
PWR_D3CR |= (PWR_D3CR_VOS_SCALE_1 << PWR_D3CR_VOS_SHIFT);
/* Delay after setting the voltage scaling */
reg32 = PWR_D3CR;
SYSCFG_PWRCR |= SYSCFG_PWRCR_ODEN;
/* Delay after setting the voltage scaling */
reg32 = PWR_D3CR;
while ((PWR_D3CR & PWR_D3CR_VOSRDY) == 0) {};
/* Select clock parameters (CPU Speed = 480MHz) */
pllm = 1;
plln = 120;
pllp = 2;
pllq = 20;
pllr = 2;
d1cpre = RCC_PRESCALER_DIV_NONE;
hpre = RCC_PRESCALER_DIV_2;
d1ppre = (RCC_PRESCALER_DIV_2 >>1 );
d2ppre1 = (RCC_PRESCALER_DIV_2>>1);
d2ppre2 = (RCC_PRESCALER_DIV_2 >>1);
d3ppre = (RCC_PRESCALER_DIV_2 >>1);
flash_waitstates = 4;
flash_set_waitstates(flash_waitstates);
/* Enable internal high-speed oscillator. */
RCC_CR |= RCC_CR_HSION;
DMB();
while ((RCC_CR & RCC_CR_HSIRDY) == 0) {};
/* Select HSI as SYSCLK source. */
reg32 = RCC_CFGR;
reg32 &= ~((1 << 2) |(1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | RCC_CFGR_SW_HSISYS);
DMB();
/* Enable external high-speed oscillator. */
reg32 = RCC_CR;
reg32 |= RCC_CR_HSEBYP;
RCC_CR = (reg32 | RCC_CR_HSEON);
DMB();
while ((RCC_CR & RCC_CR_HSERDY) == 0) {};
/*
* Set prescalers for D1: D1CPRE, D1PPRE, HPRE
*/
RCC_D1CFGR |= (hpre << 0); //RM0433 - 7.7.8- RCC_CFGR
DMB();
reg32 = RCC_D1CFGR;
reg32 &= ~(0xF0); //don't change bits [0-3] that were previously set
RCC_D1CFGR = (reg32 | (d1ppre << 4)); //RM0433 - 7.7.8- RCC_CFGR
DMB();
reg32 = RCC_D1CFGR;
reg32 &= ~(0x100); //don't change bits [0-7]
RCC_D1CFGR = (reg32 | (d1cpre << 8)); //RM0433 - 7.7.8- RCC_CFGR
DMB();
/*
* Set prescalers for D2: D2PPRE1, D2PPRE2
*/
reg32 = RCC_D2CFGR;
reg32 &= ~(0xF0); //don't change bits [0-3]
RCC_D2CFGR = (reg32 | (d2ppre1 << 4)); //RM0433 - 7.7.8- RCC_CFGR
DMB();
reg32 = RCC_D2CFGR;
reg32 &= ~(0x100); //don't change bits [0-7]
RCC_D2CFGR = (reg32 | (d2ppre2 << 8)); //RM0433 - 7.7.8- RCC_CFGR
DMB();
/*
* Set prescalers for D3: D3PPRE
*/
reg32 = RCC_D3CFGR;
RCC_D3CFGR = (reg32 | (d3ppre << 4)); //RM0433 - 7.7.8- RCC_CFGR
DMB();
/*
* Set PLL config
*/
/*PLL Clock source selection + DIVM1*/
reg32 = RCC_PLLCKSELR;
reg32 |= RCC_PLLCKSELR_PLLSRC_HSE;
reg32 |= ((pllm) << 4);
RCC_PLLCKSELR = reg32;
DMB();
reg32 = RCC_PLL1DIVR;
reg32 |= (plln -1);
reg32 |= ((pllp - 1) << 9);
reg32 |= ((pllq - 1) << 16);
reg32 |= ((pllr - 1) << 24);
RCC_PLL1DIVR = reg32;
DMB();
RCC_PLLCFGR |= (RCC_PLLCFGR_PLL1RGE_2_4 << RCC_PLLCFGR_PLL1RGE_SHIFT);
RCC_PLLCFGR |= RCC_PLLCFGR_DIVP1EN;
RCC_PLLCFGR |= RCC_PLLCFGR_DIVQ1EN;
RCC_PLLCFGR |= RCC_PLLCFGR_DIVR1EN;
RCC_CR |= RCC_CR_PLL1ON;
DMB();
while ((RCC_CR & RCC_CR_PLL1RDY) == 0) {};
/* Select PLL as SYSCLK source. */
reg32 = RCC_CFGR;
reg32 &= ~((1 << 2) |(1 << 1) | (1 << 0));
RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL);
DMB();
/* Wait for PLL clock to be selected. */
while ((RCC_CFGR & ((1 << 2) | (1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {};
}
void hal_init(void)
{
clock_pll_on(0);
}
void hal_prepare_boot(void)
{
clock_pll_off();
}

50
hal/stm32h7.ld 100644
View File

@ -0,0 +1,50 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = ##WOLFBOOT_PARTITION_BOOT_ADDRESS##
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */
}
SECTIONS
{
.text :
{
_start_text = .;
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
. = ALIGN(4);
_end_text = .;
} > FLASH
.edidx :
{
. = ALIGN(4);
*(.ARM.exidx*)
} > FLASH
_stored_data = .;
.data : AT (_stored_data)
{
_start_data = .;
KEEP(*(.data*))
. = ALIGN(4);
KEEP(*(.ramcode))
. = ALIGN(4);
_end_data = .;
} > RAM
.bss (NOLOAD) :
{
_start_bss = .;
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > RAM
. = ALIGN(4);
}
END_STACK = ORIGIN(RAM) + LENGTH(RAM);

View File

@ -0,0 +1,94 @@
/* stm32h7.c
*
* Test bare-metal application.
*
* Copyright (C) 2019 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "system.h"
#include "hal.h"
#define AHB4_CLOCK_ER (*(volatile uint32_t *)(0x580244E0))
#define GPIOB_AHB4_CLOCK_ER (1 << 1)
#define GPIOE_AHB4_CLOCK_ER (1 << 4)
#define GPIOB_BASE 0x58020400
#define GPIOE_BASE 0x58021000
#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
#define GPIOB_PUPD (*(volatile uint32_t *)(GPIOB_BASE + 0x0c))
#define GPIOB_BSRR (*(volatile uint32_t *)(GPIOB_BASE + 0x18))
#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
#define GPIOE_MODE (*(volatile uint32_t *)(GPIOE_BASE + 0x00))
#define GPIOE_PUPD (*(volatile uint32_t *)(GPIOE_BASE + 0x0c))
#define GPIOE_BSRR (*(volatile uint32_t *)(GPIOE_BASE + 0x18))
#define GPIOE_AFL (*(volatile uint32_t *)(GPIOE_BASE + 0x20))
#define GPIOE_AFH (*(volatile uint32_t *)(GPIOE_BASE + 0x24))
#define LED_BOOT_PIN (0) //PB0 - Nucleo LD1 - Green Led
#define LED_USR_PIN (1) //PE1 - Nucleo LD2 - Yellow Led
static void boot_led_on(void)
{
uint32_t reg;
uint32_t pin = LED_BOOT_PIN;
AHB4_CLOCK_ER |= GPIOB_AHB4_CLOCK_ER;
reg = GPIOB_MODE & ~(0x03 << (pin * 2));
GPIOB_MODE = reg | (1 << (pin * 2));
reg = GPIOB_PUPD & ~(0x03 << (pin * 2));
GPIOB_PUPD = reg | (1 << (pin * 2));
GPIOB_BSRR |= (1 << pin);
}
static void boot_led_off(void)
{
GPIOB_BSRR |= (1 << (LED_BOOT_PIN + 16));
}
void usr_led_on(void)
{
uint32_t reg;
uint32_t pin = LED_USR_PIN;
AHB4_CLOCK_ER |= GPIOE_AHB4_CLOCK_ER;
reg = GPIOE_MODE & ~(0x03 << (pin * 2));
GPIOE_MODE = reg | (1 << (pin * 2));
reg = GPIOE_PUPD & ~(0x03 << (pin * 2));
GPIOE_PUPD = reg | (1 << (pin * 2));
GPIOE_BSRR |= (1 << pin);
}
void usr_led_off(void)
{
GPIOE_BSRR |= (1 << (LED_USR_PIN + 16));
}
void main(void)
{
hal_init();
boot_led_on();
usr_led_on();
boot_led_off();
while(1)
;
}