Migration from Arduino IDE to ESP-IDF
Migration from Arduino IDE to ESP-IDF
Arduino IDE for ESP32 has some important limitations. So I decided to migrate to ESP-IDF.
I installed Arduino as ESP-IDF component as first step for this purpose:
https://github.com/espressif/arduino-es ... -component
But this solution was not completely successful. I got some troubles when I tried to define a custom partition table and with the integration of components written in C and C++ (for example, spiffs).
So, I would like to move my project to ESP-IDF with no Arduino components.
But this is easy so say but difficult to do. My main problem is the lack of documentation. A lot of time is lost trying to find useful information.
I need to develop a couple of routines for the measurement of microseconds and milliseconds similar to the Arduino functions micros() and millis(). I suppose that these functions are not available in ESP-IDF. Therefore, I have to write my own functions.
I believe that I have to use one or two hardware timers:
https://esp-idf.readthedocs.io/en/lates ... timer.html
But I ignore if some of those timers are being used by the ESP-IDF system ( RTOS, tick, etc). I would like to know which ESP32 hardware resources are assigned to ESP-IDF and which others are available for apps.
My particular question is simple: which timer(s) should I use for programing my functions millis() and micros()?.
My current problem is related to timers but probably this is not the only case where the system is allocating hardware resources that are not available for apps.
Thanks in advance for your help.
I installed Arduino as ESP-IDF component as first step for this purpose:
https://github.com/espressif/arduino-es ... -component
But this solution was not completely successful. I got some troubles when I tried to define a custom partition table and with the integration of components written in C and C++ (for example, spiffs).
So, I would like to move my project to ESP-IDF with no Arduino components.
But this is easy so say but difficult to do. My main problem is the lack of documentation. A lot of time is lost trying to find useful information.
I need to develop a couple of routines for the measurement of microseconds and milliseconds similar to the Arduino functions micros() and millis(). I suppose that these functions are not available in ESP-IDF. Therefore, I have to write my own functions.
I believe that I have to use one or two hardware timers:
https://esp-idf.readthedocs.io/en/lates ... timer.html
But I ignore if some of those timers are being used by the ESP-IDF system ( RTOS, tick, etc). I would like to know which ESP32 hardware resources are assigned to ESP-IDF and which others are available for apps.
My particular question is simple: which timer(s) should I use for programing my functions millis() and micros()?.
My current problem is related to timers but probably this is not the only case where the system is allocating hardware resources that are not available for apps.
Thanks in advance for your help.
Re: Migration from Arduino IDE to ESP-IDF
Can you use the same implementation as arduino?
millis() https://github.com/espressif/arduino-es ... misc.c#L50
micros() https://github.com/espressif/arduino-es ... misc.c#L33
millis() https://github.com/espressif/arduino-es ... misc.c#L50
micros() https://github.com/espressif/arduino-es ... misc.c#L33
Re: Migration from Arduino IDE to ESP-IDF
The suggested way of obtaining time is POSIX gettimeofday function (and you can set time using settimeofday).
Both Timer Group peripherals are also available for applications to use, ESP-IDF does not use them internally.
Both Timer Group peripherals are also available for applications to use, ESP-IDF does not use them internally.
Re: Migration from Arduino IDE to ESP-IDF
Hi f.h-f.s,f.h-f.s. wrote:Can you use the same implementation as arduino?
millis() https://github.com/espressif/arduino-es ... misc.c#L50
micros() https://github.com/espressif/arduino-es ... misc.c#L33
Hmmm. Your proposal seems interesting but it requires an important knowledge about the internal Xtensa microprocessor architecture and how it works.
Code: Select all
unsigned long IRAM_ATTR micros()
{
static unsigned long lccount = 0;
static unsigned long overflow = 0;
unsigned long ccount;
portENTER_CRITICAL_ISR(µsMux);
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
if(ccount < lccount){
overflow += UINT32_MAX / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
}
lccount = ccount;
portEXIT_CRITICAL_ISR(µsMux);
return overflow + (ccount / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
}
I am not sure if I understand this instruction:
Code: Select all
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
Yes. I can copy the code and test if it works but I would like to know a little bit of theory before to start the test.
Thanks for your contribution.
Last edited by lmarmisa on Thu Jul 27, 2017 3:15 pm, edited 1 time in total.
Re: Migration from Arduino IDE to ESP-IDF
i think %0 is NULL
Re: Migration from Arduino IDE to ESP-IDF
Hi ESP_igrr,ESP_igrr wrote:The suggested way of obtaining time is POSIX gettimeofday function (and you can set time using settimeofday).
Both Timer Group peripherals are also available for applications to use, ESP-IDF does not use them internally.
thanks for your information.
At this time my interest is related to a function similar to micros(). I need such function for the measurement of the duration of very short events.
The hardware timers look a very promising solution. They are 64-bit generic timers based on 16-bit pre-scalers and 64-bit auto-reload-capable up/down counters. Using the pre-scaler I wish to count with a frequency of 1 MHz (counting up from zero). 64 bit counter is great because there is no problem related to overflow during a half million years.
Re: Migration from Arduino IDE to ESP-IDF
In the inline assembly block, %0 is the reference to the first register in the capture list (given after the assembly statement); and count is the name of the special register. The whole thing looks a bit confusing because both the special register and the variable have the same name.
Re: Migration from Arduino IDE to ESP-IDF
oeh ok, xD good to know
Re: Migration from Arduino IDE to ESP-IDF
Yes. I noticed that the name of the special register is ccount (cycle count register). The assembler statement uses a local variable with the same name for storing the read value. Not so confusing now.ESP_igrr wrote:In the inline assembly block, %0 is the reference to the first register in the capture list (given after the assembly statement); and count is the name of the special register. The whole thing looks a bit confusing because both the special register and the variable have the same name.
Code: Select all
unsigned long IRAM_ATTR micros()
{
static unsigned long lccount = 0;
static unsigned long overflow = 0;
unsigned long ccount;
portENTER_CRITICAL_ISR(µsMux);
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
if(ccount < lccount){
overflow += UINT32_MAX / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
}
lccount = ccount;
portEXIT_CRITICAL_ISR(µsMux);
return overflow + (ccount / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
}
Rollover is a potential problem too. The rollover period is only 17 sec if the standard CPU frequency of 240 MHz is selected. Really a bit short time compared with a 64 bit hardware timer solution.
My first test of micros() was positive. Apparently it works just like in the Arduino environment.
I have to check the alternative solution base on a hardware timer. I have detected a little problem. The function timer_get_counter_value() (esp-idf/components/driver(timer.c) is not defined with the IRAM_ATTR option. Therefore a workaround will be necessary for calling the function millis64() from a interrupt handler routine. Nothing important, I guess.
Re: Migration from Arduino IDE to ESP-IDF
This is because the code modifies static variables. If micros is called from two CPUs around the same time, or if an ISR could preempt a call to micros and call micros again, these variables could be set to inconsistent values. To prevent this, a critical section is used.I have still a doubt. Why a critical section where the interrupts are disabled?. It's really necessary even in the case of nested ISRs?.
This is not the case in ESP-IDF, in general. The interrupt code needs to be in IRAM only if you use ESP_INTR_FLAG_IRAM flag when allocating an interrupt. If you don't use this flag, you can place your interrupt code into flash.Therefore a workaround will be necessary for calling the function millis64() from a interrupt handler routine.
Also, it may not be the right solution for your case, but just for others who might be reading this later: gettimeofday returns time with microsecond precision, and handles wraparounds correctly, so it can be used in place of micros as well.
Who is online
Users browsing this forum: No registered users and 80 guests