Use of dual core

kamesh
Posts: 35
Joined: Sat Aug 06, 2016 5:14 am

Use of dual core

Postby kamesh » Tue Dec 20, 2016 7:24 am

Hi,

ESP32 is having dual core processor. I need to know what is dual core processor and how to use single , dual processor and how to segregate from one to another. Can anyone give suggestion on this.



Thanks,
Kamesh.

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

Re: Use of dual core

Postby ESP_Sprite » Tue Dec 20, 2016 9:29 am

Okay, you're asking about a pretty broad subject. Is there anything in particular you need to know?

kamesh
Posts: 35
Joined: Sat Aug 06, 2016 5:14 am

Re: Use of dual core

Postby kamesh » Tue Dec 20, 2016 9:41 am

hi,

I need to use one processor some time and other for later times.

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

Re: Use of dual core

Postby ESP_Sprite » Tue Dec 20, 2016 1:05 pm

Sorry, you're about as clear as mud. What exactly are you trying to archieve, with which tools, and how do you feel dual-core is a solution to that? What have you already tried, and where did you get stuck?

BakerMan
Posts: 7
Joined: Tue Jan 24, 2017 1:26 pm

Re: Use of dual core

Postby BakerMan » Tue Jan 24, 2017 1:48 pm

Hello Folks,

i also have a question about using the second core of the ESP32.
Iam quite new in bussines, so i have to appologize, if i describe or understood something wrong.

I want to run one single task on each CPU-core. The first task executes time critical GPIO-Operations. The second Task performs UART Communiation. Both tasks should have (threadsave) access to several data buffers. Usually i programm in C#, so i dont have to care about memory management. I got a lot of crashes before i realized, that big arrays wont fit into the stack. I have the choice to make the stack bigger, or i allocate memory inside the heap. So here are my questions:

1) How do i enable the second core ? Is it done with the settings in the sdkconfig-file only?
2) How i do assign a single task to each core? Is this possible, or does rtos manage this for me?
3) How do i define the size of the heap for each task?
4) In the technical papers i found out, that the hole memory is split into several pieces, for example SRAM2 (200KB), wich is shared between the cores at the same adress range. Can i allocate memory for buffer arrays on a fixed place (for example in SRAM2), which
can be acessed easily by both cores? How do i do that? My Code is controlled by on task only, and there are mechanisms to make it threadsave. But i dont have a clue how to do this in ESP32.

Please help a willing to learn noob.

Kind Regards

Tino

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

Re: Use of dual core

Postby ESP_Sprite » Wed Jan 25, 2017 9:59 am

The second core is normally enabled. You can disable it using the sdkconfig file, which you would normally 'edit' by running 'make menuconfig'. If you start up a task using the FreeRTOS xTaskCreate function, FreeRTOS will automatically run the task on any of the two CPUs, whichever one is free. You can also 'pin' a task to one single CPU by using xTaskCreatePinnedToCore. All memory* is shared between both CPUs; a you can happily reference a variable and get the same data regardless of where your task runs. In your case, for instance, you can just make a global array, or a global pointer to a malloc()'ed memory region, and you can use that as shared memory. Please do look at the various functions FreeRTOS has to offer for cross-thread interaction (queues, semaphores, muxes): these work in exactly the same way for tasks that run on different cores.


*: With the exception of some ROM; unless you're hacking in the innards of esp-idf you shouldn't notice that however.

BakerMan
Posts: 7
Joined: Tue Jan 24, 2017 1:26 pm

Re: Use of dual core

Postby BakerMan » Thu Jan 26, 2017 1:37 pm

Hello again!

Thank you very much for your advice. That helped a lot. What i have done in the main task is:

1) Allocate several Memory-Areas with a Start Pointers. For example

Code: Select all

 char *Buf = pvPortMallocCaps(DATA_BUFFER_SIZE, MALLOC_CAP_8BIT);


2) Defined a Struct Type Containing these Pointers.

Code: Select all

typedef struct  {
   char *BufStartAdress;
...
}paramSet;


3) create a paramSet with that struct type and initialized it with the Memory-Pointers:

Code: Select all

   paramSet *ParamPTR = pvPortMallocCaps(8, MALLOC_CAP_32BIT);
   ParamPTR->BufStartAdress    = Buf;


4) Started one task for each CPU and give them the ParamSet as single Parameter

