Sleep on one core negatively impacts execution on the other core #873
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#873
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hi, I originally opened an issue for this in arduino-pico (see https://github.com/earlephilhower/arduino-pico/issues/637) before discovering the issue happens even using the Pico SDK directly. There are more details in that issue, but basically calling sleep_us() on one core while the other core is working seems to have a huge impact on the other core that interrupts its execution part way and is causing communication failures for me even though I'm using the PIO for my comms and it's 100% stable when I'm not using multicore.
Code to reproduce:
Every time core 1 is about to come out of a sleep, core 0 appears to "stall" in some way. It's not exactly a stall, because it doesn't just continue where it left off. Instead, it actually never does things that it should have, or gets interrupted halfway through doing something and never finishes it.
Logic analyzer trace of the above code:
I just tested this with core 0 and core 1's roles swapped and the result is not exactly the same but there is clearly still some impact:
sleep_us will use an alarm in the default alarm pool (which is on core 0) to wake itself up after a period of time (it can stay ni a lower power state). 4us which you see above is presumably the alarm IRQ handler.
You can use
busy_wait_usinstead...I'm still somewhat confused how this is causing more issues than the USB timer alarm in arduino-pico. Like, I'll be in an
pio_sm_put_blocking()on core 0 and somehow that can get interrupted halfway and never finishes. Even with interrupts it should still continue what it was doing before, right? If it did, it probably wouldn't be an issue, but in reality it's completely messing up what core 0 is doing.And that workaround is a bit of a problem when I'm using libraries which are using sleep and I need to use them with multicore :-/
The delay you see in your traces is expected. The fact that it is causing your real use case problems is surprising, unless your use case cannot handle the brief delay.
Indeed, the IRQ should have no effect on the interrupted code (other than the delay)... are you sure something else isn't happening (e.g. stack overflow - possibly during the exception handler)
Ah it looks like it's not actually being interrupted while sending the response, but it's actually sending a shorter response than expected because it thinks it received a different command. The way core 1 is affecting core 0 somehow causes it to misread the received command byte. So, sometimes it misses responding to a poll command completely (probably because it looked like an invalid command), and sometimes it thinks it received a probe command and sends the wrong response (3 bytes instead of 8). But this doesn't really make sense to me either, because the actual reading of bits is handled by the PIO so it should not be affected unless the system clock speed is varying. If it was missing whole bytes that would be more explainable, but that doesn't seem to be the case here.
Example of correct behaviour (received poll command and responded correctly with 8 bytes of data):

Example of received poll command but no response (only happening when using sleep on core 1):

Example of received poll but responded with only 3 bytes (also only happens when using sleep on core 1):

I've been able to do plenty of other things on core 1 with the same code running on core 0 and it hasn't been a problem, but anything with a sleep completely breaks it.
@JonnyHaystack Looking at https://github.com/raspberrypi/pico-sdk/blob/master/src/common/pico_time/time.c#L375 do you want to try setting
PICO_TIME_DEFAULT_ALARM_POOL_DISABLEDto 1, and seeing if that makes your code behave differently?@lurch unfortunately that didn't work at all. Seems to result in the signal from core 0 staying high forever and the signal from core 1 stays low forever. Also for my actual use case I'm using arduino-pico, which won't even compile if I set that flag (error below).