2008-11-22 22 views
18

Estoy construyendo un pequeño dispositivo con su propia CPU (AVR Mega8) que se supone que se conecta a una PC. Suponiendo que se ha logrado la conexión física y el paso de bytes, ¿cuál sería el mejor protocolo para usar sobre esos bytes? La computadora necesita poder establecer ciertos voltajes en el dispositivo y volver a leer otros voltajes.Protocolos utilizados para hablar entre una CPU integrada y una PC

Por el momento, estoy pensando en un protocolo síncrono completamente impulsado por el host: solicitudes de envío de la computadora, la CPU incrustada responde. ¿Alguna otra idea?

Respuesta

6

Modbus puede haber Qué estás buscando. Fue diseñado exactamente para el tipo de problema que tienes. Hay muchos códigos/herramientas y el cumplimiento de un estándar podría significar una fácil reutilización posterior. También es compatible con ASCII legible por humanos, por lo que aún es fácil de entender/probar.

Ver FreeModBus para Windows y fuente integrada.

6

Hay mucho que decir acerca de la arquitectura cliente-servidor y los protocolos síncronos. Simplicidad y solidez, para comenzar. Si la velocidad no es un problema, puede considerar un protocolo compacto y legible por humanos para ayudar con la depuración. Estoy pensando en las líneas de los comandos AT del módem: una secuencia de "activación" seguida de un comando set/get, 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 agotar el tiempo si no ve el corchete de cierre, y habían volver a sincronizar en el siguiente paréntesis abierto, que no puede aparecer dentro del propio mensaje.

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

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

También es útil para definir mensajes de error, en caso de que necesite depurar.

+0

+1 para lectura humana –

1

USB bus responderán a todas sus necesidades. Puede ser un dispositivo usb muy simple con solo un tubo de control para enviar solicitudes a su dispositivo o puede agregar un tubo de interrupción que le permitirá notificar al host sobre los cambios en su dispositivo. Hay varios controladores usb simples que se pueden usar, por ejemplo Cypress o Microchip.

El protocolo en la parte superior de la transferencia es realmente acerca de sus requisitos. Según su descripción, parece que el simple protocolo síncrono es definitivamente suficiente. ¿Qué te hace vagar y buscar un enfoque adicional? Comparte tus dudas e intentaremos ayudar :).

3

Adam Liss tiene muchos puntos buenos. La simplicidad y la solidez deberían ser el foco. Las transferencias ASCII legibles por humanos ayudan MUCHO durante la depuración. Grandes sugerencias

Pueden ser exagerados para sus necesidades, pero HDLC y/o PPP agregan el concepto de capa de enlace de datos y todos los beneficios (y costos) que vienen con una capa de enlace de datos. La gestión de enlaces, el encuadre, las sumas de comprobación, los números de secuencia, las retransmisiones, etc., ayudan a garantizar comunicaciones sólidas, pero agregan complejidad, procesamiento y tamaño de código, y pueden no ser necesarios para su aplicación en particular.

1

Si no esperaba realizar transferencias binarias eficientes, me decantaría por la interfaz de estilo de terminal ya sugerida.

Si yo quiero hacer un formato de paquete binario, que tienden a usar algo vagamente basada en el formato PPP byte ASNC HDLC, que es extremadamente simple y fácil para enviar reciben, básicamente:

Los paquetes de inicio y finalice con 0x7e Usted escapa de un carácter prefijándolo con 0x7d y alternar el bit 5 (es decir,XOR con 0x20) Así 0x7E se convierte en 0x7D 0x5E y 0x7D se convierte en 0x7D 0x5D

Cada vez que vea un 0x7E entonces, si usted tiene almacenados los datos, puede procesarla.

Normalmente hago cosas sincrónicas basadas en host a menos que tenga una muy buena razón para hacer lo contrario. Es una técnica que se extiende desde el punto de referencia simple RS232 hasta el multipunto RS422/485 sin problemas, a menudo una ventaja.

+0

