2010-11-30 8 views
4

Je suis en train de travailler avec un périphérique embarqué connecté à un PC via RS232.Comment pourrais-je implémenter un protocole de communication série sous une forme orientée objet?

J'ai besoin de faire un logiciel pour communiquer avec ce périphérique embarqué.

Je programme en Delphi. Je n'ai jamais utilisé d'objets orientés dans le passé. Mais j'essaie de changer cela.

Je ne suis pas capable de penser d'une manière orientée objet pour résoudre ce problème.

Je possède ce protocole:

<STX><STX><COMMAND>[<DATA><DATA>...]<CHKSUM><ETX> 

où:

<STX> is the Start of TeXt (0x55); 
<COMMAND> can be 0x01 for read, 0x02 for write, etc; 
<DATA> is any value; 
<CHKSUM> is the checksum; 
<ETX> is the End of TeXt (0x04). 

L'ordinateur logiciel envoie une commande par série, et l'appareil répondra, en utilisant le même protocole.

Par exemple:

Reset command 
PC sends  : <STX><STX><0x09><0x00><CHKSUM><ETX> 
Device answer: <STX><STX><0x09><0x00><CHKSUM><ETX> 

Get Version 
PC sends  : <STX><STX><0x00><0x02><CHKSUM><ETX> 
Device answer: <STX><STX><0x00><0x00><VER_L><VER_H><CHKSUM><ETX> 

Je dois envoyer un flux de fichier sur le périphérique.

Je voudrais obtenir des suggestions et/ou des exemples de la meilleure façon d'implémenter ceci d'une manière orientée objet. J'aimerais pouvoir faire des tests unitaires aussi.

Merci

+0

Les communications série nécessitent une machine d'état pour fonctionner correctement. Il y a de nombreuses façons de faire des machines à états orientées objet. – mj2008

Répondre

0

Trier difficile à répondre, mais de la petite quantité d'informations dont je dispose, voici comment je le ferais:

Soit vous classe qui sait comment sérialiser themself ou que vous utilisez le visiteur modèle pour la sérialisation. Cela a l'avantage de découpler vos données de la sérialisation et de vous permettre de mettre en œuvre plus facilement d'autres mécanismes de sérialisation. Par conséquent, j'aurais une classe de données, une classe de commande qui contient une collection (choisissez votre conteneur préféré) de données. La classe de commande gérerait probablement le calcul de somme de contrôle via une méthode publique. J'aurais aussi un cours de communication pour encapsuler le commandement et commencer et terminer la communication. Ensuite, j'aurais une classe responsable de l'interfaçage avec le port série qui aurait une méthode Send qui prendrait une référence sur la classe de communication.

D'après les informations disponibles, c'est ce que je peux trouver en matière de design.

En ce qui concerne les tests unitaires, avec un bon design, vous devriez pouvoir tester presque tout. N'oubliez pas d'utiliser les stubs, vous ne voulez pas toucher ce port série pendant les tests, alors faîtes une fausse classe de communication série qui écrit dans une chaîne par exemple et comparez la chaîne sortie à la spécification de valeur attendue sage.

1

Eh bien, je suppose qu'il y a autant de solutions que de programmeurs. Sans en savoir plus sur votre système j'irais probablement avec cette approche:

Créer une classe de commande de base, disons; TBaseCommand. Définissez votre interface commune à ce niveau, comme Send(), Receive(), Run() etc ...

Remplissez uniquement le code pour les fonctions communes à toutes les commandes, telles que l'envoi, la réception etc ...

Les fonctions qui diffèrent dans l'exécution sont rendues virtuelles pour être définies dans la couche suivante. De cette derive une nouvelle classe pour chaque commande et remplir le code spécifique à la commande, comme Run(). Un Run() vous permettra de simuler facilement vos commandes à l'écran en remplaçant la fonction Run().

, et sont votre protocole de transport et doivent être appliquées et dépouillées par votre interface de communication (classe de protocole séparée?). Votre classe de protocole peut également gérer les erreurs de checksum et essayer de renvoyer etc. Si elle ne peut pas être résolue, signalez l'erreur.

Ce fut seulement quelques petites choses au-dessus de ma tête avec votre description limitée ...

3

Vous devriez regarder autre série envoyer/recevoir des modèles de communication, tels que HTTP. Dans .NET, l'objet HTTPWebRequest est l'endroit où vous rassemblez toutes les informations à envoyer sur le réseau, y compris la commande (HTTP METHOD: GET, PUT, POST, etc.) et le flux d'octets. L'objet HTTPWebRequest (et la pile HTTP) gère en interne la "paperasse" de calcul des sommes de contrôle des données, le regroupement de grandes données en paquets plus petits, etc. Tout ce que votre code a à faire est de construire l'objet request, flux de données à la propriété de l'objet de requête, et envoyer. Une autre raison pour laquelle vous devriez regarder des modèles d'objets de communication existants comme HTTP .NET est que les communications série sont généralement asynchrones du point de vue de votre CPU hôte. Beaucoup de temps CPU peut passer en transmettant les caractères de la requête sur le port série, et en attendant la réponse. Utilisez un modèle asynchrone pour votre demande/réponse afin de ne pas bloquer le thread appelant et potentiellement geler votre interface utilisateur.

Pour continuer l'exemple HTTP .NET, HTTPWebRequest possède une méthode GetResponse qui envoie la requête et bloque le thread appelant jusqu'à ce qu'une réponse soit reçue. HTTPWebRequest a également une paire BeginGetResponse()/EndGetResponse() de sorte que vous pouvez envoyer la demande et fournir un rappel à exécuter lorsque la réponse arrive à un moment ultérieur.

Même si votre conception immédiate est compatible avec un modèle d'appel synchrone bloquant les threads, vous devez au moins étudier les modèles de codage asynchrones et envisager d'implémenter votre objet en tant que tel. Vous pouvez toujours appeler une méthode asynchrone d'une manière synchrone bloquant le thread, mais il est beaucoup plus difficile d'appeler une méthode synchrone de manière asynchrone. Investissez un peu de temps maintenant pour vous donner plus d'options sur la route.

+0

Ce sont des protocoles énormes avec un niveau de complexité bien au-delà de ses besoins. Rester simple! La méthode recommandée (par Microsoft) consiste à utiliser des threads pour TX et RX avec la structure de chevauchement en attente d'événements. Dès qu'il n'y a plus rien à faire, les fils vont dormir et libérer le processus. –

+2

Je n'ai pas suggéré qu'il utilise HTTP pour implémenter des communications série. Il demandait des idées sur la façon d'organiser un modèle d'objet. Il devrait utiliser un modèle d'objet d'appel asynchrone, et HTTP est un modèle largement disponible pour trouver des idées sur ce qu'il faut construire dans votre propre modèle d'objet asynchrone. La structure d'E/S chevauchée de l'API ne fournit aucune indication sur la façon de créer un modèle d'objet pratique et robuste. C'est un détail de bas niveau qu'un modèle d'objet utiliserait probablement, mais le modèle d'objet doit probablement faire plus que simplement appeler l'API. – dthorpe

Questions connexes