¿Protocolo general para la transferencia de datos de un sistema a otro?

¿Cuál es el protocolo general para enviar información de un sistema a otro? Por ejemplo, supongamos que tenemos información recopilada del microcontrolador durante un período de tiempo que queremos enviar a otro microcontrolador. He oído hablar de las interfaces SPI e I2C, pero no tengo claro cuándo usa un método sobre otro y cómo lo implementa. ¿Existen otros métodos además de SPI e I2C que sean comunes? ¿El proceso de implementación es similar para diferentes microcontroladores? ¿Básicamente está analizando bytes de datos que estoy haciendo en el microcontrolador receptor?

¿Qué es lo concreto que quieres hacer?
Solo pensando en cómo hacer que diferentes partes de un sistema se pasen datos entre sí en una caja pequeña, por lo que se puede suponer que la distancia es muy corta. La razón de tener diferentes piezas en una caja es simplificar las funciones para que cada pieza tenga su propia función (esperemos que eso tenga sentido...)
eso no es lo que la gente normalmente llama un sistema. Esos son más lo que yo definiría como subsistemas. Forman parte de lo que se podría considerar un único sistema que realiza un único conjunto de tareas. Es semántica, pero creo que muchas de sus respuestas son muy amplias porque no tienen una idea perfecta de lo que está buscando en la pregunta.
en la línea de lo que dijo Kortuk, ayuda a definir el problema. Una pregunta importante que debe hacerse es si podría tener la intención de reemplazar subsistemas individuales con diferentes implementaciones de la misma función, o si se trata de un diseño único tal como está. Si usa un bus real y expone los detalles de implementación de los subsistemas a su CPU, entonces un cambio de subsistema requiere un cambio as/w para su controlador, mientras que si usa una interfaz de comunicación, no importa cómo implemente un (reemplazo ) subsistema, siempre que cumpla con el mismo protocolo de mensajes.
No es más sencillo dividir la funcionalidad en varios dispositivos sin más motivo que separar las tareas. Las comunicaciones y la sincronización son más complejas que tener dos procesos en el mismo micro. Ahora bien, si estos procesos tienen perfiles de latencia particularmente incompatibles (uno debe actualizarse rápidamente mientras que el otro puede tardar algún tiempo en completar una parte), entonces PUEDE haber una razón válida para dividirlos. Incluso entonces, la solución más común es usar interrupciones o encontrar una manera de dividir aún más la tarea más larga. Con lo que has descrito, me inclino a pensar que deberías repensar esto.
Una comparación útil de SPI vs I2C: electronics.stackexchange.com/questions/29037/…

Respuestas (7)

SPI e I2C son algo similares, ya que en realidad se usan más para conectar dispositivos periféricos a un controlador o CPU que para transferir datos entre sistemas. USB es otra interfaz que la gente parece querer tratar como un sistema de comunicación, que de hecho es un bus de conexión de periféricos.

La comunicación entre sistemas no es exactamente como conectar un dispositivo a un bus. La conexión de bus permite que el procesador golpee directamente los registros en un dispositivo, mientras que una interfaz de comunicación le permite enviar/recibir flujos de datos. Un dispositivo conectado en un bus generalmente necesita un controlador de dispositivo, mientras que con las comunicaciones, realmente no importa lo que esté conectado en el otro extremo, en lo que respecta a la computadora host.

Por supuesto, esto se está convirtiendo en un límite más confuso todo el tiempo. Cosas como PCI e ISA son indiscutiblemente buses; Podría decirse que I2C, SPI, USB son buses; mientras que RS232, RS485 y ethernet son definitivamente interfaces de comunicación. Pero luego hay cosas como el bus CAN y 1553, que definitivamente se trata de mover datos, pero de una manera muy complicada.

