Skip to content
Merged
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
2 changes: 0 additions & 2 deletions docs/ota.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
OTA Updates
===========

**NOTE:** OTA is not yet supported on the RP2350. PRs gladly accepted!

Introduction
------------

Expand Down
1 change: 0 additions & 1 deletion docs/rp2350.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ is supported by the core with some minor caveats:
* PSRAM is supported via a new ``pmalloc`` call and ``PSRAM`` variable decorator.
* Both RP2350A and RP2350B (48 GPIOs) are supported.
* Only ARM mode is available. For RISC-V (Hazard3), please use the raw SDK.
* OTA is not yet supported.

P2350-E9 Errata ("Increased leakage current on Bank 0 GPIO when pad input is enabled")
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
21 changes: 19 additions & 2 deletions lib/rp2350/memmap_default.ld
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
__stack (== StackTop)
*/




MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = __FLASH_LENGTH__
Expand All @@ -42,6 +45,20 @@ SECTIONS
__flash_binary_start = .;
} > FLASH

.ota : {
/* Start image with OTA */
KEEP (*(.OTA))
*ota.o
} > FLASH

.partition : {
. = __flash_binary_start + 0x2ff0;
LONG(__FS_START__)
LONG(__FS_END__)
LONG(__EEPROM_START__)
LONG(__FLASH_LENGTH__)
} > FLASH

/* The bootrom will enter the image at the point indicated in your
IMAGE_DEF, which is usually the reset handler of your vector table.

Expand All @@ -53,8 +70,8 @@ SECTIONS
*/

.text : {
__logical_binary_start = .;
KEEP (*(.vectors))
__logical_binary_start = .;
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
Expand Down Expand Up @@ -276,7 +293,7 @@ SECTIONS
.flash_end : {
KEEP(*(.embedded_end_block*))
PROVIDE(__flash_binary_end = .);
} > FLASH =0xaa
} > FLASH = 0xaa

