Page 1 of 1

Wait microsecond

Posted: Thu Jan 05, 2017 5:48 pm
by Espagnole
How to wait eg. 40 microsecond inside a task? Time can be longer (interrupts execution), but shouldn't be shorter.

Is this optimal?

Code: Select all

vTaskDelay(configTICK_RATE_HZ / 20000); // 50us

Re: Wait microsecond

Posted: Thu Jan 05, 2017 10:49 pm
by ESP_Angus
The RTOS tick period is (by default) 1ms, so vTaskDelay() will round this down to 0 ticks, and you'll either get no delay or a full time slice (1ms) delay while another task runs. It's not advisable to make the tick period any shorter than 1ms.

The ROM function ets_delay_us() (defined in rom/ets_sys.h) will allow you to busy-wait for a correct number of microseconds. Note that this is busy-waiting, so unlike vTaskDelay it does not allow other tasks to run (it just burns CPU cycles.)

Also it doesn't guarantee that the task won't be preempted by a higher priority task or an interrupt, although you send that longer delays don't matter so this is probably OK in your case.

Re: Wait microsecond

Posted: Fri Jan 06, 2017 3:23 am
by kolban
If we had to do something that was extremely time critical for a short period of time, can we "suspend interrupts" and context switches? Lets say for example I need exclusive CPU control for the next 500 microseconds and was (for some reason) banging bits myself at ultra high precision ... can we do that?

Re: Wait microsecond

Posted: Fri Jan 06, 2017 4:12 am
by ESP_Sprite
Yes, you can. Basically, call portDISABLE_INTERRUPTS (and portENABLE_INTERRUPTS after you're done) and the interrupts on that core should stop firing, stopping task switches as well. Be aware that dependent on what you do, instructions may still not execute at the same speed because of e.g. bus contention, cache misses etc. If you need 100% accurate timings, it's better to wait until a timer has a certain value than executing a loop of instructions. Or, if possible, use a hardware peripherals to generate/capture the signals you need alltogether, negating the need for precise timings.

Re: Wait microsecond

Posted: Tue Jun 20, 2017 6:00 pm
by Ritesh
ESP_Angus wrote:The RTOS tick period is (by default) 1ms, so vTaskDelay() will round this down to 0 ticks, and you'll either get no delay or a full time slice (1ms) delay while another task runs. It's not advisable to make the tick period any shorter than 1ms.

The ROM function ets_delay_us() (defined in rom/ets_sys.h) will allow you to busy-wait for a correct number of microseconds. Note that this is busy-waiting, so unlike vTaskDelay it does not allow other tasks to run (it just burns CPU cycles.)

Also it doesn't guarantee that the task won't be preempted by a higher priority task or an interrupt, although you send that longer delays don't matter so this is probably OK in your case.
Hi,

We have used ets_delay_us API to achieve 10 usec and 40 usec delay as per our requirement and that delay is used in some instructions to update firmware into another module which is attached with UART.

So, we are facing watchdog trigger issue while updating firmware into that module. Does that ets_delay_us API will create issue and generate watchdog trigger?

I have also asked same thing in my question thread. Please find below link for that.

viewtopic.php?f=13&t=2214

Let me Know if you have any idea for that.

Re: Wait microsecond

Posted: Tue Jun 20, 2017 6:02 pm
by Ritesh
Hi All,

Please let me know if anyone has achieved this type of micro seconds delay support in application firmware.

I need 10 and 40 microseconds delay support as per request.

Re: Wait microsecond

Posted: Tue Jun 20, 2017 10:00 pm
by kolban

Re: Wait microsecond

Posted: Sat May 04, 2019 11:09 pm
by burgersonbrioche
The arduino-esp32 core achieves this using the following code for the delayMicroseconds() func.

Code: Select all

#include "freertos/FreeRTOS.h"

#define NOP() asm volatile ("nop")

unsigned long IRAM_ATTR micros()
{
    return (unsigned long) (esp_timer_get_time());
}
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();
        }
    }
}
I know this is a bit of an old thread but hoping this will help if anyone runs into this issue.

Re: Wait microsecond

Posted: Sun May 05, 2019 5:02 pm
by Ritesh
burgersonbrioche wrote:
Sat May 04, 2019 11:09 pm
The arduino-esp32 core achieves this using the following code for the delayMicroseconds() func.

Code: Select all

#include "freertos/FreeRTOS.h"

#define NOP() asm volatile ("nop")

unsigned long IRAM_ATTR micros()
{
    return (unsigned long) (esp_timer_get_time());
}
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();
        }
    }
}
I know this is a bit of an old thread but hoping this will help if anyone runs into this issue.
Thanks for your response..