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

开箱测评-STM32H5内部TCP/IP UDP 通讯测试(2)

[复制链接]
guoyuli 发布时间:2023-9-11 12:52
对我启发较大的是 App_Link_Thread_Entry 线程,这个线程会定期检测网络物理连接。9 t( J! ?5 f3 @+ e/ z2 X% M9 h
接下来是 App_Main_Thread_Entry 线程,这个线程主要是完成联网的准备工作。还有就是对 App_Link_Thread_Entry 线程数据的初始化。
  1. $ E% f3 f6 `; [5 Y
  2. /* Exported macro ------------------------------------------------------------*/
    ! c' M0 f. o6 B, i, g
  3. /* USER CODE BEGIN EM */
    2 \: ?- G, L; o5 `  \- n: O
  4. #define PRINT_IP_ADDRESS(addr)    do { \9 i9 ~+ H' a: k1 R
  5.              printf("STM32 %s: %lu.%lu.%lu.%lu \n", #addr, \
    5 U8 l$ Y( i' y
  6.              (addr >> 24) & 0xff,                          \/ k& y  {: y& y! [9 r+ h
  7.              (addr >> 16) & 0xff,                          \3 {* g6 D( y, Y- `* A8 I
  8.              (addr >> 8) & 0xff,                           \3 ?+ a+ {) L5 f1 X3 J. g- i
  9.              (addr & 0xff));                               \
    ! h3 X. A+ {( F! ]1 N
  10.              } while(0)
复制代码

) |- j9 V. n4 g: C# l. W4 {
主要的工作线程是 App_SNTP_Thread_Entry,这个线程完成整个过程。
  1. /**/ [/ w6 N3 \2 i! b6 Q: L7 z" u
  2. * @brief  SNTP thread entry.
    5 X* y$ J7 P& G
  3. * @param thread_input: ULONG user argument used by the thread entry
    7 I& G$ V2 b( \1 H1 y$ d- Y
  4. * @retval none8 z' W8 ~5 n9 j* s8 [# k& _
  5. */
    & h* l% a2 T- |9 W+ R3 q; [1 C
  6. /* Define the client thread.  */
    ( J1 s- ]5 x$ ~/ {
  7. static void App_SNTP_Thread_Entry(ULONG info)# X1 F/ g9 \+ |1 E
  8. {
    3 F/ f& h8 C* e) N. w
  9.   UINT ret;# b5 p. O$ g& }+ W0 j. R$ K
  10.   RtcHandle.Instance = RTC;5 ]( E, ]$ v* P+ l$ ?4 x
  11.   ULONG  seconds, fraction;
    , {6 I1 L# h! t# J1 T
  12.   ULONG  events = 0;* E: [$ t; Q# \+ A. D) r" w+ E, _
  13.   UINT   server_status;
    0 F; i% q) C4 u2 T, e  w
  14.   NXD_ADDRESS sntp_server_ip;$ o  o1 u6 b  l  v
  15.   NX_PARAMETER_NOT_USED(info);
    ! [: g( V( I2 X; F0 r
  16.   sntp_server_ip.nxd_ip_version = 4;# K1 S; S  l0 ]& [
  17.   /* Create a DNS client */
    ) U0 ^" D- B/ r7 V+ X: \
  18.   ret = dns_create(&DnsClient);
    5 }( Q! e0 _' G, E' Q* R; a
  19.   if (ret != NX_SUCCESS)
    / x# m% T+ q9 H3 B, D; X' `  J
  20.   {) Y2 Y) H  \- b1 d! Y# Z
  21.     Error_Handler();& ]$ @$ C! _5 a. ^' v
  22.   }
    - N; @' U4 P0 H# N
  23.   /* Look up SNTP Server address. */: U+ a7 ?4 K( }% Y: m( V
  24.   ret = nx_dns_host_by_name_get(&DnsClient, (UCHAR *)SNTP_SERVER_NAME,  W6 _& u6 F5 y2 M0 O2 R6 O. o
  25.                                 &sntp_server_ip.nxd_ip_address.v4, NX_APP_DEFAULT_TIMEOUT);
    $ e% _* o. F+ f& r9 D4 }4 i
  26.     /* Check for error. */5 F9 k; d$ c6 x3 i6 o
  27.   if (ret != NX_SUCCESS)
    ; I0 V" w; Z8 f8 d% O9 U
  28.   {3 @5 G% Q( V9 s% o2 u2 a) i; i) s
  29.     Error_Handler();# G) r& N2 H6 p
  30.   }
    ) a* Y& P) ]7 g# h
  31.    /* Create the SNTP Client */
    ' ^* ^: X  I7 U% h4 N
  32.   ret =  nx_sntp_client_create(&SntpClient, &NetXDuoEthIpInstance, iface_index, &NxAppPool, NULL, kiss_of_death_handler, NULL);
    6 Y' z( r" C5 p, t
  33.   /* Check for error. */
    + C) F, R7 H7 h3 `% d7 C
  34.   if (ret != NX_SUCCESS)
    . G4 H" {2 t! P4 Y5 U
  35.   {
    . S7 [7 L$ f/ }6 @3 R
  36.     Error_Handler();
    / ?& P5 ^" |  h5 e4 F
  37.   }
    + L# i3 h6 ~5 R& Y  R
  38.   /* Setup time update callback function. */
    ) \7 w6 Z8 o  H  B& P
  39.    nx_sntp_client_set_time_update_notify(&SntpClient, time_update_callback);, i7 M2 y7 y+ x. X& x. ^8 E5 Y
  40.   /* Use the IPv4 service to set up the Client and set the IPv4 SNTP server. */
    # t; Z( R6 n- D. a0 N& r
  41.   ret = nx_sntp_client_initialize_unicast(&SntpClient, sntp_server_ip.nxd_ip_address.v4);
    $ ]* m1 O# o$ W, X$ s' q% a
  42.   if (ret != NX_SUCCESS)/ m# `. r8 r: V8 d5 s, E
  43.   {
    7 \' B1 f3 z. h4 `: K+ L, V
  44.     Error_Handler();3 t! z0 B9 f" O: q
  45.   }# f8 D# J$ H( _# r6 @) T4 t0 J, Q5 v
  46.   /* Run whichever service the client is configured for. */
    $ \- V5 i( M$ w) \) B
  47.   ret = nx_sntp_client_run_unicast(&SntpClient);9 @( s4 I; L; U! O
  48.   if (ret != NX_SUCCESS)6 y+ E1 E# M8 F1 O- [: S( ?& o) }+ n
  49.   {
    9 X) s" M6 @& P4 z# E
  50.     Error_Handler();
    ! d2 T/ @7 V1 I5 L4 Q6 j
  51.   }. V  ]" J' v7 |+ D
  52.   else
    ! Y) |0 K4 @9 K4 G2 D8 M3 [( d! u. |
  53.   {2 J% f6 u5 @1 `! X+ j2 [8 z4 g2 G
  54.     PRINT_CNX_SUCC();  ^% q$ v  v2 m; j; b
  55.   }2 L( }  w6 e9 ~  T, V% L
  56.   /* Wait for a server update event. */: Y- }5 _! I! D( G; |3 ^' o
  57.   tx_event_flags_get(&SntpFlags, SNTP_UPDATE_EVENT, TX_OR_CLEAR, &events, PERIODIC_CHECK_INTERVAL);
    # p4 f& l* ]( O3 b' K4 O$ i6 N
  58.   if (events == SNTP_UPDATE_EVENT)
    3 B5 s6 F" }" |: _& c# H( V6 M
  59.   {
      W6 _/ v! ]) c% R
  60.     /* Check for valid SNTP server status. */5 V0 S5 |$ @, b) ?! X
  61.     ret = nx_sntp_client_receiving_updates(&SntpClient, &server_status);  \' D% P/ a2 m0 F0 C
  62.     if ((ret != NX_SUCCESS) || (server_status == NX_FALSE)): O+ ^9 b6 m/ K& f! a. U
  63.     {
    4 [" u; u/ e- V1 n0 ^
  64.       /* We do not have a valid update. */
    . T3 _8 f+ L8 y9 u2 l
  65.       Error_Handler();- E/ p7 \" p% n9 @( K6 Y+ i
  66.     }1 w4 m: M9 @$ J0 r" R: m
  67.     /* We have a valid update.  Get the SNTP Client time.  */; u" @. _$ q1 a* R9 R% }* y+ p# ^
  68.     ret = nx_sntp_client_get_local_time_extended(&SntpClient, &seconds, &fraction, NX_NULL, 0);4 U) `3 B9 ^! |) |6 j7 B
  69.     ret = nx_sntp_client_utility_display_date_time(&SntpClient,buffer,64);
    + S& D# z& ?7 ~3 H; }
  70.     if (ret != NX_SUCCESS)+ ]5 I6 ~& {  Q9 r* W, C( [
  71.     {
    ' A, v( q- H8 x6 x: o8 c" S6 [" m
  72.       printf("Internal error with getting local time 0x%x\n", ret);  j, `" j# {& D0 p7 \. A
  73.       Error_Handler();
    . f6 P+ E, n$ n
  74.     }& _7 R0 ^1 M: n2 U% ]7 C
  75.     else
    ! w: [8 A  n; D" N; _
  76.     {( Y9 f- m/ n+ v! l2 }$ f
  77.       printf("\nSNTP update :\n");
    6 H4 Y! a; i$ r7 S" Z$ Q
  78.       printf("%s\n\n",buffer);
    1 y* F1 P2 X: e+ [- C1 d
  79.     }
    * i2 n( W$ e: S7 y
  80.   }! d- }1 A7 a( I4 s& ]7 G
  81.   else9 A+ ~% ^" b4 o2 c
  82.   {/ f; ~7 y: Y5 N% r2 o
  83.     Error_Handler();
    . T# i0 l' q& H" ?% C
  84.   }
    $ s7 \$ @$ T2 t! @
  85.   /* Set Current time from SNTP TO RTC */
    8 _4 _) S  }3 i+ o3 ?
  86.   rtc_time_update(&SntpClient);0 p3 ^+ }; z, f3 Z0 T, R! e
  87.   /* We can stop the SNTP service if for example we think the SNTP server has stopped sending updates */5 @8 D& X7 o4 A0 @+ g
  88.   ret = nx_sntp_client_stop(&SntpClient);# q& w- Z" X) S+ ?' z4 p: u
  89.   if (ret != NX_SUCCESS)* M" s" M, Q" m& z6 d* ]
  90.   {' i( r, r! G% y2 b6 _" x
  91.     Error_Handler();# U; y7 z/ x: h8 X5 y# N) N3 J
  92.   }& A5 x; H6 t/ N
  93.   /* When done with the SNTP Client, we delete it */
    5 e! v; H# e' _5 f/ c! n" T/ H
  94.   ret = nx_sntp_client_delete(&SntpClient);/ b% h% |' H" F# f* ]8 _+ J
  95.   if (ret != NX_SUCCESS)
    / l+ G/ V: F; j: E# H
  96.   {
    2 \' j8 G& {0 |( n$ A
  97.     Error_Handler();
    ) E  Q5 E; J1 V+ ?4 X+ x- o% E/ h% g5 H
  98.   }4 G  ?- m8 D; t. \7 D
  99.   /* Toggling LED after a success Time update */
    2 h* c( k, e% h' z8 Q+ w( k* x
  100.   while(1)
    1 g# x- N( }! n% r: c
  101.   {
    + }  W5 @& X0 K4 Q4 B1 \2 l! Z
  102.     /* Display RTC time each second  */
      X2 v- ^/ e6 H( u, {
  103.     display_rtc_time(&RtcHandle);9 X$ h4 O5 P+ z3 T7 d' Z8 h% O
  104.     HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    # `) K4 B+ e; e
  105.     /* Delay for 1s */
    + c% t: e. }& T# r# c' T! G0 x
  106.     tx_thread_sleep(100);: I5 t/ l  u3 k' m8 j" F
  107.   }
    & I3 @2 o4 K7 d) M) Y/ w$ j* d6 Z
  108. }