.psram (NOLOAD) : {
__psram_start__ = .;
Expand Down
Binary file modified lib/rp2350/ota.o
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

#include <PicoOTA.h>
#include <LittleFS.h>
#include "blink_100_1000.h"
#include "blink_100_1000_rp2040.h"
#include "blink_500_500_rp2350.h"

void setup() {
Serial.begin(115200);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#ifdef PICO_RP2040
const unsigned char blink_gz[] = {
0x1f, 0x8b, 0x08, 0x08, 0x86, 0x7e, 0xf3, 0x62, 0x02, 0x03, 0x73, 0x6b,
0x65, 0x74, 0x63, 0x68, 0x5f, 0x61, 0x75, 0x67, 0x31, 0x30, 0x61, 0x2e,
Expand Down Expand Up @@ -3896,3 +3897,4 @@ const unsigned char blink_gz[] = {
0x03, 0xeb, 0x79, 0x7c, 0xf6, 0x3f, 0x01, 0xa8, 0x7b, 0x69, 0xf7, 0x10,
0x11, 0x01, 0x00
};
#endif
3,931 changes: 3,931 additions & 0 deletions libraries/PicoOTA/examples/OTAfromFile-Compressed/blink_500_500_rp2350.h

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion libraries/PicoOTA/examples/OTAfromFile/OTAfromFile.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

#include <PicoOTA.h>
#include <LittleFS.h>
#include "blink_100_1000.h"
#include "blink_100_1000_rp2040.h"
#include "blink_500_500_rp2350.h"

void setup() {
Serial.begin(115200);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#ifdef PICO_RP2040
const unsigned char blink[] = {
0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21,
0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b,
Expand Down Expand Up @@ -5826,3 +5827,4 @@ const unsigned char blink[] = {
0xc1, 0x45, 0x00, 0x10, 0x9d, 0x48, 0x00, 0x10, 0xad, 0x4b, 0x00, 0x10,
0xed, 0x63, 0x00, 0x10
};
#endif
5,684 changes: 5,684 additions & 0 deletions libraries/PicoOTA/examples/OTAfromFile/blink_500_500_rp2350.h

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions ota/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ if (${cpu} MATCHES "rp2040")
set(PICO_BOARD pico)
set(PICO_PLATFORM rp2040)
set(PICO_CYW43_SUPPORTED 0)
set(OBJARCH armv6-m)
set(WRAP -Wl,--wrap=clocks_init)
elseif(${cpu} MATCHES "rp2350")
set(PICO_BOARD pico2)
set(PICO_PLATFORM rp2350)
set(PICO_CYW43_SUPPORTED 0)
set(OBJARCH armv8-m)
set(WRAP )
else()
message(FATAL_ERROR "Unknown CPU, '${cpu}'")
endif()
Expand Down Expand Up @@ -71,7 +75,7 @@ target_compile_options(ota PUBLIC
)

target_link_options(ota PUBLIC
-Wl,--wrap=clocks_init
${WRAP}
-Wl,--wrap=exit
-Wl,--wrap=atexit
-Wl,--wrap=panic_unsupported
Expand All @@ -97,7 +101,7 @@ target_link_libraries(ota
)

add_custom_command(TARGET ota POST_BUILD
COMMAND ../../system/arm-none-eabi/bin/arm-none-eabi-ld -r -A armv6-m -b binary -o ota.o ota.bin
COMMAND ../../system/arm-none-eabi/bin/arm-none-eabi-ld -r -A ${OBJARCH} -b binary -o ota.o ota.bin
COMMAND ../../system/arm-none-eabi/bin/arm-none-eabi-objcopy --rename-section .data=.OTA ota.o ../../lib/${cpu}/ota.o
COMMAND cp ../ota_command.h ../../include/${cpu}/pico_base/pico/.
)
152 changes: 104 additions & 48 deletions ota/memmap_ota_rp2350.ld
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@

MEMORY
{
FLASH(rx) : ORIGIN = 0x10000100, LENGTH = 16384k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 212k
/* We split RAM into main (where the flash->ram code will be copied) and GLOBALS which has all large arrays */
/* By placing those arrays at the end of RAM we can avoid overwriting uninitialize_ram from the main app as */
/* long as those vars are stored after 12K by using an alignment value in the main app linker file. */
INCLUDE "pico_flash_region.ld"
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 212k
GLOBALS(rwx) : ORIGIN = 0x20035000, LENGTH = 44k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
}

ENTRY(_entry_point)

SECTIONS {
SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
and checksummed. It is usually built by the boot_stage2 target
in the Raspberry Pi Pico SDK
Expand All @@ -45,57 +43,71 @@ SECTIONS {
.globals (NOLOAD) : {
} > GLOBALS


.flash_begin : {
__flash_binary_start = .;
} > FLASH
/*
.boot2 : {
__boot2_start__ = .;
KEEP (*(.boot2))
__boot2_end__ = .;
} > FLASH

ASSERT(__boot2_end__ - __boot2_start__ == 256,
"ERROR: Pico second stage bootloader must be 256 bytes in size")
*/
/* The second stage will always enter the image at the start of .text.
/* The bootrom will enter the image at the point indicated in your
IMAGE_DEF, which is usually the reset handler of your vector table.

The debugger will use the ELF entry point, which is the _entry_point
symbol if present, otherwise defaults to start of .text.
This can be used to transfer control back to the bootrom on debugger
launches only, to perform proper flash setup.
symbol, and in our case is *different from the bootrom's entry point.*
This is used to go back through the bootrom on debugger launches only,
to perform the same initial flash setup that would be performed on a
cold boot.
*/

.flashtext : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
__embedded_block_end = .;
KEEP (*(.reset))
}
. = ALIGN(4);
} > FLASH

.rodata : {
/* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > FLASH

.ARM.extab : {
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH

__exidx_start = .;
.ARM.exidx : {
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;

/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > FLASH
__binary_info_end = .;
. = ALIGN(4);

/* Vector table goes first in RAM, to avoid large alignment hole */
.ram_vector_table (COPY): {
.ram_vector_table (NOLOAD): {
*(.ram_vector_table)
} > RAM

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

.text : {
__ram_text_start__ = .;
*(.init)
Expand All @@ -119,7 +131,7 @@ SECTIONS {
__ram_text_end__ = .;
} > RAM AT> FLASH
__ram_text_source__ = LOADADDR(.text);

. = ALIGN(4);

.data : {
__data_start__ = .;
Expand Down Expand Up @@ -176,6 +188,50 @@ SECTIONS {
*(.uninitialized_data*)
} > RAM

.tdata : {
. = ALIGN(4);
*(.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);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)

__tls_end = .;
} > RAM

.bss : {
. = ALIGN(4);
__tbss_end = .;

*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
PROVIDE(__global_pointer$ = . + 2K);
*(.sbss*)
. = ALIGN(4);
__bss_end__ = .;
} > RAM

.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
/* 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 */
. = ORIGIN(RAM) + LENGTH(RAM);
__HeapLimit = .;
} > RAM

/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
Expand All @@ -193,22 +249,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 @@ -218,16 +258,19 @@ 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*)
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > SCRATCH_Y

.flash_end : {
__flash_binary_end = .;
} > FLASH
KEEP(*(.embedded_end_block*))
PROVIDE(__flash_binary_end = .);
} > FLASH =0xaa

/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
Expand All @@ -237,10 +280,23 @@ 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")*/
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")

/* todo assert on extra code */
}

Loading