added bootloader target and auto combining par runner with stock bootloader

pull/1/head
Piotr Lewandowski 2023-06-25 19:24:02 +02:00
rodzic 4c833d8bfc
commit 1c79b4de00
15 zmienionych plików z 43 dodań i 484 usunięć

Wyświetl plik

@ -1,2 +1,3 @@
add_subdirectory(orginal_fw)
add_subdirectory(par_runner)
# add_subdirectory(ocl_loader)

Wyświetl plik

@ -1,62 +0,0 @@
set(NAME ocl_loader)
set(MCU_TARGET_FILES_DIR ../mcu_target_common)
add_executable(${NAME}
main.c
)
target_link_libraries(${NAME}
mcu_drivers
)
target_include_directories(${NAME} PUBLIC
./
Drivers/CMSIS/Device/ST/STM32G0xx/Include
Drivers/CMSIS/DSP/Include
Drivers/CMSIS/Include
)
target_compile_definitions(${NAME} PRIVATE
${STM32_DEFINES}
$<$<CONFIG:Debug>:DEBUG_ENABLED>
)
target_compile_options(${NAME} PRIVATE
-mthumb -mcpu=cortex-m0plus -mfpu=auto -mfloat-abi=soft -fno-exceptions
-msoft-float -Wall $<$<COMPILE_LANGUAGE:CXX>:-Wno-register> -Wno-unknown-pragmas
-O${OPTI_FLAG} $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
$<$<CONFIG:Debug>:--debug -DDEBUG>
-ffunction-sections -fdata-sections -gdwarf-3
-nostartfiles -fno-strict-aliasing
)
target_link_options(${NAME} PRIVATE
#-print-multi-lib
-T ${CMAKE_CURRENT_SOURCE_DIR}/ram.lds #${CMAKE_SOURCE_DIR}/
-mcpu=cortex-m0plus
-mthumb
-mfpu=auto
-mfloat-abi=soft #lets go fpu
-specs=nosys.specs
-specs=nano.specs
-lc
-lm
-lnosys
-Wl,-Map=${PROJECT_NAME}.map,--cref
-Wl,--gc-sections
-Wl,--print-memory-usage
-Wstack-usage=128
-Wno-register
)
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND arm-none-eabi-size ${NAME}
)
#convert to hex
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND arm-none-eabi-objcopy -O ihex ${NAME} ${NAME}.hex
COMMAND arm-none-eabi-objcopy -O binary ${NAME} ${NAME}.bin
)

Wyświetl plik

