Page 3 of 4

Re: Variable doesn't update between cores

Posted: Wed Apr 03, 2019 5:18 pm
by fly135
I learned something today. I didn't realize that FreeRTOS ran in the Aurduino environment. :D

John A

Re: Variable doesn't update between cores

Posted: Thu Apr 04, 2019 11:44 am
by mikemoy
I learned something today. I didn't realize that FreeRTOS ran in the Aurduino environment. :D
Yup, you should give platformIO a try. you can do both with it IDF and ADF. Though i will send a word of caution though with ADF and I2C. In my first days using ADF i liked it because of the ease of OTA over the air that platformIO implements. Over time I have seen many times I2C get choked up. But when using IDF its been a rock. So I no longer do ADF anymore. Not to mention using ADF is a pig on flash and ram.

Re: Variable doesn't update between cores

Posted: Fri Apr 05, 2019 12:21 pm
by HelWeb
For me a similar problem (core 0 tasks data --> core 1 tasks) had been solved with "volatile" variables
for ONE direction. For both directions or more than 2 tasks writing use a semaphore.

Re: Variable doesn't update between cores

Posted: Mon Apr 08, 2019 5:06 am
by spyder0069
HelWeb wrote:
Fri Apr 05, 2019 12:21 pm
For me a similar problem (core 0 tasks data --> core 1 tasks) had been solved with "volatile" variables
for ONE direction. For both directions or more than 2 tasks writing use a semaphore.
Were your failures random? I am still trying to narrow things down. I have built several of my project up just so I can possibly troubleshoot quicker since sometime it can run for days without a failure. This has put me back a week trying to figure this one out. I will see if I can try using a semaphore. Did your task completely halt when you had a problem?

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 2:01 am
by HelWeb
I transfered the code to IDF.
There it works, after i stopped the WatchDog for core 1 <<<
Arduino delay () is not the same as vTaskDelay() - which you should use.
delay() does not a taskswitching, vTaskDelay does.
A Semaphore is not necessary . The access may give a confilict, but until the next test ist done Task1 has the time
to set variable1. But volatile variables should be used.

But it runs without delays and without volatile!

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 2:01 am
by HelWeb
[Codebox]

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"



TaskHandle_t Task0;
TaskHandle_t Task1;

//byte variable1=0;
//byte variable2=0;

// this works
int variable1=0;
int variable2=0;


// this works, its saver
//volatile int variable1=0;
//volatile int variable2=0;


void Task0code( void * pvParameters ){
//delay(1000);
vTaskDelay(1000);
for (;;){ //create an infinate loop
//Serial.println("variable1=" + String(variable1));
printf("Variable 1: %d\n",variable1);
if(variable1>0){
variable1=0;
}else{
variable2=1;
}
//delay(5);
//vTaskDelay(5);

if(variable2==1){
//Serial.println("error");
printf("Error\n");
//delay(1000);
vTaskDelay(1000);

}

}
}



void Task1code( void * pvParameters ){
for (;;){ //create an infinate loop
variable1=1;
//delayMicroseconds(1);
}
}

[/Codebox]

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 2:04 am
by HelWeb
Sorry, a part was missing


[Codebox]
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"



TaskHandle_t Task0;
TaskHandle_t Task1;

//byte variable1=0;
//byte variable2=0;

// this works
int variable1=0;
int variable2=0;


// this works, its saver
//volatile int variable1=0;
//volatile int variable2=0;


void Task0code( void * pvParameters ){
//delay(1000);
vTaskDelay(1000);
for (;;){ //create an infinate loop
//Serial.println("variable1=" + String(variable1));
printf("Variable 1: %d\n",variable1);
if(variable1>0){
variable1=0;
}else{
variable2=1;
}
//delay(5);
//vTaskDelay(5);

if(variable2==1){
//Serial.println("error");
printf("Error\n");
//delay(1000);
vTaskDelay(1000);

}

}
}



void Task1code( void * pvParameters ){
for (;;){ //create an infinate loop
variable1=1;
//delayMicroseconds(1);
}
}




void app_main(void) {
//Serial.begin(115200);



//create a task that will be executed in the Task1code() function, with priority 1 and executed on core 0
xTaskCreatePinnedToCore(
Task0code, /* Task function. */
"Task0", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
2, /* priority of the task */
&Task0, /* Task handle to keep track of created task */
0); /* pin task to core 0 */
//delay(500);
vTaskDelay(500);

//create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1
xTaskCreatePinnedToCore(
Task1code, /* Task function. */
"Task1", /* name of task. */
10000, /* Stack size of task */
NULL, /* parameter of the task */
2, /* priority of the task */
// when priority was set to 100 then network scan would not complete
&Task1, /* Task handle to keep track of created task */
1); /* pin task to core 1 */
//delay(500);
printf("Tasks started\n");
vTaskDelay(500);
}




[/Codebox]

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 4:59 am
by spyder0069
Thank you for the reply. I had looked up the the vtaskdelay vs delay before and came across a post that stated:

"Delay is an arduino function wrapper that calls vtaskdelay. You should use it if you are using arduino"

The page is here:
https://www.esp32.com/viewtopic.php?t=2379

Do you feel this user is wrong then? I don't know enough to be able to look into that and verify it.

In my project I now have it narrowed down to a small section of code that causes my lockup. If I comment those few lines out everything appears to be fine. It takes about a day to verify if things are working or not as it runs fine with no symptoms until it just hangs core1. So I am just going to keep updating a couple of lines at a time until I can better narrow down exactly what line it is and then try to understand whats going on.

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 8:49 am
by boarchuz
HelWeb wrote:
Wed Apr 10, 2019 2:01 am
Arduino delay () is not the same as vTaskDelay() - which you should use.
delay() does not a taskswitching, vTaskDelay does.
FYI vTaskDelay is exactly the way ESP32 implements delay in Arduino.
https://github.com/espressif/arduino-es ... isc.c#L124

Code: Select all

void delay(uint32_t ms)
{
    vTaskDelay(ms / portTICK_PERIOD_MS);
}

Re: Variable doesn't update between cores

Posted: Wed Apr 10, 2019 1:04 pm
by spyder0069
In the delayMicrosecond code on that page it shows that is loops and checks the micros. A note on the arduino page says "As of Arduino 0018, delayMicroseconds() no longer disables interrupts". I wonder if the background housekeeping task may be causing the slightly shakey output of my zero crossing. My pic microcontrollers are very rock solid with the same code. I thought it may have to do with the esp not having a schmitt trigger input like the pic does. Maybe there is something in the background or this implementation of the delayMicroseconds command? On the scope it only varies by maybe 10-50us in between pulses. Is there a way to turn all interrupts off that would affect a delay running in core1 that would not cause problems with wifi and a program running in core0?

Code: Select all

void IRAM_ATTR delayMicroseconds(uint32_t us)
{
    uint32_t m = micros();
    if(us){
        uint32_t e = (m + us);
        if(m > e){ //overflow
            while(micros() > e){
                NOP();
            }
        }
        while(micros() < e){
            NOP();
        }
    }
}