2023-05-24 08:28 AM - last edited on 2025-02-17 05:46 PM by Andrew Neil
Edit : see this post for answers :
https://www.reddit.com/r/embedded/comments/13rcrqf/stm32h723zg_creating_tcpip_with_lwip_but_cannot/
reddit dot com /r/embedded/comments/13rcrqf/stm32h723zg_creating_tcpip_with_lwip_but_cannot/
Hello
Summary
##### WHAT I WANT TO DO #####
I want to send protobuf message from my STM32H723ZG (as a client) to a Raspberry using ethernet communication.
So far I am just trying to create an ethernet connection and to ping the adress of the stm.
##### WHAT I HAVE DONE #####
I looked at ressources online.
The most ineteresting seemed to be this set of videos from controllersTech expaining hwo to do a bunch of ethernet thin on stm32H7xxx:
as well as this github repo + video of a polish person doing a HTTPd project ont the exact same card as me stm32h723zg:
this tutoriel from ST on how to use MPU:
honorable mention to user manual lwIP (um1713) but it doesn't talk about cubeMx so not interesting for now.
I tried initializing a simple lwIp project on cubeMx
Following the controllersTech's videos I :
From there I can generate the project.
I add "extern struct netif gnetif;" in the main and "ethernetif_input(&gnetif);" and "sys_check_timeouts();" to the super loop (while(1)).
I should now be able to build and run my program and ping the IP address but when debugging it I instantly get a hardfault.
When debugging using "step over", I notice that the programm/thread is stuck during "SCB_EnableDCache();"
I added
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x30000000);
*(.RxDescripSection)
. = ABSOLUTE(0x30000060);
*(.TxDescripSection)
. = ABSOLUTE(0x300000C0);
*(.RxArraySection)
} >RAM_D2
In the flash script and i added the lines regarding the RxBuff
__attribute__((at(0x30000000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((at(0x30000060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
__attribute__((at(0x300000C0))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
#elif defined ( __GNUC__ ) /* GNU Compiler */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE] __attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffer */
in the ethernetif.c (only the 2 lines regarding RxBuff, the otehr one already existed).
No change in behavior.
I can see that the domaine 2 now have lwip_sec however it is only 192Kb (the descriptors but not the buffer) and I cannot click it in the memory details window to show what is inside (on the controllersTech video he can click on it to show what is inside).
I tried using the cubeMx files from the github repo mentionned earlier
The github repo seems to have everything working well.
Since I cannot specify the buffer memory address I looked at his cubeMx file.
It uses an older version of cubeMx so I had the choice to continue or to migrate, I tried both and migrate worked.
Indeed his cubeMx file is different than mine: in ETH, he can specify the memory address of the buffer! (at the time I am writting that i cannot reproduce this but I clearly remember it)
The rest of the setup is similar.
However, I added some print on the console through UART to send the ip address (as decimal).
The whole project can be found here : https://drive.google.com/drive/folders/1GFPTB1tn3KoMvoncMS5x6Oi6IVztdZYd?usp=sharing
In that project I am able to run the project for about 2 seconds the first time I launch it before it gets stuck into hardfault.
When i run it after that it run for .5 second.
##### Question #####
If you can answer one of those that would greatly help me:
1) Do you see a problem in my cubeMx setup?
2) Do you see a problem in my code?
3) Do you have an exemple of a working TCP/IP client or server ?
4) Do you know why I cannot set the memory address of the buffer in cubeMx?
5) Do you know why I get hardfaults?
6) Why do I only get 192KB in lwip_sec (no buffer)?
7) Why can't I see what is inside lwip_sec?
Golden question ) How to make it work?
Thanks in advance for you response.
If something isn't clear, feel free to ask.
Regards
2023-06-02 12:39 AM - edited 2024-06-05 06:09 AM
:)
2025-02-17 03:56 PM
Hello. Thank you for your post because you helped me figure out my problems. I had the same issue on STM32H750VBT6 but solved.
You must pay attention to every detail because I had little mistakes that prevented my project from working. For example, one of my mistakes was configuring one of adreses missing one zero. Another time, I forgot to give all permissions in MPU according to the youtube video you provided. Another time I forgot to enable MPU to exclude the ethernet ram regions from cache. If it get cached, then the ethernet and LWIP software would not know if new data was written on the buffer by someone like the ethernet DMA. Another problem was signal integrity because I'm using an external module and wired with some clumsy board to board wires with poor shilding and grounding. That RMII digital signal is 50MHz by the way! But it worked after I cut those wires short enough. Now I'm using 10cm board to board wires again with no shilding and proper transmission line impedance control (line impedance, impedance matching, termination). It is a good idea to check if the communication with LAN8742 using that MDIO is ok. I'm not an exert but I think it serves as an auxiliary communication for configuration and some other perposes. You can check if Link is Up and speed is 10 or 100MB/s using the code I provide you in the end. Pay attention is some LWIP software package versions, the name "RxArraySection" is different. for me it is "Rx_PoolSection". My flash linker code in the sections part is as follows:
.lwip_sec (NOLOAD) :
{
. = ABSOLUTE(0x30000000);
*(.RxDecripSection)
. = ABSOLUTE(0x30000080);
*(.TxDecripSection)
. = ABSOLUTE(0x30000100);
*(.Rx_PoolSection)
} >RAM_D2
My last problem was that I thought it is not neccessary to read the buffer by my self manually for only ICMP (ping) protocol. But it seems like to be mandatory. You should check the buffer frequently using the code provided in that video you addressed:
finally if everything is ok you can use the command "arp -a" in a command window in windows to see if your device is visible in the ip map of your local network. Also I suggest you not to use DHCP in the beginning. Use a static IP first and then move on to DHCP. I also set the MPU for ethernet region as sharable. I don't know if it has any effect.
Another problem I was facing was that the first time after MCU boot or reset, it would transmit an ARP packet to my laptop and it would appear in the list but ping did not respond at all. I mean you should check ping and do not rely on arp command alone because I think somewhere in LWIP or ethernet interrupt routine, some flags were not cleared properly. It only interrupted one time. I also checked if you do not read the buffer frequently this probelm would happen. I connected the LAN8742 directly to my laptop using static IP. Another problem you might face is windows firewall. As of my last attempt, windows 11 does not let you easily change the type of this direct ethernet network to a secure one and always count it as public unsafe and firewall rules apply. There are various solutions available but simplest is to disable firewall or configure special rule for the specific static IP adress of your device. It is a good practice to check your ethernet packets using wireshark.
My test codes for RMII and LWIP are as follows: