Question

Je veux vérifier les paquets de données entrants sur le port série, en utilisant boost.asio. Chaque paquet de données commence par un en-tête est un octet, et précisera ce type de message a été envoyé. Chaque autre type de message a sa propre longueur. La fonction que je veux écrire doit écouter les nouveaux messages entrants sans cesse, et quand il en trouve un, il faut le lire, et appeler une autre fonction pour l'analyser. Mon code actuel est le suivant:

void check_for_incoming_messages()
{
    boost::asio::streambuf response;
    boost::system::error_code error;
    std::string s1, s2;
    if (boost::asio::read(port, response, boost::asio::transfer_at_least(0), error)) {
        s1 = streambuf_to_string(response);
        int msg_code = s1[0];
        if (msg_code < 0 || msg_code >= NUM_MESSAGES) {
            // Handle error, invalid message header
        }
        if (boost::asio::read(port, response, boost::asio::transfer_at_least(message_lengths[msg_code]-s1.length()), error)) {
            s2 = streambuf_to_string(response);
            // Handle the content of s1 and s2
        }
        else if (error != boost::asio::error::eof) {
            throw boost::system::system_error(error);
        }
    }
    else if (error != boost::asio::error::eof) {
        throw boost::system::system_error(error);
    }
}

est boost::asio::streambuf l'outil à utiliser? Et comment puis-je extraire les données de ce que je peux donc analyser le message? Je veux aussi savoir si je dois avoir un thread séparé qui appelle cette fonction que, pour qu'il soit appelé plus souvent. Dois-je être inquiet de perdre des données entre deux appels à la fonction en raison du trafic élevé et la mémoire tampon du port série court? J'utilise les bibliothèques de Qt pour l'interface graphique et je ne sais pas vraiment combien de temps il faut pour traiter tous les événements.

Modifier La question intéressante est: comment puis-je vérifier s'il y a des données entrantes sur le port série? S'il n'y a pas de données entrantes, je ne veux pas la fonction de bloquer ...

Était-ce utile?

La solution

Cet article est utile pour comprendre comment ASIO peut être utilisé de manière asynchrone avec des ports série:

Mise à jour (2019-03) :

L'article original que j'avais lié à n'est plus disponible et il est difficile de trouver même dans Internet Archive. (Voici un instantané.). Il y a maintenant des articles les plus récents sur l'utilisation ASIO pour les E / S série trouvé facilement en effectuant une recherche, mais cet article est encore plus très utile. Je mets dans un fond public pour qu'il ne soit pas perdu:

Le code décrit dans l'article semble avoir été copié ici:

L'auteur semble avoir mis à jour pour 11 C ++. Je crois que l'article était écrit à l'origine par fede.tft .

Autres conseils

Jason,

S'il est adapté à votre demande, je vous recommande fortement la mise en œuvre d'une série asynchrone basée rappel-RX. Comment puis-je effectuer une lecture non bloquante à l'aide asio? a un petit exemple de la façon de mettre en œuvre série asynch avec un délai d'attente. Comme vous l'avez reconnu, il faudra une mise en œuvre multi-thread pour obtenir les avantages de performance, vous aurez donc besoin de mettre un peu la pensée où vos données REÇU seront mises en mémoire tampon pour vous assurer que vous ne faites pas beaucoup de copie.

En ce qui concerne les choses de boost::streambuff va, je préfère juste pour bloquer une mémoire comme un tableau de caractères - char m_RXBuffer[m_RXBuffSize] et utiliser boost::asio::buffer(m_RXBuffer, m_RXBuffSize) pour passer le tampon cible dans async_read_some. En particulier pour RS232, je l'ai toujours trouvé le fait que les données sous-jacente est un flux d'octets correspond naturellement beaucoup mieux sur un simple tableau char que l'une des structures de données plus complexes.

Bonne chance!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top