2024-03-12 12:26 AM
Hi,
I am new to STM32 and installed the following tools:
STM32CubeIDE Version: 1.14.1 Build: 20064_20240111_1413 (UTC)
STM32CubeMX Version: 6.10.0-RC9 Build: 20231120-2037 (UTC)
I am trying to make an LWIP application work on Nucleo-F767ZI without RTOS, I have worked on this for more than a week and am still struggling at debugging. I wrote a post days ago and didn't receive expected number of suggestions or comments, probably because it takes too much time to work through:
Last night I read through the following post wrote by @Adam BERLINGER :
This post was wrote for H7 two years ago with earlier versions of CubeMX, I am not sure whether or not it still applies to the problem I am facing with latest version of CubeMX. At least when I try to follow the post to configure the MPU I don't know how to choose memory addresses (e.g. MPU Region Base Addresses and their sizes). Especially I am concerning about the warning from Parameter Settings TAB in eth configuration:
"The ETH can work only when RAM is pointing at 0x24000000"
While under the warning, the First Tx/Rx Descriptor Adresses are specified at 0x2007c0a0 / 0x2007c000
This looks confusing to me, and the two addresses are not editable.
I tried to copy a working LWIP configurations from Cube examples in Information Center, but found none of the LWIP examples has .ioc file.
There is only one LWIP example for Nucleo-F767ZI board: LwIP_HTTP_Server_Netconn_RTOS
I found the following difference on memory setup between my xx_FLASH.ld and the one in this example:
Memory_B1(xrw) : ORIGIN = 0x2007C000, LENGTH = 0xA0
Memory_B2(xrw) : ORIGIN = 0x2007C0A0, LENGTH = 0xA0
.RxDecripSection (NOLOAD) : { *(.RxDescripSection) } >Memory_B1
.TxDescripSection (NOLOAD) : { *(.DMATxDscrTab_section) } >Memory_B2
And copied them into my xx_FLASH.ld, then build and run, unfortunately it does not work.
I did tests with LWIP_RAW Apis and LWIP_TCP Apis, the latest debug log files and the main.c are attached for reference. The app (192.168.3.168) sends a very short message every second to a server (192.168.3.40:5189) set up on a PC, and the server has no client connected (I also did tests with the server connected by one client, but they do not make difference). Pings to the F767 board are OK.
In LWIP_TCP Api test, after power on, only if I step into tcp_connect and step over some code once, the call to tcp_connect returns ERR_OK in following runnings of the test, otherwise it returns ERR_RTE. Once the tcp_connect returns ERR_OK, the pcb state stays on SYN_SENT untill tcp_slowtmr reaches max SYN retries at the 19th second and the pcb state changes into CLOSED state. For all incoming ARP requests, etharp_input reports "ARP request was not for us" with etharp_update_arp_entry: 192.168.31.1 - d4:da:21:6b:3f:47, in my network environment, this is a non-existent IP address(?). In this test, it looks like not all messages handled by tcp_write were really sent out.
In LWIP_RAW Api test, it behaves different from the LWIP_TCP Api test. After raw_connect, the test sends a short message every second by raw_send, I am not sure whether or not the message was sent out because pbuf_add_header reports failure and ethernet_output complains "could not allocate room for header", but the application receives an incoming packet from the server every second with a strange destination addr of 192.168.3.255:
app_run(): tick = 2s
raw_sendto
pbuf_add_header: old 0x20000d3e new 0x20000d2a (20)
pbuf_remove_header: old 0x20000d2a new 0x20000d3e (20)
pbuf_add_header: old 0x20000d3e new 0x20000d2a (20)
ip4_output_if: st0
IP header:
+-------------------------------+
| 4 | 5 | 0x00 | 44 | (v, hl, tos, len)
+-------------------------------+
| 1 |000| 0 | (id, flags, offset)
+-------------------------------+
| 255 | 6 | 0x0000 | (ttl, proto, chksum)
+-------------------------------+
| 168 | 3 | 168 | 192 | (src)
+-------------------------------+
| 40 | 3 | 168 | 192 | (dest)
+-------------------------------+
ip4_output_if: call netif->output()
pbuf_add_header: failed as 0x20000d1c < 0x20000d28 (not enough space for new header size)
ethernet_output: could not allocate room for header.
sct calling h=ip_reass_tmr t=65 arg=0x80180c8
tcpip: ip_reass_tmr()
sys_timeout: 0x200008b8 abs_time=5068 handler=ip_reass_tmr arg=0x80180c8
sct calling h=etharp_tmr t=63 arg=0x80180d4
tcpip: etharp_tmr()
etharp_timer
sys_timeout: 0x20000cd8 abs_time=5083 handler=etharp_tmr arg=0x80180d4
pbuf_alloced_custom(length=0)
ethernet_input: dest:0hx:0hx:0hx:0hx:0hx:0hx, src:0hx:0hx:0hx:0hx:0hx:0hx, type:ff
pbuf_remove_header: old 0x20001bb0 new 0x20001bbe (14)
ip_input: iphdr->dest 0xff03a8c0 netif->ip_addr 0xa803a8c0 (0x3a8c0, 0x3a8c0, 0xff000000)
ip4_input: packet accepted on interface st
ip4_input:
IP header:
+-------------------------------+
| 4 | 5 | 0x00 | 78 | (v, hl, tos, len)
+-------------------------------+
| 20330 |000| 0 | (id, flags, offset)
+-------------------------------+
| 128 | 17 | 0x62bd | (ttl, proto, chksum)
+-------------------------------+
| 192 | 168 | 3 | 40 | (src)
+-------------------------------+
| 192 | 168 | 3 | 255 | (dest)
+-------------------------------+
ip4_input: p->len 78 p->tot_len 78
pbuf_remove_header: old 0x20001bbe new 0x20001bd2 (20)
udp_input: received datagram of length 58
UDP header:
+-------------------------------+
| 137 | 137 | (src port, dest port)
+-------------------------------+
| 58 | 0x7eab | (len, chksum)
+-------------------------------+
udp (192.168.3.255, 137) <-- (192.168.3.40, 137)
pbuf_free(0x20001b90)
pbuf_free: deallocating 0x20001b90
app_run(): tick = 3s
The both tests did not apply @Adam BERLINGER's suggestions in his post because of the reason said above, but applied the difference found in LwIP_HTTP_Server_Netconn_RTOS example.
Any suggestions or comments will be appreciated!
Best Regards
Chao
2024-03-13 03:35 PM
Unfortunately this task is not easy for a person new to the STM32 "ecosystem".
STM32H7 examples are helpful but not directly suitable for STM32F7. Common aspects between 'H7 and 'F7 MCUs is that both are CM7, both have data cache with same line size (32 bytes) and similar cache management logic. In both, the ETH device DMA has access only to certain part of memory space. But there are differences in the ETH module and the memory/bus structure. If you need to send data out of not-accessible memory, you need to copy it to "good" memory. The LwIP library has also been evolved and old examples show their age. Note that ETH driver calls in ethernetif.c differ between RTOS and no-RTOS examples. The bottom line is that there's no good ready examples for your case. One possible route (besides of finding a consultant) is porting LwiP & no RTOS examples for other STM32F7 boards.
2024-03-14 03:47 PM
Thank you for your valuable reply.
What I really concern is that I need the LWIP application to work on differnt target MCUs, to make it work on Nucleo-F767 is only the start. It looks like it's hard to achieve according to your comments.
What about using the TCP functionality in FreeRTOS, I just need the TCP/IP for low data throughput communication, and don't care about the performance etc.?
Would the use of the TCP functionality in FreeRTOS face the same issues as LWIP?
Chao
2024-03-14 05:39 PM - edited 2024-03-14 05:44 PM
@Chao The FreeRTOS project has their own TCP/IP stack and their own low-level drivers for STM32.
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/main/source/portable/NetworkInterface/STM32Fxx
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/tree/main/source/portable/NetworkInterface/STM32Hxx
They seem to test this and support (as far as FreeRTOS itself is supported vs paid variants).
It's up to you to decide which RTOS stack to use: FreeRTOS once was hot, then ThreadX/NetX until Microsoft dumped it. The new favorite is.... Zephyr?