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:
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...)
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í.
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.
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 .
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.
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.
eliot alderson
usuario1850479
colin