Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 4684

SDK • A bizarre isr_hardfault

$
0
0
I started experimenting with some bootloader code, and running it in gdb-multiarch, I realized that it hardfaulted right at start. This happened for pico-sdk 2.1.0, and just today I updated to

Then I tried making a minimal reproducible example - and that one, of course, works fine (no hardfault, gdb shows it ultimately settles on the ""while(1){};" line with an infinite loop, as expected). So, that is the one I'm going to be posting - one difference from the use in my real project, is that in the real project this bootloader resides in a subdirectory, and the main project CmakeLists.txt "includes" it via `add_subdirectory` (and therefore the bootloader CMakeLists.txt does not include pico_sdk_init.cmake, and does not call pico_sdk_init()):

main.c

Code:

#include "hardware/clocks.h"    // set_sys_clock_pll#include "hardware/structs/bus_ctrl.h" // bus_ctrl_hwuint8_t status = 0;extern char __BOOTLOADER_LENGTH;uint16_t BOOTLOADER_LENGTH;static void setup_hardware( void );int main( void ){  BOOTLOADER_LENGTH = (uint16_t)(((uintptr_t)&__BOOTLOADER_LENGTH) % 0xFFFF);  status = 0;  setup_hardware();  while(1){};}static void setup_hardware( void ){  set_sys_clock_pll( 1596000000, 6, 2 ); // 133 MHz  bus_ctrl_hw->priority = BUSCTRL_BUS_PRIORITY_PROC0_BITS ;}
CMakeLists.txt

Code:

cmake_minimum_required(VERSION 3.15)# initialize the SDK directlyinclude($ENV{PICO_SDK_PATH}/pico_sdk_init.cmake)project(my_project)# initialize the Raspberry Pi Pico SDKpico_sdk_init()# rest of your projectset(PICO_COPY_TO_RAM 1)add_compile_options(-Wall  -Wno-format          # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int  -Wno-unused-function # we have some for the docs that aren't called  -Wno-maybe-uninitialized  -Os # Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.)add_executable(hello_world    main.c)pico_set_binary_type(hello_world copy_to_ram)# Add pico_stdlib library which aggregates commonly used featurestarget_link_libraries(hello_world  #pico_stdlib  #pico_platform  pico_standard_link  pico_crt0  pico_runtime_headers  pico_bootrom  pico_runtime  hardware_clocks)# create map/bin/hex/uf2 file in addition to ELF.pico_add_extra_outputs(hello_world)pico_minimize_runtime(hello_world EXCLUDE ALL)pico_set_linker_script(hello_world ${CMAKE_CURRENT_SOURCE_DIR}/memmap_copy_to_ram_bl.ld)
memmap_copy_to_ram_bl.ld linker script is a copy of memmap_copy_to_ram.ld; instead of posting the whole file which is large-ish, here is the output of `diff -Naur --strip-trailing-cr /src/pico-sdk/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld memmap_copy_to_ram_bl.ld`:

Code:

--- /src/pico-sdk/src/rp2_common/pico_crt0/rp2040/memmap_copy_to_ram.ld2025-03-02 18:23:01.110668270 +0100+++ memmap_copy_to_ram_bl.ld2025-03-03 01:57:05.521966619 +0100@@ -21,10 +21,13 @@     __stack (== StackTop) */ +/* memmap_defines.ld: __BOOTLOADER_LENGTH ; */+INCLUDE "/home/user/Desktop/test/memmap_defines.ld"+ MEMORY {-    INCLUDE "pico_flash_region.ld"-    RAM(rwx) : ORIGIN =  0x20000000, LENGTH = 256k+    FLASH(rx) : ORIGIN = 0x10000000, LENGTH = __BOOTLOADER_LENGTH+    RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k     SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k     SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k }@@ -180,7 +183,7 @@      .tdata : {         . = ALIGN(4);-*(.tdata .tdata.* .gnu.linkonce.td.*)+  *(.tdata .tdata.* .gnu.linkonce.td.*)         /* All data end */         __tdata_end = .;     } > RAM AT> FLASH@@ -199,7 +202,7 @@         __tls_end = .;     } > RAM -    .bss  : {+    .bss : {         . = ALIGN(4);         __tbss_end = .; @@ -284,4 +287,3 @@     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 */ }-
memmap_defines.ld is just a single line:

Code:

__BOOTLOADER_LENGTH = 44k;
Here is how I confirm in the debugger that it hardfaults with the real project:

Code:

(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/user/Desktop/REAL_project/build/Debug/bootload_subdir/bootload_subdir.elf target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00[New Thread 2]Thread 1 received signal SIGTRAP, Trace/breakpoint trap.isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170170decl_isr_bkpt isr_hardfault(gdb) bt#0  isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170#1  <signal handler called>#2  0x2000012a in spin_locks_reset () at /src/pico-sdk/src/rp2_common/hardware_sync_spin_lock/sync_spin_lock.c:12#3  0x10000226 in platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:455Backtrace stopped: previous frame identical to this frame (corrupt stack?)(gdb) 
Here is the result of stepping through in debugger - since this is copy_to_ram, we have to have first breakpoint on platform_entry (I have found armex function via Debugging multicore crash - Raspberry Pi Forums):

Code:

(gdb) b platform_entryBreakpoint 1 at 0x1000021e: file /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S, line 452.Note: automatically using hardware breakpoints for read-only addresses.(gdb) rThe program being debugged has been started already.Start it from the beginning? (y or n) yStarting program: /home/user/Desktop/REAL_project/build/Debug/bootload_subdir/bootload_subdir.elf target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00[New Thread 2]Thread 1 hit Breakpoint 1, platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:452452    ldr r1, =runtime_init(gdb) n453    blx r1(gdb) ntarget halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00454    ldr r1, =main(gdb) n455    blx r1(gdb) ntarget halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x00000138 msp: 0x20041f00Thread 1 received signal SIGTRAP, Trace/breakpoint trap.isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170170decl_isr_bkpt isr_hardfault(gdb) bt#0  isr_hardfault () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:170#1  <signal handler called>#2  0x2000012a in spin_locks_reset () at /src/pico-sdk/src/rp2_common/hardware_sync_spin_lock/sync_spin_lock.c:12#3  0x10000226 in platform_entry () at /src/pico-sdk/src/rp2_common/pico_crt0/crt0.S:455Backtrace stopped: previous frame identical to this frame (corrupt stack?)(gdb) armexEXEC_RETURN (LR):lr             0xfffffff9          -7Uses MSP 0x20041fe0 return.xPSR            0x21000000ReturnAddress   0x2000012aLR (R14)        0x10000227R12             0x4001801cR3              0x8R2              0x0R1              0x20000111R0              0x0Return instruction:   0x2000012a <spin_locks_reset+18>:pop{r4, pc}LR instruction:   0x10000227 <platform_entry+8>:ldrr1, [pc, #88]; (0x10000280 <data_cpy_table+72>)
Well, from what I can tell, it is `platform_entry` or `data_cpy_table` - pico-sdk functions - causing the hardfault?! Hard to believe, yet, there it is ... For reference, this is what `arm-none-eabi-objdump -d --dwarf=follow-links bootload_subdir.elf` gives me for these two functions - I am pretty bad at assembly, but maybe others can recognize something:

Code:

1000021e <platform_entry>:1000021e:       4916            ldr     r1, [pc, #88]   ; (10000278 <data_cpy_table+0x40>)10000220:       4788            blx     r110000222:       4916            ldr     r1, [pc, #88]   ; (1000027c <data_cpy_table+0x44>)10000224:       4788            blx     r110000226:       4916            ldr     r1, [pc, #88]   ; (10000280 <data_cpy_table+0x48>)10000228:       4788            blx     r11000022a:       be00            bkpt    0x00001000022c:       e7fd            b.n     1000022a <platform_entry+0xc>10000238 <data_cpy_table>:10000238:       10000830        .word   0x100008301000023c:       20000650        .word   0x2000065010000240:       20000860        .word   0x2000086010000244:       10000a40        .word   0x10000a4010000248:       20040000        .word   0x200400001000024c:       20040000        .word   0x2004000010000250:       10000a40        .word   0x10000a4010000254:       20041000        .word   0x2004100010000258:       20041000        .word   0x200410001000025c:       00000000        .word   0x0000000010000260:       4770            bx      lr10000262:       0000            .short  0x000010000264:       00000000        .word   0x0000000010000268:       e000ed08        .word   0xe000ed081000026c:       d0000000        .word   0xd000000010000270:       20000860        .word   0x2000086010000274:       200008a0        .word   0x200008a010000278:       20000621        .word   0x200006211000027c:       20000111        .word   0x2000011110000280:       200005e5        .word   0x200005e5
So, how can I get this code working without it hardfaulting at the very start?

Statistics: Posted by sdbbs — Mon Mar 03, 2025 1:24 am — Replies 2 — Views 76



Viewing all articles
Browse latest Browse all 4684

Trending Articles