12 votos

STM32F407 + LAN8720A + lwIP + FreeRTOS = No se reciben tramas Ethernet

Estoy tratando de levantar un PCB que utiliza un STM32F407 y LAN8720A Ethernet PHY, y parece que no puedo recibir ninguna trama de Ethernet - a pesar de que no tengo ningún problema de transmisión de tramas.

Configuración del hardware

Schematic of Ethernet PHY Tengo un cristal de 25 MHz en el STM32F4, que conduce un pin de salida de reloj de 25 MHz al LAN8720A, que está en modo REF_CLK_OUT - y conduce un reloj de 50 MHz de vuelta al STM32F4 como parte de la interfaz RMII.

El gato/magnético es una pieza genérica. Aquí está la hoja de datos: enter image description here

Software

Estoy usando la última actualización de STM32CubeMX para generar un proyecto de System Workbench para STM32 que contiene FreeRTOS, lwIP, más los drivers de los periféricos ETH. Realmente no he tocado nada del código generado - así que la pila de lwIP se inicializa dentro de una pila de FreeRTOS.

Experimentos

Con el lwIP de mi placa configurado para una IP estática 10.0.0.2, y un dongle USB-a-ethernet en mi ordenador configurado para una IP estática 10.0.0.1, conecto los dos dispositivos directamente con un cable Ethernet, y mi placa intenta conectarse a un servicio en el puerto 80 del ordenador. Capturo la interacción entre mi placa y el ordenador utilizando Wireshark (que se ejecuta en el ordenador, y está vinculado al convertidor de USB a Ethernet).

Debido al problema de los fotogramas no recibidos, nunca pasamos de este asunto del ARP: Wireshark capture Como puedes ver, el Stmicroe (mi placa) puede enviar paquetes ARP - escuchados por mi ordenador - pero nunca parece escuchar la respuesta de mi ordenador, ya que sigue enviando paquetes ARP.

Ambos dispositivos están configurados con una máscara 255.255.255.0, y ambos están configurados con una dirección de puerta de enlace de 10.0.0.1 (el ordenador). He oído que las tablas ARP se estropean y que los ordenadores ignoran los paquetes ARP, pero no puedo imaginar que la placa ignore los paquetes ARP dirigidos específicamente a ella por mi ordenador - en respuesta a las peticiones que la placa hizo en primer lugar.

Entonces, me sumerjo en el archivo ethernetif.c de lwIP y noto que HAL_ETH_GetReceivedFrame_IT(&heth) devuelve un error. Esa función devuelve un error porque (heth->RxDesc->Status & ETH_DMARXDESC_OWN) == 0, en lugar de 1. Interpreto que eso significa que los buffers DMA están actualmente armados para el periférico MAC, y no han recibido nada todavía.

Además, he comprobado que el HAL_ETH_IRQHandler nunca es llamado.

¿Un problema con el PHY?

En este punto, sospeché que el culpable era mi propio PHY.

Para investigar más a fondo, conecté mi Saleae Logic Pro 16 a todas las señales relevantes, y noté que hay mucho tráfico tanto en las líneas TX0/TX1, como en las RX0/RX1. Aquí hay una captura de algo de tráfico RX con el reloj de entrada de 25 MHz:

Capture of received packet

RX_ERR está bajo todo el tiempo, a menos que intente capturar la salida del reloj de 50 MHz (lo que obviamente es un reto con un dispositivo como el Saleae): en ese caso, RX_ERR se eleva ocasionalmente durante unos pocos paquetes (lo que en realidad es una buena señal - el pin parece estar funcionando).

Próximos pasos

He intentado habilitar manualmente las interrupciones ETH llamando a HAL_NVIC_EnableIRQ(ETH_IRQn); después de tcpip_init() se llama en el MX_LWIP_Init() tarea, y eso no parece solucionar el problema. No estoy del todo seguro de que la rutina de interrupción de Ethernet sea siquiera se supone que se llama - eso es lo difícil de subir un diseño nuevo; estoy luchando por determinar cuál sería el comportamiento adecuado del sistema, para luego poder determinar cómo difiere mi configuración.

Aunque ya he utilizado el material de STM32/STM32CubeMX/FreeRTOS, nunca he utilizado el periférico Ethernet de STM32, y mi única experiencia con este material es en sistemas Linux embebidos personalizados, que siempre parecían funcionar sin más. Este es un nuevo territorio para mí.

Estoy seguro de que hay una estúpida casilla de verificación en algún lugar o mágica Ethernet_EnableReceive() pero no puedo encontrar ninguna documentación que sugiera la necesidad de habilitar explícitamente esas cosas, y los mensajes que estoy viendo en Internet son todos debidos a problemas no relacionados.

Si alguien tiene alguna idea, ¡me encantaría recibir ayuda!

Apéndice: Deshacerse de FreeRTOS

Sólo para eliminar cosas, he eliminado el componente del proyecto FreeRTOS, volviendo a un proyecto bare-metal. En mi bucle principal, llamo a MX_LWIP_Process() . Este método debería eliminar la necesidad de interrupciones, pero no soluciona el problema; sigo sin poder recibir tramas. Esto me hace pensar que hay algo en el código ETH HAL generado por STM32CubeMX.

