mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +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
|
* Miscellaneous
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
@ -1958,6 +2046,10 @@ void SyslogAsync(bool refresh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) {
|
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
|
// Skip initial buffer fill
|
||||||
if (strlen(TasmotaGlobal.log_buffer) < LOG_BUFFER_SIZE - LOGSZ) { return false; }
|
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 (TasmotaGlobal.uptime < 3) { return false; } // Allow time to setup correct log level
|
||||||
if (!req_loglevel || (index == TasmotaGlobal.log_buffer_pointer)) { return false; }
|
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
|
if (!index) { // Dump all
|
||||||
index = TasmotaGlobal.log_buffer_pointer +1;
|
index = TasmotaGlobal.log_buffer_pointer +1;
|
||||||
if (index > 255) { index = 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) {
|
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 "
|
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());
|
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) &&
|
if ((loglevel <= TasmotaGlobal.seriallog_level) &&
|
||||||
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
|
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
|
||||||
Serial.printf("%s%s\r\n", mxtime, log_data);
|
Serial.printf("%s%s\r\n", mxtime, log_data);
|
||||||
|
@ -171,6 +171,7 @@ struct {
|
|||||||
char mqtt_topic[TOPSZ]; // Composed MQTT topic
|
char mqtt_topic[TOPSZ]; // Composed MQTT topic
|
||||||
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
|
char mqtt_data[MESSZ]; // MQTT publish buffer and web page ajax buffer
|
||||||
char log_buffer[LOG_BUFFER_SIZE]; // Web log buffer
|
char log_buffer[LOG_BUFFER_SIZE]; // Web log buffer
|
||||||
|
void *log_buffer_mutex; // control, access to log buffer
|
||||||
} TasmotaGlobal;
|
} TasmotaGlobal;
|
||||||
|
|
||||||
#ifdef SUPPORT_IF_STATEMENT
|
#ifdef SUPPORT_IF_STATEMENT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user