Update RepeatTimer example

Implement semaphore and mutex to safeguard the ISR.
This is the proper way to handle hardware Interrupts with FreeRTOS. The
more regular approach may/will lead to exceptions
This commit is contained in:
me-no-dev 2017-02-20 15:08:11 +02:00
parent e873d577f7
commit b5ac95b274

View File

@ -12,17 +12,21 @@
#define BTN_STOP_ALARM 0
hw_timer_t * timer = NULL;
volatile SemaphoreHandle_t timerSemaphore;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void onTimer(){
static unsigned int counter = 1;
volatile uint32_t isrCounter = 0;
volatile uint32_t lastIsrAt = 0;
Serial.print("onTimer no. ");
Serial.print(counter);
Serial.print(" at ");
Serial.print(millis());
Serial.println(" ms");
counter++;
void IRAM_ATTR onTimer(){
// Increment the counter and set the time of ISR
portENTER_CRITICAL_ISR(&timerMux);
isrCounter++;
lastIsrAt = millis();
portEXIT_CRITICAL_ISR(&timerMux);
// Give a semaphore that we can check in the loop
xSemaphoreGiveFromISR(timerSemaphore, NULL);
// It is safe to use digitalRead/Write here if you want to toggle an output
}
void setup() {
@ -31,6 +35,9 @@ void setup() {
// Set BTN_STOP_ALARM to input mode
pinMode(BTN_STOP_ALARM, INPUT);
// Create semaphore to inform us when the timer has fired
timerSemaphore = xSemaphoreCreateBinary();
// Use 1st timer of 4 (counted from zero).
// Set 80 divider for prescaler (see ESP32 Technical Reference Manual for more
// info).
@ -48,6 +55,21 @@ void setup() {
}
void loop() {
// If Timer has fired
if (xSemaphoreTake(timerSemaphore, 0) == pdTRUE){
uint32_t isrCount = 0, isrTime = 0;
// Read the interrupt count and time
portENTER_CRITICAL(&timerMux);
isrCount = isrCounter;
isrTime = lastIsrAt;
portEXIT_CRITICAL(&timerMux);
// Print it
Serial.print("onTimer no. ");
Serial.print(isrCount);
Serial.print(" at ");
Serial.print(isrTime);
Serial.println(" ms");
}
// If button is pressed
if (digitalRead(BTN_STOP_ALARM) == LOW) {
// If timer is still running