STM32F407 + LAN8720A + lwIP + FreeRTOS = Nenhum quadro Ethernet recebido

9

Estou tentando abrir uma placa de circuito impresso que usa um PHY Ethernet STM32F407 e LAN8720A e não consigo receber nenhum quadro Ethernet - mesmo que eu não tenha problemas para transmitir quadros.

Configuração de hardware

Diagrama esquemático da Ethernet PHY Eu tenho um cristal de 25 MHz no STM32F4, direcionando um pino de saída de clock de 25 MHz para o LAN8720A, que está no modo REF_CLK_OUT - e direciona um relógio de 50 MHz de volta para o STM32F4 como parte da interface RMII.

O jack / magnetismo é uma parte genérica. Aqui está a folha de dados: insira a descrição da imagem aqui

Programas

Estou usando a atualização mais recente do STM32CubeMX para gerar um projeto do System Workbench for STM32 que contém FreeRTOS, lwIP e os drivers periféricos ETH. Eu realmente não toquei nenhum código gerado - portanto, a pilha lwIP é inicializada dentro de uma pilha do FreeRTOS.

Experiências

Com o lwIP da minha placa configurado para um IP estático 10.0.0.2 e um dongle USB-ethernet no meu computador configurado para um IP estático 10.0.0.1, conecto os dois dispositivos diretamente com um cabo Ethernet, e minha placa tenta se conectar para um serviço na porta 80 do computador. Capto a interação entre minha placa e o computador usando o Wireshark (em execução no computador e vinculado ao conversor USB-Ethernet).

Devido ao problema de quadros não recebidos, nunca Captura de Wireshark superamos esse material ARP: Como você pode ver, o Stmicroe (minha placa) pode enviar pacotes ARP - ouvidos pelo meu computador - mas nunca parece ouvir a resposta do meu computador , uma vez que continua lançando pacotes ARP.

Ambos os dispositivos são configurados com uma máscara 255.255.255.0 e os dois são configurados com um endereço de gateway 10.0.0.1 (o computador). Ouvi falar de tabelas ARP sendo estragadas e computadores ignorando pacotes ARP, mas não consigo imaginar que a placa ignore pacotes ARP especificamente endereçados a ela pelo meu computador - em resposta às solicitações feitas pela placa em primeiro lugar.

Então, eu mergulho no arquivo ethernetif.c do lwIP e percebo que HAL_ETH_GetReceivedFrame_IT(&heth)está retornando um erro. Essa função retorna um erro porque (heth->RxDesc->Status & ETH_DMARXDESC_OWN)== 0, em vez de 1. Eu interpreto isso como significando que os buffers DMA estão atualmente armados para o periférico MAC e ainda não receberam nada.

Além disso, verifiquei que o HAL_ETH_IRQHandler nunca é chamado.

Um problema com o PHY?

Nesse ponto, eu suspeitava que meu próprio PHY fosse o culpado.

Para investigar mais, anexei meu Saleae Logic Pro 16 a todos os sinais relevantes e notei que há muito tráfego nas linhas TX0 / TX1 e RX0 / RX1. Aqui está uma captura de algum tráfego RX com o relógio de entrada de 25 MHz:

Captura do pacote recebido

O RX_ERR fica baixo o tempo todo, a menos que eu tente capturar a saída do clock de 50 MHz (o que é obviamente um desafio para um dispositivo como o Saleae): nesse caso, o RX_ERR é ocasionalmente alto para alguns pacotes (o que é realmente um bom sinal - o alfinete parece estar funcionando).

Próximos passos

Tentei ativar manualmente as interrupções do ETH chamando HAL_NVIC_EnableIRQ(ETH_IRQn);depois de tcpip_init()ser chamado na MX_LWIP_Init()tarefa e isso não parece resolver o problema. Não tenho certeza absoluta de que a rotina de interrupção da Ethernet esteja sendo chamada - essa é a coisa desafiadora de criar um novo design; Estou lutando para determinar qual seria o comportamento adequado do sistema, para que eu possa determinar como minha configuração difere.

Embora eu tenha usado o material STM32 / STM32CubeMX / FreeRTOS antes, nunca usei o periférico Ethernet do STM32, e minha única experiência com esse material é em sistemas Linux embarcados personalizados, que sempre pareciam funcionar imediatamente. Este é um novo território para mim!

Tenho certeza de que há uma caixa de seleção estúpida em algum lugar ou Ethernet_EnableReceive()função mágica que eu esqueço de chamar, mas não consigo encontrar nenhuma documentação que sugira a necessidade de ativar explicitamente essas coisas, e as postagens que estou vendo na internet são todas não relacionadas problemas.

