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

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

[复制链接]
guoyuli 发布时间:2023-9-11 12:52
对我启发较大的是 App_Link_Thread_Entry 线程,这个线程会定期检测网络物理连接。- k9 r5 L( _4 W: [+ h5 ?4 G
接下来是 App_Main_Thread_Entry 线程,这个线程主要是完成联网的准备工作。还有就是对 App_Link_Thread_Entry 线程数据的初始化。

  1. 2 t7 }+ x8 S. x( E
  2. /* Exported macro ------------------------------------------------------------*/
    & Y9 W# G% Z, V2 ~0 b
  3. /* USER CODE BEGIN EM */
    7 s* v9 W3 p) c, z- o5 m% q: C2 I
  4. #define PRINT_IP_ADDRESS(addr)    do { \
    2 ~" C0 n- U2 L' G$ w* X1 ~
  5.              printf("STM32 %s: %lu.%lu.%lu.%lu \n", #addr, \
    + k9 `* Q9 S/ [7 R+ {% d
  6.              (addr >> 24) & 0xff,                          \
    3 c- w- p: V! K
  7.              (addr >> 16) & 0xff,                          \# U8 P, E( `5 V. ]9 N: z4 a) D
  8.              (addr >> 8) & 0xff,                           \( W0 D6 B+ P6 b* T% ~& ?% B
  9.              (addr & 0xff));                               \
    ) D$ p( Z' U2 J% a, M
  10.              } while(0)
复制代码

