#include "rs232_port_owner.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" static SemaphoreHandle_t s_owner_mutex; static rs232_port_owner_t s_owner = RS232_PORT_OWNER_NONE; esp_err_t rs232_port_owner_init(void) { if (s_owner_mutex != NULL) { return ESP_ERR_INVALID_STATE; } s_owner_mutex = xSemaphoreCreateMutex(); return s_owner_mutex != NULL ? ESP_OK : ESP_ERR_NO_MEM; } esp_err_t rs232_port_claim(rs232_port_owner_t owner) { if (s_owner_mutex == NULL || owner == RS232_PORT_OWNER_NONE || owner == RS232_PORT_OWNER_FAULT) { return ESP_ERR_INVALID_ARG; } xSemaphoreTake(s_owner_mutex, portMAX_DELAY); esp_err_t result = ESP_ERR_INVALID_STATE; if (s_owner == RS232_PORT_OWNER_NONE) { s_owner = owner; result = ESP_OK; } xSemaphoreGive(s_owner_mutex); return result; } esp_err_t rs232_port_release(rs232_port_owner_t owner) { if (s_owner_mutex == NULL) { return ESP_ERR_INVALID_STATE; } xSemaphoreTake(s_owner_mutex, portMAX_DELAY); esp_err_t result = ESP_ERR_INVALID_STATE; if (s_owner == owner) { s_owner = RS232_PORT_OWNER_NONE; result = ESP_OK; } xSemaphoreGive(s_owner_mutex); return result; } void rs232_port_mark_fault(rs232_port_owner_t previous_owner) { if (s_owner_mutex == NULL) { return; } xSemaphoreTake(s_owner_mutex, portMAX_DELAY); if (s_owner == previous_owner) { s_owner = RS232_PORT_OWNER_FAULT; } xSemaphoreGive(s_owner_mutex); } rs232_port_owner_t rs232_port_get_owner(void) { if (s_owner_mutex == NULL) { return RS232_PORT_OWNER_FAULT; } xSemaphoreTake(s_owner_mutex, portMAX_DELAY); rs232_port_owner_t owner = s_owner; xSemaphoreGive(s_owner_mutex); return owner; } const char *rs232_port_owner_to_string(rs232_port_owner_t owner) { switch (owner) { case RS232_PORT_OWNER_NONE: return "idle"; case RS232_PORT_OWNER_PHASE0: return "Phase 0 diagnostics"; case RS232_PORT_OWNER_SERVICE: return "serial service"; case RS232_PORT_OWNER_FAULT: return "fault (reboot required)"; default: return "unknown"; } }