Se alguém tiver alguma idéia, eu adoraria alguma ajuda!

Adendo: Como se livrar do FreeRTOS

Apenas para eliminar coisas, removi o componente do projeto FreeRTOS, voltando a um projeto bare-metal. No meu loop principal, eu ligo MX_LWIP_Process(). Este método deve eliminar a necessidade de interrupções, mas não resolve o problema; Ainda não consigo receber quadros. Isso me faz pensar que há algo no código ETH HAL gerado pelo STM32CubeMX.

Solução

Caso alguém se depare com essa questão no futuro, o problema acabou sendo os pinos RXD0 e RXD1. Foi por isso que consegui ver o tráfego no meu analisador lógico, mas não foi decodificado pelo meu MCU.

Como alguém apontou, os magnéticos que usei são assimétricos e não devem ser usados ​​para o auto-MDI-X. Eu não tive nenhum problema. Eu prevejo que uma das duas coisas está acontecendo: - as magnéticas não funcionam na outra orientação, mas como tudo o que tenho usa o MDI-X automático, minha placa permanece essencialmente fixa na configuração que funciona, enquanto o outro dispositivo está ligado. o cabo orienta seus sinais para que correspondam. - o magnetismo fornece integridade de sinal adequada, dadas as pequenas execuções Ethernet, mas uma análise a longo prazo mostra taxas mais altas de queda de pacotes ou problemas em execuções mais longas.

Honestamente, não está claro para mim por que isso importaria para qual lado do transformador 1: 1 os filtros de linha estão instalados; portanto, fora dos aplicativos PoE, não sei ao certo por que um projeto simétrico versus assimétrico importaria.

Jay Carlson
fonte
Onde o Wireshark está instalado?
Anônimo
O computador ao qual a placa estava tentando se conectar. Vou editar a pergunta para adicionar clareza a isso.
Jay Carlson
FWIW, eu recomendaria o uso da pilha FreeRTOS. (Percebo que isso não funciona com sua consulta específica.) Não posso fazer nada até esta noite, mas se ajudou, tenho certeza de que tenho um projeto para esse processador que recebeu pings na pilha do FreeRTOS. Porém, não sei qual PHY estava no quadro. De qualquer forma, deixe-me saber se você quer o projeto, posso colocá-lo no site interativo FreeRTOS.
DiBosco
Isso seria super útil. Sou totalmente independente da pilha que estou usando - só preciso de algo que possa ser iniciado rapidamente.
Jay Carlson
1
Tentei trocar magnéticos por algo simétrico, e isso não resolveu o problema. Contudo! Eu estava observando meu esquema e percebi que tinha RXD0 e RXD1 trocados. Doh! Foi por isso que vi dados RX sendo expulsos do PHY, mas nada recebido pelo MAC. Eu posso voltar a soldar meus antigos magnéticos de volta ao quadro (só para não ter algo pendurado na mesa) e sinto que o protocolo auto-MDI-X deve resolver isso, certo? O LED "link" deve acender apenas quando um link RX / TX válido é estabelecido, certo? Sempre foi iluminado, mesmo com os antigos magnéticos assimétricos.
Jay Carlson

Respostas:

0

Você tem o wireshark instalado no PC e, como diz, usa o adaptador USB-para-LAN. Não sei em que ponto físico o Wireshark captura pacotes em sua instalação e, portanto, é uma boa pergunta se os pacotes de saída realmente aparecem na rede física . Eu recomendo que você conecte outro PC à interface de rede e verifique se esses computadores podem se comunicar comparando a saída do Wiresharks neles.

Sua saída do wireshark não mostra nenhum problema, o PC anuncia três vezes que está na rede local e possui o endereço IP 10.0.0.1 (se receber resposta a qualquer uma dessas 3 solicitações de ARP, o sistema operacional aparecerá com conflito de endereço IP).

Então, sua diretoria pergunta constantemente Quem tem 10.0.0.1? Diga 10.0.0.2 e PC respostas com 10.0.0.1 está em ... . A questão é por que isso acontece em loop:

  1. a placa não recebe fisicamente o pacote de resposta enviado pelo PC;
  2. A placa espera outra coisa, ou o pacote recebido está corrompido e descarta o pacote.

