How to Reserve core 1 for single task

Giles314
Posts: 4
Joined: Sun Apr 02, 2023 10:25 pm

How to Reserve core 1 for single task

Postby Giles314 » Sun Apr 02, 2023 11:01 pm

Hi,

I am using an ESP32 Xtensa dual core.

I would like my main task running on core 1 (APP) having 100% of this core CPU. I have pinned all my other tasks on CPU 0. But I still lose 10us CPU time every 1ms (probably each tick).

I have tried to configure FreeRTOS with

Code: Select all

#define CONFIG_FREERTOS_UNICORE 1
but this does not seem to help. I may miss some constraint because I did not find any help on how to use this configuration.

I have tried to clear DPORT_APP_INTR_STATUS_REG_0_REG to block interrupts on APP core but it seems that it gets set again later on so interrupts still occur. And moreover that seems to cause issues in FreeRTOS (I got it to hang randomly - even reset and download fails).

What would be the right way to avoid any interrupts to occur on core 1?

Giles

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: How to Reserve core 1 for single task

Postby ESP_Sprite » Mon Apr 03, 2023 12:26 am

On the ESP32, this is not trivial - you're likely seeing the FreeRTOS tick interrupt interrupting your program, but there's more that can do that - anything from a high-level interrupt to work around a D-port ECO, to an AHB write stuck behind another one to a slow peripheral, to a flash write holding everything up. Is there a reason you need this level of availability? I find that in most cases, the issue can be solved by using one of the ESP32 peripherals instead.

Giles314
Posts: 4
Joined: Sun Apr 02, 2023 10:25 pm

Re: How to Reserve core 1 for single task

Postby Giles314 » Mon Apr 03, 2023 7:17 pm

Thanks for your answer. I am trying to detect state changes on a collection of input ports, that may be as short as 1us and to date them at +/- 250ns relative precision. I have not been able to find a peripheral that could do that. I have thought to add a FPGA to do the precise part of the job but this increases significantly the complexity compared to a simple ESP32.

I can accept the delays due to cache random delays especially that I make frequent use of MEMW, L32AI and S32RI so cache must stay mostly up-to-date if I well understood how work those instructions. I will not use flash during running periods. The only concurrent highly demanding processing on Core 0 is the Wifi MAC peripheral that should not steal more than one or 2 DMA cycles every 250ns I suppose. I have even written my own ring library to be sure it makes no call to FreeRTOS kernel to communicate between cores. So at this stage I hope the only remaining source of significant delay (>250ns) is the tick interrupt. At least, up to now I did not observe any other timing anomaly greater to the +/-25Ons tolerance. So if there is a way to avoid tick interruptions on Core 1 I suppose this would met my requirement.

Is there a way for CONFIG_FREERTOS_UNICORE really not involving core 1 in scheduling?

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: How to Reserve core 1 for single task

Postby ESP_Sprite » Tue Apr 04, 2023 2:20 am

No, not running FreeRTOS on core 1 leaves you effectively without a way to start anything on that core. You could disable the FreeRTOS tick interrupt manually, that should at least get rid of most the interruptions. You could also write a high-level interrupt in assembly; these get priority above (=can run while the CPU is in) the 'normal' interrupts, if memory serves.

But as an alternative, the RMT peripheral is pretty good at detecting changing inputs. You can also run the I2S peripheral in parallel ('camera') mode and parse the data it reads from its inputs.

Giles314
Posts: 4
Joined: Sun Apr 02, 2023 10:25 pm

Re: How to Reserve core 1 for single task

Postby Giles314 » Fri Apr 07, 2023 11:27 pm

I read for few days the ESP manuals to try to understand how to implement the interrupt solution. But after reading them I still do not understand how when passing NULL to esp_intr_alloc it will be able to guess magically where is my interrupt routine (manuals are not really explicit about that!). But in my reading I discover the special register INTENABLE. And I understand that I don't need to enter interrupt to inhibit the interrupts. I have just added:
  1.   movi.n a4, 0
  2.   xsr    a4, INTENABLE
  3.   s32i   a4, a1, SaveMask

<Protected loop code>

  1.   l32i   a4, a1, SaveMask
  2.   wsr    a4, INTENABLE

My first tests show that it works well. During some periods I observe processing speed reduction for a little tens of uS. This is probably the effect of concurrent processing in Core 0. But there is no processing stop period which is what I was expecting.

Giles314
Posts: 4
Joined: Sun Apr 02, 2023 10:25 pm

Re: How to Reserve core 1 for single task

Postby Giles314 » Sun Apr 09, 2023 12:41 pm

Doing more testing I have observed that the behavior of the Core 0 is affected during the time the Core 1 is running with interruptions disabled. Tasks continue to run, but interrupt processing seems not working correctly. In particular no WIFI exchange takes place during that time.

If the interruption disable is continuously maintained too long (approximately more that 1s) the ESP reboots.

I have not yet found a workaround for those behaviors.

MicroController
Posts: 1709
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: How to Reserve core 1 for single task

Postby MicroController » Sun Apr 09, 2023 8:50 pm

I have thought to add a FPGA
Might be overkill :) (Many of the 8-bit AVR uCs have "input capture" functionality in their timers (up to 20MHz), some(?) STM32 can also do it. Probably a cheaper option at scale, but maybe not for one-offs/prototypes of course, if you already have FPGA development infrastructure in place.)

That said, timer input capture would be a useful feature to have in future ESPs... (@Espressif team... *hint* *hint*) :D

Who is online

Users browsing this forum: No registered users and 114 guests