你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0) 精华  

[复制链接]
STM32F103-34799 发布时间:2014-3-30 14:22
之前手里有一块stm32f407discovery。最近想测试一下F407 Ethernet MAC外设。实现mcu网络通信功能的方案有很多种,包括SPI接口的ENC28J60,成本很低,而且源码很丰富,但是总觉得用spi搞以太网毕竟不够直接;还可以用W5100/w5200(没记错的话这个芯片好像是W5100+STM32F103集成在一起了,ST可能把103的核卖给那个韩国公司了?)系列以及CH395等硬件集成了以太网TCP/IP协议的芯片开发,与mcu的接口依然是spi,这种方式开发非常简单,不需要非常了解与网络相关的协议即可;最后一种利用mcuMAC配合一个PHY实现网络功能。最后我选的是最后一种方案,一来多学点东西,二来非常好奇STmac怎么工作(第一次接触stm32的时候在103107之间徘徊了很久,怎奈鱼和熊掌不可兼得)
硬件配置:stm32f407discovery + 微雪DP83848模块。(RMII接口,没接DP的中断,汗)
DP83848.jpg



ETH_MDIO ---------------------------------------------------> PA2
ETH_MDC ----------------------------------------------------> PC1
ETH_PPS_OUT ---------------------------------------------> PB5
ETH_RMII_REF_CLK--------------------------------------> PA1
ETH_RMII_CRS_DV ---------------------------------------> PA7
ETH_RMII_RXD0 -------------------------------------------> PC4
ETH_RMII_RXD1 -------------------------------------------> PC5
ETH_RMII_TX_EN ------------------------------------------> PB11
ETH_RMII_TXD0 --------------------------------------------> PB12
ETH_RMII_TXD1 --------------------------------------------> PB13
DP83848_INT------------------------------------------------->PB14
其中,ETH_PPS_OUT可以不接,硬件也可以不设置,没记错的话,这个管脚和八线的以太网有关,详情问百度。以太网时钟采用的是模块上50M的有源晶振,通过PA1参考时钟和F407同步。中断引脚可以连接也可以不连接,影响不大。另外,在图中用的是杜邦线连接的两个模块,导致最后的实现有10%~20%的丢包率,所以以后能开板还是开板吧,毕竟50M的速率还是要考虑一下信号的感受。后来加工了一下连接了PHYINT引脚(没有会很蛋疼),不过这个引脚是OD的,要把407的内部IO设置成上拉。
开始用固件库配置好底层之后,想不移植TCP/IP协议栈直接用。直接从mac接收数据然后处理,发现处理一般的TCP传输还可以(其实不可靠),处理HTTP的时候,只要网页里有图片,就很容易挂掉(网页里显示的内容重复很多,版面很乱,可见tcp没有正确处理重传机制真的不行)。后来看lwip的源码才知道tcp的复杂性(lwip用了一半的代码量实现tcp),这个东西要用个定时器来处理超时重发等等机制保证数据传输的完整可靠。tcp的状态机在老衲五木的LWIP源码详解里有介绍。看了之后有一种望尘莫及,连尘土都看不到的感觉。

