Page 7 of 11
Re: [DEV] RP2040 support
Posted: Tue Apr 20, 2021 10:46 pm
by stapelberg
Thanks for your work on supporting the Raspberry Pi Pico!
It seems like ChibiOS can currently only be loaded into RAM using a debugger (e.g. another Raspberry Pi Pico with picoprobe firmware), as it has the wrong entrypoint to be written to flash.
I can successfully load demos/RP/RT-RP2040-PICO from ChibiOS (git commit 3c77181e9c1073035c297d0c9fab60f619f261a5) onto the Pi Pico, and the LED starts blinking. I can also use the serial interface to get a shell and run the tests.
However, the USB stack doesn’t seem to work yet. On the host, all I see is:
Code: Select all
Apr 20 23:40:42 midna kernel: usb 1-13.4-port1: attempt power cycle
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: new full-speed USB device number 46 using xhci_hcd
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: Device not responding to setup address.
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: Device not responding to setup address.
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: device not accepting address 46, error -71
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: new full-speed USB device number 47 using xhci_hcd
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: Device not responding to setup address.
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: Device not responding to setup address.
Apr 20 23:40:43 midna kernel: usb 1-13.4.1: device not accepting address 47, error -71
Apr 20 23:40:43 midna kernel: usb 1-13.4-port1: unable to enumerate USB device
Is this a known issue?
Re: [DEV] RP2040 support
Posted: Wed Apr 21, 2021 7:51 am
by Giovanni
Hi,
We are still in early development so loading in RAM is just what we do currently, flash support will come, it requires a different scatter file and the "loader" expected by the boot ROM like in SDK demos.
About USB, there is not yet a driver in the HAL, are you trying the Pico-SDK driver?
Giovanni
Re: [DEV] RP2040 support
Posted: Wed Apr 21, 2021 5:14 pm
by stapelberg
Giovanni wrote:Hi,
We are still in early development so loading in RAM is just what we do currently, flash support will come, it requires a different scatter file and the "loader" expected by the boot ROM like in SDK demos.
About USB, there is not yet a driver in the HAL, are you trying the Pico-SDK driver?
I was just trying out the demo without checking where USB software support stands.
If USB support is not yet done, that explains the behavior of the device on the USB bus

Thanks for clarifying the current status!
Re: [DEV] RP2040 support
Posted: Wed Apr 21, 2021 5:17 pm
by Giovanni
stapelberg wrote:Giovanni wrote:If USB support is not yet done, that explains the behavior of the device on the USB bus

LOL, yes, it is a clear case of missing code

