FreeRTOS, dual-core, two task, ...to slow

ThomasK
Posts: 25
Joined: Wed Mar 20, 2019 2:33 am

FreeRTOS, dual-core, two task, ...to slow

Postby ThomasK » Wed Mar 20, 2019 2:54 am

A question about the FreeRTOS and dual-core function:
I want to realize a fast loop function that should run in a core. All other side functions should run non-time critical in the other core. I have two tasks, one in each core.
After a few attempts, I did not succeed in realizing this because each task requires a delay(x) with x >= 1ms for the FreeRTOS system. Despite many attempts ... e.g. (esp_task_wdt_add (NULL); esp_task_wdt_reset ();) instead of delay(x) in aCore ... nothing makes me run a fast loop :(
Is it therefore impossible to use it e.g. to run a program loop faster than 1kHz without crashing?
while (1) {
     for (i = 0; i <1000; i ++)
      digitalWrite (pin, HIGH);
     for (i = 0; i <1000; i ++)
      digitalWrite (pin, LOW);
     }
This is of course just an example with the pin, it should then run a measurement program there, but please with about 20kHz and not <1kHz... with a DSO you can see the breaks on the pin.
How can I realize this? I want to use one task in each core, or does this work only if I use only one core for everything, without a task?
I like the ESP32 with its many possibilities and its performance, hopefully not only on paper ....
Thanks for suggestions.

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

Re: FreeRTOS, dual-core, two task, ...to slow

Postby ESP_Sprite » Wed Mar 20, 2019 7:34 am

The proper solution would be: don't. In all likeliness, the ESP32 has got a bunch of peripherals that are way better suited to the job. Look into RMT, and if that doesn't fit, (parallel) I2S or SPI; they're all pretty flexible. If you tell us what problem you're trying to solve, we can probably give you some hints in the right direction.

ThomasK
Posts: 25
Joined: Wed Mar 20, 2019 2:33 am

Re: FreeRTOS, dual-core, two task, ...to slow

Postby ThomasK » Wed Mar 20, 2019 11:23 am

Thanks, I have already tested some internal functions, WIFI, I2S, CAN, ... it works very well.
In general my wish for the project:
My goal is not only to pay for the second core of the ESP32, but also to use it. That's why I wanted to do the time-critical main task in one core and all the other tasks in the second core. So I would have no problems, even slow tasks to do uncomplicated, without disturbing the actual main task.
If I only have one core (or use it), then I will do it and think it works too. With a second independent core, I could do several things for the user that are not needed to live, but would be nice.
1) The main-question: Can I use both core for such a project, if so how? Remember, I want one continuous loops much faster than 1kHz in a core.
2) If I only use one core it is probably possible to increase the clock rate, if necessary up to 240 MHz. In that case, would it be that the other core sleeps or runs at full speed and eat the current, even though it has nothing to do?

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: FreeRTOS, dual-core, two task, ...to slow

Postby idahowalker » Wed Mar 20, 2019 11:31 am

You know you can use vTaskDelay( x ) where x is the number of CPU clock ticks you want to delay? With the ESP32 CPU running at 240Mhz, you get a clock tick every 0.0000041666666666667 ms. All you do is figure out how many clock ticks you want to wait or! You can use vTaskDelayUntil https://www.freertos.org/vtaskdelayuntil.html

To me, now this is just me, assigning one core to that task is a waste of resources at that task will not be doing anything useful for most of the time.

Also, 1000 is not 1mS. if you want the number of clock ticks in a mS use the pdMS_TO_TICKS( x ) macro where x is the number of mS you desire.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: FreeRTOS, dual-core, two task, ...to slow

Postby WiFive » Wed Mar 20, 2019 12:25 pm

idahowalker wrote:
Wed Mar 20, 2019 11:31 am
You know you can use vTaskDelay( x ) where x is the number of CPU clock ticks you want to delay? With the ESP32 CPU running at 240Mhz, you get a clock tick every 0.0000041666666666667 ms. All you do is figure out how many clock ticks you want to wait or! You can use vTaskDelayUntil https://www.freertos.org/vtaskdelayuntil.html

To me, now this is just me, assigning one core to that task is a waste of resources at that task will not be doing anything useful for most of the time.

Also, 1000 is not 1mS. if you want the number of clock ticks in a mS use the pdMS_TO_TICKS( x ) macro where x is the number of mS you desire.
No, it is not in CPU ticks, it is in freertos tick interrupt ticks, which is 1ms or 10ms usually.

ThomasK
Posts: 25
Joined: Wed Mar 20, 2019 2:33 am

Re: FreeRTOS, dual-core, two task, ...to slow

Postby ThomasK » Wed Mar 20, 2019 12:31 pm

