Protocolos utilizados para hablar entre una CPU incrustada y una PC -- embedded campo con avr campo con communication-protocol camp Relacionados El problema

Protocols used to talk between an embedded CPU and a PC


18
vote

problema

Español

Estoy construyendo un pequeño dispositivo con su propia CPU (AVR MEGA8) que se supone que se conecta a una PC. Suponiendo que la conexión física y el paso de los bytes se han logrado, ¿cuál sería el mejor protocolo para usar en la parte superior de esos bytes? La computadora debe poder establecer ciertos voltajes en el dispositivo, y leer algunos otros voltajes.

En este momento, estoy pensando en un protocolo sincrónico completamente impulsado por el host: solicitudes de envío de computadoras, las respuestas de CPU incrustadas. ¿Alguna otra idea?

Original en ingles

I am building a small device with its own CPU (AVR Mega8) that is supposed to connect to a PC. Assuming that the physical connection and passing of bytes has been accomplished, what would be the best protocol to use on top of those bytes? The computer needs to be able to set certain voltages on the device, and read back certain other voltages.

At the moment, I am thinking a completely host-driven synchronous protocol: computer send requests, the embedded CPU answers. Any other ideas?

        

Lista de respuestas

6
 
vote
vote
La mejor respuesta
 

Modbus podría ser lo que está buscando. Fue diseñado para exactamente el tipo de problema que tiene. Hay muchos códigos / herramientas por ahí y la adhesión a un estándar podría significar una reutilización fácil más tarde. También es compatible con ASCII legible humana, por lo que aún es fácil de entender / probar.

Consulte freemodbus para Windows y fuente incrustada.

 

Modbus might be what you are looking for. It was designed for exactly the type of problem you have. There is lots of code/tools out there and adherence to a standard could mean easy reuse later. It also support human readable ASCII so it is still easy to understand/test.

See FreeModBus for windows and embedded source.

 
 
6
 
vote

Hay mucho que decir para la arquitectura cliente-servidor y los protocolos síncronos. Sencillez y robustez, para empezar. Si la velocidad no es un problema, puede considerar un protocolo compacto y legible para humanos para ayudar con la depuración. Estoy pensando en las líneas de módem a los comandos: una secuencia de "activación" seguida de un comando set / recibe, seguido de un terminador.

  Host -->  [V02?]      // Request voltage #2 AVR  -->  [V02=2.34]  // Reply with voltage #2 Host -->  [V06=3.12]  // Set voltage #6 AVR  -->  [V06=3.15]  // Reply with voltage #6   

Cada lado podría salir tiempo si no ve el soporte de cierre, y se volverían a sincronizar en el siguiente soporte abierto, lo que no puede aparecer dentro del mensaje en sí.

Dependiendo de los requisitos de velocidad y confiabilidad, puede codificar los comandos en uno o dos bytes y agregar una suma de comprobación.

Siempre es una buena idea responder con el voltaje real , en lugar de simplemente hacer eco del comando, ya que ahorra una operación de lectura posterior.

También útil definir los mensajes de error, en caso de que deba depurar.

 

There's a lot to be said for client-server architecture and synchronous protocols. Simplicity and robustness, to start. If speed isn't an issue, you might consider a compact, human-readable protocol to help with debugging. I'm thinking along the lines of modem AT commands: a "wakeup" sequence followed by a set/get command, followed by a terminator.

Host -->  [V02?]      // Request voltage #2 AVR  -->  [V02=2.34]  // Reply with voltage #2 Host -->  [V06=3.12]  // Set voltage #6 AVR  -->  [V06=3.15]  // Reply with voltage #6 

Each side might time out if it doesn't see the closing bracket, and they'd re-synchronize on the next open bracket, which cannot appear within the message itself.

Depending on speed and reliability requirements, you might encode the commands into one or two bytes and add a checksum.

It's always a good idea to reply with the actual voltage, rather than simply echoing the command, as it saves a subsequent read operation.

Also helpful to define error messages, in case you need to debug.

 
 
5
 
vote

Mi voto es para el legible humano.