在移植前请确保MACPHY都已经移植好了我使用的官方的DP83848,所以这点省略了,其他phy的移植大同小异都是通过两个stm32F4提供的库函数通过MDIO和MDC接口配置访问的,这两个函数是ETH_ReadPHYRegisterETH_WritePHYRegister。这是因为MII/RMII(介质无关接口)对任何phy芯片的管理接口是统一的,事实上,IEEE规定了一些通用的寄存器定义用于实现网络的基本功能,这些公用寄存器和phy自定义的寄存器都是通过MDIO和MDC接口访问控制。如果是使能了自动协商,就要保证在硬件初始化之前网络硬件连接是ok的,否则F407的以太网初始化函数ETH_Init会因为连接自动协商超时返回失败
对于tcpip协议的具体实现,这里做了简化。如果想更详细的了解其实现过程,可以参考社区的帖子http://st.eefocus.com/bbs/article_1277_584994.html这个帖子里有视频。讲了tcpip的具体实现细节。包括arp,icmp,dns的介绍。ip包格式,ip分包;tcp协议包格式,传输过程(连接建立和终止,三次握手,SYN,SYN/ACK,SYN,四步终止,fin ack),分包,重传,流控制,拥塞控制,快速恢复等内容。
软件配置:uC/OS-III V3.03 + lwip1.4.0
uC/OS移植注意事项:移植ucos-III的博客一抓一大把,这里就不多说了,只是要注意下fpu的支持问题(需要处理一下cpu部分汇编代码,任务切换的时候多保存几个寄存器。 在使用FPU的情况下,异常到来的时候,CORTEX-M4会将部分FPU的寄存器也一起自动入栈,包括一个未知的字,一个FPSCR寄存器,以及S15-S0,所以如果要使UCOS支持FPU,就必须配合M4的这种入栈/出栈行为相应地修改任务堆栈的结构以及任务切换时的入栈/出栈汇编代码,摘自阿莫论坛,修改的基于STM32F407的官方版UCOS III源码,增加了FPU浮点支持,具体可以看这个帖子),支持fpu的话要添加__FPU_PRESENT = 1 __FPU_USED = 1(mdk4.72版本),不搞这个会进硬fault,另外在用的时候注意任务堆栈的大小,这个如果太小也会进硬fault,还一个就是中断的问题,ucos-iii的中断可以用它自己移植好的中断,也可以用st官方的中断函数,关键是要保证中断函数和st启动文件里的中断ISR名字一致。
lwip1.4.0说明:lwip是一种tcp/ip协议栈,与uip相比,功能相对全面。ROM和RAM占用资源较多。使用方式灵活。uip适合8、16位单片机使用,资源占用少,但是主函数会写很长。lwip主要有三种访问方式:RAW_API方式;LWIP_API方式;BSD套接字方式。三种方式各有特点,RAW_API(单线程方式):使用回调函数方式实现,占用资源最少。但实现略复杂,效率不高,据老衲五木说。LWIP_API(多线程方式):使用简单灵活,但是需要OS配合进行多线程操作,lwip会使用OS的信号量,邮箱等进行进程同步,移植复杂。BSD套接字方式,适应软件socket编程,与LWIP_API方式类似,但是lwip进行了封装,更像socket编程了,但是lwip的支持不足,需要用户直接访问lwip协议栈以完善套接字功能。另外LWIP1.4.0相对于之前的版本多了一个timers.c文件处理和定时器相关的所有内容,使得lwip的源码和app的代码分割比以前清晰了。所以在不用OS的情况下,要用sys_check_timeouts()函数代替之前版本在main.c里循环调用的LwIP_Periodic_Handle函数,这个函数主要负责检查相关定时器的超时事件的处理,同时需要实现一个sys_now的函数,用来获得当前的时间,这个时间是在systick中断函数里累加的值,而在LWIP_API(多线程方式)中是通过对信号量的超时判断,来实现LWIP与os时间上的同步的。相对于LWIP1.4.1来说,1.4.0缺少了对ICMP校验和的宏判断,导致使用F407的mac的硬件校验和会ping不通,需要对lwip的源码做简单的修改。需要注意的是,LWIP的源代码(文件名为lwip-x.x.x)和应用实例(contrib-x.x.x)是需要分别下载的。官方的源码包文件结构如下:
lwip源码文件结构.jpg
如果需要移植lwip的话,doc中的两个文件sys_arch.txt 和rawapi.txt需要阅读。src中主要是lwip的源码,其中的ethernetif.c文件提供了软件移植的模板,需要自己根据网卡进行修改实现,包括ethernetif_init、ethernetif_input、low_level_output、low_level_input、low_level_init的实现模板和注释。changelog包括维护的bug,与之前版本的差异、upgrading包括新版本的新特性。不加后缀可能是为了linux的缘故吧,这些文件基本都是文本文件。
在lwip的contrib-x.x.x文件夹下,一般只有两个文件夹,一个是app,一个是port。其中app主要是使用lwip协议栈实现的具体应用。下图为app文件夹下的内容。
app.jpg
其中httpserver和httpserver_raw分别为使用多线程API函数形式的和使用单线程raw回调函数形式的web服务器的简单实现。stm32官方的以太网例程就是对这两个文件夹进行了扩充和改写实现的。下图是httpserver_raw文件夹的内容,rar文件是我压缩的,可以忽略。用过stm32官方以太网例程的同学,应该很熟悉这几个文件吧~
httpserver_raw.jpg
httpserver文件夹下只有三个文件,httpserver-netconn.c/.h文件和一个readme文件。通过对比httpserver-netconn.c和httpd.c文件,你就会明白我为什么要用多线程LWIP_API实现网络通信了。
下面再来说下contrib-x.x.x的另一部分,port部分。这个部分是和平台密切相关的,文件构成各异。但是一般都包括一个include文件夹、一个sys_arch模块的实现,一个ethernetif.c.h模块,以及一个雷打不动的lwipopts.h配置文件。include文件夹中一般包括很多头文件,但它们其实都很简单,比如cpu.h看着很复杂的感觉,其实里面只定义了一个cpu大小端的宏。需要注意的文件并不多,主要是cc.h文件,用于定义lwip会用到的数据类型,以及禁止字对齐编译器指令,这样就可以将数据包中指定格式的内容强制转换为结构体访问了,提高处理效率。sys_arch.h文件用于定义信号量,邮箱,线程等与系统相关的数据类型。ethernetif.c.h就是之前说的要根据实际网卡实现的5个函数。sys_arch.c就是实现与线程以及信号量,邮箱相关的函数。对于stm32这种官网支持比较全面的芯片来说,port只要从官网上下载就可以了。对于资料比较少的芯片,工作量相应的就比较大,这也是我为什么总喜欢用stm32的一个原因。
这样我们就把要移植的部分顺了一下。为下面的移植工作确定了目标。不过我还是不太敢往下写lwip和uC/OS-III的移植。请看下回:大胆发言,小心求证
工程布局.jpg
文件夹.jpg
工程布局.jpg
CCM.jpg
result.jpg

