Delay in mS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
vTaskDelay(2000 / portTICK_PERIOD_MS);
The RTOS tick period is (by default) 10ms
N.B. vTaskDelay is no good for small mS delays. It is based on the RTOS tick rate. If you select a value < portTICK_PERIOD_MS you may get a zero delay or you may get a delay of portTICK_PERIOD_MS (so 10mS).
We’ve also found instances where (10 / portTICK_PERIOD_MS) results in a delay of 100mS regardless of the value used! Even vTaskDelay(10) does it. This may be a bug that might get fixed, but one to watch out for if you get weird slowness
Delay in uS
The ROM function ets_delay_us() (defined in rom/ets_sys.h) will allow you to busy-wait a specified number of uS.
Note that this is busy-waiting – it does not allow other tasks to run, it just burns CPU cycles.
#include <rom/ets_sys.h>
ets_delay_us(10); //Stalls execution for #uS
Exact delays
If you have to do something that is extremely time critical for a short period of time you can suspend interrupts and context switches. 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.