¿CANbus está muy involucrado y Ethernet no? CAN es muy fácil de poner en funcionamiento para enviar mensajes de ida y vuelta. Son chips dedicados y la mayoría de las familias son compatibles con el interior de sus microcontroladores.
@Kortuk: en la medida en que algo como 232 tiene una especie de simetría de igual a igual, mientras que 1553 o PUEDE imponer una relación maestro/esclavo, sí. No creo haber dicho que Ethernet es simple, solo que no impone una distinción de controlador de bus/dispositivo de bus en los puntos finales.
también, divulgación completa: mi opinión de CAN proviene completamente de la exposición tangencial; ha sido un periférico opcional no utilizado en varios sistemas en los que he trabajado, pero después de cientos de pasos a través de la documentación, absorbe un poco sobre las opciones no utilizadas solo por ósmosis. Así que estoy trabajando bajo la suposición de que CAN es un tipo de arquitectura de controlador/dispositivo controlado.
Creo que autobús tiene diferentes significados en diferentes contextos. Desde un nivel esquemático, cualquier interfaz con múltiples señales puede considerarse un bus. A medida que avanza a niveles más altos con más abstracción, bus cambia de significado. Un poco más alto, el bus generalmente significa que hay o puede haber varios dispositivos involucrados. El multipunto RS485 es definitivamente un bus, por ejemplo. Mucho más arriba, desde el punto de vista de un dispositivo Linux, RS485 vuelve a ser una interfaz de comunicación y deja de ser un bus... hasta que agrega su propia capa de protocolo encima y lo vuelve a convertir en un bus. En cada nivel tiene diferentes significados.

No hay una única forma de enviar datos, hay muchas formas diferentes de comunicarse dependiendo de la distancia, la velocidad de datos, el entorno, la aplicación...

La capa más baja es la capa física , que en realidad mueve los bits.

  • SPI e I²C son para distancias cortas dentro de un dispositivo, donde no hay mucho ruido que pueda perturbar la transmisión.

  • Para una comunicación no demasiado rápida a distancias de hasta algunas decenas de metros, la comunicación en serie a través de RS-232 es una buena opción.

  • Si hay más ruido o mayor distancia se utilizan señales diferenciales, por ejemplo en RS-485. Para una transmisión de datos más rápida existe Ethernet, que se está volviendo cada vez más popular.

  • Luego también hay varios estándares inalámbricos.

Además de la capa física, hay más capas que organizan cómo se envían los datos, para detectar y corregir errores en la transmisión, el enrutamiento en una red y muchas otras cosas. Por ejemplo, el protocolo de Internet es una pila bastante compleja de varias capas, generalmente sobre el protocolo Ethernet.

Se puede usar un UART serial simple (una línea Tx y una Rx sin reloj discreto) y se puede adaptar fácilmente para cruzar entre diferentes potenciales (incluso circuitos primarios y secundarios) con optoaisladores o aisladores magnéticos .

En lo que respecta a los protocolos, cualquier cosa con bytes de comando definidos y algún tipo de esquema de suma de verificación funcionará bien. Realmente no existe un protocolo estándar que cubra todo y que se adapte a todos los tipos de comunicaciones. I2C tiene estándares de señalización (que definen el direccionamiento, las paradas, los inicios, etc.), pero el protocolo de lo que realmente se comunica depende únicamente del desarrollador.

PMBus , por ejemplo, es un protocolo de comunicación de fuente de alimentación que utiliza I2C como medio físico.

Como señaló @Jon, un problema al seleccionar una interfaz de comunicaciones es si una entidad siempre será responsable de iniciar las comunicaciones o si más de una entidad puede ser responsable. Un asunto relacionado es si una entidad siempre estará lista para recibir comunicaciones no solicitadas. SPI se usa con frecuencia en aplicaciones donde un lado siempre estará listo para recibir comunicación. Algo así como un registro de desplazamiento 74HC595, por ejemplo, nunca está "ocupado". Si bien SPI es bueno para la comunicación entre un microcontrolador y el hardware que se supone que controla el micro, en realidad no es bueno para la comunicación entre dos microcontroladores. Cuando dos procesadores con hardware I2C lo utilizan para comunicarse, el software puede tardar todo el tiempo que quiera (dentro de unas limitaciones muy generosas) en hacer frente a lo que está pasando. sin causar pérdida de datos. Si un procesador tomara 100 microsegundos para procesar cada byte entrante, eso limitaría severamente el rendimiento, pero el remitente se ralentizaría lo suficiente como para que el receptor se mantuviera al día. La única forma en que generalmente puede suceder con SPI es si uno tiene un cable separado para el protocolo de enlace.

I2C es realmente un protocolo maravilloso. Las mayores limitaciones que le impiden ser el protocolo más perfecto imaginable son

  1. Su velocidad es algo limitada; SPI puede ir mucho más rápido, e incluso los UART a veces pueden ir un poco más rápido
  2. (2) Si bien es muy conveniente que I2C solo necesite dos cables, ambos cables deben ser capaces de comunicación bidireccional de colector abierto. Esto dificulta el envío de I2C a través de repetidores.

