Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by yvesds on October 17, 2017

Hi,

Some help needed (tips, tricks, example code for a absolute beginner on FreeRTOS and ESP32) I have some working example code from my Arduino setup (working with ESP32) but I would love to understand the real FreeRTOS code, that does exactly the same thing for me on the ESP32

Can I post code here (Arduino code - setup() / loop() ) and ask for help, or is that "not done" on this forum I dont need a whole project to be translated, just some tips and explanation of the way FreeRTOS does the same work as the example code I would like to post.

edit : my working platform : Windows 7, Visual Studio Code and Platformio installed and working fine. Arduino IDE with the ESP32 toolchain and working fine. Two ESP32 dev boards : NodeMCU-32S and Wemos LOLINS ESP32, both working well Tried some pure ESP32-IDF FreeRTOS examples and some Arduin ESP32 Toolchain examples (Wifi, Interrupts, ....) all working well

Grtz Yves


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by rtel on October 17, 2017

I'm not so familiar with Arduino, but you can try posting the code as long as there is not too much to read through. Make sure you use the markup tags for pre-formatted code though, otherwise the SourceForge forum will interpret special characters within the code as markup - which you will not notice until after hitting the 'post' button.


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by yvesds on October 17, 2017

Hi, > I'm not so familiar with Arduino, but you can try posting the code as long as there is not too much to read through <

I do not need pure arduino code, more something like : "i do this routine with arduino - how can obtain the same result with FreeRTOS"

Is that OK for this forum

Grtz, Yves


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by rtel on October 17, 2017

Sure.


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by yvesds on October 17, 2017

so here we go with a first example: this code runs perfectly on a NodeMCU-32S.

my goal would be to use both ESP cores - one for the logic (monitoring the interrupts) and one for the output (serial monitor). so one way or another a certain signal will be needed to attend core 2 it has some output to work with :)

first we have to declare a pin for a interrupt, a volatile integer for the counter and a last a integer for counting the number of times the interrupt fired (and to restart the system for example) ~~~ /* let the system know we are on Arduino framework */

include

/* pin where the interrupt will be monitored*/ const byte interruptPin = 25;

/* a overall accessible variable to flag a interrupt */ volatile int interruptCounter = 0;

/* var used for counting */ int numberOfInterrupts = 0;

/* var used for a timestamp */ volatile long interruptFiredTime = 0; ~~~

then we have to set the setup() function, who runs one time on (re-)startup. here we define the serial communication with the monitor, and set the interrupt pin to input and give it a pull-up status. we also have to decide what function will run, once the interrupt gets fired. ~~~ void setup() { /* communication speed with the serial monitor */ Serial.begin(115200);

/* draw some text, so the user knows setup() did run */ Serial.println("Monitoring interrupts: ");

/* set the pinnumber for the interrupt and set the resistor to Pull-up */ pinMode(interruptPin, INPUT_PULLUP);

*/ setup what function has to be called when the interrupt gets fired - "handleInterrupt" - on a falling edge signal */ attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING); } ~~~

then make a ISR function ~~~ /* normaly i would make the ISR as compact as possible and use a flag, but this is to demonstrate / void handleInterrupt() { interruptCounter++; / set the flag to 1 / interruptFiredTime = micros(); / capture a timestamp / } ~~~ we need the loop() function to make this run, in this case it can be used to restart the Mcu, this is a endless loop in Arduino ~~~ void loop(){ if(interruptCounter>0){ / reset the ISR flag to 0 */ interruptCounter--;

   /* counter goes one up */
   numberOfInterrupts++;

   /* display results */
   Serial.print("An interrupt has occurred. Total: ");
   Serial.print(numberOfInterrupts);
   Serial.print("at : ");
   Serial.println(interruptFiredTime);

   /* reset system once we get to 25 */
   if(numberOfInterrupts > 25){
   Serial.println("System restart");
   esp_restart();
   }
 }

} ~~~ So, basicaly there are two things to learn here for me, how to use the 2 cores (xTaskCreatePinnedToCore) and how to make a ISR funtcion that gets information from the interrupt (like a timestamp) and passes it to a function in Core 2 to display this information on the serial monitor


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by edwards3 on October 20, 2017

