1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00
19411: cpu/gd32v: add riotboot support r=benpicco a=gschorcht

### Contribution description

This PR provides `riotboot` support for GD32V.

### Testing procedure

Use any GD32V board with a JTAG adapter and flash the bootloader:
```python
PROGRAMMER=openocd BOARD=sipeed-longan-nano make -C bootloaders/riotboot flash
```
Flash slot 0 and set `RIOT_VERSION` to 1
```python
USEMODULE=stdio_uart FEATURES_REQUIRED=riotboot RIOT_VERSION=1 \
PROGRAMMER=openocd BOARD=sipeed-longan-nano make -C tests/shell riotboot/flash-slot0
...
### Flashing Target ###
Binfile detected, adding ROM base address: 0x08000000
Flashing with IMAGE_OFFSET: 0x08001000
```
```python
> main(): This is RIOT! (Version: 1)
test_shell.
```
Flash slot 1 and set `RIOT_VERSION` to 2
```python
USEMODULE=stdio_uart FEATURES_REQUIRED=riotboot RIOT_VERSION=2 \
PROGRAMMER=openocd BOARD=sipeed-longan-nano make -C tests/shell riotboot/flash-slot1
...
### Flashing Target ###
Binfile detected, adding ROM base address: 0x08000000
Flashing with IMAGE_OFFSET: 0x08010800
```
```python
> main(): This is RIOT! (Version: 2)
test_shell.
```

### Issues/PRs references


Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
This commit is contained in:
bors[bot] 2023-04-19 12:58:03 +00:00 committed by GitHub
commit 88d1d2eb64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 143 additions and 20 deletions

View File

@ -1 +1,3 @@
CPU = gd32v
FEATURES_PROVIDED += riotboot

View File

@ -22,6 +22,7 @@ config BOARD_SEEEDSTUDIO_GD32
select HAS_PERIPH_TIMER
select HAS_PERIPH_UART
select HAS_PERIPH_USBDEV
select HAS_RIOTBOOT
select HAS_TINYUSB_DEVICE
select HAVE_SAUL_GPIO

View File

@ -23,6 +23,7 @@ config BOARD_SIPEED_LONGAN_NANO
select HAS_PERIPH_TIMER
select HAS_PERIPH_UART
select HAS_PERIPH_USBDEV
select HAS_RIOTBOOT
select HAS_TINYUSB_DEVICE
select HAVE_SAUL_GPIO

View File

@ -76,13 +76,6 @@ ifneq (,$(filter usbus_dfu tinyusb_dfu,$(USEMODULE)))
else
RIOTBOOT_LEN ?= 0x1000
endif
# Currently 2 slots are supported by default, equals in length
NUM_SLOTS ?= 2
# Take the whole flash minus RIOTBOOT_LEN and divide it by NUM_SLOTS
SLOT0_LEN ?= $(shell printf "0x%x" $$((($(ROM_LEN:%K=%*1024)-$(RIOTBOOT_LEN)) / $(NUM_SLOTS))))
SLOT1_LEN ?= $(SLOT0_LEN)
SLOT0_LEN := $(SLOT0_LEN)
SLOT1_LEN := $(SLOT1_LEN)
# JLink is able to flash any ARM CPUs
PROGRAMMERS_SUPPORTED += jlink