@ -1,189 +0,0 @@
#include "registers.hpp"
#include <stdint.h>
#include "stm32l4x.h"
static inline __attribute__((always_inline))
void copy_buffer_u32(uint32_t *dst, uint32_t *src, int len)
{
for (int i = 0; i < len; i++)
dst[i] = src[i];
}
/* this function is assumes that fifo_size is multiple of flash_word_size
* this condition is ensured by target_run_flash_async_algorithm
*/
void write(volatile struct stm32l4_work_area *work_area,
uint8_t *fifo_end,
uint8_t *target_address,
uint32_t count)
{
volatile uint32_t *flash_sr = (uint32_t *) work_area->params.flash_sr_addr;
volatile uint32_t *flash_cr = (uint32_t *) work_area->params.flash_cr_addr;
/* optimization to avoid reading from memory each time */
uint8_t *rp_cache = work_area->fifo.rp;
/* fifo_start is used to wrap when we reach fifo_end */
uint8_t *fifo_start = rp_cache;
/* enable flash programming */
*flash_cr = FLASH_PG;
while (count) {
/* optimization to avoid reading from memory each time */
uint8_t *wp_cache = work_area->fifo.wp;
if (wp_cache == 0)
break; /* aborted by target_run_flash_async_algorithm */
int32_t fifo_size = wp_cache - rp_cache;
if (fifo_size < 0) {
/* consider the linear fifo, we will wrap later */
fifo_size = fifo_end - rp_cache;
}
/* wait for at least a flash word */
while (fifo_size >= work_area->params.flash_word_size) {
copy_buffer_u32((uint32_t *)target_address,
(uint32_t *)rp_cache,
work_area->params.flash_word_size / 4);
/* update target_address and rp_cache */
target_address += work_area->params.flash_word_size;
rp_cache += work_area->params.flash_word_size;
/* wait for the busy flag */
while (*flash_sr & work_area->params.flash_sr_bsy_mask)
;
if (*flash_sr & FLASH_ERROR) {
work_area->fifo.rp = 0; /* set rp to zero 0 on error */
goto write_end;
}
/* wrap if reach the fifo_end, and update rp in memory */
if (rp_cache >= fifo_end)
rp_cache = fifo_start;
/* flush the rp cache value,
* so target_run_flash_async_algorithm can fill the circular fifo */
work_area->fifo.rp = rp_cache;
/* update fifo_size and count */
fifo_size -= work_area->params.flash_word_size;
count--;
}
}
write_end:
/* disable flash programming */
*flash_cr = 0;
/* soft break the loader */
__asm("bkpt 0");
}
/* by enabling this define 'DEBUG':
* the main() function can help help debugging the loader algo
* note: the application should be linked into RAM */
/* #define DEBUG */
#ifdef DEBUG
/* device selector: STM32L5 | STM32U5 | STM32WB | STM32WL | STM32WL_CPU2 | STM32G0Bx | ... */
#define STM32U5
/* when using a secure device, and want to test the secure programming enable this define */
/* #define SECURE */
#if defined(STM32U5)
# define FLASH_WORD_SIZE 16
#else
# define FLASH_WORD_SIZE 8
#endif
#if defined(STM32WB) || defined(STM32WL)
# define FLASH_BASE 0x58004000
#else
# define FLASH_BASE 0x40022000
#endif
#if defined(STM32G0Bx)
# define FLASH_BSY_MASK (FLASH_BSY | FLASH_BSY2)
#else
# define FLASH_BSY_MASK FLASH_BSY
#endif
#if defined(STM32L5) || defined(STM32U5)
# ifdef SECURE
# define FLASH_KEYR_OFFSET 0x0c
# define FLASH_SR_OFFSET 0x24
# define FLASH_CR_OFFSET 0x2c
# else
# define FLASH_KEYR_OFFSET 0x08
# define FLASH_SR_OFFSET 0x20
# define FLASH_CR_OFFSET 0x28
# endif
#elif defined(STM32WL_CPU2)
# define FLASH_KEYR_OFFSET 0x08
# define FLASH_SR_OFFSET 0x60
# define FLASH_CR_OFFSET 0x64
#else
# define FLASH_KEYR_OFFSET 0x08
# define FLASH_SR_OFFSET 0x10
# define FLASH_CR_OFFSET 0x14
#endif
#define FLASH_KEYR (uint32_t *)((FLASH_BASE) + (FLASH_KEYR_OFFSET))
#define FLASH_SR (uint32_t *)((FLASH_BASE) + (FLASH_SR_OFFSET))
#define FLASH_CR (uint32_t *)((FLASH_BASE) + (FLASH_CR_OFFSET))
int main()
{
const uint32_t count = 2;
const uint32_t buf_size = count * FLASH_WORD_SIZE;
const uint32_t work_area_size = sizeof(struct stm32l4_work_area) + buf_size;
uint8_t work_area_buf[work_area_size];
struct stm32l4_work_area *workarea = (struct stm32l4_work_area *)work_area_buf;
/* fill the workarea struct */
workarea->params.flash_sr_addr = (uint32_t)(FLASH_SR);
workarea->params.flash_cr_addr = (uint32_t)(FLASH_CR);
workarea->params.flash_word_size = FLASH_WORD_SIZE;
workarea->params.flash_sr_bsy_mask = FLASH_BSY_MASK;
/* note: the workarea->stack is not used, in this configuration */
/* programming the existing memory raw content in workarea->fifo.buf */
/* feel free to fill the memory with magical values ... */
workarea->fifo.wp = (uint8_t *)(&workarea->fifo.buf + buf_size);
workarea->fifo.rp = (uint8_t *)&workarea->fifo.buf;
/* unlock the flash */
*FLASH_KEYR = KEY1;
*FLASH_KEYR = KEY2;
/* erase sector 0 */
*FLASH_CR = FLASH_PER | FLASH_STRT;
while (*FLASH_SR & FLASH_BSY)
;
/* flash address, should be aligned to FLASH_WORD_SIZE */
uint8_t *target_address = (uint8_t *) 0x8000000;
write(workarea,
(uint8_t *)(workarea + work_area_size),
target_address,
count);
while (1)
;
}
#endif /* DEBUG */
__attribute__ ((section(".entry"))) void entry(void)
{
main();
}