That's right, unfortunately :(
So the maximum frequency of this task is again 1 kHz if I set "const TickType_t xFrequency = 1".

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: FreeRTOS, dual-core, two task, ...to slow

Postby idahowalker » Wed Mar 20, 2019 1:13 pm

WiFive wrote:
Wed Mar 20, 2019 12:25 pm
idahowalker wrote:
Wed Mar 20, 2019 11:31 am
You know you can use vTaskDelay( x ) where x is the number of CPU clock ticks you want to delay? With the ESP32 CPU running at 240Mhz, you get a clock tick every 0.0000041666666666667 ms. All you do is figure out how many clock ticks you want to wait or! You can use vTaskDelayUntil https://www.freertos.org/vtaskdelayuntil.html

To me, now this is just me, assigning one core to that task is a waste of resources at that task will not be doing anything useful for most of the time.

Also, 1000 is not 1mS. if you want the number of clock ticks in a mS use the pdMS_TO_TICKS( x ) macro where x is the number of mS you desire.
No, it is not in CPU ticks, it is in freertos tick interrupt ticks, which is 1ms or 10ms usually.
Thanks for that bit on info.

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: FreeRTOS, dual-core, two task, ...to slow

Postby idahowalker » Wed Mar 20, 2019 1:14 pm

In that case one could use ESP.getCycleCount(): https://www.instructables.com/id/625-Na ... icrocontr/

Actually doing a search on " freertos timing faster than millisecond" gives a number of work arounds to the 1mS limit.

There is also using a Hardware Timer and a event trigger to get faster times then 1mS. https://docs.espressif.com/projects/esp ... ialization

ThomasK
Posts: 25
Joined: Wed Mar 20, 2019 2:33 am

Re: FreeRTOS, dual-core, two task, ...to slow

Postby ThomasK » Wed Mar 20, 2019 1:54 pm

I'm an ESP32 freshman ...
The question is not to find a fast timer, but runs the loop faster in a task.
Specifically, perhaps the following example:

void task1 (void * pvParameters) {
   esp_task_wdt_add (NULL);
...
  while (1) {
     for (i = 0; i <1000; i ++)
      digitalWrite (tick, HIGH);
     for (i = 0; i <1000; i ++)
      digitalWrite (tick, LOW);
     esp_task_wdt_reset ();
     }
  }
this works without crash and without delay(x) in a task, but after about 3 clean cycles, the "system" takes about 1ms time, so that high or low are stretched. What makes the "system" in these many times with these many cycles, drink coffee? A cycle time of <0.1 ms should be possible in today's time with these fast cores... or not?

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: FreeRTOS, dual-core, two task, ...to slow

Postby idahowalker » Wed Mar 20, 2019 4:35 pm

This loop does nothing for most of the time it is running but occupy CPU clock ticks

Code: Select all

 while (1) {
     for (i = 0; i <1000; i ++)
      digitalWrite (tick, HIGH);
     for (i = 0; i <1000; i ++)
      digitalWrite (tick, LOW);
     esp_task_wdt_reset ();
     }
   
Your code, from the looks of it, writes 1000 times a HIGH and 1000 times a LOW when all is needed is one write per time cycle. Write the pin high once it stays there, write the pin low once, it stays there.


Code: Select all

#define evtTask     ( 1 << 1 ) // 1
///////////////////////////////////////////////////////////////////////
/* create event group */
EventGroupHandle_t eg;
#define TimerDivider 40
#define TIMER_FOUR 3
#define TaskStack15K 15000
#define Priority5 5
#define TaskCore1 1
#define OneK 1000

hw_timer_t * timer = NULL;

void IRAM_ATTR onTimer()
{
  BaseType_t xHigherPriorityTaskWoken;
  xEventGroupSetBitsFromISR(eg, evtTask, &xHigherPriorityTaskWoken); //
} // void IRAM_ATTR onTimer()

void setup()
{

  eg = xEventGroupCreate();
xTaskCreatePinnedToCore ( task1, "task1", TaskStack15K, NULL, Priority5, NULL, TaskCore1 ); // assigned to core

timer = timerBegin( TIMER_FOUR, TimerDivider, true );
  timerAttachInterrupt( timer, &onTimer, true );
  timerAlarmWrite(timer, OneK, true);
  timerAlarmEnable(timer);
}

void task1 (void * pvParameters) 
{
Bool FlipFlop = true;

  while (1) {
   xEventGroupWaitBits (eg, evtTask, pdTRUE, pdTRUE, portMAX_DELAY);
     If (FlipFlop )
{
      digitalWrite (tick, HIGH);
FlipFlop = false
}
else
{
      digitalWrite (tick, LOW);
 FlipFlop = true;
     }
 vTaskDelete( NULL );
  }
  }

Who is online

Users browsing this forum: mike_dawes and 69 guests