Portanto, como próxima etapa de solução de problemas, pegue outro PC com interface Ethernet "normal", instale o Wireshark nele, configure sua rede da mesma maneira que você fez para a placa e tente telnet 10.0.0.1 80ver se ele aparece no Wiresharks nas duas máquinas. Dessa forma, você garantiria que o PC com seu adaptador USB-Ethernet funcione corretamente.

Seus próximos passos dependerão do que você vê nesses Wiresharks.

Atualizar:

Estou recebendo pacotes, caso contrário, os pinos RXD0 / D1 não mostrariam atividade, correto?

Incorreto. Você quer pensar que sua placa recebe pacotes. Você vê que há alguma alteração no nível dos sinais de entrada PHY, mas eles não representam necessariamente pacotes válidos. O fato de RX_ERR não alternar imediatamente não me convence de que PHY está funcionando corretamente nos eventos recebidos, ou que as informações que chegam formam pacotes adequados.

De qualquer forma, depende de você, minha teoria da solução de problemas é simples - você deve garantir em um nível superior onde encontra o problema e depois pesquisar na parte respectiva do design. Cavar em todas as partes e suspeitar de tudo é inútil. Seria uma grande sorte se você encontrar um problema em espalhar o foco; você já está tentando simplificar o software; se não der certo, provavelmente começará a substituir os chips.

Não acho que minha etapa de solução de problemas seja tão complicada para garantir que outro PC possa se comunicar com o dongle e me provar que estou certo ou errado e, assim, garanto que você está certo em cavar profundas suspeitas de PHY, MAC e software da placa trabalhando em eles.

Anônimo
fonte
Embora eu aprecie o fato de você dedicar um tempo para escrever isso, é bastante claro que meu PHY está recebendo pacotes do meu PC, mas não está sendo recebido pela minha placa. Caso contrário, eu não veria os dados Rx nas linhas RMII, certo? Não acho que seja uma pergunta simples e de alto nível sobre redes.
Jay Carlson
@JayCarlson Você ainda precisa provar que os sinais elétricos na extremidade do cabo da sua placa representam pacotes adequados que podem ser capturados e não descartados. Por que aprofundar a tecnologia sem provar coisas tão simples?
Anônimo
É sua teoria de que meu computador não está realmente enviando os pacotes que deveria estar enviando (e que o Wireshark diz que está enviando)? Quais são os pacotes que minha placa está recebendo, então? A placa está conectada diretamente ao meu computador. Esta não é uma configuração de rede complicada, e qualquer pacote recebido pelo PHY na minha placa deve ser originário do meu computador, certo? Estou recebendo pacotes, caso contrário, os pinos RXD0 / D1 não mostrariam atividade, correto? Sua hipótese é que algo está descartando pacotes, certo? O que é? O PHY? O bit RX_ERR nunca é definido. O MAC do MCU? o ISR de recebimento nunca é acionado.
Jay Carlson
Eu atualizei a resposta. Não seja duvidoso e preconcebido. Coisas complexas podem parecer mais simples do que você pensa. Basta agir e coletar informações.
Anônimo
1
Tudo bem, conectei meu computador a outro usando o mesmo cabo e adaptador USB-Ethernet. Eu executei uma instância do Wireshark nos dois computadores e eles mostram dados idênticos - alguma conversa ARP e, em seguida, uma conexão bem-sucedida a um serviço netcat em execução na porta 80. Eu testei isso nos dois sentidos. Tentei conectar-me a esse serviço a partir da minha placa incorporada e, como disse, nunca recebo mensagens ARP passadas. Se eu tentar conectar à placa do meu computador, ele não passará do estágio ARP, pois a placa nunca responde às solicitações de ARP do meu computador. Realmente não acho que esteja ouvindo pacotes.
Jay Carlson
0

Desculpe ressuscitar este tópico. Eu não poderia passar sem mencionar minha experiência.

Eu usei este HR911105A (RJ45 com ímã) em um dos meus projetos.

HR911105A: insira a descrição da imagem aqui De relance, uma coisa chamou minha atenção: a conexão entre o LAN8720 e o RJ45, conforme o seu esquema.

Desde que eu vejo que a conexão parece crossover. Embora os sistemas conectados usem principalmente o MDI-X e, portanto, detectem pares de recebimento / transmissão, seria bom fornecer uma conexão menos confusa assim:

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

Pin #4 and Pin #5(portanto, os resistores pull-up 49.9R) seriam bons se conectados 3V3_ANno seu esquema, enquanto o outro lado deveria ser acoplado ao GND por meio de um capacitor (0,1uF ou 0,022uF).

Sener
fonte