Wyświetl plik

@ -1,44 +0,0 @@
ENTRY( entry )
/* System memory map */
MEMORY
{
/* Application is stored in and executes from SRAM */
PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x1BD8
}
/* Section allocation in memory */
SECTIONS
{
.text :
{
_text = .;
*(.entry*)
*(.text*)
_etext = .;
} > PROGRAM
.data :
{ _data = .;
*(.rodata*)
*(.data*)
_edata = .;
}
.bss :
{
__bss_start__ = .;
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
__bss_end__ = .;
} > PROGRAM
.stack :
{
_stack = .;
*(.stack*)
_estack = .;
} > PROGRAM
}

Wyświetl plik

@ -1,18 +0,0 @@
#pragma once
struct TFlash
{
unsigned int CFG;
unsigned int ADDR;
unsigned int WDATA;
unsigned int START;
unsigned int ST;
unsigned int LOCK;
unsigned int UNLOCK;
unsigned int MASK;
unsigned int ERASETIME;
unsigned int PROGTIME;
};
#define FLASH_BASAE 0x4006F000
#define FLASH ((TFlash*)FLASH_BASAE)

Wyświetl plik

@ -1,152 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/***************************************************************************
* Copyright (C) 2015 by Uwe Bonnes *
* bon@elektron.ikp.physik.tu-darmstadt.de *
***************************************************************************/
#ifndef OPENOCD_FLASH_NOR_STM32L4X
#define OPENOCD_FLASH_NOR_STM32L4X
#include <stdint.h>
/* IMPORTANT: this file is included by stm32l4x driver and flashloader,
* so please when changing this file, do not forget to check the flashloader */
/* FIXME: #include "helper/bits.h" cause build errors when compiling
* the flashloader, for now just redefine the needed 'BIT 'macro */
#ifndef BIT
#define BIT(nr) (1UL << (nr))
#endif
/* FLASH_CR register bits */
#define FLASH_PG BIT(0)
#define FLASH_PER BIT(1)
#define FLASH_MER1 BIT(2)
#define FLASH_PAGE_SHIFT 3
#define FLASH_BKER BIT(11)
#define FLASH_BKER_G0 BIT(13)
#define FLASH_MER2 BIT(15)
#define FLASH_STRT BIT(16)
#define FLASH_OPTSTRT BIT(17)
#define FLASH_EOPIE BIT(24)
#define FLASH_ERRIE BIT(25)
#define FLASH_OBL_LAUNCH BIT(27)
#define FLASH_OPTLOCK BIT(30)
#define FLASH_LOCK BIT(31)
/* FLASH_SR register bits */
#define FLASH_BSY BIT(16)
#define FLASH_BSY2 BIT(17)
/* Fast programming not used => related errors not used*/
#define FLASH_PGSERR BIT(7) /* Programming sequence error */
#define FLASH_SIZERR BIT(6) /* Size error */
#define FLASH_PGAERR BIT(5) /* Programming alignment error */
#define FLASH_WRPERR BIT(4) /* Write protection error */
#define FLASH_PROGERR BIT(3) /* Programming error */
#define FLASH_OPERR BIT(1) /* Operation error */
#define FLASH_EOP BIT(0) /* End of operation */
#define FLASH_ERROR (FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | \
FLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR)
/* register unlock keys */
#define KEY1 0x45670123
#define KEY2 0xCDEF89AB
/* option register unlock key */
#define OPTKEY1 0x08192A3B
#define OPTKEY2 0x4C5D6E7F
/* FLASH_OPTR register bits */
#define FLASH_RDP_MASK 0xFF
#define FLASH_G0_DUAL_BANK BIT(21)
#define FLASH_G4_DUAL_BANK BIT(22)
#define FLASH_L4_DUAL_BANK BIT(21)
#define FLASH_L4R_DBANK BIT(22)
#define FLASH_LRR_DB1M BIT(21)
#define FLASH_L5_DBANK BIT(22)
#define FLASH_L5_DB256 BIT(21)
#define FLASH_U5_DUALBANK BIT(21)
#define FLASH_TZEN BIT(31)
/* FLASH secure block based bank 1/2 register offsets */
#define FLASH_SECBB1(X) (0x80 + 4 * (X - 1))
#define FLASH_SECBB2(X) (0xA0 + 4 * (X - 1))
#define FLASH_SECBB_SECURE 0xFFFFFFFF
#define FLASH_SECBB_NON_SECURE 0
/* IDCODE register possible addresses */
#define DBGMCU_IDCODE_G0 0x40015800
#define DBGMCU_IDCODE_L4_G4 0xE0042000
#define DBGMCU_IDCODE_L5 0xE0044000
#define UID64_DEVNUM 0x1FFF7580
#define UID64_IDS 0x1FFF7584
#define UID64_IDS_STM32WL 0x0080E115
/* Supported device IDs */
#define DEVID_STM32L47_L48XX 0x415
#define DEVID_STM32L43_L44XX 0x435
#define DEVID_STM32C01XX 0x443
#define DEVID_STM32C03XX 0x453
#define DEVID_STM32G05_G06XX 0x456
#define DEVID_STM32G07_G08XX 0x460
#define DEVID_STM32L49_L4AXX 0x461
#define DEVID_STM32L45_L46XX 0x462
#define DEVID_STM32L41_L42XX 0x464
#define DEVID_STM32G03_G04XX 0x466
#define DEVID_STM32G0B_G0CXX 0x467
#define DEVID_STM32G43_G44XX 0x468
#define DEVID_STM32G47_G48XX 0x469
#define DEVID_STM32L4R_L4SXX 0x470
#define DEVID_STM32L4P_L4QXX 0x471
#define DEVID_STM32L55_L56XX 0x472
#define DEVID_STM32G49_G4AXX 0x479
#define DEVID_STM32U57_U58XX 0x482
#define DEVID_STM32WB1XX 0x494
#define DEVID_STM32WB5XX 0x495
#define DEVID_STM32WB3XX 0x496
#define DEVID_STM32WLE_WL5XX 0x497
/* known Flash base addresses */
#define STM32_FLASH_BANK_BASE 0x08000000
#define STM32_FLASH_S_BANK_BASE 0x0C000000
/* offset between non-secure and secure flash registers */
#define STM32L5_REGS_SEC_OFFSET 0x10000000
/* 100 bytes as loader stack should be large enough for the loader to operate */
#define LDR_STACK_SIZE 100
struct stm32l4_work_area {
struct stm32l4_loader_params {
uint32_t flash_sr_addr;
uint32_t flash_cr_addr;
uint32_t flash_word_size;
uint32_t flash_sr_bsy_mask;
} params;
uint8_t stack[LDR_STACK_SIZE];
struct flash_async_algorithm_circbuf {
/* note: stm32l4_work_area struct is shared between the loader
* and stm32l4x flash driver.
*
* '*wp' and '*rp' pointers' size is 4 bytes each since stm32l4x
* devices have 32-bit processors.
* however when used in openocd code, their size depends on the host
* if the host is 32-bit, then the size is 4 bytes each.
* if the host is 64-bit, then the size is 8 bytes each.
* to avoid this size difference, change their types depending on the
* usage (pointers for the loader, and 32-bit integers in openocd code).
*/
#ifdef OPENOCD_CONTRIB_LOADERS_FLASH_STM32_STM32L4X
uint8_t *wp;
uint8_t *rp;
#else
uint32_t wp;
uint32_t rp;
#endif /* OPENOCD_CONTRIB_LOADERS_FLASH_STM32_STM32L4X */
} fifo;
};
#endif