Pero si va binario, intente colocar un byte de encabezado al principio para marcar el comienzo de un paquete. Siempre he tenido mala suerte con los protocolos en serie saliendo de la sincronización. El byte del encabezado permite que el sistema integrado se vuelva a sincronizar con la PC. Además, agregue una suma de comprobación al final.

 

My vote is for the human readable.

But if you go binary, try to put a header byte at the beginning to mark the beginning of a packet. I've always had bad luck with serial protocols getting out of sync. The header byte allows the embedded system to re-sync with the PC. Also, add a checksum at the end.

 
 
4
 
vote

He hecho cosas como esta con un simple formato binario

  struct PacketHdr {   char syncByte1;   char syncByte2;   char packetType;   char bytesToFollow;  //-or- totalPacketSize };  struct VoltageSet {     struct PacketHdr;    int16 channelId;    int16 voltageLevel;     uint16 crc; };  struct VoltageResponse {    struct PacketHdr;    int16 data[N];  //Num channels are fixed    uint16 crc; }   

Los bytes de sincronización son menos críticos en un protocolo síncrono que en una asencrónica, pero aún así ayudan, especialmente cuando el sistema integrado se está encendiendo primero, y no sabe si el primer byte que recibe es el medio de un mensaje o no.

El tipo debe ser un enumeración que le indique cómo interpretar el paquete. El tamaño podría inferirse del tipo, pero si lo envía explícitamente, entonces el receptor puede manejar tipos desconocidos sin asfixia. Puede usar el 'tamaño total del paquete', o 'bytes a seguir'; Este último puede hacer que el código receptor sea un poco más limpio.

El CRC al final agrega más seguridad de que tiene datos válidos. A veces, he visto al CRC en el encabezado, lo que facilita la declaración de estructuras, pero ponerla al final, le permite evitar un paso adicional sobre los datos al enviar el mensaje.

El remitente y el receptor deben tener los tiempos de espera que comienzan después de que se recibe el primer byte de un paquete, en caso de que se caiga un byte. El lado de la PC también necesita un tiempo de espera para manejar la caja cuando el sistema incrustado no está conectado y no hay respuesta en absoluto.

Si está seguro de que ambas plataformas usan flotadores IEEE-754 (PC) y tienen la misma endia, puede usar los flotadores como el tipo de datos. De lo contrario, es más seguro usar enteros, ya sea bits A / D RAW, o una escala preestablecida (I.E. 1 bit = .001V da una gama +/- 32.267 V)

 

I've done stuff like this with a simple binary format

struct PacketHdr {   char syncByte1;   char syncByte2;   char packetType;   char bytesToFollow;  //-or- totalPacketSize };  struct VoltageSet {     struct PacketHdr;    int16 channelId;    int16 voltageLevel;     uint16 crc; };  struct VoltageResponse {    struct PacketHdr;    int16 data[N];  //Num channels are fixed    uint16 crc; } 

The sync bytes are less critical in a synchronous protocol than in an asynchronous one, but they still help, especially when the embedded system is first powering up, and you don't know if the first byte it gets is the middle of a message or not.

The type should be an enum that tells how to intepret the packet. Size could be inferred from type, but if you send it explicitly, then the reciever can handle unknown types without choking. You can use 'total packet size', or 'bytes to follow'; the latter can make the reciever code a little cleaner.

The CRC at the end adds more assurance that you have valid data. Sometimes I've seen the CRC in the header, which makes declaring structures easier, but putting it at the end lets you avoid an extra pass over the data when sending the message.

The sender and reciever should both have timeouts starting after the first byte of a packet is recieved, in case a byte is dropped. The PC side also needs a timeout to handle the case when the embedded system is not connected and there is no response at all.

If you are sure that both platforms use IEEE-754 floats (PC's do) and have the same endianness, then you can use floats as the data type. Otherwise it's safer to use integers, either raw A/D bits, or a preset scale (i.e. 1 bit = .001V gives a +/-32.267 V range)

 
 
3
 
vote

Adam Liss hace muchos puntos grandes. La simplicidad y la robustez deben ser el enfoque. Las transferencias de ASCII legibles humanas ayudan mucho mientras se depura. Grandes sugerencias.

Pueden estar exagerados para sus necesidades, pero HDLC y / o PPP agregan en el concepto de una capa de enlace de datos, y todos los beneficios (y costos) que vienen con una capa de enlace de datos. Gestión de enlaces, enmarcar, comprobaciones de comprobaciones, números de secuencia, re-transmisiones, etc. Todos ayudan a garantizar comunicaciones robustas, pero agregue complejidad, procesamiento y tamaño de código, y es posible que no sea necesario para su aplicación en particular.

 

Adam Liss makes a lot of great points. Simplicity and robustness should be the focus. Human readable ASCII transfers help a LOT while debugging. Great suggestions.

They may be overkill for your needs, but HDLC and/or PPP add in the concept of a data link layer, and all the benefits (and costs) that come with a data link layer. Link management, framing, checksums, sequence numbers, re-transmissions, etc... all help ensure robust communications, but add complexity, processing and code size, and may not be necessary for your particular application.

 
 
1
 
vote

USB Bus responderá a todos sus requisitos. Puede ser un dispositivo USB muy simple con solo tubería de control para enviar solicitud a su dispositivo o puede agregar un tubo de interrupción que le permitirá notificar al host sobre los cambios en su dispositivo. Hay una serie de simples controladores USB que se pueden usar, por ejemplo, Cypress o Microchip .

El protocolo en la parte superior de la transferencia es realmente sobre sus requisitos. De su descripción Parece que el simple protocolo síncrono es definitivamente suficiente. ¿Qué te hace pasar por completo y buscar un enfoque adicional? Comparte tus dudas y trataremos de ayudar :).

 

USB bus will answer all your requirements. It might be very simple usb device with only control pipe to send request to your device or you can add an interrupt pipe that will allow you to notify host about changes in your device. There is a number of simple usb controllers that can be used, for example Cypress or Microchip.

Protocol on top of the transfer is really about your requirements. From your description it seems that simple synchronous protocol is definitely enough. What make you wander and look for additional approach? Share your doubts and we will try to help :).

 
 
1
 
vote

Si no esperaba necesitar hacer transferencias binarias eficientes, iría a la interfaz de estilo terminal ya sugerida.

Si quiero hacer un formato de paquetes binarios, tiendo a usar algo libremente basado en el formato HDLC de PPP Byte-ASNC, que es extremadamente simple y fácil de enviar, básicamente:

Los paquetes comienzan y terminan con 0x7e Escapas un char al prefijarse con 0x7d y alterna el bit 5 (I.E. XOR con 0x20) Así que 0x7e se convierte en 0x7d 0x5e y 0x7d se convierte en 0x7d 0x5d

Cada vez que vea un 0x7E, entonces, si tiene algún dato almacenado, puede procesarlo.

Por lo general, hago cosas síncronas impulsadas por el host a menos que tenga una muy buena razón para hacer lo contrario. Es una técnica que se extiende desde el simple punto de punta RS232 a MULTISTROP RS422 / 485 sin problemas, a menudo una bonificación.

 

If I wasn't expecting to need to do efficient binary transfers, I'd go for the terminal-style interface already suggested.

If I do want to do a binary packet format, I tend to use something loosely based on the PPP byte-asnc HDLC format, which is extremely simple and easy to send receive, basically:

Packets start and end with 0x7e You escape a char by prefixing it with 0x7d and toggling bit 5 (i.e. xor with 0x20) So 0x7e becomes 0x7d 0x5e and 0x7d becomes 0x7d 0x5d

Every time you see an 0x7e then if you've got any data stored, you can process it.

I usually do host-driven synchronous stuff unless I have a very good reason to do otherwise. It's a technique which extends from simple point-point RS232 to multidrop RS422/485 without hassle - often a bonus.

 
 
 
 
1
 
vote

Como puede haber determinado de todas las respuestas que no lo indiquen directamente a un protocolo, para que un enfoque sea su propio enfoque para que sea su mejor opción.

Entonces, esto me hizo pensar y bueno, aquí están algunos de mis pensamientos,

Dado que este chip tiene 6 canales ADC, lo más probable es que esté utilizando RS-232 Serial COM (una conjetura de su pregunta) y, por supuesto, el espacio limitado del código, que define una estructura de comando simple ayudará, como señala Adam. - Es posible que desee mantener el procesamiento de entrada al mínimo en el chip, por lo que los sonidos binarios son atractivos, pero el comercio se adapta a la facilidad de desarrollo y el servicio (es posible que tenga que tener problemas para disparar una entrada muerta de 6 meses a partir de ahora) - HyperTerminal Es una poderosa herramienta de depuración, por lo que, eso me hizo pensar cómo implementar una estructura de comando simple con una buena confiabilidad.

Algunas consideraciones generales -

Mantener los comandos del mismo tamaño: facilita la decodificación.

Enmarcar los comandos y suma de verificación opcional, ya que los puntos de Adam se pueden envolver fácilmente alrededor de sus comandos. (Con pequeños comandos, una simple comprobación XOR / ADD es rápida e indolora)

Recomendaría un anuncio de inicio al host con la versión de firmware en RESET - E.G., "Hola; Firmware versión 1.00Z", le diría al anfitrión que el objetivo acaba de comenzar y qué se está ejecutando.

Si está supervisando principalmente, es posible que desee considerar un modo de "ejecución gratuita" donde el objetivo simplemente recorrería las lecturas analógicas y digitales, por supuesto, esto no tiene que ser continuo, puede ser espaciado a 1, 5, 10 segundos, o simplemente en comando. Su micro siempre está escuchando, por lo que enviar un valor actualizado es una tarea independiente.

Terminando cada línea de salida con un CR (u otro carácter) hace la sincronización en el huésped recto.

Por ejemplo, su micro simplemente podría generar las cadenas;

    V0=3.20   V1=3.21   V2= ...   D1=0   D2=1   D3=...   and then start over --    

también, los comandos podrían ser realmente simples -

? - Leer todos los valores: no hay muchos de ellos, así que obtenga todos.

x = 12.34 - Para establecer un valor, el primer byte es el puerto, luego el voltaje y yo recomendaría mantener el "=" y el "". como enmarcado para asegurar un paquete válido si renuncia a la suma de comprobación.

Otra posibilidad, si sus salidas están dentro de un rango establecido, podría prescentarlas. Por ejemplo, si la salida no tiene que ser exacta, podría enviar algo como

  5=0  6=9 2=5     

que establecería el puerto 5 de descuento, el puerto 6 para completar, y el puerto de 2 a medio valor, con este enfoque, ASCII y los datos binarios se encuentran en la misma posición en lo que respecta a los recursos de computación / decodificación en la micro. O para más precisión, haga que la salida 2 bytes, por ejemplo, 2 = 54, o, agregue una tabla de XREF y los valores, ni siquiera tienen que ser lineales donde el byte de datos es un índice en una tabla de búsqueda. .

como me gusta decir; Simple suele ser mejor, a menos que no lo haga.

Espero que esto ayude un poco.


tuvo otro pensamiento al volver a leer; Agregar un comando "*" podría solicitar los datos envueltos con las etiquetas HTML y ahora su aplicación de host podría simplemente redirigir la salida de su micro a un navegador y WALA, el navegador listo -

:)

 

