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

【经验分享】使用 CubeMX 生成 TCPEchoServer 工程

[复制链接]
STMCU小助手 发布时间:2022-2-11 22:50
前言8 s' O+ O& l6 }9 x5 S
在 STM32 的众多外设中,以太网这个外设相对而言还是比较复杂,初始化的过程也比较复杂,涉及到 MAC,DMA,PHY 好几块内容的初始化。可能有时候 datasheet 都看得头疼了,可初始化还是有问题。而 STM32CubeMX 工具就可以帮我们轻松完成这部分工作。在本文中,将分别以 STM3220G-EVAL 板为例,通过 CubeMXv4.11 来新建一个基于 RAW API 的TCPEchoServer 的工程。
, k8 x0 l: r# y. \/ q1 y& W0 k8 F
用 CubeMX 建立基于 STM3220G-EVAL 的工程! O; z0 s5 O' g; {' t' R2 E" O4 J
用 CubeMX 进行初始化配置
3 k6 f1 P, M' q3 j$ I. P) U1. 新建一个 Project,在向导中选择 STM3220G-EVAL 板- o# [5 F2 x6 w. s$ }/ X) J
; i& J7 o- ^9 L& R0 L, E9 o$ D; A
ET((P`SC~[7X_B(NDTWW28U.png
/ n+ f3 Y) ?" W1 U) \/ _: F/ h3 h- B( h! t" o
2. 因为我们直接选择了 STM3220G-EVAL 板,新建的 CubeMX 工程打开时就已经有默认的配置在里面了。所以我们只需要打开以太网和加入 LWIP 中间件就可以了。
3 _2 Z. f/ |  |- z& c' S   1)在 ETH 下面选择 MII 模式;
  w7 c# D. t4 P1 p( F' _   2)使能 LWIP。
0 q+ h# Z/ t8 c0 Z( E4 _# I+ ]; e. I% y) C" I" W/ P0 L
W946HQ6%HH[~]XL]IQ[QF]S.png 1 z& e% o3 S8 l' m- C$ x  S/ e
& \4 i# Y! x2 B. R7 @3 {' Q
3. 配置以太网的参数( U; U3 T! e- T* o: m
) }/ |# Z7 D" q! C' o
X2OVW$_)[%~]V_8FUACVK_E.png 5 V( e& u7 _, d9 S: X+ X! [

' J( r& a: `5 |8 m+ Z   在 Parameter Settings 页面,可以配置 MAC 地址,PHY 的地址,是否进行自动协商等。
9 W  W* n* I4 o; g. K) l   这里,我们设置了 MAC 地址为 02 :00 :00 :00 :00 :00,PHY 地址为 1。( X- S# }% \/ @* i
. A* O1 A2 l  N+ [. ^
MA$ESFO)M)UQRH~WA)N6PBK.png
' T- z! f! L- k) U% Z- [' V: \3 A
   在 CubeMXv4.11 版本里,以太网的参数设置还增加了 Advanced Parameters 页,可以根据所用的 PHY 修改寄存器的地址和一些 MASK 的设置。CubeMX 中默认的配置是以 DP83848C 为例进行设置的。STM3220G-EVAL 用的 PHY 就是 DP83848C,所以不用修改也可以用。对于其他的 PHY,不能完全通过 CubeMX 来配置,需要根据 PHY 的数据手册,手动的修改代码。将有冲突的地方删除,或者添加某个功能。
5 K+ ^, q: g) s: k, u" ~- J8 F9 Z   Advanced Parameters 页分为三个部分:
$ v& _% c5 F3 w' B# I9 ]    External PHY Configuration 。复位延时,读/写超时的参数设置8 z4 z# R* N, X2 w1 G
    Common :External PHY Configuration。PHY 的基础寄存器配置,这部分寄存器对于大部分 PHY 都是相同或类似的。
