¿Cómo transmitir datos desde el sistema integrado a la PC rápidamente?

Estoy trabajando en un sistema integrado que generará datos a una velocidad bastante alta, 100-300 Mbit/s. Esto viene de un grupo de buses SPI. Necesito poner esto en una PC con Linux. ¿Cuál es la mejor manera de hacer eso?

Por el momento tengo una pequeña porción de esto construido con un microcontrolador STM32F4 como prueba de concepto. Obtiene datos a alrededor de 20 Mbit/s. Me doy cuenta de que (a) probablemente no haya forma de que el F4 lea datos a más de 100 Mbit, y eso probablemente siga siendo difícil/imposible para partes más rápidas como F7 o H7, ya que el reloj APB está limitado a 100 MHz; y (b) tampoco hay forma de enviar datos a una PC tan rápido desde estos microcontroladores, especialmente durante la lectura y el envío. Leer y enviar simultáneamente a 20 Mbit es probablemente (apenas) posible.

Las principales opciones para enviar datos a la PC parecerían ser USB o ethernet. El USB de alta velocidad es teóricamente lo suficientemente rápido a 480 Mbit, pero la mayoría de los microcontroladores ST no lo tienen, aunque parece que algunas partes tienen ULPI. Ethernet de 100 Mbit no es lo suficientemente rápido; gigabit es teóricamente lo suficientemente rápido, pero ninguno de los microcontroladores ST tiene eso (o SGMII). No sé cuál es el techo de velocidad práctico para la transmisión de datos a través de HS-USB o ethernet de 100 MBit, pero supongo que es mucho menor que la velocidad teórica.

Entonces, la pregunta es, ¿cuál es la mejor manera de transmitir datos a las velocidades agregadas que necesito? (ya sea con un microcontrolador rápido compatible con IO, o algo más).

Algunas opciones:

  • divida el dispositivo en varios dispositivos independientes (quizás 4-8 más o menos) y envíe datos de cada uno a través de HS-USB con un chip USB ULPI (USB3300 o similar) o ethernet de 100 Mbit a la PC con múltiples puertos USB/múltiples puertos ethernet - la PC puede volver a ensamblar estos flujos, o
  • Lo mismo, pero ponga algo al frente para agregar las conexiones: concentrador USB o conmutador ethernet. podría estar a bordo del dispositivo reducir la cantidad de cables físicos o un dispositivo separado
  • use un microcontrolador o SOC diferente que pueda manejar la tasa de datos total en un dispositivo
  • use un FPGA (pero ¿cuál? parece que la mayoría de los FPGA de bajo costo como ICE40 tampoco tienen SGMII)

En este caso, literalmente, no se produce ningún procesamiento; el micro envía algunos comandos de configuración a los buses SPI y luego solo pasa datos (posiblemente ensamblando los datos en bloques y agregando encabezados por bloque en la salida). Tampoco hay requisitos especiales de tiempo/latencia, siempre que los datos puedan transmitirse de forma continua sin perder nada. Quiero una configuración que sea lo más simple y robusta posible. Estoy muy familiarizado con los microcontroladores ARM; menos con los FPGA. Me gustaría evitar piezas de gama alta/especializadas (por supuesto, un Kintex FPGA podría manejar esto, pero...)

Nadie sabe lo que es "mejor" para ti excepto tú. Tiene algunos requisitos vagos (¿qué significa "gama alta"? ¿Qué significa "pero ..."?), por lo que esta es más o menos una pregunta de opinión y, por lo tanto, está fuera de tema.
¿Funcionaría un ASIC USB3? He usado el fx3 a más de 3 Gbit/s.
Muchas de las partes del STM32 tienen USB de alta velocidad, solo necesitan un PHY externo. Sin embargo, el STM32f723 tiene un PHY interno de alta velocidad.

Respuestas (6)

Bien, después de las primeras líneas, correctamente, descartó los microcontroladores. Entonces, ¡has descartado los microcontroladores !

Lo que necesita es algo que, como ha notado, "habla" una interconexión rápida en un lado y múltiples buses SPI en el otro.