As you may have already determined from all the responses not directly directing you to a protocol, that a roll your own approach to be your best choice.

So, this got me thinking and well, here are a few of my thoughts --

Given that this chip has 6 ADC channels, most likely you are using Rs-232 serial comm (a guess from your question), and of course the limited code space, defining a simple command structure will help, as Adam points out -- You may wish to keep the input processing to a minimum at the chip, so binary sounds attractive but the trade off is in ease of development AND servicing (you may have to trouble shoot a dead input 6 months from now) -- hyperterminal is a powerful debug tool -- so, that got me thinking of how to implement a simple command structure with good reliability.

A few general considerations --

keep commands the same size -- makes decoding easier.

Framing the commands and optional check sum, as Adam points out can be easily wrapped around your commands. (with small commands, a simple XOR/ADD checksum is quick and painless)

I would recommend a start up announcement to the host with the firmware version at reset - e.g., "HELLO; Firmware Version 1.00z" -- would tell the host that the target just started and what's running.

If you are primarily monitoring, you may wish to consider a "free run" mode where the target would simply cycle through the analog and digital readings -- of course, this doesn't have to be continuous, it can be spaced at 1, 5, 10 seconds, or just on command. Your micro is always listening so sending an updated value is an independent task.

Terminating each output line with a CR (or other character) makes synchronization at the host straight forward.

