firmware: discard partial RS485 echoes
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
- Added standalone XIAO ESP32-C6 BNO086/MAX-M10S sensor-node firmware and a versioned RS485 telemetry contract without changing Cargo `/api/v1` or JBD/NimBLE behavior.
|
- Added standalone XIAO ESP32-C6 BNO086/MAX-M10S sensor-node firmware and a versioned RS485 telemetry contract without changing Cargo `/api/v1` or JBD/NimBLE behavior.
|
||||||
- Added XIAO-side persistent level calibration with stability checking and RS485 start/clear commands; no dashboard behavior changed.
|
- Added XIAO-side persistent level calibration with stability checking and RS485 start/clear commands; no dashboard behavior changed.
|
||||||
- Prevented echoed or oversized RS485 frames from starving the XIAO sensor loop.
|
- Prevented echoed or oversized RS485 frames from starving the XIAO sensor loop.
|
||||||
|
- Silently discard malformed partial RS485 echoes instead of emitting recursive `invalid_json` responses.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ void pollRs485Commands(HardwareSerial& serial, const ImuState& imu) {
|
|||||||
StaticJsonDocument<192> request;
|
StaticJsonDocument<192> request;
|
||||||
DeserializationError error = deserializeJson(request, commandBuffer);
|
DeserializationError error = deserializeJson(request, commandBuffer);
|
||||||
commandBuffer = "";
|
commandBuffer = "";
|
||||||
if (error) { publishCalibrationResult(serial, "invalid_json"); continue; }
|
// Partial self-echoes and line noise are not commands. Dropping them
|
||||||
|
// silently avoids turning one bad fragment into a response/echo loop.
|
||||||
|
if (error) continue;
|
||||||
String type = request["type"] | "";
|
String type = request["type"] | "";
|
||||||
// Some RS485 boards echo transmitted frames into RX. Ignore our own output.
|
// Some RS485 boards echo transmitted frames into RX. Ignore our own output.
|
||||||
if (type == "sensor_status" || type == "calibration_response") continue;
|
if (type == "sensor_status" || type == "calibration_response") continue;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ def test_rs485_echo_cannot_starve_sensor_loop():
|
|||||||
assert "bytesRemaining" in transport
|
assert "bytesRemaining" in transport
|
||||||
assert "discardCommandUntilNewline" in transport
|
assert "discardCommandUntilNewline" in transport
|
||||||
assert 'type == "sensor_status"' in transport
|
assert 'type == "sensor_status"' in transport
|
||||||
|
assert 'publishCalibrationResult(serial, "invalid_json")' not in transport
|
||||||
|
|
||||||
def test_node_does_not_take_cargo_or_ble_authority():
|
def test_node_does_not_take_cargo_or_ble_authority():
|
||||||
combined = "\n".join(p.read_text() for p in NODE.glob("*.*"))
|
combined = "\n".join(p.read_text() for p in NODE.glob("*.*"))
|
||||||
|
|||||||
Reference in New Issue
Block a user