Re: [DEV] RP2040 support
Posted: Sun Jul 11, 2021 10:31 am
by szilveszter
Hello Giovanni,
Played a bit with the new ChibiOS RT 7.0 on a Raspberry PI Pico and everything seems to work well so far; however without startup support for the flash memory the use cases are very limited. Is there any intention to introduce in the near future a linker script which supports writing programs into the flash memory? Do you accept some kind contribution If I manage to somehow get it running?
Regards,
Szilveszter
Re: [DEV] RP2040 support
Posted: Sun Jul 11, 2021 11:17 am
by Giovanni
Hi,
Yes, it is in the to-do lists. The boot code is already in the Pico SDK so it should not be a big deal, please let me know when you succeed.
Giovanni
Re: [DEV] RP2040 support
Posted: Tue Jul 13, 2021 10:24 pm
by szilveszter
Finally I managed to get Chibios booting from the Pico's own flash storage. It wasn't that trivial as expected or at least not for me.
*kitchen language warning: I am not an expert in this area therefore I could sometimes use incorrect terminology.
So here is what I found:
The RP2040's boot sequence is burned into its ROM memory and therefore it cannot be omitted nor changed. In the processor controlled boot sequence, the top (or bottom?) 256 bytes of the flash storage is loaded searching for a correct second stage bootloader by verifying the checksum of the loaded bytes. If the checksum is not ok - there is no correct second stage bootloader in place - then the RP2040 enters into USB device mode. If the checksum is ok this second stage bootloader is executed initializing some further stuff (for example the Execute In Place (XIP) hardware). After finished its work the second stage bootloader jumps with the program counter to the next address in the flash (base_address + 256 bytes) to execute the user code.
There are a few different second stage bootloader variants in Pico SDK for (I think) different flash storage types. The right fit for the board is chosen and compiled at build time. There is also a Python script which adds the padding to it. For more details refer to the RP2040 datasheet.
So here is what I did:
I cloned the ChibiOS'
os/common/startup/ARMCMx/compilers/GCC/ld/RP2040_RAM.ld and added the following two sections from the Pico SDK's linker script and of course changed the necessary regions to point to the flash1:
Code: Select all
/*
* RP2040 memory setup.
*/
MEMORY
{
flash0 (rx) : org = 0x00000000, len = 16k /* ROM */
flash1 (rx) : org = 0x10000000, len = 2048k /* XIP (length TBD) */
flash2 (rx) : org = 0x00000000, len = 0
flash3 (rx) : org = 0x00000000, len = 0
flash4 (rx) : org = 0x00000000, len = 0
flash5 (rx) : org = 0x00000000, len = 0
flash6 (rx) : org = 0x00000000, len = 0
flash7 (rx) : org = 0x00000000, len = 0
ram0 (wx) : org = 0x20000000, len = 256k /* SRAM0 striped */
ram1 (wx) : org = 0x00000000, len = 256k /* SRAM0 non striped */
ram2 (wx) : org = 0x00000000, len = 0
ram3 (wx) : org = 0x00000000, len = 0
ram4 (wx) : org = 0x20040000, len = 4k /* SRAM4 */
ram5 (wx) : org = 0x20041000, len = 4k /* SRAM5 */
ram6 (wx) : org = 0x00000000, len = 0
ram7 (wx) : org = 0x20041f00, len = 256 /* SRAM5 boot */
}
/* For each data/text section two region are defined, a virtual region
and a load region (_LMA suffix).*/
/* Flash region to be used for exception vectors.*/
REGION_ALIAS("VECTORS_FLASH", flash1);
REGION_ALIAS("VECTORS_FLASH_LMA", flash1);
/* Flash region to be used for constructors and destructors.*/
REGION_ALIAS("XTORS_FLASH", flash1);
REGION_ALIAS("XTORS_FLASH_LMA", flash1);
/* Flash region to be used for code text.*/
REGION_ALIAS("TEXT_FLASH", flash1);
REGION_ALIAS("TEXT_FLASH_LMA", flash1);
/* Flash region to be used for read only data.*/
REGION_ALIAS("RODATA_FLASH", flash1);
REGION_ALIAS("RODATA_FLASH_LMA", flash1);
/* Flash region to be used for various.*/
REGION_ALIAS("VARIOUS_FLASH", flash1);
REGION_ALIAS("VARIOUS_FLASH_LMA", flash1);
/* Flash region to be used for RAM(n) initialization data.*/
REGION_ALIAS("RAM_INIT_FLASH_LMA", flash1);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("MAIN_STACK_RAM", ram4);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("PROCESS_STACK_RAM", ram4);
/* RAM region to be used for Main stack. This stack accommodates the processing
of all exceptions and interrupts.*/
REGION_ALIAS("C1_MAIN_STACK_RAM", ram5);
/* RAM region to be used for the process stack. This is the stack used by
the main() function.*/
REGION_ALIAS("C1_PROCESS_STACK_RAM", ram5);
/* RAM region to be used for data segment.*/
REGION_ALIAS("DATA_RAM", ram0);
REGION_ALIAS("DATA_RAM_LMA", flash1);
/* RAM region to be used for BSS segment.*/
REGION_ALIAS("BSS_RAM", ram0);
/* RAM region to be used for the default heap.*/
REGION_ALIAS("HEAP_RAM", ram0);
SECTIONS
{
.flash_begin : {
__flash_binary_start = .;
} > flash1
.boot2 : {
__boot2_start__ = .;
KEEP (*(.boot2))
__boot2_end__ = .;
} > flash1
ASSERT(__boot2_end__ - __boot2_start__ == 256,
"ERROR: Pico second stage bootloader must be 256 bytes in size")
}
/* Generic rules inclusion.*/
INCLUDE rules_stacks.ld
INCLUDE rules_stacks_c1.ld
INCLUDE rules_code.ld
INCLUDE rules_data.ld
INCLUDE rules_memory.ld
SECTIONS
{
.flash_end : {
__flash_binary_end = .;
} > flash1
}
The .boot2 section comes from boot_stage2. Here I took an already built boot_stage2 file and added to the end of linking command (similarly to how they the Pico team does). Finally I had to change the .vectors section in the
os/common/startup/ARMCMx/compilers/GCC/ld/rules_code.ld to not be aligned which causes not to be placed right after the .boot2 section and to not starting up ChibiOS ( probably there are alternatives such as changing the second stage boot-loader's code to load the vectors from the aligned address).
After all of that, ChibiOS is successfully boots from the flash.
Szilveszter
Re: [DEV] RP2040 support
Posted: Thu Jul 15, 2021 9:35 pm
by electronic_eel
Hi Szilveszter,
thanks for working on this. I'm also interested in the RP2040, but I haven't started working on it since my dev boards haven't arrived yet.
From looking at your linker script it looks like you put the whole executable code into the flash and execute it directly from there (XIP). Is this correct?
I think when doing it this way, the execution speed will be severely limited by the speed of the flash and the cores will often have to wait for new code being downloaded from the flash. The cache of the RP2040 will help sometimes, but very often the cores will have to wait. Also the RP2040 has a lot of RAM, so I think the designers planned that the user will often load parts of the code into the RAM and execute it from there.
So loading for example the interrupt code and the core parts of ChibiOS, probably also some important or time critical parts of the user code, into RAM should speed up execution a lot. The linker script could provide a special section for it and startup code must then copy this section into RAM. The functions that should be copied can be given a section attribute to place them into the wanted section, like this:
Code: Select all
extern void foobar (void) __attribute__ ((section ("copytoram")));
The problem I see is finding a convenient way to mark many functions (like all of ChibiOS core, but not external libraries like lwip or wolfssl) this way without having to list each individual function. Also the user should have control over which function to copy, as the user has to decide on the tradeoff between free RAM needed for data and RAM for fast execution. This means even if the actual code is part of ChibiOS, the sectioning should be part of the user code or at least easily customizable.
Re: [DEV] RP2040 support
Posted: Fri Jul 16, 2021 10:55 am
by alex31
Hello,
Being able to place functions in ram is beyond the case of RP2040, one should probably think at a portable way to express it : In many STM32 families, there is ITCM memory that is here to execute hot code without wait state cycle, and for now, as far as I know, there is no mechanism to use it with chibios.
Alexandre
Re: [DEV] RP2040 support
Posted: Fri Jul 16, 2021 11:20 am
by Giovanni
alex31 wrote:Hello,
Being able to place functions in ram is beyond the case of RP2040, one should probably think at a portable way to express it : In many STM32 families, there is ITCM memory that is here to execute hot code without wait state cycle, and for now, as far as I know, there is no mechanism to use it with chibios.
Alexandre
You need to create a custom scatter file, you can place things where you want.
Giovanni