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

SDK • Re: RP2040 inter thread synchronisation

$
0
0
The only thing I can see wrong is your interrupt acknowledgement logic - you don't need to call multicore_fifo_clear_irq() if there's data in the FIFO, reading the word out of it implicitly clears the IRQ. But you do need to clear it manually if the overflow/underflow flags ever get set. So the code should look like this:
if (multicore_fifo_rvalid()) { // should always be valid if IRQ fired but prevent blocking
multicore_fifo_pop_blocking(); // clear FIFO, drop ret value

getdata(); // ~300us I2C
}
else multicore_fifo_clear_irq(); // Clear overflow/underflow interrupt
However, that would give you the handler being called continually, rather than what you are actually seeing which is it not being called at all.

I'm wondering if your Setup1() is actually running on core 1, if it completes successfully (assert in irq_set_exclusive_handler() because something else already using it maybe?), and what it does afterwards.

One point not mentioned - if your main loop on core1 has put the core to sleep with a WFE instruction, then core0 needs to do SEV to wake it up again as well as putting the word in the FIFO. This is needed as part of the process to get your own code running on core1 - after power-up it's running bootrom code and does a WFE - and this startup logic also uses the FIFO, but presumably you are using SDK functions for that and it should all be done for you.

Unfortunately, my code using the FIFO is all (for historical/porting reasons) written with direct register access rather than SDK functions, so is not directly comparable to yours. In my interrupt handler I have the following to acknowledge the interrupt (which should be equivalent to the modified version of yours above):

Code:

    // Check for all the bits in the status that can cause interrupts    // (but not RDY which will normally be set)    while ((st = (sio_hw->fifo_st &        (SIO_FIFO_ST_VLD_BITS | SIO_FIFO_ST_WOF_BITS | SIO_FIFO_ST_ROE_BITS)) ))    {        if (st & SIO_FIFO_ST_VLD_BITS)  // Normal case - word in FIFO, read it            (void)sio_hw->fifo_rd;        else sio_hw->fifo_st = 0;       // Error bits - clear them.    }
In my setup I just have (noting that my setup is the mirror image of yours - I have core1 doing work and sending interrupts to core0):

Code:

    // Enable core1 FIFO interrupt through NVIC    // (SIO_IRQ_PROC0 is for our end of the FIFO - in core0 )    nvic_hw->iser = 1 << SIO_IRQ_PROC0;
And to send the interrupt:

Code:

        // If we've just completed a set of measurements, wake up the other CPU        sio_hw->fifo_wr = 0;

As an aside, I get the impression that you are using the SDK documentation as your primary reference. I tend to work the other way round - I use the datasheet as my primary reference to know what the hardware can do, then when necessary refer to the SDK documentation to find the SDK functions that drive it.

Statistics: Posted by arg001 — Fri Aug 09, 2024 9:27 pm



Viewing all articles
Browse latest Browse all 4863

Trending Articles