Solución

Por si acaso alguien se tropieza con esta pregunta en el futuro, el problema resultó ser que los pines RXD0 y RXD1 estaban invertidos. Por eso pude ver el tráfico en mi analizador lógico, pero no fue decodificado por mi MCU.

Como alguien ha señalado, los imanes que utilicé son asimétricos, y no deberían utilizarse para auto-MDI-X. No he tenido ningún problema. Preveo que una de dos cosas está pasando - los magneticos no funcionan realmente en la otra orientacion, pero como todo lo que tengo usa auto-MDI-X, mi placa esencialmente se mantiene fija en la configuracion que funciona, mientras que el otro dispositivo en el cable orienta sus senales para que coincidan. - Los imanes proporcionan una integridad de la señal adecuada en los tramos cortos de Ethernet, pero un análisis a largo plazo mostraría mayores tasas de caída de paquetes o problemas en tramos más largos.

Sinceramente, no me queda claro por qué importaría en qué lado del transformador 1:1 se instalan los filtros de línea, así que fuera de las aplicaciones PoE, no estoy seguro de por qué importaría un diseño simétrico o asimétrico.

1voto

user126869 Puntos 121

Perdón por resucitar este tema. No podía pasar sin mencionar mi experiencia.

He utilizado este HR911105A (RJ45 con imán) con uno de mis proyectos.

HR911105A: enter image description here De un vistazo, una cosa me llamó la atención que fue la conexión entre LAN8720 y RJ45 según su esquema.

Ya que veo que la conexión parece cruzada. Aunque los sistemas conectados en su mayoría utilizan MDI-X y por lo tanto detectan los pares de recepción / transmisión, sería bueno darle una conexión menos confusa como esa:

LAN -> RJ45
=====================
TXP -> TD+ (Pin #1)
TXN -> TD- (Pin #2)
RXP -> RD+ (Pin #3)
RXN -> RD- (Pin #6)

Pin #4 and Pin #5 (por lo que las resistencias pull-up de 49,9R) serían buenas si se conectan a 3V3_AN en su esquema, mientras que el otro lado debería estar acoplado a la GND a través de un condensador (0,1uF o 0,022uF).

0voto

krum85 Puntos 306

Tienes wireshark instalado en el PC, y como dices usas el adaptador de USB a LAN. No estoy seguro de en qué punto físico Wireshark captura los paquetes en su configuración, y por lo tanto es una buena pregunta si los paquetes de salida son realmente aparecen en el físico red. Te recomiendo que conectes otro PC con interfaz de red, y veas si estos PCs pueden comunicarse entre sí comparando la salida de Wiresharks en ellos.

Tu salida de wireshark no muestra ningún problema, el PC anuncia tres veces que está en la red local y que tiene la dirección IP 10.0.0.1 (si recibiera respuesta a cualquiera de estas 3 peticiones ARP entonces el SO aparecería con un conflicto de direcciones IP).

Entonces, su junta directiva está constantemente preguntando ¿Quién tiene 10.0.0.1? Diga 10.0.0.2 y el PC responde con 10.0.0.1 está en ... . La cuestión es por qué se produce en bucle:

  1. la placa no recibe físicamente el paquete de respuesta enviado por el PC;
  2. la placa espera otra cosa, o el paquete recibido está corrupto, y descarta el paquete.

Por lo tanto, como siguiente paso para la resolución de problemas, tome otro PC con una interfaz Ethernet "normal", instale Wireshark en él, configure su red de la misma manera que lo hizo para la placa, e intente telnet 10.0.0.1 80 y ver que aparece en Wiresharks en ambas máquinas. De esta forma te asegurarías de que el PC con su adaptador USB a Ethernet funciona correctamente.

Tus próximos pasos dependerán de lo que veas en estos Wiresharks.

Actualización:

Estoy recibiendo paquetes, de lo contrario los pines RXD0/D1 no mostrarían actividad, ¿correcto?

No es correcto. Quieres pensar que tu junta recibe paquetes. Ves que hay algún cambio en el nivel de las señales de entrada del PHY, pero no necesariamente representan paquetes válidos. El hecho de que RX_ERR no conmute no me convence inmediatamente de que el PHY está trabajando correctamente en los eventos entrantes, o la información que llega compone paquetes adecuados.

De todos modos, depende de ti, mi teoría de la resolución de problemas es sencillo: hay que asegurarse en el nivel superior de dónde se encuentra el problema, y luego profundizar en la parte respectiva del diseño. Indagar en todas las partes y sospechar de todo es inútil. Sería una gran suerte si encuentra el problema extendiendo el enfoque; ya está intentando simplificar el software, si no tiene éxito lo más probable es que empiece a reemplazar los chips.

No creo que mi paso de solución de problemas es tan complicado para que sea para asegurarse de que otro PC puede comunicarse con el PC con dongle y demostrar que estoy equivocado o correcto, y por lo tanto asegurarse de que usted está en lo correcto cavar en profundidades sospechar de la placa PHY, MAC y el software de trabajo en ellos.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X