Variable doesn't update between cores

spyder0069
Posts: 35
Joined: Tue Jan 29, 2019 2:46 am

Re: Variable doesn't update between cores

Postby spyder0069 » Tue Apr 02, 2019 12:23 pm

I appreciate your input. I thought since I had nothing in the loop that it took no resources. What should be put in Loop so that it doesn't bog the two tasks down? Will a delay command be all that is necessary?

For what I am trying to accomplish with the zero crossing task dedicated to core1 if that is put in the loop instead of a separate task will it run on core1 and if so will it be less of a priority or interrupted by other things going on?

Does the priority level just assign clock cycles to each task? Why would a bogged down core have an effect on the other core? Would it somehow change the amount of clock cycles the other core is allowed?

username
Posts: 479
Joined: Thu May 03, 2018 1:18 pm

Re: Variable doesn't update between cores

Postby username » Tue Apr 02, 2019 1:50 pm

I appreciate your input. I thought since I had nothing in the loop that it took no resources. What should be put in Loop so that it doesn't bog the two tasks down? Will a delay command be all that is necessary?
Loop is constantly running, granted there is nothing for it to do when its empty. But in essence you have have 3 tasks. The two you created and then Loop. I'd just put a delay of a second in there.

I don't use ESP-ADF so my example with be in ESP-IDF. The concept is the same. You may look at this code example and think it would work just fine. Yet it doen't work at all. You may be saying I have a a higher priority for task1, and its pinned to its own core. What could be the issue. Well. you need to learn about what is called the scheduler in a RTOS environment. If your task never releases itself to the scheduler your going to run into trouble. The scheduler is like the overlord who tells what to run next and for how long.


Code: Select all

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "sdkconfig.h"


xTaskHandle TaskHandle_Task1;
xTaskHandle TaskHandle_Task2;

/* Can run 'make menuconfig' to choose the GPIO to blink,
   or you can edit the following line and set a number here.
*/
#define BLINK_GPIO CONFIG_BLINK_GPIO

void task1(void *pvParameter)
{
    gpio_pad_select_gpio(BLINK_GPIO);

	/* Set the GPIO as a push/pull output */
    gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
    while(1) 
    {
        /* Blink off (output low) */
        gpio_set_level(BLINK_GPIO, 0);
        //vTaskDelay(1 / portTICK_PERIOD_MS);
        /* Blink on (output high) */
        gpio_set_level(BLINK_GPIO, 1);
        //vTaskDelay(1 / portTICK_PERIOD_MS);
    }
}
void task2(void *pvParameter)
{
	uint16_t x = 0;

	while (1) 
	{
		printf("Hello World:%u\r\n", x++);
		vTaskDelay(200 / portTICK_PERIOD_MS);
	}
}

void app_main()
{
	xTaskCreatePinnedToCore(&task1, "task1", 2048, NULL, 10, &TaskHandle_Task1, 0);
	xTaskCreatePinnedToCore(&task2, "task2", 2048, NULL, 5, &TaskHandle_Task2, 1);
}

Here is what the output is doing when you run this.

E (370292) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (370292) task_wdt: - IDLE0 (CPU 0)
E (370292) task_wdt: Tasks currently running:
E (370292) task_wdt: CPU 0: task1
E (370292) task_wdt: CPU 1: IDLE1
Now if you un-comment the delays in task 1 you may now think "Hey I have a delay in there now things are good to go" but still no. a delay of 1 is not enough time to release this Task to perform any other tasks you created and all the background stuff (things you dont see that keep the processor going). So you still stave the other tasks for CPU time and you will get this in the output even with those delays in there.
E (30292) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (30292) task_wdt: - IDLE0 (CPU 0)
E (30292) task_wdt: Tasks currently running:
E (30292) task_wdt: CPU 0: task1
E (30292) task_wdt: CPU 1: IDLE1
Now if you change the delays to say 10, then it will run and you will now get this in the output.
Hello World:0
Hello World:1
Hello World:2
Hello World:3
Hello World:4
Hello World:5
and so on...
Now, your not out of the woods just yet. Just because its working now does not mean its working right. with a delay of 10 it works but with a delay of 5 it doesn't. So whats happening here is that with a delay of 10 your on the border line. Though it works, your not giving enough time for other tasks to run. With a delay of 200 (I.E. 200 ms) you should get a Hello World output 4 times a second, and in this example you do. But if you change that to say 25, Task1 is not going to give Task2 enough time to do spit those out fast enough anymore.

Basically is a balance game of what your trying to do per task and priority, delays, and other options so you can ensure each task is getting enough time to do what it needs to do and not hinder another task from getting CPU time to run.

Like another poster mentioned there are even yet other ways to skin this cat like using semaphores.

You can even do something like this as well. So that this task will do nothing until its signaled to do so. Thus you dont need to be concerned about delays here.

Code: Select all

const int ALARM_NORMAL_TIMER_START_BIT = BIT0;
EventGroupHandle_t timer_event_group;

void alarmTaskNormal(void * parameter)
{
	timer_event_group = xEventGroupCreate();
	
	// Clear the bit
	xEventGroupClearBits(timer_event_group, TIMER_START_BIT);

	for (;;)
	{
		// Wait here until we are signaled to start
		xEventGroupWaitBits(timer_event_group, TIMER_START_BIT, true, false, portMAX_DELAY);

		printf("Timer Triggered\r\n");
	}
}


