调试STM32H743,RTThread&LwIP,踩坑记录

很久之前看过LwIP的一些内容,感觉好复杂。这次一个项目用到了网口,打算结合RT-Thread,移植一下LwIP。鉴于MDK中Compiler 5已经不再更新,此次移植直接基于Compiler 6。因为公司之前有一个很简单的UDP的协议,基本可以直接跑通的,要移植一个自己不太熟的协议栈,心里还是做了很多斗争的。

先确定技术路线吧。RT-Thread有官方移植好LwIP,但是公司现在还没有使用RT的那一套环境开发,一直以来用的是CubeMX。CubeMX里RT-Thread和LwIP能单独配置,但是不能生成驱动代码。那么只能用CubeMX,配置FreeRTOS和LwIP生成工程模板,供后面参考。

  1. 用CubeMX配置RT-Thead,并将RT-Thead跑通。此步非常简单。
  2. 在工程中添加LwIP。
  3. 将模板里的代码,并结合RT-Thread官方包里的arch内容,将工程编译通过。
  4. 将工程跑起来。

将工程跑起来,没那么容易。首先工程运行起来两三秒的时候就进入Hardfault。根据RT-Thread给出的LR寄存器的值,结合汇编代码找到导致Hardfault的大致位置。最后发现问题出在LwIP的以下代码处:

  /* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
   * structure packing (not using structure copy which breaks strict-aliasing rules). */
  IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
  IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr);

展开宏定义如下:

#define IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t))
#define SMEMCPY(dst,src,len)            memcpy(dst,(char*)src,len)

打眼一看,不能够啊,memcpy都能跑进Hardfault?调试进去,发现 &hdr->sipaddr的值不是4字节对齐,问题应该就是出现在这里。上网查资料,找到一篇不错的介绍非对齐访问的文章。内存类型分为Strongly-ordered,Device,Normal三种。其中Cortex M7只有Normal这种内存类型支持非对齐访问。查询上述地址,对上述地址设置MPU,将内存类型设置成Normal类型,再运行,没有进入HardFault了。

用网络调试助手给板子发消息,可以正常产生中断,也可以接收到数据,但是数据就是发不出来。用wireshark捕获,发现PC端一直是发的arp数据包,没有接收到回复。自己检查heth和gnetif的内容,发现他们的mac地址并不一致。发现是由于初始化的时候,传给heth的mac地址是一个局部变量,改成全局变量就一致了。

测试网络还是不通,把网络的GPIO速率设置到HIGH以上,收发就可以了。此处的设置也是参考的ST的示例工程的设置。奈何用CubeMX自动生成的代码默认是LOW速率。

STM32H743的MPU确实是个大坑。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值