pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

repeating timer stop fire when GPIO-IRQ is in use

Open ruehlchris opened this issue 2 years ago • 6 comments

Hi All,

I have a problem with my application using core 0 & 1, a repeat timer to poll sensors and two gpio-irq from NRF24L01+ and ENS160 interrupt lines. Timer callback and interrupt handler use multicore_fifo_push_blocking() to wakeup core1 to work and nothing is done in the IRQ context themself. ENS160IRQ hammers every second and the NRF24IRQ after a Bluetooth transmission. The repeating timer from default alarm pool, is set to 5 Seconds interval. To serialize both interrupt & timer handlers, I added a mutex but this doesn't make any difference.

void __not_in_flash_func(controller::gpio_irq_callback)(uint gpio, uint32_t event)
{
 mutex_enter_blocking(&_syncmutex);
 if (gpio == ENS160IRQ) {
#ifdef HAVE_ENS160
		 multicore_fifo_push_blocking(ENS160IRQEVENT);
#endif
 }
 else if (gpio == NRF24IRQ) {
		 multicore_fifo_push_blocking(NRF24IRQEVENT);
 }
 mutex_exit(&_syncmutex);
}

bool __not_in_flash_func(controller::timer_callback)(repeating_timer_t *rt)
{
 mutex_enter_blocking(&_syncmutex);
	/* wakeup core1 to work for probing */
	multicore_fifo_push_blocking(PROBEEVENT);
 mutex_exit(&_syncmutex);
	return true;
}

After a while the repeating timer stops firing. Interrupts are working without interruption.

Any Idea what cause this?

-Chris

ruehlchris avatar Oct 31 '23 04:10 ruehlchris

Interesting workaround and a hint to hunt this bug down. I do not send anything from core1 back to core0 in my implementation and therefore replaced the sleep_ms() in the main() with multicore_fifo_pop_blocking() and the repeating timer keeps working.

But not for that long, :( after 45min the timer sleep again.

int main(void) 
{
	stdio_init_all();
	std::cout << "Probe starting\n";
	controller c;
	c.start();
	while(true) {
	 // sleep_ms(60000);
	 uint32_t evt = multicore_fifo_pop_blocking();
	 std::cout << "main sleep again" << evt << std::endl;
	};
	return 0;
}

ruehlchris avatar Oct 31 '23 07:10 ruehlchris

Additional, I had the system running over night, and the timer comes and goes. That is very strange!

ruehlchris avatar Nov 01 '23 01:11 ruehlchris

Hi, digging around I read a comment in the header files for the multicore_fifo** implementation to be caution using this for your own implementation and use instead the "pico/util/queue.h" which is IRQ and thread save .

I changed my implementation now using queue_add_blocking() queue_remove_blocking(). So far my app becomes stable!

Chris

ruehlchris avatar Nov 14 '23 02:11 ruehlchris

Glad you found the issue. I guess I can close this unless you think there is a bug in the sdk.

peterharperuk avatar Nov 14 '23 09:11 peterharperuk

Peter, I had the application running over night and again the repeating timer go for sleep again. Only Interrupt remains working. I already started a sample application triggered by external Arduino board for the IRQ while have a repeating timer running. Not able yet to trigger the bug. But I'm on it.

ruehlchris avatar Nov 15 '23 00:11 ruehlchris

I wonder if it's another case of this https://github.com/raspberrypi/pico-sdk/issues/1552

peterharperuk avatar Nov 20 '23 12:11 peterharperuk