makefsdata.rar

下载

6.57 KB, 下载次数: 792

ETH微雪官方F4例程.rar

下载

2.62 MB, 下载次数: 4845

sys_arch1.4.0官方说明.pdf

下载

115.08 KB, 下载次数: 1158

LwIP协议栈源码详解.pdf

下载

1.49 MB, 下载次数: 1747

lwip1.4.0源码包.zip

下载

599.53 KB, 下载次数: 1494

lwip1.4.0实现例子_官方网址下载.zip

下载

454.31 KB, 下载次数: 2190

lwip-1.4.1源码包.zip

下载

595.11 KB, 下载次数: 2593

lwip1.4.1实现例子官网下载.zip

下载

430.39 KB, 下载次数: 3339

评分

参与人数 1 ST金币 +22 收起 理由
wofei1314 + 22

查看全部评分

收藏 26 评论121 发布时间:2014-3-30 14:22

举报

121个回答
STM32F103-34799 回答时间:2014-3-30 14:23:29

RE:【MCU实战经验】+ uCOS-III(V3.0.3) + LWIP(V1.4.0)

有人会看这么多字么
ustbyf 回答时间:2014-3-31 09:29:54

回复:【MCU实战经验】stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

 有
STM32F103-34799 回答时间:2014-3-31 11:39:25

回复:【MCU实战经验】stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

多谢支持!.
weiyongwill 回答时间:2014-4-4 10:11:27

回复:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

看完了,期待下一章
STM32F103-34799 回答时间:2014-4-6 10:49:50

RE:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

帖子没有设置回复可见,希望各位如果有兴趣能回复一下,支持一下,谢啦
STM32F103-34799 回答时间:2014-4-6 10:51:34

RE:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

如果有新的内容,帖子可能会不时更新,请各位多多支持,更请各位高手批评指正,谢谢
STM32F103-34799 回答时间:2014-4-6 11:21:03

RE:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

注:MAC地址不可以随意设置,特别是在使用DHCP的情况下。MAC的前三个字节是OUI,OUI是“组织唯一标示符”,由签发给各类组织的唯一标识符。其中MAC的第48bit(即MAC_ADDR0的最低位)是单播/组播位,如果为0表示这是一个单播地址,如果为1表示这是一个组播地址,网卡的MAC地址是单播的,因此需要将这一位设置为0,即MAC_ADDR0必须为偶数,否则,无法获得动态IP地址。
jwg 回答时间:2014-4-7 15:18:12

RE:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

支持一下,正在学习中.
duzhongliang 回答时间:2014-4-7 15:58:22

RE:【MCU实战经验】+stm32f4 + uCOS-III(V3.0.3) + LWIP(V1.4.0)

学习学习

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版