STM32H7LWIP,过滤,配置opt,调整rxbuffer大小等
尴尬的发现搞单片机的人越来越少了,查lwip资料查不到很新的,自己看代码,走了很多弯路,本文不太适合教初学者怎么跑通lwip。在h7上跑通lwip有很多博主去实现过了,大家自己搜吧。
讲讲ping不通和lwip内存分配
lwip跑不通的原因有很多,其中有个原因是h7有mpu,cubemx生成的代码使用gnu编译器,需要自己在flash.ld链接文件里添点东西,给buffer和描述符指定地址。
我再说一下为啥需要配:cubemx生成的代码在cubeide运行时,使用的是gnu编译器,这个分配地址关键字需要在.ld里配置,因为eth外设的dma只能指定到D2区域,所以不论你啥编译器都得配这个地址,只是都是自动配的。
简单说下这三个数组在干嘛吧,rx和txtab 也就是描述符,查了手册,其实是个软件和硬件结合的东西,是对应起来的,里面存放了发送和接收的时候 rx和txbuff的地址,和一些标志位。eth会操作这些标志位和读取rxbuff要朝哪儿放。而Rx_Buff就是我们真正以太网dma传送数据存的地址,这块内存的数据,lwip是不搬运的,所以有被覆盖的风险,这也是我们为啥要扩容,不然你碰到1us给你发十几个包的交换机,啥数据都被覆盖了,因为一个描述符只能放一个报文。
关于DMA描述符
具体的怎么去配置,找不到链接我也就不放链接了,大家自己去配,注意配mpu和ld文件,以及描述符的起始地址其实是d2区域的末尾,其实d2前面的内存没用到的话可以朝前提,如果向前放的话,自然可以对ETH_RX_DESC_CNT的数量进行扩容了。
#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 Buffers */
#endif
其次是关于内存池和一些相关的配置选项,比如netconn的数量之类的,能不能全双工读写,这个东西也很重要,当你发现ping大包会丢包的时候你就需要下面这个博客。
配置opt.h和lwipopt.h
cubemx配置的东西其实就是这个,新手的话按照这个文章里的来也可以,这个文章对我帮助很大,就找到个这么老的文章,没找到啥好的,有好文章欢迎留言。
聊聊lwip内核的线程工作原理
eth中断只是起到释放信号量的作用,真正去处理数据的是一个优先级48的线程会去打包数据做一些处理,然后默认的在tcpip.c下有个优先级24的tcpipthread,这里是处理rawcallback和arp icmp相关报文的地方,所以你如果在rawcallback里处理的太长时间,你会发现ping的延时很高,netconn和socket就不存在这个问题,他们是单独的线程。
最底层的发送和接收被官方封在了lowlevelinput和output里,有兴趣的自己去看ethernetif.c文件,这个文件是st提供的。
再聊聊mac、ip等其他的过滤
大家自己去查h743手册,可以看到整个eth的工作过程,mac过滤是第一道门槛,是将报文挡在CPU和内存之外,外设直接帮你把不符合的mac地址过滤掉了,具体的操作函数在hal库里有,大家自己去翻,提供个我用的例子,然后mac地址怎么找,去内存里找,嵌入式c语言最大的优势就是内存随便你翻,知道以太网报文格式,要啥都有。
ip过滤是需要自己操作寄存器的,大家可以自己研究。
ETH_MACFilterConfigTypeDef macfilter;
HAL_ETH_GetMACFilterConfig(&heth, &macfilter);
macfilter.ReceiveAllMode=0;
macfilter.SrcAddrFiltering=1;
macfilter.PromiscuousMode=0; macfilter.ControlPacketsFilter=ETH_MACPFR_PCF_FORWARDPASSEDADDRFILTER;
HAL_ETH_SetMACFilterConfig(&heth, &macfilter);
HAL_ETH_SetSourceMACAddrMatch(&heth, ETH_MAC_ADDRESS1, macaddr);
有空我接着更新lwip的ftpserver+fatfs、tftp、webserver、如何重新sntp为netconn,因为sntp有bug会在lwip定时器时间到了调用的时候影响默认tcpip,24优先级的线程的运行。
最后欢迎翻一下我的收藏,lwip那个目录。
我最近一直在搞不过滤,加快lwip运行速度,让h7不回复超时的问题,有想法的同学欢迎联系。