Skip to content

Commit 2fcfb34

Browse files
committed
Initial commit
0 parents  commit 2fcfb34

File tree

5 files changed

+160
-0
lines changed

5 files changed

+160
-0
lines changed

platformio.ini

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[env:debug]
2+
board = nanorp2040connect
3+
framework = arduino
4+
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
5+
board_build.core = earlephilhower
6+
platform_packages =
7+
framework-arduinopico@symlink://../arduino-pico
8+
build_flags =
9+
-DLIB_PICO_MULTICORE=1
10+
-DDEBUG_RP2040_PORT=Serial1
11+
-fno-lto
12+
-Og
13+
-g
14+
debug_tool = cmsis-dap
15+
upload_protocol = cmsis-dap
16+
debug_extra_cmds =
17+
set remotetimeout 5
18+
source scripts/combined_debug.gdb

scripts/capture_race_state.gdb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
set pagination off
2+
set print pretty on
3+
4+
# Initialize tracking variables
5+
set $cycle = 1
6+
7+
break async_context_base_remove_when_pending_worker
8+
commands
9+
silent
10+
printf "\n[Cycle: %d] remove worker: %p\n", $cycle, worker
11+
printf "[TIMESTAMP] Exit: %llu\n", timestamp_exit
12+
info args
13+
info address worker
14+
x/16wx worker
15+
set $w = (async_when_pending_worker_t *)worker
16+
p *$w
17+
if ($w->do_work != 0x1000a499)
18+
printf "\n[CORRUPTED] do_work changed from 0x1000a499 to %p!\n", $w->do_work
19+
end
20+
# Log but don't break for these fields
21+
if ($w->next != 0 && ($w->next < 0x20000000 || $w->next > 0x20042000))
22+
printf "\n[WARNING] next pointer invalid: %p\n", $w->next
23+
end
24+
if ($w->work_pending > 1)
25+
printf "\n[WARNING] work_pending invalid: %d\n", $w->work_pending
26+
end
27+
bt
28+
set $cycle = $cycle + 1
29+
continue
30+
end
31+
32+
break async_context_base_execute_once
33+
commands
34+
silent
35+
set $worker = (async_when_pending_worker_t *)self->when_pending_list
36+
printf "\n[Cycle: %d] execute once: %p\n", $cycle, $worker
37+
printf "[TIMESTAMP] Enter: %llu\n", timestamp_enter
38+
if $worker != 0
39+
x/4wx $worker
40+
p *$worker
41+
# Print timestamp info if worker exists
42+
end
43+
continue
44+
end

scripts/combined_debug.gdb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Load the race‑capture script that watches execute_sync()
2+
source scripts/capture_race_state.gdb
3+
# Load the standard hard‑fault diagnostics
4+
source scripts/hardfault_debug.gdb

scripts/hardfault_debug.gdb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
break isr_hardfault
2+
commands
3+
silent
4+
echo \n=========== HardFault detected ===========\n
5+
info reg
6+
echo \nStacked registers (r0‑r3,r12,lr,pc,xPSR):\n
7+
x/8wx $sp
8+
set $fault_pc = *((unsigned int *)$sp + 6)
9+
printf "\nCode around faulting PC (0x%08x):\n", $fault_pc
10+
disassemble $fault_pc-8, $fault_pc+8
11+
bt
12+
echo \n==========================================\n
13+
end

src/main.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#include <Arduino.h>
2+
#include "pico/async_context_threadsafe_background.h"
3+
4+
bool core1_separate_stack = true;
5+
6+
volatile bool operational = false;
7+
volatile bool serial_ready = false;
8+
static volatile uint64_t timestamp_exit = 0;
9+
static volatile uint64_t timestamp_enter = 0;
10+
11+
static async_context_threadsafe_background_t asyncCtx;
12+
13+
uint32_t doSomeWork(void* param) {
14+
const auto value = static_cast<uint32_t*>(param);
15+
(*value)++;
16+
// Log timestamp right before sem_release will happen
17+
if (const auto worker = static_cast<async_when_pending_worker*>(asyncCtx.core.when_pending_list)) {
18+
Serial1.printf("[INFO][%u][%llu] Pre-sem_release worker state:\n"
19+
" address: %p\n"
20+
" next: %p\n"
21+
" do_work: %p\n"
22+
" work_pending: %d\n"
23+
" value: %d\n",
24+
get_core_num(),
25+
to_us_since_boot(get_absolute_time()),
26+
worker,
27+
worker->next,
28+
worker->do_work,
29+
worker->work_pending,
30+
*value);
31+
}
32+
return *value;
33+
}
34+
35+
void setup() {
36+
Serial1.setRX(PIN_SERIAL1_RX);
37+
Serial1.setTX(PIN_SERIAL1_TX);
38+
Serial1.setPollingMode(true);
39+
Serial1.begin(115200);
40+
41+
while (!Serial1) {
42+
delay(10);
43+
}
44+
45+
RP2040::enableDoubleResetBootloader();
46+
serial_ready = true;
47+
while (!operational) {
48+
delay(10);
49+
}
50+
51+
Serial1.printf("C0 ready...\n");
52+
}
53+
54+
void setup1() {
55+
while (!serial_ready) {
56+
delay(10);
57+
}
58+
async_context_threadsafe_background_config_t cfg = async_context_threadsafe_background_default_config();
59+
operational = async_context_threadsafe_background_init(&asyncCtx, &cfg);
60+
assert(operational);
61+
Serial1.printf("C1 ready...\n");
62+
}
63+
64+
void loop() {
65+
static unsigned long c0_counter = 0;
66+
static uint32_t myNumber = 0;
67+
68+
if (c0_counter % 111 == 0) {
69+
timestamp_enter = to_us_since_boot(get_absolute_time());
70+
const auto rc = async_context_execute_sync(&asyncCtx.core, doSomeWork, &myNumber);
71+
assert(rc == myNumber);
72+
timestamp_exit = to_us_since_boot(get_absolute_time());
73+
Serial1.printf("value: %d; enter: %llu; exit: %llu\n", rc, timestamp_enter, timestamp_exit);
74+
}
75+
c0_counter++;
76+
delay(1);
77+
}
78+
79+
void loop1() {
80+
tight_loop_contents();
81+
}

0 commit comments

Comments
 (0)