Una alternativa al encuadre PPP es [COBS] (http://www.stuartcheshire.org/papers/COBSforToN.pdf). He hecho una [implementación de C] (http://bitbucket.org/cmcqueen1975/cobs-c/) y una [implementación de Python] (http: // packages.python.org/cobs/). –

5

Mi voto es para el humano legible.

Pero si vas binario, intenta poner un byte de encabezado al principio para marcar el comienzo de un paquete. Siempre he tenido mala suerte con los protocolos serie que no están sincronizados. El byte del encabezado permite que el sistema integrado se vuelva a sincronizar con la PC. Además, agregue una suma de verificación al final.

4

que he hecho este tipo de cosas 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íticas en un protocolo síncrono que en uno asíncrono, pero todavía ayuda, especialmente cuando el sistema embebido es primero encendido, y no sabes si el primer byte que recibe es el medio de un mensaje o no.

El tipo debe ser una enumeración que indique cómo interpretar el paquete. El tamaño se puede deducir del tipo, pero si lo envía explícitamente, el receptor puede manejar tipos desconocidos sin ahogarse. Puede usar 'tamaño total del paquete' o 'bytes a seguir'; este último puede hacer que el código del 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 el CRC en el encabezado, lo que hace que declarar las estructuras sea más fácil, pero ponerlo al final le permite evitar un pase adicional sobre los datos al enviar el mensaje.

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

Si está seguro de que ambas plataformas usan flotadores IEEE-754 (las PC lo hacen) y tienen el mismo endianness, entonces puede usar flotantes como el tipo de datos. De lo contrario, es más seguro usar enteros, bits A/D sin procesar o una escala preestablecida (es decir, 1 bit = .001V da un rango de +/- 32.267 V)

1

Como ya puede haber determinado de todas las respuestas no directamente dirigiéndolo a un protocolo, que su propio enfoque sea su mejor elección.

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

Teniendo en cuenta que este chip tiene 6 canales ADC, más probable es que esté utilizando RS-232 comunicación en serie (una suposición de su pregunta), y por supuesto el espacio de código limitado, que define una estructura de comando simple ayudará, como lo señala Adam. Puede desear mantener el procesamiento de entrada al mínimo en el chip, por lo que el binario suena atractivo pero el intercambio está en facilidad de desarrollo Y mantenimiento (puede que tenga que solucionar el problema de una entrada muerta dentro de 6 meses) - hyperterminal es una poderosa herramienta de depuración - entonces, eso me hizo pensar cómo implementar una estructura de comando simple con buena confiabilidad.

Algunas consideraciones generales - Comandos

mantener el mismo tamaño - Hace que la decodificación más fácil.

Enmarcar los comandos y la suma de verificación opcional, como señala Adam, se puede ajustar fácilmente a sus comandos. (con comandos pequeños, una suma de comprobación XOR/ADD simple es rápida e indolora)

Recomendaría un anuncio de inicio al host con la versión de firmware en el reinicio, por ejemplo, "HOLA; Versión de firmware 1.00z" - decirle al anfitrión que el objetivo acaba de comenzar y lo que está funcionando.

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

Terminar cada línea de salida con un CR (u otro carácter) hace que la sincronización en el host sea directa.

por ejemplo, su micro podría simplemente dar salida a las cadenas;

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

Además, los comandos podrían ser muy simple -

? - Lee todos los valores - no hay muchos, así que entiéndelos.

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

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

5=0 
6=9 
2=5 

que fijaría el puerto 5 de descuento, puerto 6 de lleno, y el puerto 2 a la mitad del valor - Con este enfoque , Ascii y los datos binarios están casi en pie de igualdad con respecto a los recursos de computación/decodificación en el micro. O para mayor precisión, haga que la salida sea de 2 bytes, por ejemplo, 2 = 54 - O, agregue una tabla 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 es usualmente mejor, a menos que no lo sea.

Espero que esto ayude un poco.


Tuve que pensar mientras releía; la adición de un comando "*" podría solicitar los datos entre etiquetas HTML y ahora su aplicación anfitrión podría simplemente redirigir la salida de su micro a un navegador y wala, navegador listo -

:)

Cuestiones relacionadas