for example your micro could simply output the strings;

  V0=3.20   V1=3.21   V2= ...   D1=0   D2=1   D3=...   and then start over --  

Also, commands could be really simple --

? - Read all values -- there's not that many of them, so get them all.

X=12.34 - To set a value, the first byte is the port, then the voltage and I would recommend keeping the "=" and the "." as framing to ensure a valid packet if you forgo the checksum.

Another possibility, if your outputs are within a set range, you could prescale them. For example, if the output doesn't have to be exact, you could send something like

5=0  6=9 2=5   

which would set port 5 off, port 6 to full on, and port 2 to half value -- With this approach, ascii and binary data are just about on the same footing in regards to computing/decoding resources at the micro. Or for more precision, make the output 2 bytes, e.g., 2=54 -- OR, add an xref table and the values don't even have to be linear where the data byte is an index into a look-up table ...

As I like to say; simple is usually better, unless it's not.

Hope this helps a bit.


Had another thought while re-reading; adding a "*" command could request the data wrapped with html tags and now your host app could simply redirect the output from your micro to a browser and wala, browser ready --

:)

 
 

Relacionados problema

0  ¿Cómo pueden los microservicios comunicarse entre sí?  ( How can microservices communicate with each other ) 
Quiero transitar mi aplicación actualmente monolítica a un modelo de Microservices. Actualmente estoy atrapado en averiguar la mejor manera de que los microse...

