Hur hanterar man inläsning av USB med hjälp av Boost Asio i C++?
Jag använder mig av Boost Asio för att läsa och skriva via USB. Att skriva...inga problem.
Men att läsa är något lite svårare.
Kodmässigt är det inte svårare, utan det handlar om att pricka rätt på tiden.
Det jag vill göra är att jag vill skicka data visa USB från min dator, till en enhet. Enheten läser meddelandet och skickar genast tillbaka ett svar till min dator.
Om inte min dator hinner läsa meddelandet, så går meddelandet förlorat. Och hur ska jag lösa detta?
Jag har tidigare använt mig av trådar, men jag tror att trådar kanske inte riktigt var det mest skonsammaste för USB porten då man fick ha mycket try-catch för att fånga upp alla meddelanden. Det var dessutom mycket trixande med globala variabler för att stänga av tråden på ett snyggt sätt. Så jag tyckte lösningen verkade vara en ful-lösning.
Det alternativ jag använder nu är att
#include <iostream>
#include <boost/asio.hpp>
void handleRead(const boost::system::error_code& error, std::size_t bytesTransferred, std::vector<char>& buffer)
{
if (!error) {
// Extrahera meddelandet från bufferten
std::string message(buffer.begin(), buffer.begin() + bytesTransferred);
// Hantera meddelandet
std::cout << "Mottaget meddelande: " << message << std::endl;
} else {
// Hantera fel
std::cerr << "Fel vid mottagning av meddelande: " << error.message() << std::endl;
}
}
int main()
{
boost::asio::io_context io;
boost::asio::serial_port serialPort(io);
// Öppna seriell port
serialPort.open("/dev/ttyUSB0");
// Ställ in seriella portinställningar
serialPort.set_option(boost::asio::serial_port_base::baud_rate(9600));
serialPort.set_option(boost::asio::serial_port_base::character_size(8));
serialPort.set_option(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
serialPort.set_option(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));
serialPort.set_option(boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none));
// Skapa en buffert för att lagra inkommande data
std::vector<char> buffer(1024);
// Skapa timer
int timeOutMilliseconds = 1000;
boost::asio::steady_timer timer(io, std::chrono::milliseconds(timeOutMilliseconds));
// Läs in meddelanden från seriell port
serialPort.async_read_some(boost::asio::buffer(buffer), [&](const boost::system::error_code& error, std::size_t bytesTransferred) {
handleRead(error, bytesTransferred, buffer);
});
// Start asynkron timer
timer.async_wait([&](const boost::system::error_code& errorCode) {
// Timer löper ut, gör något här om det behövs
});
// Kör event-loop
io.run();
return 0;
}
Trots detta, så fungerar det ändå inte. Det är som att meddelandet hinner att försvinna innan jag läser det.
Finns det några bättre sätt hur man ska bemästra dessa funktioner?
Så frågan är om man helt enkelt skulle kunna använda sig av en while loop som bara körs hela tiden?
Tänk om halva meddelandet läses bara?
Eller är tanken att jag ska
1. Först starta en läs process
2. Skicka mitt meddelande
3. Läs datan som har kommit tillbaka
Är det så Boost Asio ska fungera?