Skip to content

Add support for rp2350 and dynamic flash sizing. Update to modern SDK. #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 30 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@

cmake_minimum_required(VERSION 3.13)

if(${PICO_PLATFORM} STREQUAL "rp2350-arm-s")
set(CPU "2350")
else()
set(CPU "2040")
endif()

########################################
# CMake options
########################################
Expand All @@ -30,6 +36,18 @@ option(PFB_WITH_IMAGE_ENCRYPTION "Enables image encryption using AES ECB algorit
option(PFB_AES_KEY "AES key used for image encryption and decryption")
option(PFB_WITH_SHA256_HASHING "Enables image SHA256 appending and checking" ON)

if ( NOT PFB_RESERVED_FILESYSTEM_SIZE_KB )
set(PFB_RESERVED_FILESYSTEM_SIZE_KB 0)
endif()

########################################
# Build linker definitions
########################################
# PICO_FLASH_SIZE_BYTES
execute_process(
COMMAND cat ${CMAKE_CURRENT_LIST_DIR}/linker_common/linker_definitions.in
COMMAND ${CMAKE_C_COMPILER} -DFLASH_SIZE=${PICO_FLASH_SIZE_BYTES} -DFILESYSTEM_SIZE=${PFB_RESERVED_FILESYSTEM_SIZE_KB} -E -P -o ${CMAKE_BINARY_DIR}/linker_definitions.ld -
)
########################################
# Check and set AES key
########################################
Expand Down Expand Up @@ -66,7 +84,7 @@ target_link_libraries(pico_fota_bootloader_lib PUBLIC
target_link_libraries(pico_fota_bootloader_lib PRIVATE
pico_mbedtls)
target_link_options(pico_fota_bootloader_lib PRIVATE
"-T${CMAKE_CURRENT_SOURCE_DIR}/linker_common/linker_definitions.ld")
"-T${CMAKE_CURRENT_BINARY_DIR}/linker_definitions.ld")

if (PFB_WITH_IMAGE_ENCRYPTION)
target_compile_definitions(pico_fota_bootloader_lib PRIVATE PFB_WITH_IMAGE_ENCRYPTION)
Expand All @@ -82,8 +100,14 @@ set(BOOTLOADER_DIR_GLOBAL ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
# Manage application binary
########################################
function(pfb_compile_with_bootloader Target)
target_link_options(${Target} PRIVATE "-L${BOOTLOADER_DIR_GLOBAL}/linker_common")
pico_set_linker_script(${Target} ${BOOTLOADER_DIR_GLOBAL}/linker_common/application.ld)
if(${PICO_PLATFORM} STREQUAL "rp2350-arm-s")
set(CPU "2350")
else()
set(CPU "2040")
endif()

target_link_options(${Target} PRIVATE "-L${BOOTLOADER_DIR_GLOBAL}/linker_common" "-L${CMAKE_CURRENT_BINARY_DIR}")
pico_set_linker_script(${Target} ${BOOTLOADER_DIR_GLOBAL}/linker_common/app${CPU}.ld)

if (PFB_WITH_SHA256_HASHING OR PFB_WITH_IMAGE_ENCRYPTION)
find_package(Python COMPONENTS Interpreter REQUIRED)
Expand Down Expand Up @@ -134,13 +158,14 @@ function (target_compile_link_options Name Option)
target_link_options(${Name} PRIVATE ${Option})
endfunction ()

target_compile_definitions(pico_fota_bootloader PRIVATE -DPICO_PLATFORM=${PICO_PLATFORM})
target_compile_link_options(pico_fota_bootloader "-Os")
target_compile_link_options(pico_fota_bootloader "-ffunction-sections")
target_compile_link_options(pico_fota_bootloader "-fdata-sections")
target_compile_link_options(pico_fota_bootloader "-L${CMAKE_CURRENT_SOURCE_DIR}/linker_common")
target_compile_link_options(pico_fota_bootloader "-L${CMAKE_CURRENT_SOURCE_DIR}/linker_common" "-L${CMAKE_CURRENT_BINARY_DIR}")
target_link_options(pico_fota_bootloader PRIVATE "LINKER:--gc-sections")

pico_set_linker_script(pico_fota_bootloader ${CMAKE_CURRENT_SOURCE_DIR}/linker_common/bootloader.ld)
pico_set_linker_script(pico_fota_bootloader ${CMAKE_CURRENT_SOURCE_DIR}/linker_common/boot${CPU}.ld)
pico_add_extra_outputs(pico_fota_bootloader)

########################################
Expand Down
8 changes: 8 additions & 0 deletions bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@
#include <stdio.h>
#include <string.h>

#if PICO_PLATFORM == rp2350-arm-s
#include <RP2350.h>
#else
#include <RP2040.h>
#endif
Comment on lines +26 to +30
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't do such comparison on preprocesor macro. Even if PICO_PLATFORM is equal to "rp2040", the #if PICO_PLATFORM == rp2350-arm-s will be evaluated to true and the build will fail.

You should use some other preprocesor constants or create compile-time definitions like PICO_PLATFORM_RP2040 in CMakeLists.txt file.


#include <hardware/flash.h>
#include <hardware/resets.h>
#include <hardware/sync.h>
#include <pico/stdlib.h>

#include <pico_fota_bootloader.h>
#include <stdlib.h>

#include "linker_common/linker_definitions.h"

Expand Down Expand Up @@ -115,6 +121,7 @@ static void jump_to_vtor(uint32_t vtor) {

static void print_welcome_message(void) {
#ifdef PFB_WITH_BOOTLOADER_LOGS
uint32_t space = PFB_ADDR_AS_U32(__FLASH_SWAP_SPACE_LENGTH) / 1024;
puts("");
puts("***********************************************************");
puts("* *");
Expand All @@ -123,6 +130,7 @@ static void print_welcome_message(void) {
puts("* *");
puts("***********************************************************");
puts("");
printf("Maximum code length: %luK\r\n", space);
#endif // PFB_WITH_BOOTLOADER_LOGS
}

Expand Down
128 changes: 80 additions & 48 deletions linker_common/application.ld → linker_common/app2040.ld
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Based on pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld file */
/* Based on pico-sdk/src/rp2_common/pico_crt0/rp2040/memmap_default.ld */

INCLUDE linker_definitions.ld

Expand Down Expand Up @@ -43,6 +43,27 @@ SECTIONS
*(SORT(.dtors.*))
*(.dtors)

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
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 = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);

*(.eh_frame*)
. = ALIGN(4);
} > FLASH
Expand Down Expand Up @@ -77,13 +98,15 @@ SECTIONS
__binary_info_end = .;
. = ALIGN(4);

/* End of .text-like segments */
__etext = .;

.ram_vector_table (COPY): {
.ram_vector_table (COPY): {
*(.ram_vector_table)
} > RAM

.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM

.data : {
__data_start__ = .;
*(vtable)
Expand All @@ -108,38 +131,51 @@ SECTIONS
PROVIDE_HIDDEN (__mutex_array_end = .);

. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
*(.jcr)
. = ALIGN(4);
} > RAM AT> FLASH

.tdata : {
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);

/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);

.tbss (NOLOAD) : {
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)

*(.jcr)
__tls_end = .;
} > RAM

.bss (NOLOAD) : {
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM AT> FLASH
__data_source__ = LOADADDR(.data);
__tbss_end = .;

.uninitialized_data (COPY): {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
*(.uninitialized_data*)
__bss_end__ = .;
} > RAM

.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
} > RAM
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
__HeapLimit = ORIGIN(RAM) + LENGTH(RAM);

/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
Expand All @@ -157,23 +193,6 @@ SECTIONS
} > SCRATCH_Y AT > FLASH
__scratch_y_source__ = LOADADDR(.scratch_y);

.bss : {
. = ALIGN(4);
__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > 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
Expand All @@ -183,21 +202,22 @@ SECTIONS
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (COPY):
.stack1_dummy (NOLOAD):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (COPY):
.stack_dummy (NOLOAD):
{
*(.stack*)
KEEP(*(.stack*))
} > SCRATCH_Y

.flash_end : {
KEEP(*(.embedded_end_block*))
/* Align binary size to 256 bytes */
. = . + 1;
. = ALIGN(256) - 1;
BYTE(0);
__flash_binary_end = .;
PROVIDE(__flash_binary_end = .);
} > FLASH

/* stack limit is poorly named, but historically is maximum heap ptr */
Expand All @@ -208,9 +228,21 @@ SECTIONS
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);

/* picolibc and LLVM */
PROVIDE (__heap_start = __end__);
PROVIDE (__heap_end = __HeapLimit);
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );

/* llvm-libc */
PROVIDE (_end = __end__);
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")

ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
/* todo assert on extra code */
}

Loading