Code: Select all

   xReturned1 = xTaskCreatePinnedToCore(&UartAndOther, "UartAndOther", 2048, ParamPTR, 1, NULL, 0);
   xReturned2=  xTaskCreatePinnedToCore(&RealTimeThread, "RealTimeThread", 2048, ParamPTR, 25, NULL, 1);


After that the original maintask terminates. I know its possible, to keep all the Uart stuff running from this task, and i dont have to start a new one. Everything works fine, but...unfortunately...i have Problems with the Tick-Event from RTOS. There is a gap of about 5usecs every 1msec (1000HZ) in my test signal which is generated als simple while loop on CPU 1. This is not acceptable in my application. Ive tried a lot without success. So i have to ask if there is one of the following things possible:

a) Starting Programm-Code on CPU1 without RTOS. There is an Option in Menuconfig to rum Rtos on CPU0 only, but then i cant start the task on CPU1. How else can i put code on that RTOS-Disabled CPU1?
b) Disabling RTOS on CPU1 inside the task because there is only this single "task" running.
c) Disabling the Tick-Timer (global interrupt?). The vTaskSuspendAll() function still keeps the ticks.

What i whould like to have is an RTOS controlled Environment on CPU0 with a lot of threads, and a NON-RTOS Enviroment on CPU1 for time crittical GPIO Stuff. I dont intend to use timers or Interrupts on this CPU at all. Its a pure while loop brutforcing incoming and outgoing data on an interface, which is connected to GPIO Pins. The Thread gets controlled over the shared memory given as pointer over via paramset.

It would be creat if you can help me...

Thank you very much

Kind regards

P.S: There are some threads with similar issues in this forum. Maybe this post can be linked to them.
viewtopic.php?f=13&t=802&p=3373&hilit=disable+freertos#p3373

ESP_igrr
Posts: 714
Joined: Tue Dec 01, 2015 8:37 am

Re: Use of dual core

Postby ESP_igrr » Thu Jan 26, 2017 4:25 pm

If you don't want to run FreeRTOS on CPU1, you can override startup code by implementing void start_cpu1(void) function, similar to this:

Code: Select all

void IRAM_ATTR start_cpu1_default(void)
{
    // Wait for the app to initialze on CPU0
    while (!g_my_app_init_done) {
        ;
    }
    // do things
}


Take note though, all your code on APP CPU has to be in IRAM in this case, and all read-only data (strings included) has to be explicitly placed into DRAM (using IRAM_ATTR and DRAM_ATTR). This is because tasks running on the CPU 0 may disable flash cache at some times. Normally, when FreeRTOS is running on both cores, there is mechanism which prevents non-cached code from running on the other CPU while cache is disabled. Without support from FreeRTOS scheduler, you're on your own though.

Also make sure you disable interrupt watchdog on CPU1 when not using RTOS (the option is called "Also watch CPU1 tick interrupt" under "ESP32-specific" menu).

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

Re: Use of dual core

Postby ESP_Sprite » Fri Jan 27, 2017 1:51 am

Alternatively, you can do what you do now, but disable the tick interrupt on the app cpu. Executing that is essentially what causes the 5uS delay. (Also disable the tick interrupt app watchdog, as Ivan said, otherwise it'll complain.)

BakerMan
Posts: 7
Joined: Tue Jan 24, 2017 1:26 pm

Re: Use of dual core

Postby BakerMan » Fri Jan 27, 2017 9:22 am

Good Morning,

thank you for your answers!

Ive tried to implement my own "cpu1_start"-procedure. It seemed to work until i used the command "gpio_set_level" which worked excatly one time. If i want to set the level to low, the uController resets. I keep investigating on that, maybe i get a solutiion there.

The cpu1 task watchdogis already disabled. So maybe the advice from ESP_Sprite whould be an alternative solution. As compromise i dont want to let the scheduler tick 1000 times per second async, it also can tick 8000 times per second syncrounus to my task for example, or less frequent. The 3-5usecs are only a problem because they appear when data is arrived. So ive to ask if:

1) Is it possible to let the os tick when i want to? Maybe with a different rate like on cpu0? I know, its a little bit shitty, to let control the os from a task. Ive read yesterday, that you can put code in a "critical statement", but i did not succeed to keep the tick away.
2) Iam pretty limited in my knowledge and abilities with the ESP32, so can you please giv me an advice how i isable and enable the os-tick?

Thank you very much, without you i whouldnt have gone so far...

Kind regards

Who is online

Users browsing this forum: No registered users and 4 guests