Use esp_timer_get_time as time source for micros and mills (#1424)

esp_timer_get_time returns monotonic time in microseconds, as a 64-bit
number. It can be called from tasks and interrupts, does not use any
critical sections/mutexes, and is thread safe.
This commit is contained in:
Ivan Grokhotkov 2018-05-22 16:12:30 +02:00 committed by Me No Dev
parent dd639c4a02
commit 93c45af256
2 changed files with 3 additions and 41 deletions

View File

@ -21,7 +21,7 @@
#include "nvs.h" #include "nvs.h"
#include "esp_partition.h" #include "esp_partition.h"
#include "esp_log.h" #include "esp_log.h"
#include "pthread.h" #include "esp_timer.h"
#include <sys/time.h> #include <sys/time.h>
//Undocumented!!! Get chip temperature in Farenheit //Undocumented!!! Get chip temperature in Farenheit
@ -38,51 +38,14 @@ void yield()
vPortYield(); vPortYield();
} }
portMUX_TYPE microsMux = portMUX_INITIALIZER_UNLOCKED;
static pthread_key_t microsStore=NULL; // Thread Local Storage Handle
void microsStoreDelete(void * storage) { // release thread local data when task is delete.
if(storage) free(storage);
}
unsigned long IRAM_ATTR micros() unsigned long IRAM_ATTR micros()
{ {
if (!microsStore) { // first Time Ever thread local not init'd return (unsigned long) esp_timer_get_time();
portENTER_CRITICAL_ISR(&microsMux);
pthread_key_create(&microsStore,microsStoreDelete); // create initial holder
portEXIT_CRITICAL_ISR(&microsMux);
}
uint32_t *ptr;// [0] is lastCount, [1] is overFlow
ptr = pthread_getspecific(microsStore); // get address of storage
if(ptr == NULL) { // first time in this thread, allocate mem, init it.
portENTER_CRITICAL_ISR(&microsMux);
ptr = (uint32_t*)malloc(sizeof(uint32_t)*2);
pthread_setspecific(microsStore,ptr); // store the pointer to this thread's values
ptr[0] = 0; // lastCount value
ptr[1] = 0; // overFlow
portEXIT_CRITICAL_ISR(&microsMux);
}
unsigned long ccount;
portENTER_CRITICAL_ISR(&microsMux);
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); //get cycle count
if(ccount < ptr[0]) { // overflow occurred
ptr[1] += UINT32_MAX / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
}
ptr[0] = ccount;
portEXIT_CRITICAL_ISR(&microsMux);
return ptr[1] + (ccount / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ);
} }
unsigned long IRAM_ATTR millis() unsigned long IRAM_ATTR millis()
{ {
return xTaskGetTickCount() * portTICK_PERIOD_MS; return (unsigned long) (esp_timer_get_time() / 1000);
} }
void delay(uint32_t ms) void delay(uint32_t ms)

View File

@ -14,7 +14,6 @@ void loopTask(void *pvParameters)
{ {
setup(); setup();
for(;;) { for(;;) {
micros(); //update overflow
loop(); loop();
} }
} }