La única forma en que veo que eso suceda es un FPGA.

La conexión de FPGA a Gigabit ethernet es bastante estándar, y es muy probable que cualquiera que sea la FPGA que elija, su fabricante tiene un bloque Ethernet MAC listo para usar que "solo" tiene que conectar a sus controladores SPI que implementa dentro de la FPGA, y escribir un poco de máquina de estado para transmitir los datos (muchos diseños incluso implementan una pequeña CPU como un picoRV32 en el FPGA para controlar la transmisión/encuadre). Todo lo que necesita hacer es conectar un PHY y un conector Ethernet que contenga el magnetismo. Muchos FPGA vienen con Evalboards que llevan exactamente eso. Un ECP5 podría ser una entrada barata aquí.

Tiene la impresión equivocada de que el FPGA traería una interfaz SGMII por sí mismo; no, el punto central de los FPGA es que puede configurar su lógica de modo que construya dicha interfaz.

Si desea seguir la ruta USB, también hay bloques de controlador USB2 (menos comunes) para FPGA, y conozco al menos un controlador USB3 de código abierto y gratuito en desarrollo (Luna de Kate Temkin). Sin embargo, la ruta habitual sería conectar su FPGA a un IC de controlador USB especializado; FX2 y FX3 de Cypress son los "clásicos" aquí.

Estaba mirando FPGA simples/pequeños como ICE40 y Max5/10; tal vez me estoy perdiendo el "cómo", pero no parece que haya ninguna forma de construir una interfaz SGMII sin transceptores. (aunque tal vez RGMII sea posible) El núcleo de IP Ethernet de celosía parece ser solo ECP2M/3/5 latticesemi.com/en/Products/DesignSoftwareAndIP/…
Ice40, Max5 realmente podría ser muy pequeño, y Max10 es... más pequeño que cómodo. Sí, te estás perdiendo el punto. Las interfaces SGMII son solo lógica adjunta a uno de los muchos pines IO de un FPGA. Básicamente, puede hacer eso en cualquier FPGA, dado que es lo suficientemente rápido y dado que los estándares de voltaje de los puertos IO lo permiten (y los niveles de voltaje RGMII son exactamente para lo que están diseñados los pines FPGA IO ...). No tiene que usar los bloques de IP proporcionados por el proveedor, puede ser cómodo. Ya recomendé ECP5, así que...

STM32H7 probablemente sería lo suficientemente rápido para manejarlo. Lo he usado para un propósito similar , con datos que ingresan a más de 100 MByte/s, que luego se comprimieron en tiempo real a aproximadamente 30 MByte/s que se transmitieron a través de USB de alta velocidad.

Usar USB HS en STM32 no es particularmente difícil. Solo necesita el PHY externo que está conectado a través de los pines ULPI y el controlador de software que admite el modo de alta velocidad. Usé Chibios, y fue fácil comenzar. En ese momento, no admitía DMA para las transferencias de memoria a periféricos USB, pero no parecía ser un cuello de botella en mi aplicación.

Introducir los datos en el procesador puede ser más problemático, ya que las interfaces no son tan flexibles como las de una FPGA. Si los periféricos SPI normales son lo suficientemente rápidos para su propósito, puede usarlos con DMA. El intercalado de datos de múltiples periféricos SPI se puede hacer con DMA, o puede transmitirlos en paquetes separados y procesarlos en la PC. DCMI también se puede (ab)utilizar para leer hasta 14 señales síncronas de hasta 100 MHz. El periférico QuadSPI puede administrar lecturas de 200 MHz en modo DDR, pero parece tener un límite de tamaño de transferencia de 4 GByte .

Si no ha desarrollado FPGA antes, lograr que la comunicación USB funcione puede ser todo un desafío, incluso si utiliza un núcleo IP prefabricado para ello. Contrariamente a otras afirmaciones, estoy seguro de que 300 Mbit/s es manejable en un STM32H7 de 480 MHz y ni siquiera necesita mucha optimización.