复制代码
4 K; u  |; R2 M1 ]4 I$ {* ^: M
这个程序目的是完成 SNTP 获取,设置到操作系统参数和 RTC 设置中,就可以不断地获取时间了。
640 (2).jpg

' w: ~' C2 Q2 @
可以看到时间显示出来了。但这里需要注意一个“坑”,就是发现时间好像和计算机显示的时间对不上,因为这个时间与UTC时间在不同时区,随即找到以下程序,
  1. /* EPOCH_TIME_DIFF is equivalent to 70 years in sec# ]6 p# s8 t1 ~9 k* W# t2 P. E
  2. calculated with www.epochconverter.com/date-difference; P$ U  n7 R* d6 l. s
  3. This constant is used to delete difference between :* v. m" V0 Z) F
  4. Epoch converter (referenced to 1970) and SNTP (referenced to 1900) */
    6 V8 d6 Z6 N4 a* ]* g+ d" K
  5. time_t timestamp = client_ptr->nx_sntp_current_server_time_message.receive_time.seconds - EPOCH_TIME_DIFF;
复制代码

9 {0 _" \- M: l+ V; \
将程序修改成:
  1. /* EPOCH_TIME_DIFF is equivalent to 70 years in sec
    * O: ?1 x) j: \! D
  2. calculated with www.epochconverter.com/date-difference- b9 p; ^8 |" C& R3 z8 T, F5 M
  3. This constant is used to delete difference between :0 b& m0 d5 J2 Y
  4. Epoch converter (referenced to 1970) and SNTP (referenced to 1900) */
    1 o' c9 a1 f2 k" Y( C9 B- f0 s) o
  5. time_t timestamp = client_ptr->nx_sntp_current_server_time_message.receive_time.seconds - EPOCH_TIME_DIFF + 28800U;
复制代码
3 O4 A% b4 M+ f
这样转换成 UTC 0800 时区时间。
640 (3).jpg

  p% n7 w. |7 h
后记:这个程序经长达3小时测试,未发现任何中断现象。反复的ping单片机地址,TTL 值一直很稳定,相比 lwIP 程序改善很多。

5 _; y# |4 L; y! R9 Q& H
7 W; |9 Y2 N6 Q: P+ z
来源:EEWORLD论坛网友 bigbat 版权归原作者所有
; A+ D5 W+ k' H: [3 e0 x
/ z% a3 O- p- Y' M
收藏 评论0 发布时间:2023-9-11 12:52

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版