Personalmente, me gustaría ver que los proveedores de controladores admitan una variante de SPI de tres hilos que incluya protocolo de enlace. Sin embargo, no conozco ningún controlador que lo haga.

Es gracioso que mencione esto... Tengo que convertir una interfaz SPI en una interfaz no bidireccional similar a I2C (el primer byte es una dirección) para permitir que muchos más dispositivos participen en el bus de los que tengo para seleccionar chips . Funciona si sus dispositivos esclavos son todos FPGA. :) Yo también he deseado que hubiera algo entre esos dos principales estándares sincrónicos.
Oh, supongo que debería aclarar que las habilitaciones de salida en los esclavos no se afirman hasta que se recibe el byte de dirección y permanecen encendidas hasta que se anula la selección de un solo chip... por lo que obviamente es ligeramente diferente al SPI normal + nivel alto protocolo. Sin embargo, es totalmente compatible con SPI estándar desde el punto de vista de un dispositivo maestro. (como un microprocesador)
@darron: Genial. Me pregunto qué tendría que pasar para que la industria comenzara a usar un bus de comunicaciones de tres hilos de estándar abierto donde los cables se conducen activamente hacia arriba y hacia abajo. Supongo que hay un pequeño conflicto entre evitar pull-ups pasivos y permitir que cualquier dispositivo señale una interrupción, aunque eso podría remediarse agregando un pin de interrupción que podría conectarse al maestro o no según la conveniencia de los esclavos (mi implementación actual de el protocolo solo tiene un esclavo, por lo que puede usar el cable de retorno de datos para señalar de forma asíncrona cuándo desea recibir servicio).
@darron: para evitar tener que usar un pin de selección de chip, el maestro señala el inicio del comando enviando dos flancos ascendentes en el cable de datos mientras el reloj está bajo; los esclavos pueden indicar si su último byte de datos fue válido emitiendo un valor de estado cuando el reloj y los datos están bajos (inactivos); de lo contrario, indican que quieren atención cuando el reloj está bajo y los datos están altos. Si estuviera diseñando hardware maestro para este protocolo, agregaría la capacidad de enviar 8 pulsos de reloj donde el cable de datos reflejaba el reloj, y en el hardware esclavo incluiría un conteo asíncrono del número de flancos ascendentes durante...
@darron: ...un byte de datos. Si son cinco o más, el byte se ignorará (el esclavo asumirá que el maestro está interesado en recibir un byte de datos, pero no tiene nada que decir). Sin embargo, eso no sería tan significativo como hacer que el esclavo informe el estado del último byte cuando el reloj estaba bajo (lo que, si el dispositivo esclavo fuera un procesador, permitiría que el maestro supiera que el esclavo no estaba listo). y había perdido la última 'oportunidad de transacción'.

Realmente no hay un protocolo "general", lo que termine usando depende en gran medida de la aplicación. Para que podamos darle una mejor respuesta, necesitamos entender un poco mejor sus requisitos. Usted menciona que le gustaría tener microcontroladores separados que se comuniquen entre sí como subsistemas.

Algunas preguntas sobre esta aplicación:

  1. ¿Habrá más de 2 microcontroladores en este proyecto?
  2. ¿Cuáles son sus requisitos de velocidad y rendimiento? ¿Qué tan rápido llega la información y con qué frecuencia envía/recibe datos?

Si respondió NO a la pregunta 1:

Si solo hay 2 microcontroladores en este proyecto, definitivamente puede usar UART entre ellos. Si ambos necesitan iniciar la comunicación, use el control de flujo; de lo contrario, debería ser trivial enviar datos en una dirección. En su mayor parte, debería ser "lo suficientemente rápido" dado que selecciona una de las velocidades de transmisión más altas. I2C y SPI generalmente solo son buenos para la arquitectura maestro/esclavo.

Si respondió SÍ (más de 2 controladores) a la pregunta 1:

  • Si hay más de 2 microcontroladores en su proyecto, ¿cuál inicia las comunicaciones? ¿Será solo un controlador maestro (es decir, arquitectura maestro-esclavo)? ¿O alguno de los subsistemas podría hablar en cualquier momento?
  • ¿Es necesario que alguno de los subsistemas se comunique entre sí? por ejemplo: para los dispositivos A, B y C: A puede enviar a B y C, y B puede enviar tanto a A como a C, etc.

