mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-24 14:57:16 +00:00
Add mutex/semaphore for logging - protects new logging_buffer
This commit is contained in:
parent
9c2b8040f1
commit
6b2daa14d0
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user