+ {! g/ C$ M% J; z
主要的工作线程是 App_SNTP_Thread_Entry,这个线程完成整个过程。
  1. /**! f" }* z7 `" N7 G
  2. * @brief  SNTP thread entry.
    . ^6 _9 p* `. P! P6 V# C0 S/ H
  3. * @param thread_input: ULONG user argument used by the thread entry
    7 W1 G4 O3 k% O7 }* Y  C$ ~
  4. * @retval none
    6 c  ~: H9 ^+ o- M- \0 P, B2 L# o
  5. */
      Y: O( M( V7 k, y
  6. /* Define the client thread.  */* m4 }0 r" c! N7 H8 l  b& U
  7. static void App_SNTP_Thread_Entry(ULONG info)
    / w  ]6 M! f& ~
  8. {
    3 R1 j5 f5 z4 |7 f! X" ?, @
  9.   UINT ret;
    3 x9 E5 j, l+ L% x7 \  K4 G1 j
  10.   RtcHandle.Instance = RTC;3 U$ |: E' D) I: \* \6 e0 N
  11.   ULONG  seconds, fraction;0 o& |5 W* r' C
  12.   ULONG  events = 0;6 ^" i4 y: ]* e- u! r0 |
  13.   UINT   server_status;
    - ?% w/ o, e' i5 ~2 j
  14.   NXD_ADDRESS sntp_server_ip;+ `4 h' X. Z5 M  ]5 {8 F
  15.   NX_PARAMETER_NOT_USED(info);
    $ v. K. m0 ~* |2 p- {8 S  U
  16.   sntp_server_ip.nxd_ip_version = 4;9 q# Q: n% O7 z1 q) ?! n
  17.   /* Create a DNS client */
    7 |' O9 u9 {( v+ u; z
  18.   ret = dns_create(&DnsClient);
    " N  r9 U# y6 f; v) p( j
  19.   if (ret != NX_SUCCESS)
    1 g# U6 A2 I: L  B3 K& P) c
  20.   {
    2 B' m1 F: n4 m, F
  21.     Error_Handler();& ]. c( e& I) y$ e$ z6 \+ T
  22.   }
    # v( t: k# ?8 r% L7 L
  23.   /* Look up SNTP Server address. */- A; o# h* n4 z; \
  24.   ret = nx_dns_host_by_name_get(&DnsClient, (UCHAR *)SNTP_SERVER_NAME," Q4 D# T% t0 J6 k9 g. p1 _
  25.                                 &sntp_server_ip.nxd_ip_address.v4, NX_APP_DEFAULT_TIMEOUT);* ^1 @% s1 a+ u2 s! r& D
  26.     /* Check for error. */
    ) {6 `1 ~* u% X2 g* Q. x
  27.   if (ret != NX_SUCCESS)
    # e5 d* C/ b# ?! v, ?+ q8 r
  28.   {
    6 v4 G5 K& M  v8 a7 U
  29.     Error_Handler();
      m: D) X, X7 q2 F) o
  30.   }4 y0 r3 c! y* m. B) q
  31.    /* Create the SNTP Client */$ B7 Z$ _; ]7 g2 o$ _
  32.   ret =  nx_sntp_client_create(&SntpClient, &NetXDuoEthIpInstance, iface_index, &NxAppPool, NULL, kiss_of_death_handler, NULL);* E- |& \! S# d( O
  33.   /* Check for error. */
    0 z, U4 L# z$ B
  34.   if (ret != NX_SUCCESS)
    7 {9 W1 `( |1 P# A# i8 A0 n
  35.   {
    & o' p) Q' Y0 i9 v# H- z
  36.     Error_Handler();
    ( t' F: R6 R7 d  C
  37.   }
    3 J, T. w- Q# I) _5 k( g
  38.   /* Setup time update callback function. */& c" B7 b- o$ }; c- A
  39.    nx_sntp_client_set_time_update_notify(&SntpClient, time_update_callback);
    ' U0 y: B. I- G/ ~: a( Z& M
  40.   /* Use the IPv4 service to set up the Client and set the IPv4 SNTP server. */6 s' r5 m9 N% n5 u
  41.   ret = nx_sntp_client_initialize_unicast(&SntpClient, sntp_server_ip.nxd_ip_address.v4);
      k: i4 `( j1 z' l% ]4 p
  42.   if (ret != NX_SUCCESS)& M7 }8 b8 M) j- o8 H2 v
  43.   {
    # W2 j/ y7 @7 u0 Q# J
  44.     Error_Handler();
      C) g4 t2 ~, s
  45.   }& u7 [( L! c# @! t5 j1 I* W7 K
  46.   /* Run whichever service the client is configured for. */
    2 y9 V' ?# V0 m% H& q( i
  47.   ret = nx_sntp_client_run_unicast(&SntpClient);4 ~5 k2 S5 N% `6 c- p% L
  48.   if (ret != NX_SUCCESS)
    + Y% d* \4 i) b# q: d* b
  49.   {
    7 u: @7 P5 |  {' Q% O) o
  50.     Error_Handler();
    ! \) q- i$ ]) L) E
  51.   }
    9 }# ~9 ]5 u) r' K( v7 D) `! Q  a  M! z. a
  52.   else4 d; [" p5 b: N- X
  53.   {
    ) [0 f, ?0 _$ x5 V
  54.     PRINT_CNX_SUCC();
    . e- F. q/ F; K$ T1 y' \
  55.   }; z' b  x, I, R0 ?( k: P
  56.   /* Wait for a server update event. */! R! Z2 ]1 L4 E: P: H
  57.   tx_event_flags_get(&SntpFlags, SNTP_UPDATE_EVENT, TX_OR_CLEAR, &events, PERIODIC_CHECK_INTERVAL);7 x( X# K9 R* m( p0 T
  58.   if (events == SNTP_UPDATE_EVENT)
    % m, M( Z1 A, e
  59.   {* d+ e  C" Z' h& O9 s
  60.     /* Check for valid SNTP server status. */
    ; q. f4 Q  r6 W% p& T
  61.     ret = nx_sntp_client_receiving_updates(&SntpClient, &server_status);
    ' [6 k: S0 f7 g% w  S
  62.     if ((ret != NX_SUCCESS) || (server_status == NX_FALSE))
    $ K  N( `5 |2 x0 C* `
  63.     {2 V/ J% M% g+ D3 b+ v, e; E
  64.       /* We do not have a valid update. */
    ' \$ a' U" \) l: Z9 w  O7 U9 W
  65.       Error_Handler();! M- S( F/ T* v5 u' [
  66.     }2 J) J" c& \& y/ L2 P
  67.     /* We have a valid update.  Get the SNTP Client time.  */
    ( Z! j! ~* L/ g, b7 m- N
  68.     ret = nx_sntp_client_get_local_time_extended(&SntpClient, &seconds, &fraction, NX_NULL, 0);
    6 J5 R- [8 A* V4 k/ K& J
  69.     ret = nx_sntp_client_utility_display_date_time(&SntpClient,buffer,64);
    . Y/ v/ W- f( t9 b5 G0 q
  70.     if (ret != NX_SUCCESS)
    , P" E; W7 t/ ]$ g
  71.     {0 n& Z" g9 l' P4 K0 Y: v# w
  72.       printf("Internal error with getting local time 0x%x\n", ret);
    ; F4 \  C9 }0 L" t! O3 _$ [" @: K
  73.       Error_Handler();
    8 L3 o$ A5 q7 f; j
  74.     }4 C, e  C3 X* Y  X' ~
  75.     else( ?: D4 c# E0 K
  76.     {
    0 y9 R0 P5 z1 Q5 q, e4 \
  77.       printf("\nSNTP update :\n");5 `* s7 W! n& \# [% `( n
  78.       printf("%s\n\n",buffer);" i; c; R, G$ l) H( f' Y
  79.     }+ l2 t$ y7 D. _7 v
  80.   }3 E* V# j6 D" [
  81.   else) {$ X1 J/ Y  a* b! {  O) z% m
  82.   {7 H# r: D. ~- X* y: p# m
  83.     Error_Handler();
    6 t1 B( \- i( K
  84.   }: _; Y% I* P& b/ q" X
  85.   /* Set Current time from SNTP TO RTC */& n, ^, m5 d* }* z+ b9 k. j8 h1 m
  86.   rtc_time_update(&SntpClient);
    % R+ ]; k# Q2 y) e. g* s1 T
  87.   /* We can stop the SNTP service if for example we think the SNTP server has stopped sending updates */
    0 t2 F2 ~! u) p4 d" v. z
  88.   ret = nx_sntp_client_stop(&SntpClient);
    : t3 v8 `& I, z; m
  89.   if (ret != NX_SUCCESS)& O7 j5 Y' G# y+ b9 L0 g8 ^, `! F
  90.   {$ g+ g! Y& }6 a' ]
  91.     Error_Handler();& K4 [/ N# D+ r$ B, Q- R
  92.   }
    7 I% y( U% |& Y$ T
  93.   /* When done with the SNTP Client, we delete it */  _! `6 w* H0 L% ?( }' L7 V, U
  94.   ret = nx_sntp_client_delete(&SntpClient);
    ) ~+ i5 a8 _2 D# J& Q/ \
  95.   if (ret != NX_SUCCESS)
    ( {6 k* A: b7 X+ r
  96.   {$ V! S$ s+ @, q9 R
  97.     Error_Handler();
    ' I5 R2 b5 I8 J, {4 E; o/ y( U
  98.   }  r; }! V. w2 I0 T; B1 I
  99.   /* Toggling LED after a success Time update */  T5 k5 d) ?& }/ |  o$ z4 a* @6 `* @
  100.   while(1)' L& H9 u8 h! Z: h
  101.   {
    ) Z( b& }& B6 A' E& x% Y4 P, W
  102.     /* Display RTC time each second  */9 z; Z  a2 H9 J
  103.     display_rtc_time(&RtcHandle);
    & K: T7 M: H5 s! b- N
  104.     HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    , Y' n' Z! q3 b' @5 M/ l& m
  105.     /* Delay for 1s */
    6 @) y; u& j& R
  106.     tx_thread_sleep(100);
    * P. c3 B1 K& t
  107.   }
    * y" g4 H) U" r9 @/ b4 P4 h
  108. }
复制代码

7 ^3 z/ s' v% X( t! {( E
这个程序目的是完成 SNTP 获取,设置到操作系统参数和 RTC 设置中,就可以不断地获取时间了。
640 (2).jpg

9 R  l# S7 G+ O! i) x: \& j
可以看到时间显示出来了。但这里需要注意一个“坑”,就是发现时间好像和计算机显示的时间对不上,因为这个时间与UTC时间在不同时区,随即找到以下程序,
  1. /* EPOCH_TIME_DIFF is equivalent to 70 years in sec
    % L/ S. Z2 |7 V8 n, [
  2. calculated with www.epochconverter.com/date-difference( E  e9 y) R0 a; Z8 v% C; K
  3. This constant is used to delete difference between :
    9 X2 B. M2 O. \
  4. Epoch converter (referenced to 1970) and SNTP (referenced to 1900) */5 A5 X+ y% X" z  z4 \
  5. time_t timestamp = client_ptr->nx_sntp_current_server_time_message.receive_time.seconds - EPOCH_TIME_DIFF;
复制代码
2 z  ~. ~, H- z8 C. \1 ]
将程序修改成:
  1. /* EPOCH_TIME_DIFF is equivalent to 70 years in sec
    # ^( b, S1 }2 {2 g* l, a
  2. calculated with www.epochconverter.com/date-difference
    0 f# c6 |6 |0 T, C
  3. This constant is used to delete difference between :0 \9 Y1 Z0 J$ x7 Z# H9 K
  4. Epoch converter (referenced to 1970) and SNTP (referenced to 1900) */
    6 G3 Z" F! w9 H' p) T" R
  5. time_t timestamp = client_ptr->nx_sntp_current_server_time_message.receive_time.seconds - EPOCH_TIME_DIFF + 28800U;
复制代码
1 K( v  F* m) ?. j* H- A2 O
这样转换成 UTC 0800 时区时间。
640 (3).jpg
' W- y3 T3 f) Z. |: u
后记:这个程序经长达3小时测试,未发现任何中断现象。反复的ping单片机地址,TTL 值一直很稳定,相比 lwIP 程序改善很多。

0 s6 B1 M8 ]/ d- S0 t( |+ _
- V/ Y& i, O2 ?8 _' s) M' I- J
来源:EEWORLD论坛网友 bigbat 版权归原作者所有

, [1 z4 O- l3 x2 y$ [- K- }& I
3 o$ S  C: G9 A: L* R) D
收藏 评论0 发布时间:2023-9-11 12:52

举报

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