Entonces, ahora necesita algo más escalable donde pueda colocar dispositivos direccionables en un bus común. La respuesta a estas preguntas de seguimiento lo ayudará a decidir entre I2C y SPI (maestro-esclavo) o algo como CAN (multimaestro).

Lo más probable es que su microcontrolador tenga un periférico UART, los otros (especialmente CAN) solo pueden estar disponibles en chips de gama más alta. En cualquier caso, debe haber mucha documentación sobre cómo usar estos periféricos para mover bytes.

Sin ningún orden en particular, las instancias de capa física más populares para 2 CPU en la misma caja parecen ser:

  • SPI en cadena tipo margarita (como el utilizado por JTAG)
  • seleccionar-cable-por-esclavo SPI
  • "RS-232 de nivel TTL", también conocido como "comunicación serial asíncrona de inicio y parada" (conectando directamente el pin UART TX de una CPU al pin UART RX de otra CPU)
  • I2C
  • Datos de 8 bits + luz estroboscópica (como el puerto paralelo del puerto de impresora IEEE 1284)
  • memoria compartida (solo una CPU maneja el bus de dirección/datos/control a la vez)

Estas instancias de capa física (así como otras instancias de capa física para 2 CPU en cajas separadas) generalmente brindan un flujo de bytes al software que implementa los niveles más altos del sistema de comunicación.

Los programadores inteligentes escriben el software de tal manera que cuando el encargado del hardware decide eliminar una instancia de capa física y reemplazarla con una instancia de capa física completamente diferente, solo necesitan reescribir algunas funciones para alimentar su flujo de bytes de salida. al hardware y lee una secuencia de bytes del hardware, y todo el protocolo de nivel superior sigue funcionando sin cambios.

El protocolo para enviar información de una CPU a otra CPU casi siempre implica interpretar el flujo de bytes como una serie de paquetes:

  1. preámbulo
  2. encabezamiento
  3. (posiblemente escapado) datos serializados
  4. remolque

Algunas personas parecen disfrutar inventando protocolos completamente nuevos, personalizados e incompatibles mezclando y combinando (2) uno de los muchos tipos de estructuras de encabezado con (3a) uno de los muchos tipos de serialización de datos con (3b) uno de los muchos tipos de escapando de esos datos serializados con (4) uno de los muchos tipos de tráiler.

Algunos de los protocolos más simples para encapsular datos en un paquete incluyen:

Los protocolos un poco más complicados para encapsular datos en un paquete incluyen:

Hay una larga lista de protocolos en

Puede disfrutar leyendo "Protocol Design Folklore" de Radia Perlman, que describe cómo el diseño de protocolos puede fallar.

Ningún protocolo 'general' único. La elección puede (por ejemplo) depender de:

  • distancia
  • rendimiento requerido
  • disponibilidad de periféricos especiales
  • nivel de ruido
  • necesidad de aislamiento óptico
  • criticidad (tasa de falla tolerable)
  • potencia de CPU disponible en ambos extremos
  • pines de E/S disponibles en ambos extremos

En muchos casos, debe distinguir la capa física (niveles de señal) de la capa de enlace de datos (+/- la forma en que se codifican los datos) (consulte el modelo OSI, 2 ..4 capas inferiores). Las posibles capas físicas son, por ejemplo:

  • simple 5V o 3.3V o incluso 1.8V TTL
  • cualquiera de los anteriores pero de colector abierto en lugar de push-pull
  • señalización de voltaje lov balanceado (a menudo se usa con FPGA)
  • alto voltaje balanceado (RS485, RS432)
  • voltaje más alto de un solo extremo (RS232)
  • Trafo-acoplado balanceado (varias versiones de ethernet, audio PDIF)
  • óptico (ethernet óptico, toslink)

Puede usar una línea para transportar datos e información del reloj, o dividirla en varias líneas. Este último solía ser popular, pero hoy en día la mayoría de los protocolos nuevos/rápidos tienden a usar una línea (o un par de líneas que actúan como una sola).

Hay muchas formas de codificar datos y reloj en una línea. RS232 usa tradicionalmente NRZ, hay codificación Machester, y los varios formatos que usa en discos duros con nombres curiosos línea 2.7 RLL.

Para resumir: hay miles de formas de comunicarse entre sistemas. Y ni siquiera he mencionado los conectores o aspectos de nivel superior como la detección y recuperación de errores, la codificación de datos, la compresión y el cifrado...