Boost i odczyt z portu COM

0

(boost w wersji 1.55)
Cały dzień i pół nocy nad tym siedzę i nie udaje mi się odczytać zawartości z COM w sposób, w jaki bym chciał. Jedyne, co mi działa, to odczyt konkretnej ilości bajtów. To mi jednak nic nie daje, bo na port mogły pójść 2 bajty albo 20.

Chciałem robić to tak:

  1. Czytaj dane do bufora (ustawiony domyślnie na 512 bajtów).
  2. Jeśli odczytano 512 bajtów, to dołącz te dane do bufora wynikowego i czytaj dalej (aż odczytasz mniej niż 512).
  3. Na koniec cały bufor wynikowy wypluj do callbacka.

Dzięki temu w głównej aplikacji mam metodę, która będzie wywołana z całą odczytaną zawartością portu.

(potem, uprościłem to i założyłem, że nigdy nie będzie więcej danych niż 10 bajtów. Ale może być mniej.)
Użycie boost::read odpada, bo tam musi zostać zapełniony cały bufor. Chyba, że użyjemy funkcji transfer_at_least(1). Ale odczytywać po jednym bajcie? To mi nic i tak nie daje, bo chcę wypluć do callbacka cały ciąg i wywołać go raz, a nie kilka razy, bo to mi się mija z celem. Pomyślałem, że może transfer_at_least(0) da radę. Ale nie. On to potraktował zbyt poważnie i nigdy nie zwracał żadnych danych.

Więc mamy funkcję: boost::async_read, która.... nie działa. Mój handler NIGDY nie jest wywoływany. Nie mam pojęcia dlaczego.

Fragment kodu:

 
//ta metoda nie ma sensu, ale potrzebowałem czegokolwiek, żeby wrzucić breakpointa
void ComPort::read_handler(const boost::system::error_code & ec, size_t size)
{
    while (size > 0)
    {
        size--;
    }
}

//ta metoda jest wywoływana w osobnym wątku
void ComPort::read()
{
    //unsigned char buff[10]; - z tym jako drugim parametrem async_read też nie działa
    boost::asio::streambuf b;

    while (m_opened) //pętla dlatego, bo metoda w osobnym wątku śmiga
    {
     try
         {
            async_read(*m_pport, b, 
                boost::asio::transfer_at_least(1), //z tym, czy bez tego - nie ma różnicy
                boost::bind(&ComPort::read_handler, this,
                    boost::asio::placeholders::error, 
                    boost::asio::placeholders::bytes_transferred));
            }
            catch (exception &e)
            {
                continue; 
            }
        }
    }

Co tu jest nie tak? A może istnieje jakiś sposób, żeby użyć boost::read tak, żeby nie blokowało?

0

Timeout byłby rozwiązaniem, gdyby można go było użyć z funkcją read. Natomiast, jak napisałem, async_read u mnie nie działa.

0

Z tym deadline_timer? Hmm, na razie znalazłem gdzieś wzmiankę o io_service.run(). Dodałem to po async_read i handler jest wywoływany. Jaka jest różnica? I co to właściwie robi? Z tego, co wyczytałem, to io_service.run() wstrzymuje dalsze wykonywanie aż handler się zakończy. I to tylko o to chodzi?

Nie mam pojęcia, nie znam boosta ;) Ale czytałem porty szeregowe natywmie pod kilkoma platformami i wiem, że timeout przy Twoim problemie powinien rozwiązać sprawę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1