device-os
device-os copied to clipboard
[rtl872x] hal: fix issue that uart rx dma may hang up.
Problem
When running the Serial2 stress test app as attached below, device may hang up over time.
Solution
- Implement recursive TX/RX lock
- Fix minor bug in ring buffer
- Do not suspend DMA unless necessary.
Steps to Test
Build and run the below test app.
Example App
#include "Particle.h"
SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);
Serial1LogHandler log(115200, LOG_LEVEL_ALL, {
{"system", LOG_LEVEL_WARN}
});
constexpr uint16_t buffLen = 64;
uint8_t txBuff[buffLen];
uint8_t rxBuff[buffLen] = {};
system_tick_t was = 0;
void setup() {
Serial2.begin(115200);
for (int i = 0; i < buffLen; i++) {
txBuff[i] = (uint8_t)i;
}
was = millis();
}
bool done = true;
size_t txLen = 0;
size_t rxCnt = 0;
void loop() {
if (done) {
txLen = random(1, buffLen);
txLen = Serial2.write(txBuff, txLen);
Log.printf("TX Done: %d\r\n", txLen);
done = false;
was = millis();
rxCnt = 0;
}
size_t len = Serial2.available();
if (len) {
while (len--) {
rxBuff[rxCnt] = Serial2.read();
Log.printf("%02d ", rxBuff[rxCnt]);
rxCnt++;
}
}
if (millis() - was > 800) {
was = millis();
Log.printf("Done \r\n");
done = true;
if (rxCnt == txLen && !memcmp(txBuff, rxBuff, txLen)) {
Log.info("Test Passed! len: %d", rxCnt);
} else {
Log.info("Test Failed! TX: %d, RX: %d", txLen, rxCnt);
Serial2.breakTx();
while (1);
}
}
}
References
N/A
Completeness
- [x] User is totes amazing for contributing!
- [x] Contributor has signed CLA (Info here)
- [x] Problem and Solution clearly stated
- [ ] Run unit/integration/application tests on device
- [ ] Added documentation
- [ ] Added to CHANGELOG.md after merging (add links to docs and issues)