de acuerdo, un cortex-M7 suficientemente sincronizado serviría para el caso de ethernet, donde ni siquiera es necesario reaccionar a ninguna transacción de bus, pero puede simplemente disparar paquetes de ethernet y olvidarse. Personalmente, colocaría el STM32H7 en algún lugar entre los microcontroladores y los procesadores de aplicaciones, pero arm y ST los etiquetan como MCU, así que supongo que tiene razón.
@MarcusMüller Bueno, no estoy tan seguro sobre el caso de ethernet. Al menos STM32H7 no tiene gigabit ethernet. Pero USB-HS es más rápido que Ethernet de 100 Mbit. Y, por lo general, ethernet requiere más memoria intermedia, porque TCP puede necesitar retransmisiones después de varios milisegundos, a diferencia de USB, donde el retraso es de 125 us para USB-HS.
Buen punto, pero la transmisión a USB suele ser más difícil que la transmisión a Ethernet, porque en USB, debe proporcionar datos cuando el host los solicita, en Ethernet, puede enviar siempre que el medio no esté ocupado. El primero generalmente viene con requisitos de latencia media, lo que podría significar que el manejo de USB interfiere con el manejo de sus datos SPI. (realmente depende de la cantidad de DMA que pueda hacer antes de que realmente necesite manejar datos)
Los periféricos USB manejan esa comunicación de bajo nivel de manera completamente autónoma y, a menudo, tienen varios kilobytes de espacio FIFO. Entonces, simplemente coloca datos en FIFO y el periférico USB envía automáticamente los paquetes al host cuando los solicita, o responde con NAK si FIFO está vacío.
¡Ah, guay! Sí, entonces es bastante fácil, y USB vs Ethernet deben decidirse en función de otros factores (¿desea usar cableado/redes largos? ¿Qué es peor: necesitar un controlador en Windows o configurar su tarjeta de red?)

Debería usar un FPGA. No creo que necesites un FPGA de gama alta para este proyecto. Un Artix o Spartan 7 de Xilinx puede manejar fácilmente esos datos. Ethernet es probablemente la forma más fácil y mejor de transferir datos y dado que la velocidad de datos es de más de 100 Mbps, 1 GBe usando RGMII es el camino a seguir. El sitio FPGA Cores tiene un núcleo que puede conectar directamente a un RGMII phy y estará listo y funcionando en minutos. Los núcleos se pueden descargar gratis. He usado estos núcleos (principalmente RMII/100Mb) y es muy fácil trabajar con ellos.

Puede echar un vistazo a este ejemplo utilizando una placa Mimas Artix con Gigabit Ethernet .

Estoy de acuerdo con este enfoque. Trabajé en un proyecto integrado hace un tiempo que tenía una función MAC "fija". Básicamente, tomó un flujo de datos, lo dividió en marcos de Ethernet y los envió. No había control de flujo. La velocidad de datos entrantes era inferior a la velocidad de Ethernet. Se usó un PHY externo para adaptarse al medio (esto era 100BASE-TX, pero 1000BASE-T o cualquier otra variante también estaría bien). El USB está bien, creo, pero tiene mucho pelo. Ethernet es relativamente simple, en mi humilde opinión. Una parte complicada del diseño de los OP será fusionar los flujos sin joder al perro.

Eso realmente depende de cuántos buses SPI tenga y qué rendimiento tenga en cada uno.

Si la cantidad de buses SPI que tiene se ajusta a la cantidad de periféricos SPI disponibles en un microcontrolador que tiene USB2 y un motor DMA adecuadamente inteligente, entonces este es el camino a seguir. La velocidad del reloj es engañosa; por ejemplo, un Cortex-M4 LPC4330 de 204 MHz funcionará bien con un USB2 masivo de 480 Mbps con un pequeño porcentaje de carga de CPU en el M4, pero eso se debe a que tiene varios motores DMA de dispersión y recopilación bastante inteligentes y un rendimiento de memoria ridículo (algo así como varios gigabytes/ s) debido a la matriz de bus AHB y varios bancos de memoria que operan en paralelo. Puede usar DMA para transferir de SPI a RAM, luego el periférico USB usa DMA nuevamente. La CPU nunca toca los datos, solo baraja los punteros.

