попытка понять происходящее и устранить зависание

This commit is contained in:
2026-01-16 14:53:36 +03:00
parent 0a7db042f6
commit 05adb18909

View File

@@ -23,7 +23,7 @@ inline int64_t milliseconds() {
return ((tv.tv_sec * 1000000l) + tv.tv_usec) / 1000;
}
constexpr int64_t SBUS_SEND_FRAME_INTERVAL = 15;
constexpr int64_t SBUS_SEND_FRAME_INTERVAL = 50;
constexpr int64_t SBUS_RXLOSS_INTERVAL = 500;
class UDPServer {
@@ -186,7 +186,7 @@ public:
// Открытие последовательного порта
fd = ::open(port_path.c_str(), O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
std::cerr << "Failed to open serial port " << port_path << ": " << std::strerror(errno) << std::endl;
std::cout << "Failed to open serial port " << port_path << ": " << std::strerror(errno) << std::endl;
return false;
}
struct termios2 tio{};
@@ -208,7 +208,7 @@ public:
tio.c_cflag |= (BOTHER|CREAD|CLOCAL);
if (ioctl(fd, TCSETS2, &tio) != 0) {
std::cerr << "Failed to set termios2 attributes: " << std::strerror(errno) << std::endl;
std::cout << "Failed to set termios2 attributes: " << std::strerror(errno) << std::endl;
close(fd);
return false;
}
@@ -248,13 +248,13 @@ public:
ssize_t written = write(fd, data.data(), data.size());
if (written < 0) {
std::cerr << "Failed to write to serial port " << strerror(errno) << std::endl;
std::cout << "Failed to write to serial port " << strerror(errno) << std::endl;
return false;
}
// Принудительная отправка данных
if (drain() < 0) {
std::cerr << "Failed to flush data to serial port" << strerror(errno) << std::endl;
std::cout << "Failed to flush data to serial port" << strerror(errno) << std::endl;
return false;
}
return true;
@@ -263,7 +263,7 @@ public:
int main(int argc, char* argv[]) {
// Парсим аргументы командной строки
std::string serial_port = "/dev/ttyUSB0";
std::string serial_port = "/dev/ttyPS0";
if (argc > 1) {
serial_port = argv[1];
}
@@ -289,14 +289,23 @@ int main(int argc, char* argv[]) {
int totalPacketCount = 0;
int serialErrors = 0;
int64_t lastStatisticsShow = milliseconds();
int64_t _lastLoopNow = lastStatisticsShow;
while (true) {
pollfd udpFd{.fd = udp_server.sockfd, .events = POLLIN, .revents = 0};
poll(&udpFd, 1, SBUS_SEND_FRAME_INTERVAL / 4);
auto now = milliseconds();
if (std::abs(now - _lastLoopNow) > SBUS_SEND_FRAME_INTERVAL) {
std::cout << "Warning: Loop freeze, reset timers. now time:" << now << std::endl;
lastSbusWrite = 0;
lastSbusRecv = 0;
lastStatisticsShow = 0;
}
_lastLoopNow = now;
if (udpFd.revents & POLLIN) {
// Прием UDP пакета
std::vector<uint16_t> data = udp_server.receive();
lastSbusRecv = milliseconds();
lastSbusRecv = now;
if (!data.empty()) {
packetCount++;
@@ -320,7 +329,7 @@ int main(int argc, char* argv[]) {
}
}
const auto now = milliseconds();
std::cout << "from loop: current time " << now << std::endl;
if (now - lastSbusWrite >= SBUS_SEND_FRAME_INTERVAL && now - lastSbusRecv <= SBUS_RXLOSS_INTERVAL) {
lastSbusWrite = now;
if (!serial.writeBuffer(sb.binaryBuffer)) {
@@ -331,7 +340,7 @@ int main(int argc, char* argv[]) {
// после 50 ошибок дальше не будем пытаться что-то писать, ибо это бесполезно
if (serialErrors >= 50) {
std::cerr << "FATAL: 50 errors on serial port write operation, exit" << std::endl;
std::cout << "FATAL: 50 errors on serial port write operation, exit" << std::endl;
break;
}
}
@@ -345,7 +354,7 @@ int main(int argc, char* argv[]) {
}
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
std::cout << "Error: " << e.what() << std::endl;
return 1;
}