看了stm32h750系列的介绍,其模拟性能、运算性能和通信功能都很强,并且作为一款新的MCU,迅速在市场上普及,价格也可以接受,所以很快入手了一块stm32h750VBT6开发板,进行实验。
与之前一样,完全不使用st的固件库,只借鉴启动文件:startup_stm32h750xx.s和系统定义:stm32h750xx.h,并将其中定义的固件库相关信息删除。
CPU没有跑满480MHz,而是是用一般例程中的400MHz。
由于项目只是用udp通信,就不用lwip那么麻烦的协议栈了,自己写一个就够了,只需实现arp、icmp、ip、udp协议。当然,udp协议是简化的,最大支持包长1472字节,就是没有实现ip层在以太网帧的分包,整个网络协议含头文件不到500行
由于单片机比较新,一开始调试时还是遇到了很多问题:
1、使用jlink调试stm32H750,无法识别,使用的是6.40的dll,下载6.8的jlink驱动后,能够识别,但无法下载,一下载就报错,然后必须给芯片下电后才能再次识别。然后插上了电源适配器,就没问题了。说明是瞬间大电流导致下载失败了。
2、在AD的时钟选择,需要在RCC处选择时钟,时钟需分频
3、h750以太网调试时,接收缓存使用硬件的sram3原位操作,发生hard fault。
//memcpy(yip_buf,p,n); //收发互斥,使用同一个缓存 (这是之前可以用的代码)
u32 arp_desIP;
//memcpy(&arp_desIP,&(arp.desIP),sizeof(arp_desIP)); //错误代码
int i;
for(i=0;i<4;i++) ((u8*)&arp_desIP)[i]=((u8*)&(arp.desIP))[i]; //正确代码
if((eth.type==CHANGE_END16(ETH_TYPE_ARP)) && arp_desIP==ipaddr)//若是ARP
{
………………
后来的代码是直接使用输入指针p,就是sram3的内存,经MPU保护。为了提高效率,让协议栈在此内存处原位操作。
但在访问arp.desIP时发生错误,于是做临时变量arp_desIP,通过memcpy将sram3的内容复制到栈空间,但memcpy过程发生hard fault
所以改成for循环,按字节复制,可以通过,进而在后续处理时,memcpy的过程错误。
怀疑是内存对齐问题,必须将sram3的内容挪到带cache的内存中,就不会出现对齐问题了。
在调试中也逐渐解决了一些疑问:
1、sram3的使用是否需要开时钟?不需要
2、eth的发送描述符是否需要在sram3中?接收缓存是否需要在sram3中?也可以在D2域的其他存储器中
3、描述符中两个buf,应该是对于数据包头和数据域分离的情况,如果不使用减荷,不使用
4、环形描述符列表,尾指针和头指针怎们用,可否固定,发送尾指针移动,DMA才会取
5、在调试模式下,当前主机发送器或接收器描述符地址指针的值可在 ETH_DMACCATxDR 和 ETH_DMACCARxDR 中读取
最后,附以太网udp测试的结果:
使用猛禽的H750开发板进行以太网实验,单片机端做echo服务,udp方式。CPU空闲tick=9947
pc端连续发送udp包,每秒打印发送包数和接收包数,并查看任务管理器的网络流量
小包测试
发送包长32字节,发送2000000(2百万)包时,接收1999445包,丢555包,丢包率万分之3
数据通信速度3.8MB/s,而任务管理器中的网络流量达到78Mbit/s,说明数据包小,帧头开销很大。
帧频率为118Kf/s
CPU空闲tick=2600,CPU占用率为73%
大包测试
使用1000字节大包重复实验:
任务管理器的网络流量达到了97.5Mbit/s,基本达到百兆网极限。数据速率11.7MB/s,效率很高
发送1百万包时,丢13包,丢包率万分之0.013,比小包低两个数量级
帧频率为11.7Kf/s
CPU空闲tick=5313,CPU占用率为46%
cache性能测试
不开cache,CPU空闲tick=1935,远远低于开cache,使用小包测试,CPU100%占用,且回复速度下降了将近一半: 78 -> 48Mbit/s
结论
1. 由于以太网驱动和IP层协议没有写mac分包,所以一个udp包的最长大小在1472字节以内
2. 大数据包发送效率高,处理效率高
3. 对于小包应用场景,能保证CPU占用的帧频率需要限制在40Kf/s以下
4. 必须开cache才能保证性能,但使用DTCM存储区并没有加速,可能是cache已经很快了
5. 必须注意内存对齐,sram3上memcpy或者直接访问非对齐的u32会hard fault