switch to Recursive Mutex and non-blocking

This commit is contained in:
Hendrik Schutter 2024-12-13 22:29:48 +01:00
parent 8205253b5a
commit 1af962190e
6 changed files with 88 additions and 36 deletions

View File

@ -43,6 +43,7 @@ Safety <|-- HTTP_Metrics
-taskSafety() -taskSafety()
-setSafeState() -setSafeState()
-checkSensorSanity() -checkSensorSanity()
+getSensorSanityStates()
+getSafetyState() +getSafetyState()
} }

View File

@ -45,12 +45,12 @@ void initInputs(void)
gpio_config(&ioConfBurnerFault); gpio_config(&ioConfBurnerFault);
xMutexAccessInputs = xSemaphoreCreateBinary(); xMutexAccessInputs = xSemaphoreCreateRecursiveMutex();
if (xMutexAccessInputs == NULL) if (xMutexAccessInputs == NULL)
{ {
ESP_LOGE(TAG, "Unable to create mutex"); ESP_LOGE(TAG, "Unable to create mutex");
} }
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
BaseType_t taskCreated = xTaskCreate( BaseType_t taskCreated = xTaskCreate(
taskInput, // Function to implement the task taskInput, // Function to implement the task
@ -122,7 +122,7 @@ void taskInput(void *pvParameters)
while (1) while (1)
{ {
vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS); vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS);
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, portMAX_DELAY) == pdTRUE)
{ {
sChamperTemperature.state = MEASUREMENT_FAULT; sChamperTemperature.state = MEASUREMENT_FAULT;
sOutdoorTemperature.state = MEASUREMENT_FAULT; sOutdoorTemperature.state = MEASUREMENT_FAULT;
@ -196,7 +196,16 @@ void taskInput(void *pvParameters)
} }
} }
} }
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
sChamperTemperature.state = MEASUREMENT_FAULT;
sOutdoorTemperature.state = MEASUREMENT_FAULT;
sInletFlowTemperature.state = MEASUREMENT_FAULT;
sReturnFlowTemperature.state = MEASUREMENT_FAULT;
ESP_LOGE(TAG, "Unable to take mutex: taskInput()");
} }
} }
} }
@ -205,10 +214,14 @@ sMeasurement getChamberTemperature(void)
{ {
sMeasurement ret; sMeasurement ret;
ret.state = MEASUREMENT_FAULT; ret.state = MEASUREMENT_FAULT;
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sChamperTemperature; ret = sChamperTemperature;
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getChamberTemperature()");
} }
return ret; return ret;
} }
@ -217,10 +230,14 @@ sMeasurement getOutdoorTemperature(void)
{ {
sMeasurement ret; sMeasurement ret;
ret.state = MEASUREMENT_FAULT; ret.state = MEASUREMENT_FAULT;
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sOutdoorTemperature; ret = sOutdoorTemperature;
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getOutdoorTemperature()");
} }
return ret; return ret;
} }
@ -229,10 +246,14 @@ sMeasurement getInletFlowTemperature(void)
{ {
sMeasurement ret; sMeasurement ret;
ret.state = MEASUREMENT_FAULT; ret.state = MEASUREMENT_FAULT;
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sInletFlowTemperature; ret = sInletFlowTemperature;
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getInletFlowTemperature()");
} }
return ret; return ret;
} }
@ -241,10 +262,14 @@ sMeasurement getReturnFlowTemperature(void)
{ {
sMeasurement ret; sMeasurement ret;
ret.state = MEASUREMENT_FAULT; ret.state = MEASUREMENT_FAULT;
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sReturnFlowTemperature; ret = sReturnFlowTemperature;
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getReturnFlowTemperature()");
} }
return ret; return ret;
} }
@ -252,10 +277,14 @@ sMeasurement getReturnFlowTemperature(void)
eBurnerErrorState getBurnerError(void) eBurnerErrorState getBurnerError(void)
{ {
eBurnerErrorState ret = FAULT; eBurnerErrorState ret = FAULT;
if (xSemaphoreTake(xMutexAccessInputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessInputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sBurnerErrorState; ret = sBurnerErrorState;
xSemaphoreGive(xMutexAccessInputs); xSemaphoreGiveRecursive(xMutexAccessInputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getBurnerError()");
} }
return ret; return ret;
} }

View File

@ -205,7 +205,7 @@ void taskMetrics(void *pvParameters)
void vSetMetrics(sMetric *paMetrics, uint16_t u16Size) void vSetMetrics(sMetric *paMetrics, uint16_t u16Size)
{ {
if (xSemaphoreTake(xMutexAccessMetricResponse, (TickType_t)100) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessMetricResponse, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
memset(caHtmlResponse, 0, strlen(caHtmlResponse)); memset(caHtmlResponse, 0, strlen(caHtmlResponse));
for (uint16_t u16Index = 0U; u16Index < u16Size; u16Index++) for (uint16_t u16Index = 0U; u16Index < u16Size; u16Index++)
@ -217,7 +217,7 @@ void vSetMetrics(sMetric *paMetrics, uint16_t u16Size)
strcat(caHtmlResponse, caValueBuffer); strcat(caHtmlResponse, caValueBuffer);
strcat(caHtmlResponse, "\n"); strcat(caHtmlResponse, "\n");
} }
xSemaphoreGive(xMutexAccessMetricResponse); xSemaphoreGiveRecursive(xMutexAccessMetricResponse);
} }
else else
{ {
@ -314,10 +314,10 @@ void connect_wifi(void)
esp_err_t get_metrics_handler(httpd_req_t *req) esp_err_t get_metrics_handler(httpd_req_t *req)
{ {
if (xSemaphoreTake(xMutexAccessMetricResponse, (TickType_t)100) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessMetricResponse, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
esp_err_t err = httpd_resp_send(req, caHtmlResponse, HTTPD_RESP_USE_STRLEN); esp_err_t err = httpd_resp_send(req, caHtmlResponse, HTTPD_RESP_USE_STRLEN);
xSemaphoreGive(xMutexAccessMetricResponse); xSemaphoreGiveRecursive(xMutexAccessMetricResponse);
return err; return err;
} }
else else
@ -339,12 +339,12 @@ httpd_handle_t setup_server(void)
.handler = get_metrics_handler, .handler = get_metrics_handler,
.user_ctx = NULL}; .user_ctx = NULL};
xMutexAccessMetricResponse = xSemaphoreCreateBinary(); xMutexAccessMetricResponse = xSemaphoreCreateRecursiveMutex();
if (xMutexAccessMetricResponse == NULL) if (xMutexAccessMetricResponse == NULL)
{ {
ESP_LOGE(TAG, "Unable to create mutex for metric response"); ESP_LOGE(TAG, "Unable to create mutex for metric response");
} }
xSemaphoreGive(xMutexAccessMetricResponse); xSemaphoreGiveRecursive(xMutexAccessMetricResponse);
if (httpd_start(&server, &config) == ESP_OK) if (httpd_start(&server, &config) == ESP_OK)
{ {

View File

@ -33,12 +33,12 @@ void initOutputs(void)
gpio_config(&ioConfCirculationPump); gpio_config(&ioConfCirculationPump);
gpio_config(&ioConfBurner); gpio_config(&ioConfBurner);
xMutexAccessOutputs = xSemaphoreCreateBinary(); xMutexAccessOutputs = xSemaphoreCreateRecursiveMutex();
if (xMutexAccessOutputs == NULL) if (xMutexAccessOutputs == NULL)
{ {
ESP_LOGE(TAG, "Unable to create mutex"); ESP_LOGE(TAG, "Unable to create mutex");
} }
xSemaphoreGive(xMutexAccessOutputs); xSemaphoreGiveRecursive(xMutexAccessOutputs);
} }
eOutput getCirculationPumpState(void) eOutput getCirculationPumpState(void)
@ -48,7 +48,7 @@ eOutput getCirculationPumpState(void)
void setCirculationPumpState(eOutput in) void setCirculationPumpState(eOutput in)
{ {
if (xSemaphoreTake(xMutexAccessOutputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
sCirculationPumpState = in; sCirculationPumpState = in;
switch (sCirculationPumpState) switch (sCirculationPumpState)
@ -61,24 +61,32 @@ void setCirculationPumpState(eOutput in)
default: default:
break; break;
} }
xSemaphoreGive(xMutexAccessOutputs); xSemaphoreGiveRecursive(xMutexAccessOutputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: setCirculationPumpState()");
} }
} }
eOutput getBurnerState(void) eOutput getBurnerState(void)
{ {
eOutput ret = ENABLED; eOutput ret = ENABLED;
if (xSemaphoreTake(xMutexAccessOutputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
ret = sBurnerState; ret = sBurnerState;
xSemaphoreGive(xMutexAccessOutputs); xSemaphoreGiveRecursive(xMutexAccessOutputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getBurnerState()");
} }
return ret; return ret;
} }
void setBurnerState(eOutput in) void setBurnerState(eOutput in)
{ {
if (xSemaphoreTake(xMutexAccessOutputs, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessOutputs, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
sBurnerState = in; sBurnerState = in;
switch (sBurnerState) switch (sBurnerState)
@ -91,6 +99,10 @@ void setBurnerState(eOutput in)
default: default:
break; break;
} }
xSemaphoreGive(xMutexAccessOutputs); xSemaphoreGiveRecursive(xMutexAccessOutputs);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: setBurnerState()");
} }
} }

