Skip to content
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
88 changes: 64 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# 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.

cmake_minimum_required(VERSION 3.13)
cmake_minimum_required(VERSION 3.13...4.0)

include(pico_sdk_import.cmake)

Expand Down Expand Up @@ -53,13 +53,21 @@ pico_set_binary_type(bootloader copy_to_ram)
set_target_properties(bootloader PROPERTIES COMPILE_FLAGS "-Wall")

pico_set_linker_script(bootloader ${CMAKE_CURRENT_SOURCE_DIR}/bootloader.ld)

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(bootloader PRIVATE DEBUG)
pico_enable_stdio_usb(bootloader 1)
endif()
if(${SKIP_BOOTLOADER_ENTRY_PIN})
message(STATUS "Skipping bootloader entry pin")
add_definitions(-DSKIP_BOOTLOADER_ENTRY_PIN)
endif()
target_link_libraries(bootloader
pico_stdlib
hardware_dma
hardware_flash
hardware_structs
hardware_resets

cmsis_core)

set(BOOTLOADER_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "")
Expand All @@ -69,15 +77,16 @@ set(BOOTLOADER_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "")
function(bootloader_define_library)
set(NAME bootloader)
set(ORIGINAL_BIN ${CMAKE_CURRENT_BINARY_DIR}/${NAME}.bin)
set(NEW_BIN ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_new.bin)
set(BIN_ASM ${CMAKE_CURRENT_BINARY_DIR}/${NAME}_bin.S)

add_custom_target(${NAME}_bin DEPENDS ${ORIGINAL_BIN})
add_custom_command(OUTPUT ${ORIGINAL_BIN} DEPENDS ${NAME} COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${NAME}> ${ORIGINAL_BIN})
add_custom_command(OUTPUT ${NEW_BIN} DEPENDS ${NAME} COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${NAME}> ${NEW_BIN})