9 [; B5 Q* L( y6 q    Extended :External PHY Configuration。 PHY 的扩展寄存器配置,这部分对于每个 PHY 都是不一样的。如果是使用 DP83848C 以外的 PHY,这部分内容需要特别注意。
* w5 z+ }4 p+ Y& W   FAJDGB9P)0YW~%NVPZ9~@UX.png
% r4 V3 W' d  P: g" Y& y: i4. 修改 LWIP 的参数
. H  t# h8 u) }& A4 ]   配置好以太网的参数后,点击 OK,回到 CubeMX 的配置界面。选择 LWIP 继续进行参数配置。
% ^" l, l* F: W: h0 i) H/ [8 {' s; N4 j% x7 v* k
`IL35P~8(]%Z1}(VIL%PQY8.png
/ C* i2 ?2 }" l9 R7 B  R
9 d- y. }4 P2 `- X   首先是 General 页面,在这里我们可以看到 LWIP 的版本号。配置 IP 地址信息,可以选择通过 DHCP 的方式动态分配 IP,也可以分配一个静态的 IP 地址。这里,我们选择配置静态的 IP 地址 192.168.0.10,子网掩码 255.255.255.0,网关192.168.0.1。ICMP 协议打开,因为我们用的是 TCP 协议,所以把 UDP 协议关掉。& @( p5 p! N9 y- {( r
   不用担心不知道每项参数是做什么用的,选择每一项参数后都会在窗口的底部显示该项参数的解释。
* d- e8 |, X$ J% ?! P4 F; W, g+ P" N: A- L1 W
%VY(70JA_BB`_15V1DL%TZ7.png
9 C& H: F) b8 w/ x6 m
* a7 }: S% w. U3 ^7 a, L+ m: D   在 All LwIP Options 这一页里,有更多的参数可以配置。关于接收/发送内存的配置也是在这里。选择右上方的“ShowAdvanced Parameters”后,还有更多的参数配置项。这里,我们也可以不做修改,使用默认值。CubeMX 中每个参数项的名称和代码中的名称相同,这样也方便了在代码中进行查找。
+ B, @" q3 B( x+ N
& r- s* B# g3 O. h: N1 p; |6 Q) K 8 E- u- D' v, H" k

3 T, T1 i' V# {4 ?1 j6 \6 ?到此为止,我们在 CubeMX 中需要做的配置就全部完成了。选择 Project——>Generate Code,生成初始的工程。. C- Z3 Y: A8 u0 a" m' m9 T5 u

3 {2 q4 B. b2 ~. e$ U- |- ^ OMW`IO0M}9IH`BG)GV@EYWI.png " v4 Q9 }) a) |) ^
0 [' k, i. I& y% a% B) A5 u5 p
添加用户代码4 g* p% N/ i! \& c- L1 C  M
用 IAR 打开前面已经生成好的工程。我们还需要两步就可以完成一个简单的 TCP EchoServer 程序了。
  S6 h6 W( ^! M# J- V( p1.新建 tcp_echoserver.c 文件,在 tcp_echoserver.c 里要做下面这几件事情:
9 O0 }$ z( r; Y7 z: ?1)新建一个 tcp_echoserver_pcb(调用 tcp_new 函数);
9 i& F9 t3 r) P4 L6 C- A# P6 Y2)将新建的 tcp_echoserver_pcb 与要监听的端口绑定(调用 tcp_bind 函数)
2 I- ^4 {5 U' U2 i3)转成监听状态(调用 tcp_listen 函数)- o. {& s2 _6 `$ t8 R! o
4)注册回调函数 tcp_echoserver_accept,当有新连接5 [! q/ ?; ]  S- u; O( R
完成 tcp_echoserver.c 后,将其加入到工程项目中。
' {7 G$ w; l) F. D8 c
  1. #include "stats.h"
    % R" z* p/ J' T. C4 _" N
  2. #include "tcp.h"* I8 R7 F" m/ F$ p1 d# ^8 H
  3. void tcp_echoserver_init(void);2 J$ v4 ^& P2 ^% x" z
  4. static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb,err_t err);
    ! Y0 x- B! {% z! s7 o5 V$ v
  5. static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,err_t
    $ u, a; Z/ \3 t9 y6 g' K8 M- Y
  6. err);9 Y8 k0 ^8 T* @9 `$ h9 {/ B
  7. static struct tcp_pcb *tcp_echoserver_pcb;
    * p4 l! ^3 N3 _+ S% y: Y2 H
  8. void tcp_echoserver_init(void)
    - r3 `% e3 R( f. m
  9. {' `0 n# g$ X: L0 m7 w. N
  10. err_t err;
    ) N; n  B" y4 m$ I8 P8 e! y  a4 `
  11. tcp_echoserver_pcb = tcp_new();
    : J& N9 H7 J3 v" z

  12. ) |4 _! \3 W* ~3 l( F2 F; [
  13. if(tcp_echoserver_pcb !=NULL). g- b- g9 ~/ B* n( a8 Z" w$ q& G
  14. {, ^4 O: P$ w4 e3 T4 f, K+ F( R' g
  15. err = tcp_bind(tcp_echoserver_pcb,IP_ADDR_ANY,7);2 V4 s& O; m. b' @0 L, H' S
  16. if(err == ERR_OK)) M* J1 y' i6 g, X& c4 Z
  17. {7 e9 r9 y* p: x; k1 Y
  18. tcp_echoserver_pcb = tcp_listen(tcp_echoserver_pcb);
    , C4 V3 h% Z: P$ I( v: |
  19. tcp_accept(tcp_echoserver_pcb,tcp_echoserver_accept);
    - G, a& o  a& q5 P+ U) {& g
  20. }
    * O2 x( M0 \! n8 j1 u
  21. else
    + t: I' ]+ B) H; l& d. ^4 q
  22. {- I- [6 m4 Y7 f& l; Z
  23. memp_free(MEMP_TCP_PCB, tcp_echoserver_pcb);
    0 p! ^: x# b2 U: d+ i
  24. }/ [  _* [5 f3 W
  25. 3 K( \. M8 q+ A0 u, ~
  26. }( ~9 h# o" Q' q  U, m* W

  27. " _8 r" c6 i9 ?$ A6 j
  28. }$ E2 s9 h6 B% n# K2 }
  29. static err_t tcp_echoserver_accept(void *arg, struct tcp_pcb *newpcb,err_t err)3 A* H( d2 r* d6 c8 N3 |1 |
  30. {- @) Y0 A5 P" J+ o+ b, q
  31. /* initialize lwip tcp_recv callback function for newpcb */
    1 K& s2 `6 o, z
  32. tcp_recv(newpcb, tcp_echoserver_recv);6 W  I) b- q5 H  l

  33. 5 h  I1 I/ i2 r" z
  34. return ERR_OK;9 t/ T6 [9 O/ @# j
  35. }
    , f/ f( {# N& ]+ y- ?
  36. static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,err_t$ \" ]! ?% W5 F
  37. err)
    7 N4 g3 H+ K4 N  P7 ~
  38. {
    0 b8 d# v& W3 g7 H' d
  39. struct pbuf *ptr;
    - V8 R* q; `0 E. Q
  40. u16_t plen;
    , ?6 }9 J! s0 f9 g7 B0 T
  41. & i; y6 ^1 _3 a  m% @+ H
  42. tcp_write(tpcb,p->payload,p->len,1);: m' N! l6 e: Q. @
  43. return ERR_OK;; c3 I3 s$ b; L9 w
  44. }
复制代码
) a1 ?( t) |: x2 j- f* O  a' j
2. 在 main 函数中添加 tcp_echoserver_init(),在 while(1)中添加 MX_LWIP_Process()查询接收数据。记得要将代码加在/*USER CODE BEGIN*/和/*USER CODE END*/之间,这样才不会在下次用 CubeMX 生成代码时被覆盖掉。
/ o: u; M% A. U
  1. MX_LWIP_Init();5 [7 k0 o) U& P
  2. % \5 Y$ l# A6 L
  3. /* USER CODE BEGIN 2 */
    # B5 [; h4 ]1 V  o7 F% C; v
  4. tcp_echoserver_init();
    8 s) ~, ^0 P" D4 o( ]
  5. /* USER CODE END 2 */5 x# n  @. p( u
  6. /* Infinite loop */( D5 h1 C% X1 E2 Q
  7. /* USER CODE BEGIN WHILE */
    ) e. ]* i: H* p1 @" j
  8. while (1)" O" R) T6 Q( c& [1 G
  9. {
    - Z4 h( `& r! G
  10. /* USER CODE END WHILE */$ V! s# T3 _7 s. K, G& K/ {. I
  11. /* USER CODE BEGIN 3 */
    % X" l3 v: L5 g' q& Q9 ?
  12. MX_LWIP_Process();
    4 ~+ p& V2 ?1 A: {; B. a
  13. }6 @9 N! X$ t, E
  14. /* USER CODE END 3 */
复制代码
' t& D8 d- b$ ~* t1 r# l' ~2 ]
一个简单的 TCP Echoserver 程序就完成了。
9 q/ B! c2 V( D, V7 b7 n, W
/ q! `) u6 ?, `, [测试结果
( v/ h, t, B( D0 a/ Y我们来看一看 ping 测试和 TCP 测试工具的结果+ T9 ?5 e5 w; R# B0 ^, n" ^2 f
1. 通过电脑(192.168.0.11)ping STM3220G-EVAL 板(192.168.0.10)
* N! t- J7 ~$ ]% M% R: b- V& Y
; H8 e: j' a: R% y( S( O K70XW~[WO12NMU6[3KOH.png
$ V9 n# `% A+ E. j5 x: R
9 l" Z9 p" i2 T0 i- C3 ], p& Y2.通过 TCP 测试工具模拟客户端,向 STM3220G-EVAL 板发一串数据。$ \" P# R# S8 l& Y$ @
; f: A+ v: Y3 n+ y: T
TVV6C$C$$R{CMTTD2}WG]TP.png
$ N7 ^& B- o$ @7 d& X
9 @3 E/ v4 @0 M+ ]/ c/ _& C3 ?   测试结果说明我们刚刚建立的 TCP EchoServer 程序已经能正常工作了。
8 K2 m3 ^! K( O/ V: C   以上所介绍的只是 CubeMX 配置以太网程序的一部分功能,其他的功能稍后会一一道来!  }' p9 h5 t1 g! l
5 |) z) b) u& L2 X! @
收藏 评论0 发布时间:2022-2-11 22:50

举报

0个回答

所属标签

相似分享

官网相关资源

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