View File

@ -22,12 +22,12 @@ void setSafeState(void);
void initSafety(void) void initSafety(void)
{ {
xMutexAccessSafety = xSemaphoreCreateBinary(); xMutexAccessSafety = xSemaphoreCreateRecursiveMutex();
if (xMutexAccessSafety == NULL) if (xMutexAccessSafety == NULL)
{ {
ESP_LOGE(TAG, "Unable to create mutex"); ESP_LOGE(TAG, "Unable to create mutex");
} }
xSemaphoreGive(xMutexAccessSafety); xSemaphoreGiveRecursive(xMutexAccessSafety);
BaseType_t taskCreated = xTaskCreate( BaseType_t taskCreated = xTaskCreate(
taskSafety, // Function to implement the task taskSafety, // Function to implement the task
@ -54,11 +54,11 @@ void taskSafety(void *pvParameters)
{ {
vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS); vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS);
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessSafety, portMAX_DELAY) == pdTRUE)
{ {
checkSensorSanity(); checkSensorSanity();
xSemaphoreGive(xMutexAccessSafety); xSemaphoreGiveRecursive(xMutexAccessSafety);
} }
} }
} }
@ -128,7 +128,7 @@ void setSafeState(void)
void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks) void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks)
{ {
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessSafety, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
for (size_t i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++) for (size_t i = 0; i < NUMBER_OF_SENSOR_SANITY_CHECKS; i++)
{ {
@ -136,17 +136,26 @@ void getSensorSanityStates(sSensorSanityCheck *pSensorSanityChecks)
pSensorSanityChecks[i].status = sanityChecks[i].status; pSensorSanityChecks[i].status = sanityChecks[i].status;
strcpy(pSensorSanityChecks[i].name, sanityChecks[i].name); strcpy(pSensorSanityChecks[i].name, sanityChecks[i].name);
} }
xSemaphoreGive(xMutexAccessSafety); xSemaphoreGiveRecursive(xMutexAccessSafety);
}
else
{
ESP_LOGE(TAG, "Unable to take mutex: getSensorSanityStates()");
} }
} }
eSafetyState getSafetyState(void) eSafetyState getSafetyState(void)
{ {
eSafetyState state = SAFETY_NO_ERROR; eSafetyState state = SAFETY_NO_ERROR;
if (xSemaphoreTake(xMutexAccessSafety, portMAX_DELAY) == pdTRUE) if (xSemaphoreTakeRecursive(xMutexAccessSafety, pdMS_TO_TICKS(5000)) == pdTRUE)
{ {
state = sSafetyState; state = sSafetyState;
xSemaphoreGive(xMutexAccessSafety); xSemaphoreGiveRecursive(xMutexAccessSafety);
}
else
{
state = SAFETY_INTERNAL_ERROR;
ESP_LOGE(TAG, "Unable to take mutex: getSafetyState()");
} }
return state; return state;
} }

View File

@ -19,6 +19,7 @@ typedef enum _SafetyState
{ {
SAFETY_NO_ERROR, SAFETY_NO_ERROR,
SAFETY_SENSOR_ERROR, SAFETY_SENSOR_ERROR,
SAFETY_INTERNAL_ERROR
} eSafetyState; } eSafetyState;
typedef sMeasurement (*GetSensorValue)(); typedef sMeasurement (*GetSensorValue)();