find_package (Python3 REQUIRED COMPONENTS Interpreter)
add_custom_target(${NAME}_bin_asm DEPENDS ${BIN_ASM})
add_custom_command(OUTPUT ${BIN_ASM} DEPENDS ${ORIGINAL_BIN}
COMMAND ${Python3_EXECUTABLE} ${BOOTLOADER_DIR}/mkasm.py ${ORIGINAL_BIN} ${BIN_ASM}
add_custom_command(OUTPUT ${BIN_ASM} DEPENDS ${NEW_BIN}
COMMAND ${Python3_EXECUTABLE} ${BOOTLOADER_DIR}/mkasm.py ${NEW_BIN} ${BIN_ASM}
)

add_library(${NAME}_library INTERFACE)
Expand All @@ -92,36 +101,67 @@ bootloader_define_library()

function(bootloader_build_combined NAME)
set(APP ${NAME}_app)
set(APP_BIN ${CMAKE_CURRENT_BINARY_DIR}/${APP}.bin)
set(APP_BIN ${CMAKE_CURRENT_BINARY_DIR}/${APP}_app.bin)
set(APP_HDR ${CMAKE_CURRENT_BINARY_DIR}/${APP}_hdr.bin)

set(COMBINED ${NAME}_combined)

target_link_libraries(${NAME} bootloader_library)

pico_set_linker_script(${NAME} ${BOOTLOADER_DIR}/combined.ld)

pico_add_bin_output(${NAME})

# TODO: The hard-coded 16k here is a bit nasty
add_custom_target(${APP}_bin DEPENDS ${APP_BIN})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
pico_set_linker_script(${NAME} ${BOOTLOADER_DIR}/combined_debug.ld)
set(SKIP 44)
else()
pico_set_linker_script(${NAME} ${BOOTLOADER_DIR}/combined.ld)
set(SKIP 16)
endif()
MATH(EXPR IMAGE_HDR 0x10000000+${SKIP}*1024)
message(STATUS "IMAGE_HDR: ${IMAGE_HDR}")


# pico_add_bin_output(${NAME})

add_custom_target(${APP}_bin DEPENDS ${APP_BIN} ${NAME})
add_custom_command(OUTPUT ${APP_BIN} DEPENDS ${NAME}.bin
COMMAND dd ibs=1k iseek=16 if=${NAME}.bin of=${APP_BIN}
COMMAND dd ibs=1k skip=${SKIP} if=${NAME}.bin of=${APP_BIN}
)

# TODO: The hard-coded address here is a bit nasty
add_custom_target(${APP}_hdr DEPENDS ${APP}_bin)
add_custom_command(OUTPUT ${APP_HDR} DEPENDS ${APP_BIN}
COMMAND ${BOOTLOADER_DIR}/gen_imghdr.py -a 0x10004000 ${APP_BIN} ${APP_HDR}
)

add_custom_target(${COMBINED} ALL DEPENDS ${APP_HDR})
add_custom_command(TARGET ${COMBINED} DEPENDS ${APP_HDR}
COMMAND ${CMAKE_OBJCOPY} --update-section .app_hdr=${APP_HDR} ${NAME}.elf ${COMBINED}.elf
add_custom_target(${APP}_hdr DEPENDS ${APP}_bin ${NAME})
add_custom_command(OUTPUT ${APP_HDR} DEPENDS ${APP_BIN} ${NAME}
COMMAND ${BOOTLOADER_DIR}/gen_imghdr.py -a ${IMAGE_HDR} ${APP_BIN} ${APP_HDR}
)
if(PICO_PLATFORM STREQUAL "rp2040")
set(UF2_FAMILY "0xe48bff56")
elseif(PICO_PLATFORM STREQUAL "rp2350-arm-s")
set(UF2_FAMILY "0xe48bff59")
elseif(PICO_PLATFORM STREQUAL "rp2350-riscv")
set(UF2_FAMILY "0xe48bff5a")
else()
message(FATAL_ERROR "Unknown PICO_PLATFORM: ${PICO_PLATFORM}")
endif()
add_custom_target(${COMBINED} ALL DEPENDS ${APP_HDR} ${NAME})
add_custom_command(TARGET ${COMBINED} POST_BUILD
COMMAND "echo" "Creating ${COMBINED}.elf"
COMMAND ${CMAKE_OBJCOPY} --update-section .app_hdr=${APP_HDR} ${NAME}.elf ${COMBINED}.elf
COMMAND ${CMAKE_OBJCOPY} -Obinary ${COMBINED}.elf ${COMBINED}.bin
COMMAND rm ${NAME}.uf2 > /dev/null 2>&1 || true
COMMAND picotool uf2 convert ${COMBINED}.elf ${NAME}.uf2 --family ${UF2_FAMILY}
)
# einde




# add_custom_command(TARGET ${COMBINED} POST_BUILD
# COMMAND ${CMAKE_OBJCOPY} -Obinary ${COMBINED}.elf ${COMBINED}.bin
# COMMAND picotool uf2 convert ${COMBINED}.elf ${COMBINED}.uf2 --family ${UF2_FAMILY}
# )
# add_custom_command(TARGET ${COMBINED} POST_BUILD # This uf2 doesn't work as it has the correct ld script, but the rest wrong.
# COMMAND rm ${NAME}.uf2 > /dev/null 2>&1 || true
# )

# Assumes picotool is installed to convert the elf to uf2.
# Needs to know the family type to generate the correct uf2.
# add_custom_command(TARGET ${COMBINED} POST_BUILD
# )
endfunction()

# Provide a helper to build a standalone target
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,23 @@ There are currently two tools I know of which can be used to upload code to it:
* [serial-flash](https://github.com/usedbytes/serial-flash) - my tool written in `go`
* [pico-py-serial-flash](https://github.com/ConfedSolutions/pico-py-serial-flash) - a similar tool written in Python, contributed by another user.



# Usage
Add this folder as a submodule to your project

Add
```
set(SKIP_BOOTLOADER_ENTRY_PIN 0) # skip bootloader gpio reading if wanted
add_subdirectory(rp2040-serial-bootloader)
bootloader_build_combined($PROJECT_NAME)
```
to your CMakeLists.txt

Run make like usual

Output files will be
$PROJECT_NAME_combined.elf/.uf2/.bin

The uf2 you can flash like normal with picotool.
The normal uf2
11 changes: 6 additions & 5 deletions bootloader.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
__stack (== StackTop)
*/

/* Limit flash to 12k, so we can use 12-16k for the image header */
bootloader_size = 40k; /* 4KB stack size */
/* Limit flash to 40k, so we can use 40-44k for the image header */
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 12k
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = bootloader_size
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
Expand Down Expand Up @@ -211,7 +212,7 @@ SECTIONS
{
__end__ = .;
end = __end__;
*(.heap*)
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM

Expand All @@ -226,11 +227,11 @@ SECTIONS
*/
.stack1_dummy (COPY):
{
*(.stack1*)
KEEP(*(.stack1*))
} > SCRATCH_X
.stack_dummy (COPY):
{
*(.stack*)
KEEP(*(.stack*))
} > SCRATCH_Y

.flash_end : {
Expand Down
14 changes: 8 additions & 6 deletions combined.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
__stack (== StackTop)
*/

bootloader_size = 12k; /* 4KB stack size */
header_size = 4k;
/* Skip 16kB at the start of flash, that's where our bootloader is */
MEMORY
{
FLASH_BL(rx) : ORIGIN = 0x10000000, LENGTH = 12k
FLASH_IMGHDR(rx) : ORIGIN = 0x10000000 + 12k, LENGTH = 4k
FLASH_APP(rx) : ORIGIN = 0x10000000 + 16k, LENGTH = 2048k - 16k
FLASH_BL(rx) : ORIGIN = 0x10000000, LENGTH = bootloader_size
FLASH_IMGHDR(rx) : ORIGIN = 0x10000000 + bootloader_size, LENGTH = 4k
FLASH_APP(rx) : ORIGIN = 0x10000000 + bootloader_size + header_size, LENGTH = 2048k - bootloader_size - header_size
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
Expand Down Expand Up @@ -206,7 +208,7 @@ SECTIONS
{
__end__ = .;
end = __end__;
*(.heap*)
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM

Expand All @@ -221,11 +223,11 @@ SECTIONS
*/
.stack1_dummy (COPY):
{
*(.stack1*)
KEEP(*(.stack1*))
} > SCRATCH_X
.stack_dummy (COPY):
{
*(.stack*)
KEEP(*(.stack*))
} > SCRATCH_Y

.flash_end : {
Expand Down
Loading