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

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

[复制链接]
stm32f103vc 发布时间:2014-4-2 21:39
接上回书。
: r& ]  b  f2 M; ^& o+ `# p9 z* C上次介绍了使用stm32f407和phy芯片DP83848进行网络通信的硬件组成和注意事项。软件方面移植uC/OS-III过程中可能发生的问题。lwip的特点和组成,移植多线程lwip所需要处理的文件。下面就开始将uC/OS-III和lwip1.4.0揉在一起了。。。。真担心写不好。。。为了F429Discovery,拼了吧。9 M6 u  n2 f9 U' j* k
   本文假设uC/OS-III已经移植到stm32f407上了,并且可以完成简单的任务。在移植的过程中将会修改已经移植好的uC/OS-III工程,同时参考st官网lwip单线程的例程。那么只需要修改下lwip相关的port文件就可以了。其中ethernetif.c文件基本不用修改(需要修改的地方是这次使用stm32F407的以太网接收中断,需要在NVIC中使能这个中断,并且在stm32f4xx_int.c文件中添加对中断的处理)。需要处理的文件有sys_arch.c/.h文件;main.c或者叫app.c文件;lwip文件,用于处理lwip的初始化(与单线程的lwip初始化稍有区别);lwipopts.h文件的修改;httpserver_conn.c文件。; q  Y, q1 A! g# x" C& a
  ethernetif.c文件的修改。主要是添加stm32F407的以太网接收中断的配置,如果dp83848连接了F407的io,则可以在程序初始化时,根据dp83848状态寄存器的连接状态位来决定是否启用mac和phy的自动协商功能。等连接之后再重新初始化一下即可。% X. A6 F3 g. A" u$ e" i
修改stm32f4xx_it.c。添加对两个中断的响应函数,一是以太网接收中断,判断接收到了数据就调用ethernet_input来处理,请中断标志退出。二是处理dp过来的中断,修改连接状态的标志变量。5 V7 u: a% [: w" B9 ~
lwip文件的修改。可以参照官网lwip例程来修改,将初始化函数中的lwip_init用tcpip_init(NULL,NULL)来代替,将netif_add(&main_net, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernetif_input);最后一个参数用LWIP的api函数tcpip_input来代替。即netif_add(&main_net, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);7 N' K) l/ _; G- m; o
main.c或者叫app.c文件。修改appstarttask,添加刚刚修改的lwip的初始化函数。添加http_server_netconn_init();初始化http处理线程(这个函数在httpserver_conn.c函数中)。然后删除任务,或者循环delay,你懂的。  u' t0 V; _  K1 Q
最后修改sys_arch.c/.h。先修改sys_arch.h文件,添加在lwip中对信号量和邮箱的定义。接着是修改sys_arch.c文件,具体内容为:# N& }0 B3 w4 P, L( g
1.信号量的封装。主要是对sys_sem_new(),sys_arch_sem_wait(),sys_sem_signal(),sys_sem_free(),sys_sem_valid(),sys_sem_set_invalid()。通过对uCOS的信号量进行简单封装就可以了,成功返回0,失败返回-1,超时返回SYS_ARCH_TIMEOUT。这里不再详述。
' d' z/ u8 w2 @: K& A; Y$ E
2.互斥对象的实现。这个并不是很重要,可以简单的用信号量函数代替,也可以用uCOS的互斥对象实现。如果用信号量函数代替,需要定义宏LWIP_COMPAT_MUTEX。

+ r8 X2 C* B+ [% V& l
3.消息邮箱的封装。sys_mbox_new(),sys_mbox_free(),sys_mbox_post(),sys_mbox_trypost()相对比较简单,sys_mbox_free的实现需要在删除邮箱之前,用OSQFlush清空消息队列的内容。sys_mbox_post和sys_mbox_trypost的区别是post的次数,一个是尝试发送一次,一个是尝试发送十次左右。

( F: m8 ]/ f/ E7 {+ v; D
4.sys_arch_mbox_fetch的实现,这是一个比较重要的函数,用来阻塞一个线程,知道接收到消息。阻塞的时间视参数timeout而定,返回超时的时间。所以这个函数就是对 OSQPend的简单封装,填充传入的消息指针,返回超时时间即可。

1 Z6 i6 r. \) A
5.sys_arch_mbox_tryfetch的实现。根据lwip作者的解释,This is similar to sys_arch_mbox_fetch, however if a message is not present in the mailbox, it immediately returns with the code.
) I; _% f: l: [" \! w
To allow for efficient implementations, this can be defined as a

6 I9 J$ S0 ]! {, z
        function-like macro in sys_arch.h instead of a normal function. For

1 A7 k& W9 z3 s/ D* v# n6 Y* q
        example, a naive implementation could be:
% t" U# L: f" U- X
          #define sys_arch_mbox_tryfetch(mbox,msg) \
4 `0 e  F6 O4 N0 Z1 ~  o9 j/ r; @
            sys_arch_mbox_fetch(mbox,msg,1)
) [% j# C* t2 {& b& }
        although this would introduce unnecessary delays.

* N1 l4 o* z8 m! _/ ~/ a
就这样一个宏kill了一个函数。
( D8 H% q$ I1 l: q" Q- w: [* I
6.sys_init() 这个函数用来实现分配LWIP的任务栈空间。
0 n% L1 P9 {" O; q# T& a8 M) u
7.sys_thread_new()。这个函数是帮助LWIP创建线程的。对uCOS来说就是任务的创建。创建的时候要判断是否已经超过了LWIP的最大任务数。
/ h+ n5 O7 [- F) f" k6 j* T# c" ]
8.sys_arch_protect和sys_arch_unprotect是为了帮助lwip进出关键代码区,用来开关中断的。直接返回即可。
# |: V7 d# C: _6 U+ \5 H. ~5 F
lwipopts.h文件的修改。lwipopts.h文件要改的首先要修改 #define NO_SYS 0,告诉lwip要使用信号量和线程了。定义与创建邮箱相关的宏,TCPIP_MBOX_SIZE和DEFAULT_TCP_RECVMBOX_SIZE,DEFAULT_RAW_RECVMBOX_SIZE。在默认定义下这两个是0,会导致信号量创建失败,大小视实际情况而定。
2 h' `9 d# l  o4 f# X8 L0 ~8 y! ~
httpserver-netconn.c的移植主要是实现创建http的线程,在线程中根据HTTP的请求做出相应的响应,返回响应的网页或者图片或者对板子的指令等,具体为修改http_server_serve函数,根据http的请求行作出相应的处理。

1 K  I, o+ H: `% }3 O* G7 a
  如果要用DHCP,软件上,需要在lwipopts.h文件中定义LWIP_DHCP和USE_DHCP,在初始化的时候把ip地址,掩码和网关地址全部设为0,硬件上需要连接一个带DHCP服务器的网络。
8 _8 ^0 Q! @; E8 F* |
针对LWIP1.4.0,需要处理一下icmp.c文件,内容如下:

6 R  F- m& C; _6 i- k
#if CHECKSUM_GEN_ICMP7 _  G+ c! f+ J9 u: J$ j5 ]. c8 J
    /* adjust the checksum */
: N% l) a: j/ m+ t( V/ b! @" w$ M& U    if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO chksum += PP_HTONS(ICMP_ECHO chksum += PP_HTONS(ICMP_ECHO chksum = 0;# [0 B3 W! q6 _8 O8 a3 v' F
#endif
" R7 f4 P% R( L
并且在lwipopts.h中定义CHECKSUM_GEN_ICMP为0
: a. s/ g- E6 u# `  a9 }
再添一句,MAC地址不可以随意设置,特别是在使用DHCP的情况下。MAC的前三个字节是OUI,OUI是“组织唯一标示符”(和USB的VID相似,提供网卡或是设备供应商的ID),签发给各类组织的唯一标识符,后三个字节由供应商自己支配,和PID相似。其中MAC的第48bit(即MAC_ADDR0的最低位)是单播/组播位,如果为0表示这是一个单播地址,如果为1表示这是一个组播地址,网卡的MAC地址是单播的,因此需要将这一位设置为0,即MAC_ADDR0必须为偶数,否则,无法获得动态IP地址。
6 Y- r" n8 v" f# [+ }5 z) V
最后再说一下,调试的问题。对于有192KB SRAM的F407VG来说,我一直用的是ram调试。但这次的网页data比较大,所以想到了F407的CCM,这个模块只通过D-Bus和内核连接。所以DMA和外设是无法访问的,这样的设计一来会提高芯片的性能,二来不会被非法访问破坏数据。存放RW数据还是可以的(代码是肯定不行的,会进硬fault,但是在F3里是可以的),改了一下sct文件,发现可以用。如果以后遇到频繁处理的数据或者堆栈什么的可以放在这个内存区了,64KB 不用太可惜了。呵呵% l9 ]% z) J% f5 w: H