Pero, ¿tiene suficientes periféricos SPI para ti? Ese es el factor principal. Obviamente, con el rendimiento que necesita, no lo va a explotar. Absolutamente necesita hardware.

También tenga en cuenta que no estoy recomendando particularmente el LPC4330, es un gran chip pero es un poco viejo y la última vez que verifiqué (hace 5 años) las bibliotecas de software provistas eran basura, tuve que escribir el controlador USB yo mismo. Este suele ser el caso: obtienes un micro con un gran hardware que puede hacer fácilmente 48 Mb/s USB2 sin sudar, y el código de ejemplo es un pedazo de basura que hace 1 Mb/s. Entonces, otra cosa importante para agregar a la lista de verificación si tiene prisa es que "las bibliotecas incluyen un código de ejemplo fácil de reutilizar que realmente hace 480Mbps USB2 en masa sin fallar".

Si tiene buses SPI no tan rápidos , como 30 Mbps cada uno, pero digamos 10 de ellos, entonces ningún microcontrolador tendrá suficientes canales SPI. La solución más simple sería enchufar cada uno en un puente FT232H USB2 a SPI listo para usar. Estos harán 30 Mbps cada uno. Pros: problema resuelto, no hay hardware para diseñar, solo un poco de software en el lado de la PC. Contras: obviamente no es para producción de alto volumen, no hay sincronización entre secuencias.

Si te gusta lo sexy y lo exótico, está XMOS. Creo que puede hacer el trabajo. También es bastante fácil de usar, pero no hay muchas placas disponibles.

Además de eso, está la solución FPGA. No debería ser demasiado difícil en el lado de SPI, puede tener tantos canales como pines tenga para ellos. En el lado USB, un chip fifo USB FTDI o un chip Cypress FX2 son mucho más fáciles y rápidos de ejecutar que un núcleo USB. Intente obtener una placa que tenga un puerto USB y uno de estos chips USB, luego verifique los esquemas para asegurarse de que el chip USB no solo se use para programar el FPGA, sino que también tenga una ruta de comunicación rápida con el FPGA.

Solo consideraría que el FPGA hiciera el trabajo USB si la placa viniera con un código de ejemplo sólido y un núcleo USB que no necesita una licencia $$$.

Personalmente, no me molestaría con ethernet, a menos que... como se indicó anteriormente, obtenga una placa con un código de ejemplo sólido que funcionará a 1 Gbps. USB es mucho más simple y tiene un rendimiento total más alto si usa múltiples puertos USB2.

Podría mirar el FPGA de la serie MAX10 de Intel/Altera. Son FPGA no volátiles. La mayoría de los FPGA de gama alta necesitan una parte externa para almacenar la configuración. Soy muy principiante en FPGA. La curva de aprendizaje es bastante empinada. Terasic (enlace a continuación) tiene algunas placas de desarrollo que puede probar según su presupuesto.

También hay FPGA de Xilinx. Aunque no estoy familiarizado con ellos.

https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&CategoryNo=13&List=Simple#Category218

Es posible que desee ver la serie i.MX RT de NXP. Son piezas H7 ARM con versiones BGA que funcionan a más de 600 MHz con un HS USB PHY integrado. Sin embargo, no estoy seguro de que puedan manejar los 200-300 Mbits completos que especificó debido a la sobrecarga de procesamiento/USB.

FPGA es una ruta que generalmente no desea tomar a menos que esté extremadamente familiarizado con HDL y todas las interfaces involucradas (tiempo, protocolos, pilas de software para USB/Ethernet/lo que sea que esté implementando). Por experiencia personal, diría que poner en marcha una placa FPGA requiere aproximadamente el 2% de mi tiempo y el software + verilog + depuración ocupa el otro 98%, incluso cuando estoy algo familiarizado con los protocolos involucrados.