Add mutex/semaphore for logging - protects new logging_buffer

This commit is contained in:
Simon Hailes 2020-12-31 11:36:35 +00:00
parent 9c2b8040f1
commit 6b2daa14d0
2 changed files with 106 additions and 0 deletions

View File

@ -111,6 +111,94 @@ String GetResetReason(void)
}
}
/*********************************************************************************************\
* ESP32 AutoMutex
\*********************************************************************************************/
//////////////////////////////////////////
// automutex.
// create a mute in your driver with:
// void *mutex = nullptr;
// TasAutoMutex::init(&mutex);
//
// then protect any function with
// TasAutoMutex m(mutex);
// - it will be automagically released when the function is over.
// - the same thread can take multiple times (recursive).
// - advanced options m.give() and m.take() allow you fine control within a function.
class TasAutoMutex {
#ifdef ESP32
SemaphoreHandle_t mutex;
#endif
bool taken;
public:
TasAutoMutex(void * mutex, bool take=true);
~TasAutoMutex();
void give();
void take();
static void init(void ** ptr);
};
//////////////////////////////////////////
TasAutoMutex::TasAutoMutex(void * mutex, bool take){
#ifdef ESP32
if(mutex){
if (take){
xSemaphoreTakeRecursive(mutex, portMAX_DELAY);
this->taken = true;
}
this->mutex = (SemaphoreHandle_t ) mutex;
} else {
this->mutex = (SemaphoreHandle_t )nullptr;
}
#endif
}
TasAutoMutex::~TasAutoMutex(){
#ifdef ESP32
if (this->mutex){
if (this->taken){
xSemaphoreGiveRecursive(this->mutex);
this->taken = false;
}
}
#endif
}
void TasAutoMutex::init(void ** ptr){
#ifdef ESP32
SemaphoreHandle_t mutex = xSemaphoreCreateRecursiveMutex();
(*ptr) = (void *) mutex;
#else
// needed, else we will initialis more than once in logging
(*ptr) = (void *) 1;
#endif
}
void TasAutoMutex::give(){
#ifdef ESP32
if (this->mutex){
if (this->taken){
xSemaphoreGiveRecursive(this->mutex);
this->taken= false;
}
}
#endif
}
void TasAutoMutex::take(){
#ifdef ESP32
if (this->mutex){
if (!this->taken){
xSemaphoreTakeRecursive(this->mutex, portMAX_DELAY);
this->taken = true;
}
}
#endif
}
/*********************************************************************************************\
* Miscellaneous
\*********************************************************************************************/
@ -1958,6 +2046,10 @@ void SyslogAsync(bool refresh) {
}
bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) {
// this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex);
// Skip initial buffer fill
if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; }
@ -1973,6 +2065,10 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l
if (TasmotaGlobal.uptime < 3) { return false; } // Allow time to setup correct log level
if (!req_loglevel || (index == TasmotaGlobal.log_buffer_pointer)) { return false; }
// this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex);
if (!index) { // Dump all
index = TasmotaGlobal.log_buffer_pointer +1;
if (index > 255) { index = 1; }
@ -2011,9 +2107,18 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l
}
void AddLogData(uint32_t loglevel, const char* log_data) {
if (!TasmotaGlobal.log_buffer_mutex){
TasAutoMutex::init(&TasmotaGlobal.log_buffer_mutex);
}
char mxtime[14]; // "13:45:21.999 "
snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d.%03d "), RtcTime.hour, RtcTime.minute, RtcTime.second, RtcMillis());
// this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex);
if ((loglevel <= TasmotaGlobal.seriallog_level) &&
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
Serial.printf("%s%s\r\n", mxtime, log_data);

View File

@ -171,6 +171,7 @@ struct {
char mqtt_topic[TOPSZ]; // Composed MQTT topic
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
char log_buffer[LOG_BUFFER_SIZE]; // Web log buffer
void *log_buffer_mutex; // control, access to log buffer
} TasmotaGlobal;
#ifdef SUPPORT_IF_STATEMENT