5 a# {7 a7 w/ d! ^, \0 G
& Z" X, h$ w' X3 G7 F3 I! L
剩下的就是一堆未定义,重复定义,头文件找不到等等问题了,应该难不倒各位。先写这么多了,相关的附件都贴在上一篇了,各位移步吧。

2 P2 i! U1 d0 m+ ]( b
如果你已经移植好了,不妨考虑一下,用它玩点什么东西,比如这个。。。
- `3 _# _. c, g# Y1 W1 i/ Q9 P6 w
ccm.jpg
5 S1 R% I1 M" _, D/ `1 V# m. v8 q
还是最后一句,求板子F429Discovery

: C3 e( E& o3 Q. }
6 W/ f9 C# Y" b6 a3 F9 G1 s* u2 l
赞 收藏 3 评论15 发布时间:2014-4-2 21:39

举报

15个回答
weiyongwill 回答时间:2014-4-4 10:42:44

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

支持,投一票,我也在移植lwip,正不知所措,先按照楼主的讲解试试
stm32f103vc 回答时间:2014-4-6 10:45:38

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

多谢支持,不知道移植的怎么样,有问题一起讨论。
weiyongwill 回答时间:2014-4-14 13:35:22

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

我的QQ:③⑧①⑧⑦⑧①⑨⑥,能否沟通一下
tan-338416 回答时间:2014-4-14 17:45:36

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

请教,用样的是STM32F4DISCOVERY +微雪DP83848为什么PING不通?
stm32f103vc 回答时间:2014-4-14 21:06:22

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

回四楼,有问题,先自己看下查查,根据以往的经历加q反而效率不高。我最近一个月,会经常过来看,有问题请留言。我尽力而为,也欢迎大家讨论。
stm32f103vc 回答时间:2014-4-14 21:12:45

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

首先,你软件用的是什么版本的lwip?带os吗?1.4.0的要设置ICMP的硬件校验。
6 r$ E5 t6 L4 }0 y7 Y; x+ M; L你是用杜邦线么?我的是10cm的杜邦线,有时候也会丢包。一直ping试下,命令ping -t ip地址。ping的时候动动杜邦线,看能不能ping通,我的情况是有时候接触不良。如果还不行,就用示波器看下各个杜邦线上的信号有没有失真,失真是不是太过分了。
6 ~9 \, U2 l' l不知道具体情况现在如何?有问题再讨论。
tan-338416 回答时间:2014-4-15 11:32:28

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

 PING通了 ,网页打不开。请问这是为什么?
stm32f103vc 回答时间:2014-4-15 13:08:26

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

ping通了,说明你的网络连接ok,网页打不开,说明你的tcp可能没通,或者通了,你解析http出错了。你的信息量太少,我只能这么猜了。
MrJiu 回答时间:2014-5-14 08:17:38

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

支持一下.....
dfeiel 回答时间:2016-2-29 11:48:33
楼主求分享工程源码,万分谢谢!774270565@qq.com
tgwfcc 回答时间:2016-4-27 10:50:55
并不怎么详细
a随风飘兮 回答时间:2018-5-23 23:50:08
楼主是否有移植好了的工程让我们借鉴下
: t/ N8 m6 f8 E+ ]% a! C
xddong05 回答时间:2018-8-30 17:14:20
谢谢楼主,很有帮助!
ym1614666470 回答时间:2018-12-9 11:51:04
最近想深入了解一下lwip移植ucos的修改移植内容,学习学习。
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版