Add Phase 1 UART service foundation

Add versioned NVS-backed configuration, buffered UART1 I/O, modem
monitoring, counters, and serial console controls. Coordinate UART1
ownership with Phase 0 diagnostics and document loopback verification.
This commit is contained in:
2026-08-22 23:23:13 +02:00
parent 126314a277
commit 535c27350d
13 changed files with 1961 additions and 30 deletions
+89
View File
@@ -0,0 +1,89 @@
#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";
}
}