Wyświetl plik

@ -5,11 +5,11 @@ set(ORGINAL_FW_BIN orginal_fw.bin)
set(ORGINAL_FW_VECTORS_BIN org_vectors.bin)
set(ORGINAL_FW_VECTORS_OBJ org_vectors.o)
set(ORGINAL_FW_REST0_BIN org_rest0.bin)
set(ORGINAL_FW_REST0_OBJ org_rest0.o)
set(ORGINAL_FW_REST0_BIN org_bootloader.bin)
set(ORGINAL_FW_REST0_OBJ org_bootloader.o)
set(ORGINAL_FW_REST1_BIN org_rest1.bin)
set(ORGINAL_FW_REST1_OBJ org_rest1.o)
set(ORGINAL_FW_REST1_BIN org_fw_rest.bin)
set(ORGINAL_FW_REST1_OBJ org_fw_rest.o)
add_custom_command(OUTPUT ${ORGINAL_FW_VECTORS_BIN} ${ORGINAL_FW_REST0_BIN} ${ORGINAL_FW_REST1_BIN}
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/fw_decomposer.py 48 4096 ${CMAKE_CURRENT_SOURCE_DIR}/${ORGINAL_FW_BIN} ${ORGINAL_FW_VECTORS_BIN} ${ORGINAL_FW_REST0_BIN} ${ORGINAL_FW_REST1_BIN}
@ -19,8 +19,8 @@ add_custom_command(OUTPUT ${ORGINAL_FW_VECTORS_BIN} ${ORGINAL_FW_REST0_BIN} ${OR
add_custom_command(OUTPUT ${ORGINAL_FW_VECTORS_OBJ} ${ORGINAL_FW_REST0_OBJ} ${ORGINAL_FW_REST1_OBJ}
COMMAND arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.org_vectors ${ORGINAL_FW_VECTORS_BIN} ${ORGINAL_FW_VECTORS_OBJ}
COMMAND arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.org_fw_part0 ${ORGINAL_FW_REST0_BIN} ${ORGINAL_FW_REST0_OBJ}
COMMAND arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.org_fw_part1 ${ORGINAL_FW_REST1_BIN} ${ORGINAL_FW_REST1_OBJ}
COMMAND arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.org_bootloader ${ORGINAL_FW_REST0_BIN} ${ORGINAL_FW_REST0_OBJ}
COMMAND arm-none-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.org_fw_rest ${ORGINAL_FW_REST1_BIN} ${ORGINAL_FW_REST1_OBJ}
DEPENDS ${ORGINAL_FW_VECTORS_BIN} ${ORGINAL_FW_REST0_BIN} ${ORGINAL_FW_REST1_BIN}
COMMENT "generating vector table and fw object files"
)
@ -43,4 +43,11 @@ target_link_libraries(${LIB_NAME}
${CMAKE_CURRENT_BINARY_DIR}/${ORGINAL_FW_VECTORS_OBJ}
${CMAKE_CURRENT_BINARY_DIR}/${ORGINAL_FW_REST0_OBJ}
${CMAKE_CURRENT_BINARY_DIR}/${ORGINAL_FW_REST1_OBJ}
)
set_target_properties(${LIB_NAME} PROPERTIES BOOTLOADER_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/${ORGINAL_FW_REST0_BIN})
add_custom_target(${LIB_NAME}_bootloader_flash
COMMAND openocd -f interface/cmsis-dap.cfg -f ${PROJECT_SOURCE_DIR}/openocd_scripts/dp32g030.cfg -c "write_image ${CMAKE_CURRENT_BINARY_DIR}/${ORGINAL_FW_REST0_BIN} 0" -c "halt" -c "shutdown"
DEPENDS ${ORGINAL_FW_REST0_BIN}
)

Wyświetl plik

@ -1,4 +1,5 @@
import sys
class FwDecompozer:
def __init__(self, vector_table_size, vector_table_address, file):
self.vector_table_size = vector_table_size * 4

Wyświetl plik

@ -1,8 +1,6 @@
set(NAME par_runner)
set(MCU_TARGET_FILES_DIR ../mcu_target_common)
add_subdirectory(orginal_fw)
add_executable(${NAME}
${MCU_TARGET_FILES_DIR}/stm32f030xc.s
main.cpp
@ -62,7 +60,14 @@ add_custom_command(TARGET ${NAME}
COMMAND arm-none-eabi-objcopy -O binary ${NAME} ${NAME}.bin
)
get_target_property(BOOTLOADER_BIN_PATH orginal_fw BOOTLOADER_BIN_PATH)
add_custom_command(TARGET ${NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "generating full binary with bootloader to ${NAME}_with_bootloader.bin"
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/fw_merger.py ${BOOTLOADER_BIN_PATH} ${NAME}.bin ${NAME}_with_bootloader.bin
)
add_custom_target(${NAME}_flash
COMMAND openocd -f interface/cmsis-dap.cfg -f ${PROJECT_SOURCE_DIR}/openocd_scripts/dp32g030.cfg -c "write_image ${PROJECT_SOURCE_DIR}/build/src/par_runner/par_runner.bin 0" -c "halt" -c "shutdown"
COMMAND openocd -f interface/cmsis-dap.cfg -f ${PROJECT_SOURCE_DIR}/openocd_scripts/dp32g030.cfg -c "write_image ${PROJECT_SOURCE_DIR}/build/src/par_runner/par_runner.bin 0x1000" -c "halt" -c "shutdown"
DEPENDS ${NAME}
)

Wyświetl plik

@ -0,0 +1,16 @@
import sys
def merge_files(in1, in2, out):
f1 = open(in1, 'rb')
f2 = open(in2, 'rb')
fo = open(out, 'wb')
fo.write(f1.read())
fo.write(f2.read())
fo.close()
f1.close()
f2.close()
if __name__ == '__main__':
args = sys.argv
merge_files(args[1], args[2], args[3])

Wyświetl plik

@ -11,12 +11,6 @@ _estack = 0x20001388;
SECTIONS
{
. = 0x0;
.org_fw_part0 :
{
. = ALIGN(4);
KEEP(*(.org_fw_part0))
} > FLASH
.isr_vectors :
{
. = ALIGN(4);
@ -24,10 +18,10 @@ SECTIONS
. = ALIGN(4);
} >FLASH
.org_fw_part1 :
.org_fw_rest :
{
. = ALIGN(4);
KEEP(*(.org_fw_part1))
KEEP(*(.org_fw_rest))
} > FLASH
.org_vectors :

Wyświetl plik

@ -16,7 +16,7 @@ __attribute__ ((interrupt)) static void CommonIrqWrapper()
if (pOrgVectors->Vectors[VectorNr])
{
// pOrgVectors->Vectors[VectorNr]();
}
}
}
void System::JumpToOrginalFw()
@ -26,7 +26,7 @@ void System::JumpToOrginalFw()
TVectorTable __attribute__ ((section(".isr_vectors"))) VectorTable =
{
(VoidFxPointer)&_estack,
(VoidFxPointer)&_estack,
(VoidFxPointer)&Reset_Handler,
&CommonIrqWrapper<2>,
&CommonIrqWrapper<3>,