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

SDK • Single-core FreeRTOS doesn't observe changes stored by an ISR on the other core

$
0
0
tl;dr a method of intercore synchronization works with SMP FreeRTOS and non-FreeRTOS, but not with FreeRTOS on one core (configNUMBER_OF_CORES=1) and vanilla SDK on the other. I'm not sure if this is a bug, or a restriction on the use of FreeRTOS. The same synchronization method, but using an async_context at-time worker, does work in all 3 scenarios.

I have the ADC in free-running mode, and this ISR fires on ADC_IRQ_FIFO:

Code:

static volatile uint16_t temp_adc_raw;static critical_section_t temp_critsec;/* Runs on core0 */static void__time_critical_func(temp_isr)(void){uint16_t val = adc_fifo_get();critical_section_enter_blocking(&temp_critsec);temp_adc_raw = val;critical_section_exit(&temp_critsec);}
The idea is that the ISR runs on one core, and the value is retrieved from the other core in lwIP callbacks, with reads and writes protected by the critical section:

Code:

/* Runs on core1 */uint32_tget_temp(void){uint16_t raw;critical_section_enter_blocking(&temp_critsec);raw = temp_adc_raw;critical_section_exit(&temp_critsec);/* ... do some computation and return a value ... */}
This is all with SDK 1.5.1 and FreeRTOS kernel V11.1.0, so after the smp branch was merged to main.

In the same app, I also have a recurring async_context at-time worker initiated on the one core, which saves a static value that is retrieved by lwIP callbacks on the other core, also with a critical section for synchronization.

This all works as expected in threadsafe background and poll modes, with initialization of the ADC and IRQ, in particular irq_set_exclusive_handler(), adc_irq_set_enabled(), and irq_set_enabled(), on core0, as well as initialization of the at-time worker on core0; and with the lwIP callbacks running on core1.

The single-core FreeRTOS version (configNUMBER_OF_CORES=1) sets the lwIP callbacks in a FreeRTOS task and launches the scheduler on core0. Before that, it starts vanilla SDK code on core1 to do the ADC, ISR and at-time worker initialization; so the ISR and at-time worker run on core1.

In that version, shared access to the value stored by the at-time worker works as expected. But the lwIP callbacks, run by the FreeRTOS task scheduler on core0, see the first value stored by ISR on core1, and never observe any changes after that. The value retrieved under the critical section by core0 is always the same.

I've confirmed with printf that adc_fifo_get() is indeed returning different values from time to time. I've tried setting configSUPPORT_PICO_SYNC_INTEROP=0; and I've tried using read/write barriers -- __dmb() after writing the static variable, and __dsb () before reading it. But all with the same result.

What does work is initializing the ADC/ISR in a FreeRTOS task on core0, so that the ISR is executed on the same core as the lwIP callbacks retrieving the value. In that scenario, the at-time worker still runs on the other core. As I said, the intercore sync with the at-time worker has not been a problem in any of these scenarios.

Single-core FreeRTOS using standard SDK sync primitives with non-FreeRTOS on the other core is evidently intended to work -- the Demo apps for the RP2040 port of FreeRTOS include some examples of that:

https://github.com/FreeRTOS/FreeRTOS-Co ... %2B_RP2040

Although these aren't exactly the same -- I don't see examples using critical_section there, or of ISRs running on the non-FreeRTOS core.

Nevertheless, one core not observing changes stored by the other core smells like a bug to me, especially if it's only a problem in one specific configuration of FreeRTOS. But maybe I've missed a restriction on the proper use of FreeRTOS, for example that it can only be expected to work with an ISR running on the same core as the task scheduler.

So is it a bug? If so I can post it as an issue to the pico-sdk repo.

Statistics: Posted by slimhazard — Thu Jun 27, 2024 10:43 am



Viewing all articles
Browse latest Browse all 5359

Trending Articles