1  Tabla de comunicación Implementación  ( Communication table implementation ) 
He estado trabajando en software incrustado. Uno de los requisitos también es La comunicación sobre puede a través del protocolo propietario. El núcleo de la ...

5  Alineación byte en comunicación en serie  ( Byte aligning in serial communication ) 
Entonces, estoy tratando de definir un protocolo de comunicación para la comunicación en serie, quiero poder enviar 4 números de bytes al dispositivo, pero no...

2  Comunicación entre dos archivos de guerra sin codificar la raíz del contexto [cerrado]  ( Communication between two war files without hardcoding the context root ) 
Según lo que actualmente representa, esta pregunta no es un buen ajuste para nuestro Q & Amp; un formato. Esperamos que las...

0  Protocolo de comunicación: lector humano vs no legible no humano  ( Communication protocol human readable vs non human readable ) 
Estoy empezando a trabajar en una aplicación que consiste en múltiples componentes. Algunos de ellos residen en el lado del servidor, mientras que algunos est...

3  ¿Cómo enseño mi dispositivo a hablar DeviceNet?  ( How do i teach my device to talk devicenet ) 
Mi jefe está planeando implementar DeviceNet en algunos de nuestros productos. He mirado a través de Google y Odva.org, pero parece que no puedo encontrar nin...

2  Lata (red de área de controlador) en Android  ( Can controller area network on android ) 
Estoy tratando de conectar el control múltiple de control en la red central a través de un dispositivo de tableta / Android y tener algunos problemas que inte...

6  Plataforma transversal del mundo real descentralizado de la comunicación de igual a igual a  ( Real world cross platform decentralized asynchronous peer to peer communication ) 
Mi conocimiento sobre la programación de la red es limitado, por lo que todos los comentarios son más que bienvenidos. Esencialmente, mi pregunta se reduce a ...

2  ¿Qué encabezado debe enviarse por Maestro cuando haya múltiples esclavos cuyos datos se actualizan (marcos activados por eventos)?  ( What header should be sent by master when there are multiple slaves whose data i ) 
Queremos revisar RX de datos de esclavos en caso de marcos activados en eventos LIN. De acuerdo con nuestra comprensión, en la integración de Lin Stack para A...

11  ¿Redes de OBJETIVO-C - mejores prácticas?  ( Objective c networking best practices ) 
Estoy construyendo una aplicación Objective-C que tiene un servidor y un cliente. El cliente puede enviar actualizaciones al servidor, y el servidor debe pode...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos