자동로깅 추가, usb port추가

This commit is contained in:
2026-02-27 08:54:14 +00:00
parent 7e0e65297b
commit 961680e5ec
7 changed files with 291 additions and 21 deletions

View File

@@ -10,6 +10,10 @@ volatile uint32_t serialBaud = DEFAULT_BAUD_RATE;
volatile uint8_t serialDataBits = 8;
volatile char serialParity = 'N';
volatile uint8_t serialStopBits = 1;
volatile uint8_t serialPort = 0; // 0=UART2, 1=UART0(USB)
// Pointer to the active monitoring serial port
HardwareSerial* monSerial = &Serial2;
static SemaphoreHandle_t serialMutex = NULL;
@@ -25,7 +29,6 @@ void getTimestamp(char *buf, size_t len) {
}
static uint32_t getSerialConfig(uint8_t dataBits, char parity, uint8_t stopBits) {
// Use standard Arduino serial config constants
if (dataBits == 8 && parity == 'N' && stopBits == 1) return SERIAL_8N1;
if (dataBits == 8 && parity == 'E' && stopBits == 1) return SERIAL_8E1;
if (dataBits == 8 && parity == 'O' && stopBits == 1) return SERIAL_8O1;
@@ -41,30 +44,80 @@ static uint32_t getSerialConfig(uint8_t dataBits, char parity, uint8_t stopBits)
if (dataBits == 5 && parity == 'N' && stopBits == 1) return SERIAL_5N1;
if (dataBits == 5 && parity == 'E' && stopBits == 1) return SERIAL_5E1;
if (dataBits == 5 && parity == 'O' && stopBits == 1) return SERIAL_5O1;
return SERIAL_8N1; // default
return SERIAL_8N1;
}
// ============================================================
// Switch serial port: 0=UART2(GPIO16/17), 1=UART0(USB)
// ============================================================
void switchSerialPort(uint8_t port) {
if (serialMutex) xSemaphoreTake(serialMutex, portMAX_DELAY);
if (port == 1) {
// Switch to UART0 (USB) for testing
// Note: UART0 is already running (Serial.begin in setup)
// Just point monSerial to it. Debug output still goes to Serial TX,
// but RX task only reads what PC sends (RX buffer), so no conflict.
Serial2.flush();
Serial2.end();
monSerial = &Serial;
serialPort = 1;
Serial.println("[Serial] Switched to UART0 (USB) - test mode");
Serial.println("[Serial] Send data from PC terminal to test");
} else {
// Switch to UART2 (GPIO16/17) for field use
uint32_t config = getSerialConfig(serialDataBits, serialParity, serialStopBits);
Serial2.begin(serialBaud, config, SERIAL2_RX_PIN, SERIAL2_TX_PIN);
Serial2.setRxBufferSize(DEFAULT_RX_BUFFER);
monSerial = &Serial2;
serialPort = 0;
Serial.printf("[Serial] Switched to UART2 (TX=%d, RX=%d)\n",
SERIAL2_TX_PIN, SERIAL2_RX_PIN);
}
// Drain any old data from new port's RX buffer
while (monSerial->available()) monSerial->read();
if (serialMutex) xSemaphoreGive(serialMutex);
}
// ============================================================
// Reconfigure baud/parity/etc (applies to current port)
// ============================================================
void reconfigureSerial(uint32_t baud, uint8_t dataBits, char parity, uint8_t stopBits) {
if (serialMutex) xSemaphoreTake(serialMutex, portMAX_DELAY);
Serial2.flush();
Serial2.end();
delay(50);
monSerial->flush();
uint32_t config = getSerialConfig(dataBits, parity, stopBits);
Serial2.begin(baud, config, SERIAL2_RX_PIN, SERIAL2_TX_PIN);
Serial2.setRxBufferSize(DEFAULT_RX_BUFFER);
if (serialPort == 0) {
// UART2 - full reconfigure
Serial2.end();
delay(50);
uint32_t config = getSerialConfig(dataBits, parity, stopBits);
Serial2.begin(baud, config, SERIAL2_RX_PIN, SERIAL2_TX_PIN);
Serial2.setRxBufferSize(DEFAULT_RX_BUFFER);
} else {
// UART0 - reconfigure USB serial baud
Serial.end();
delay(50);
Serial.begin(baud);
}
serialBaud = baud;
serialDataBits = dataBits;
serialParity = parity;
serialStopBits = stopBits;
Serial.printf("[Serial] Reconfigured: %lu %d%c%d\n", baud, dataBits, parity, stopBits);
Serial.printf("[Serial] Reconfigured: %lu %d%c%d (port=%s)\n",
baud, dataBits, parity, stopBits,
serialPort == 0 ? "UART2" : "USB");
if (serialMutex) xSemaphoreGive(serialMutex);
}
// ============================================================
// Init
// ============================================================
void serialTaskInit() {
queueSD = xQueueCreate(QUEUE_SD_SIZE, sizeof(LogEntry*));
queueWeb = xQueueCreate(QUEUE_WEB_SIZE, sizeof(LogEntry*));
@@ -72,13 +125,17 @@ void serialTaskInit() {
serialMutex = xSemaphoreCreateMutex();
// Default: UART2
uint32_t config = getSerialConfig(serialDataBits, serialParity, serialStopBits);
Serial2.begin(serialBaud, config, SERIAL2_RX_PIN, SERIAL2_TX_PIN);
Serial2.setRxBufferSize(DEFAULT_RX_BUFFER);
monSerial = &Serial2;
serialPort = 0;
Serial.printf("[Serial] Init: %lu %d%c%d on TX=%d RX=%d\n",
Serial.printf("[Serial] Init: %lu %d%c%d on UART2 (TX=%d, RX=%d)\n",
serialBaud, serialDataBits, (char)serialParity, serialStopBits,
SERIAL2_TX_PIN, SERIAL2_RX_PIN);
Serial.println("[Serial] Port switchable via Settings (UART2/USB)");
xTaskCreatePinnedToCore(serialRxTask, "SerialRX", TASK_STACK_SERIAL,
NULL, TASK_PRIORITY_SERIAL, NULL, 1);
@@ -87,7 +144,9 @@ void serialTaskInit() {
NULL, TASK_PRIORITY_SERIAL - 1, NULL, 1);
}
// ============================================================
// Flush assembled line to SD and Web queues
// ============================================================
static void flushLineToQueues(char *lineBuf, int &linePos) {
if (linePos <= 0) return;
lineBuf[linePos] = '\0';
@@ -114,6 +173,9 @@ static void flushLineToQueues(char *lineBuf, int &linePos) {
linePos = 0;
}
// ============================================================
// RX Task - reads from monSerial (UART2 or UART0)
// ============================================================
void serialRxTask(void *param) {
static char lineBuf[LOG_LINE_MAX_LEN];
int linePos = 0;
@@ -122,7 +184,8 @@ void serialRxTask(void *param) {
Serial.println("[Task] SerialRX started on core " + String(xPortGetCoreID()));
while (true) {
int available = Serial2.available();
HardwareSerial* port = monSerial; // Local copy for thread safety
int available = port->available();
if (available > 0) {
int space = (int)(LOG_LINE_MAX_LEN - linePos - 1);
@@ -130,13 +193,12 @@ void serialRxTask(void *param) {
int toRead = (available < space) ? available : space;
for (int i = 0; i < toRead; i++) {
char c = Serial2.read();
char c = port->read();
if (c == '\n' || c == '\r') {
if (linePos > 0) flushLineToQueues(lineBuf, linePos);
continue;
}
// Only accept printable ASCII (0x20~0x7E) and TAB (0x09)
// Skip null bytes and noise (0x00, 0xFF, etc.)
if ((c >= 0x20 && c <= 0x7E) || c == '\t') {
lineBuf[linePos++] = c;
}
@@ -151,15 +213,20 @@ void serialRxTask(void *param) {
}
}
// ============================================================
// TX Task - writes to monSerial (UART2 or UART0)
// ============================================================
void serialTxTask(void *param) {
Serial.println("[Task] SerialTX started on core " + String(xPortGetCoreID()));
while (true) {
LogEntry *entry;
if (xQueueReceive(queueTX, &entry, pdMS_TO_TICKS(50)) == pdTRUE) {
HardwareSerial* port = monSerial;
if (serialMutex) xSemaphoreTake(serialMutex, portMAX_DELAY);
Serial2.write((uint8_t*)entry->data, entry->dataLen);
Serial2.flush();
port->write((uint8_t*)entry->data, entry->dataLen);
port->flush();
if (serialMutex) xSemaphoreGive(serialMutex);
LogEntry *sdEntry = (LogEntry*)pvPortMalloc(sizeof(LogEntry));