What happens here in this task, is it will sit and wait on xEventGroupWaitBits(). Only until another task issues this command will it then fall out from waiting and do the next line of code.
xEventGroupSetBits(timer_event_group, TIMER_START_BIT);


I cannot emphasize enough how important it is to learn how things work in a RTOS environment. Its a whole different mindset than line by line code which is what people are used to in Arduino. But I would bet anything that once a person invests the time to learn it they will never look back and only prefer a RTOS way.

spyder0069
Posts: 35
Joined: Tue Jan 29, 2019 2:46 am

Re: Variable doesn't update between cores

Postby spyder0069 » Tue Apr 02, 2019 3:17 pm

That is a lot to take in and I appreciate you taking the time to answer my questions. :^)

Its hard for me wrap my head around this.

Also I see in your code you have:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

I do not have these in mine but from what I can tell both cores and tasks are operating. I took my code from samples on someones webpage.

username
Posts: 479
Joined: Thu May 03, 2018 1:18 pm

Re: Variable doesn't update between cores

Postby username » Tue Apr 02, 2019 3:47 pm

Also I see in your code you have:
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
Yes, this is not Arduino code. There are 2 primary ways to code for the ESP32. ESP-ADF and ESP-IDF. ADF is the Arduino side of things.
Being Arduino, there is allot more things hidden from the user that is going on in the background.

spyder0069
Posts: 35
Joined: Tue Jan 29, 2019 2:46 am

Re: Variable doesn't update between cores

Postby spyder0069 » Tue Apr 02, 2019 7:59 pm

Well the good news is my issue on my project is not related to the shared variable. The bad news is its something more complexing.

I commented out that check so the only thing happening in my core1 task was the check of some buttons and I put in a delay(200). After many hours the core1 task stops running. No longer responds to button checks. My code in core0 task still is running fine as I have a webserver on that as well as some sensors and its responding just fine. I have 5 different units built and all exhibit the issue at some point. I added the delay in the normal loop and am letting a couple run. I have also removed the core1 task all together and instead put that code in the main loop to see if it ever stops responding. Any ideas what could cause a task to just stop after some time? Especially something as simple as checking button press? I though I read somewhere there was a way to see what the status of a task is. Should this be the next troubleshooting step? Have the working task report the status of the other core to see if it still exists or is running? As a newbie I am not sure what is the best way to troubleshoot this problem. Open to any advice. :^)

username
Posts: 479
Joined: Thu May 03, 2018 1:18 pm

Re: Variable doesn't update between cores

Postby username » Wed Apr 03, 2019 1:22 am

For myself, i can't help too much because its Arduino. But you should post your complete code for others to have a lookse

markkuk
Posts: 38
Joined: Wed Mar 27, 2019 11:50 am

Re: Variable doesn't update between cores

Postby markkuk » Wed Apr 03, 2019 9:52 am

spyder0069 wrote:
Tue Apr 02, 2019 7:59 pm
I though I read somewhere there was a way to see what the status of a task is. Should this be the next troubleshooting step? Have the working task report the status of the other core to see if it still exists or is running?
Set up a Task Watchdog Timer. If that doesn't help, start studying JTAG debugging.

spyder0069
Posts: 35
Joined: Tue Jan 29, 2019 2:46 am

Re: Variable doesn't update between cores

Postby spyder0069 » Wed Apr 03, 2019 2:34 pm

It didn't lock over night so I'm crossing my fingers and not touching anything for a few days and see if any of them have a problem. I don't want to add code on top until I am more confident in them.

I am using the dev boards that have an OLED display built on to them and powering them from a meanwell 5v 400ma supply. I know the normal operating current is under 200ma but I have been doing some reading that their may be spikes with the wifi (which I am using). Since this problem was pretty strange I am wondering if there was a power problem if it could cause one of the cores to lock and the other to continue running. I would have assumed the brown out detect in the chip would catch things. I also will be adding a relay to this circuit in the future which draws 100ma so I am wondering if the 400ma supply is going to be questionable.

username
Posts: 479
Joined: Thu May 03, 2018 1:18 pm

Re: Variable doesn't update between cores

Postby username » Wed Apr 03, 2019 4:04 pm

You better just play it safe and get a wall wart that is 5v 1A. They can be had all over the place for a few dollars.
While your at it you might want to get something like this to know what your actually using and the peaks.
(NOTE: not saying to get this one, so do some homework on whats best for you)

https://www.amazon.com/DROK-Accurate-Vo ... GYZKW1M9RC

or


https://www.amazon.com/DROK-Multimeter- ... ay&sr=8-49

spyder0069
Posts: 35
Joined: Tue Jan 29, 2019 2:46 am

Re: Variable doesn't update between cores

Postby spyder0069 » Wed Apr 03, 2019 4:22 pm

I am designing for a product in an enclosure. :^)

1 amp transformer is going to be larger size than the enclosure can handle. Currently I am using:

https://www.mouser.com/ProductDetail/709-IRM02-5

I have order the next step up:

https://www.mouser.com/ProductDetail/709-IRM03-5

That will get me 600ma.

I have an oscilloscope and fluke 87V. I will take a look at my power on the scope when I get a chance. The dev board has the 3.3V regulator but who knows the quality. I'll have to try attaching everything on a bench supply and see at what voltage things start having a problem.

Who is online

Users browsing this forum: No registered users and 99 guests