ESP has some code in github. Also did you see this http://blob.tomerweller.com/esp32-first-steps


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by yvesds on October 20, 2017

Hi MEdwards,

Yes i did read that article. Last night I tried some ESP-IDF examples with the VSCode and platformio setup. They all worked well. But i can not figure out how to set a Task (from interrupt input - a simple button press) on Core 0 to send a signal to Core 1 where another Task has to do some output to the serial monitor.


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by yvesds on October 20, 2017

Hi, I've been adapting a example, and i must say it came to work:

~~~

include
include
include
include "sdkconfig.h"
include "esp_system.h"
include "espheapalloc_caps.h"
include "freertos/FreeRTOS.h"
include "freertos/task.h"
include "freertos/queue.h"
include "freertos/heap_regions.h"
define outputCore 1
define logicCore 0

xQueueHandle demo_queue;

void txtask1(void *arg) { uint32t txpos=0; uint32_t myCore = xPortGetCoreID(); printf("TX1 from Core : %un",myCore);

while (1) {
	if(xQueueSendToBack(demo_queue,&txpos,1000/portTICK_RATE_MS)!=pdTRUE) {
		printf("tx_task1 can not transfer %d\n",txpos);
	}
	vTaskDelay(7000 / portTICK_RATE_MS); // delay 7s
	txpos++;
}

}

void txtask2(void *arg) { uint32t txpos=0; uint32t myCore = xPortGetCoreID(); printf("TX2 from Core :%un",myCore); while (1) { if(xQueueSendToBack(demoqueue,&txpos,1000/portTICKRATEMS)!=pdTRUE) { printf("txtask2 can not transfer %dn",txpos); } vTaskDelay(10000 / portTICKRATE_MS); // delay 10s txpos++; }

}

void rxtask(void *arg) { uint32t rxpos; uint32t myCore = xPortGetCoreID(); printf("This is the receiving Task : rxtaskn"); while (1) { printf("rxtask queue yield"); if(xQueueReceive(demoqueue,&rxpos,60000/portTICKRATEMS)!=pdTRUE) { // max wait 60s printf("nothing received!n"); } else { printf("rxtask received a value %dn",rxpos); printf("Active core : %un",myCore); } if (uxQueueMessagesWaiting(demoqueue)==0) { // no message? take a break printf("nothing to do, take a nap :-)n"); vTaskDelay(15000 / portTICKRATEMS); // delay 15s } } }

void appmain() { printf("constructing & starting ESP32 tasksn"); printf("free DRAM %u IRAM %un",espgetfreeheapsize(),xPortGetFreeHeapSizeTagged(MALLOCCAP_32BIT));

demo_queue = xQueueCreate(10, sizeof(uint32_t));

printf("free DRAM %u IRAM %u\n",esp_get_free_heap_size(),xPortGetFreeHeapSizeTagged(MALLOC_CAP_32BIT));

printf("created three tasks\n");
xTaskCreatePinnedToCore(tx_task1, "tx_task1", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,logicCore);
xTaskCreatePinnedToCore(tx_task2, "tx_task2", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,logicCore);
xTaskCreatePinnedToCore(rx_task, "rx_task", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,outputCore);

printf("end of main\n");

} ~~~ i have the following question now : can i create a ISR task and let that be pinned to a core? the goal is to trap a signal from a button by interrupt, and do some output on the other core...

ah, i have a additional question : in arduino we have something like millis() or micros() who return a timestamp from since the Mcu started after a (re-)boot - is there a similar function in IDF? Grtz, Yves


Help (on ESP32 and FreeRTOS -- migration from Arduino to IDF)

Posted by rtel on October 20, 2017

Sorry for brevity - didn't read all the code but to your two questions: > can i create a ISR task and let that be pinned to a core? > the goal is to trap a signal from a button by interrupt, and do some > output on the other core...

That functionality was added by whoever wrote the FreeRTOS version for the ESP - so sorry I'm not sure.

ah, i have a additional question : in arduino we have something like millis() or micros() who return a timestamp from since the Mcu started after a (re-)boot - is there a similar function in IDF?

You can get the tick count using xTaskGetTickCount(). The frequency is set by your configTICKRATEHZ setting in FreeRTOSConfig.h.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS