经过一个月的时间,初步能够建立一个简单的UDP服务器。所用芯片为STM32F107,板上自带MAC,需要自带PHY ,所用PHY为dp83848 。前面没有用到官方库, 程序思路 ,首先为时钟的初始化,STM32主要有四个时钟,内部高速时钟,外部高速时钟,内部低速时钟,外部低速时钟,通过对其倍频,分频给各个模块提供时钟信号,内部主要有PLL时钟,AHB时钟,APB1,APB2时钟,SYSCLK时钟,APB1最大时钟只有36MHZ,APB2可以72MHZ为STM32F107 所用I/O的初始化,管脚复用初始化,然后时钟使能。在这所遇到的问题主要是STM32F107有些寄存器的复位值居然不是从零开始.以太网MAC协议主要有RMII 和MII模式,两者的区别主要在于管脚和MCO 时钟频率的区别。MCO时钟在RMII需要50MHZ,在这里通过PLL3 10倍频获得,因为在时钟初始化之后PLL3的频率为5MHZ,在MII模式下 如果外部时钟用25MHZ可以直接为MCO输出25MHZ,提供时钟源。对DP83848的寄存器进行操作 主要通过SMI接口操作,SMI接口有两跟线分别为MDC和MDIO MDC的时钟源根据AHB总线的时钟源分频所得。然后ETH的寄存器初始化发送DMA寄存器初始化 ,ETH接受中断使能,DMA中断使能。。。。这里比较难理解 ,而且寄存器很难配置。我直接用官方的程序了。接下来就是移植LWIP 协议栈了。
LWIP 协议栈在裸机跑的时候,主要 包括 CC.H 中的数据类型定义 大小端定义(根据编译器和处理器特性)临界代码的保护 lwipopts.h 对协议栈内核的参数配置 默认的在OPT.H中, 最后就是对etnernetif.C中的计个函数的编写。low-level-init 主要为网卡的初始化和网络接口的初始化low-level-input 从网卡中得到一个数据包然后上传到协议栈里中,low-level-output 把内核中的PBUF所描述的数据发出去。
这样 在主函数中加上 LWIP 初始化,主要是网络接口 IP .MAC 初始化, 通过STM32的滴答计时器 定个基准时间 然后加上TCP定时处理函数和ARP定时处理函数就能简单的PING 通了。 PING 大包 ping不通 通过抓包软件看见 STM32 回应ICMP包 可是为什么PING 不通呢,主要原因在于STM32有硬件校验和功能 在发送字节大于一个以太网帧的时候,IP层为分片发送 而硬件校验和 自动加上校验和导致 校验和错误 PC机端认为是错误的数据直接丢弃了。现在只能关闭硬件校验和功能,其他方法还没想到。
|