31
cpu/fe310/include/cpu.h Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2023 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_fe310
* @{
*
* @file
* @brief CPU specific definitions
*/
#ifndef CPU_H
#define CPU_H
#include "cpu_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* CPU_H */
/** @} */

View File

@ -1,8 +1,30 @@
RAM_START_ADDR ?= 0x20000000
RAM_LEN ?= 32K
ROM_START_ADDR ?= 0x08000000
ROM_LEN ?= 128K
ifneq (,$(filter gd32vf103%bt6 gd32vf103%bu6,$(CPU_MODEL)))
RAM_LEN ?= 32K
ROM_LEN ?= 128K
else ifneq (,$(filter gd32vf103%8t6 gd32vf103%8u6,$(CPU_MODEL)))
RAM_LEN ?= 20K
ROM_LEN ?= 64K
else ifneq (,$(filter gd32vf103%6t6 gd32vf103%6u6,$(CPU_MODEL)))
RAM_LEN ?= 10K
ROM_LEN ?= 32K
else ifneq (,$(filter gd32vf103%4t6 gd32vf103%4u6,$(CPU_MODEL)))
RAM_LEN ?= 6K
ROM_LEN ?= 16K
else
$(error CPU model $(CPU_MODEL) not supported)
endif
FW_ROM_LEN ?= $(shell printf "0x%x" $$(($(ROM_LEN:%K=%*1024))))
RIOTBOOT_HDR_LEN ?= 0x400
ifneq (,$(filter usbus_dfu tinyusb_dfu,$(USEMODULE)))
RIOTBOOT_LEN ?= 0x4000
else
RIOTBOOT_LEN ?= 0x1000
endif
LINKER_SCRIPT ?= riscv.ld

View File

@ -41,6 +41,10 @@
#define RCU_CFG0_SCS_HXTAL (1 << RCU_CFG0_SCS_Pos)
#define RCU_CFG0_SCS_PLL (2 << RCU_CFG0_SCS_Pos)
#define RCU_CFG0_SCSS_IRC8 (0 << RCU_CFG0_SCSS_Pos)
#define RCU_CFG0_SCSS_HXTAL (1 << RCU_CFG0_SCSS_Pos)
#define RCU_CFG0_SCSS_PLL (2 << RCU_CFG0_SCSS_Pos)
#define ENABLE_DEBUG 0
#include "debug.h"
@ -115,13 +119,15 @@ void gd32vf103_clock_init(void)
* configure the AHB and APB clock dividers as configure by the board */
RCU->CFG0 = (RCU_CFG0_SCS_IRC8 | CLOCK_AHB_DIV_CONF |
CLOCK_APB1_DIV_CONF | CLOCK_APB2_DIV_CONF);
while ((RCU->CFG0 & RCU_CFG0_SCSS_Msk) !=
(RCU_CFG0_SCS_IRC8 << RCU_CFG0_SCSS_Pos)) {}
while ((RCU->CFG0 & RCU_CFG0_SCSS_Msk) != RCU_CFG0_SCSS_IRC8) {}
/* disable all active clocks except IRC8 -> resets the clk configuration */
RCU->CTL &= (RCU_CTL_IRC8MCALIB_Msk | RCU_CTL_IRC8MADJ_Msk);
RCU->CTL |= RCU_CTL_IRC8MEN_Msk;
/* reset PLL multiplier, required when configured before, e.g. in riotboot */
RCU->CFG0 &= ~(RCU_CFG0_PLLMF_3_0_Msk | RCU_CFG0_PLLMF_4_Msk);
if (IS_ACTIVE(CONFIG_BOARD_HAS_HXTAL)) {
/* if the board has an HXTAL, HXTAL is used as PLL input and PREDEV0 is set */
cpu_reg_enable_bits(&RCU->CTL, RCU_CTL_HXTALEN_Msk);
@ -147,8 +153,7 @@ void gd32vf103_clock_init(void)
RCU->AHBEN &= ~RCU_AHBEN_FMCSPEN_Msk;
while ((RCU->CFG0 & RCU_CFG0_SCSS_Msk) !=
(RCU_CFG0_SCS_PLL << RCU_CFG0_SCSS_Pos)) {}
while ((RCU->CFG0 & RCU_CFG0_SCSS_Msk) != RCU_CFG0_SCSS_PLL) {}
if (IS_ACTIVE(CONFIG_BOARD_HAS_HXTAL)) {
/* disable IRCM8 clock if HXTAL is used */

49
cpu/gd32v/include/cpu.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2023 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_gd32v
* @{
*
* @file
* @brief CPU specific definitions
*/
#ifndef CPU_H
#define CPU_H
#include "cpu_conf.h"
#include "cpu_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Returns the address of running application in flash
*/
static inline uint32_t cpu_get_image_baseaddr(void)
{
extern uint8_t _start;
return (uint32_t)&_start;
}
/**
* @brief Starts another image in flash
*/
static inline void cpu_jump_to_image(uint32_t addr)
{
__asm__ volatile ("jr %0" :: "r" (addr));
}
#ifdef __cplusplus
}
#endif
#endif /* CPU_H */
/** @} */

View File

@ -14,6 +14,10 @@ ifneq (,$(ROM_START_ADDR)$(RAM_START_ADDR)$(ROM_LEN)$(RAM_LEN))
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_start_addr=$(RAM_START_ADDR)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_rom_length=$(ROM_LEN)
LINKFLAGS += $(LINKFLAGPREFIX)--defsym=_ram_length=$(RAM_LEN)
LINKFLAGS += $(if $(ROM_OFFSET),$(LINKFLAGPREFIX)--defsym=_rom_offset=$(ROM_OFFSET) \
,$(LINKFLAGPREFIX)--defsym=_rom_offset=0x0)
LINKFLAGS += $(if $(FW_ROM_LEN),$(LINKFLAGPREFIX)--defsym=_fw_rom_length=$(FW_ROM_LEN) \
,$(LINKFLAGPREFIX)--defsym=_fw_rom_length=$(ROM_LEN))
endif
ifneq (,$(ITIM_START_ADDR))

View File

@ -22,8 +22,8 @@
#include "irq_arch.h"
#ifndef CPU_H
#define CPU_H
#ifndef CPU_COMMON_H
#define CPU_COMMON_H
#ifdef __cplusplus
extern "C" {
@ -85,5 +85,5 @@ void cpu_reg_disable_bits(volatile uint32_t *reg, uint32_t mask)
}
#endif
#endif /* CPU_H */
#endif /* CPU_COMMON_H */
/** @} */

View File

@ -22,7 +22,7 @@ INCLUDE riscv_vars.ld
MEMORY
{
flash (rxai!w) : ORIGIN = _rom_start_addr, LENGTH = _rom_length
flash (rxai!w) : ORIGIN = _rom_start_addr + _rom_offset, LENGTH = _fw_rom_length
ram (wxa!ri) : ORIGIN = _ram_start_addr, LENGTH = _ram_length
itim (wxa!ri) : ORIGIN = _itim_start_addr, LENGTH = _itim_length
}

View File

@ -24,6 +24,8 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l412kb \
saml10-xpro \
saml11-xpro \
seeedstudio-gd32 \
sipeed-longan-nano \
slstk3400a \
stk3200 \
stm32f0discovery \

View File

@ -165,7 +165,7 @@ endif
ifneq (,$(filter tinyusb_dfu usbus_dfu riotboot_reset,$(USEMODULE)))
CFLAGS += -DCPU_RAM_BASE=$(RAM_START_ADDR)
CFLAGS += -DCPU_RAM_SIZE=$(RAM_LEN)
CFLAGS += -DCPU_RAM_SIZE=$(shell printf "0x%x" $$(($(RAM_LEN:%K=%*1024))))
endif
ifneq (,$(filter test_utils_netdev_eth_minimal,$(USEMODULE)))

View File

@ -5,11 +5,20 @@
# aligned according to CPU_IRQ_NUMOF (ref: cpu/cortexm_common/Makefile.include)
RIOTBOOT_HDR_LEN ?= 0x100
# Currently 2 slots are supported by default, equals in length
NUM_SLOTS ?= 2
# Take the whole flash minus RIOTBOOT_LEN and divide it by NUM_SLOTS
SLOT0_LEN ?= $(shell printf "0x%x" $$((($(ROM_LEN:%K=%*1024)-$(RIOTBOOT_LEN)) / $(NUM_SLOTS))))
SLOT1_LEN ?= $(SLOT0_LEN)
SLOT0_LEN := $(SLOT0_LEN)
SLOT1_LEN := $(SLOT1_LEN)
# By default, slot 0 is found just after RIOTBOOT_LEN. Slot 1 after
# slot 0. The values might be overridden to add more or less offset
# if needed.
SLOT0_OFFSET ?= $(RIOTBOOT_LEN)
SLOT1_OFFSET ?= $(shell echo $$(($(SLOT0_OFFSET) + $(SLOT0_LEN))))
SLOT1_OFFSET ?= $(shell printf "0x%x" $$(($(SLOT0_OFFSET) + $(SLOT0_LEN))))
CFLAGS += -DSLOT0_LEN=$(SLOT0_LEN)
CFLAGS += -DSLOT0_OFFSET=$(SLOT0_OFFSET)

View File

@ -24,7 +24,9 @@
#include <assert.h>
#include <string.h>
#include <inttypes.h>
#include <stdio.h>
#include "container.h"
#include "cpu.h"
#include "riotboot/slot.h"
#include "riotboot/hdr.h"

View File

@ -20,6 +20,8 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l412kb \
saml10-xpro \
saml11-xpro \
seeedstudio-gd32 \
sipeed-longan-nano \
slstk3400a \
stk3200 \
stm32f0discovery \