意法半导体公司提供了 ThreadX 的 NETX Duo 支持,且提供了样例程序,该程序支持SSL版本,而且是 TLS 1.2 的版本,目前大多数网站都是使用这个版本。开始计划的测试方法考虑过于简单,以为将 Nx_MQTT_Client 例程迁移到 H563ZI 上运用就可以了,但这个过程非常困难,原因是样例芯片是 STM32H573I 而非 STM32H563ZI,需要重新的设置,设置过程走了很多弯路。
3 S8 R7 j2 }% y. x
1、Cube生成的代码不全,需要自己写很多的代码才可以,主要是三个线程和一个主线程。app_azure_rtos.c 文件不要去动,注意:Cube的代码基本上没有锁死程序的代码;样例中的代码有 Error_Handler(); 的代码,这点需要注意。 f$ ?' a: W- r8 Y: ?5 p, [) N
2、主要 任务在 app_netxduo.c 中进行,主要线程有三个- TX_THREAD AppMQTTClientThread; //MQTT的工作线程
+ N- a @) y- v A5 _ - TX_THREAD AppSNTPThread;//SNTP的工作线程
& K! x, y- @0 z - TX_THREAD AppLinkThread;//网卡连接监控线程
复制代码
3 f3 y4 @6 H0 n- k( k Q这三个线程,其中 AppSNTPThread 线程完成后,启动 AppMQTTClientThread 线程,AppSNTPThread 工作异常,AppMQTTClientThread 不会启动。
8 |5 P6 d' S, |- z5 W. t9 i6 J
0 A& P7 F" j; [& q3 [' T
8 Y$ F* I8 y4 f/ x& u- /** @brief SNTP Client thread entry. I$ s) n/ c3 ~- ]8 K5 Q3 R
- * @param thread_input: ULONG user argument used by the thread entry, C$ ^2 V" X( j- y3 k+ U
- * @retval none
- f) J: o# r6 X. o# k- D - */& u3 C$ h9 v) D9 ?! M7 I, U
- static VOID App_SNTP_Thread_Entry(ULONG thread_input)
6 `" v( ?5 Y2 s" ] - {$ z& \# K& K7 p+ e
- UINT ret;
# {& U( x/ Z6 @0 P - ULONG fraction;+ M9 E D3 [6 M; Q; E
- ULONG events = 0;
$ H# N1 K9 p9 A' f - UINT server_status;5 X3 r9 L7 r4 _6 B
- NXD_ADDRESS sntp_server_ip;. o) `8 v: B3 s6 s& y
- 4 _0 r/ F$ }0 o
- sntp_server_ip.nxd_ip_version = 4;
3 m" b2 b1 j% q8 H' J
5 S8 e, @! n& c5 U2 O- /* Look up SNTP Server address. */
0 j1 V8 @8 @: W J* `; ` - ret = nx_dns_host_by_name_get(&DnsClient, (UCHAR *)SNTP_SERVER_NAME, &sntp_server_ip.nxd_ip_address.v4, DEFAULT_TIMEOUT);2 R, J# Z k4 W8 I. N
- B) g5 r& i! F- /* Check for error. */. k! ~7 Q' ~# o% ?: x* W
- if (ret != NX_SUCCESS)* P8 v; q! v# y
- {
Q5 w. f: {/ n - Error_Handler();
* s/ ^' o" K" u4 k& K - }
9 K1 [. F) r" W: |3 F8 p/ Q! w- h' }+ _
( l' d6 i$ u( l* c, `% v- /* Create the SNTP Client */
8 ?$ `4 b6 y4 e, U$ [6 u; o - ret = nx_sntp_client_create(&SntpClient, &NetXDuoEthIpInstance, 0, &NxAppPool, NULL, NULL, NULL);6 d. \* G; v( |/ h
- 8 ^# h- w$ B1 R) ]1 |/ X3 { l
- /* Check for error. */! t& m0 c# D( z6 C0 D, T
- if (ret != NX_SUCCESS)
# k; J* U1 j, z: U' P% v& S - {3 q4 i! x/ w/ Q# x7 P8 H+ p
- Error_Handler();. B6 G+ k' `9 x0 N3 v1 M# x
- }) o7 d/ A6 k1 m/ u4 D: b! ]
. q& J2 V7 D1 N- /* Setup time update callback function. */6 ~) v I. f9 C
- nx_sntp_client_set_time_update_notify(&SntpClient, time_update_callback);
, o; a3 F1 m; d5 v8 s- _4 L
- i# e, J( u8 R# u; `) w9 a$ W8 F; L- /* Use the IPv4 service to set up the Client and set the IPv4 SNTP server. */1 H2 Y7 C4 `6 E8 k+ b7 e. o8 H: C' ]
- ret = nx_sntp_client_initialize_unicast(&SntpClient, sntp_server_ip.nxd_ip_address.v4);) ]: F1 t8 k% x( R) P3 `
2 k+ R+ B D0 M/ V- if (ret != NX_SUCCESS)0 i; Z* G. ]: L( R- Z( e$ u
- {
# z. y9 ^) I7 F# h$ W - Error_Handler();
) g0 W8 z/ I8 g [/ D - }2 o9 U3 C" a! U( F; ^7 u
+ h! j6 s2 f9 K* Q$ M* h$ }- /* Run whichever service the client is configured for. */, f: n& ^# T+ h+ f! m* f% \) w
- ret = nx_sntp_client_run_unicast(&SntpClient);, Z9 {* r6 `: [8 [7 Y2 J/ N
& P, C+ ^/ `5 Q2 ?$ T ?- W1 \- if (ret != NX_SUCCESS)
% x8 k8 d# X2 y3 r1 W - {) h9 F% X) Z8 O9 ?' z$ ]
- Error_Handler();
+ p0 C. U% x0 ^ - }" B+ U& A& E; t3 C, a- A
* Z9 E% M) {" d0 X- /* Wait for a server update event. */
/ z! c1 q5 X. S - tx_event_flags_get(&SntpFlags, SNTP_UPDATE_EVENT, TX_OR_CLEAR, &events, PERIODIC_CHECK_INTERVAL);
) b" o3 Y; k9 n2 c" U - 4 M5 u8 x' u- m( |
- if (events == SNTP_UPDATE_EVENT)
1 i! d# M& _4 d: G5 O; t: K9 k - {7 u2 w, B- E! |( Y- }/ ~* T
- /* Check for valid SNTP server status. */, S+ T6 l% h* m& H3 d7 s$ ^1 ?! |# u
- ret = nx_sntp_client_receiving_updates(&SntpClient, &server_status);) _( a& n1 `. U y0 N9 m' f
0 ?! ^+ W$ h9 Q+ W* t7 d- if ((ret != NX_SUCCESS) || (server_status == NX_FALSE))6 c3 ^) }' ~" C' R8 U# F
- {
& l$ |* U3 Y2 ^- q - /* We do not have a valid update. */
( k' e0 f, ~8 }6 Z* E. z - Error_Handler();( h) A) Z2 E, m* r7 y! o
- }& v/ I) d# W& r
- /* We have a valid update. Get the SNTP Client time. */
8 \# Z; g; D& b% t3 {- Q4 B - ret = nx_sntp_client_get_local_time_extended(&SntpClient, ¤t_time, &fraction, NX_NULL, 0);
' [6 ^/ C8 G3 s6 C. U$ e# p" ?& V
+ h& i9 ~& F \! p5 y- /* take off 70 years difference */
2 x K0 R: J6 V - current_time -= EPOCH_TIME_DIFF;- J* b/ E9 }1 C+ e7 w/ j, k
5 C% H- l7 K, R6 M( J) ~- }
$ @- f$ T, L# n - else
' V2 K; U! N$ ?1 x - {
4 @9 e5 [( a4 ~3 K& z3 I - //一旦服务异常就锁死程序,所以需要除去错误处理- M' U- Q' m, k3 |( D4 e
- //Error_Handler();2 _2 b8 s7 o G; j
- }
1 {' w& R6 x9 u+ |& i1 P
, v/ s0 S2 b9 M O) X! {8 `* |* W- /* start the MQTT client thread */
3 v$ t6 W' O! y7 V' J2 @: f - //如果出错就不会启动MQTT线程
4 D9 W" f$ r! i! j3 v; q' B5 a8 @ - tx_thread_resume(&AppMQTTClientThread);
# M# t: g- e. F# Z$ G
7 K1 R( [4 ~( F" d7 h- }
复制代码 这个关系很重要,经过很长时间的调试才找到这个坑。3、SSL证书的生成,在 readme.html 文档中有说明。
2 S' n4 N, h p5 G- Notes& h+ U# Q! K% d8 S( Q( [
- To make an encrypted connection with MQTT server, user should follow these steps to add an x509 certificate to the mqtt_client and use it to ensure server’s authentication :7 ]- Y" I6 a. o5 s& w, b
- download certificate authority CA (in this application “mosquitto.org.der” downloaded from test.mosquitto# K! z G( V* D0 _6 h% q {
- 0 I0 f' v2 \" v+ T& q
- convert certificate downloaded by executing the following cmd from the file downloaded path :6 z2 J0 _* @* X
3 U- ^6 Y# G. R% ~& m: I" Q- xxd.exe -i mosquitto.org.der > mosquitto.cert.h
j, H9 v$ T8 o. g6 W* m - add the converted file under the application : NetXDuo/Nx_MQTT_Client/NetXDuo/App
$ E0 P9 D$ J& g' g! L
, p7 Z/ k, ? Z- configure MOSQUITTO_CERT_FILE with your certificate name.
复制代码 xxd.exe 工具是一个 linux 工具,有 windows 版本。证书可以从 mosquitto.org 下载,按照说明操作可以得到证书。& z" @8 d+ t# H8 n- c
5 X4 M2 c5 l/ A! E: y0 d: u6 a
* v% p" \4 `. o2 w. I. ~
1 G9 J' O: f/ C$ m h4 i. f生成的文件 mosquitto.cert.h 拷贝到 app_netxduo.c 所在的目录。; s2 o" o0 {8 m* C# V
7 K. F$ G( H( |0 [; K
4、将例程中的 app_netxduo.c 和 app_netxduo.h 文件的主要函数复制到目标文件中,需要做些改动,注释掉错误处理。- if (events == SNTP_UPDATE_EVENT)
0 |- z9 ^1 i M0 T7 z7 V; ~% V - {
' G2 {( r: s, I: |7 W - /* Check for valid SNTP server status. */
0 q7 h: O J* Q R( w - ret = nx_sntp_client_receiving_updates(&SntpClient, &server_status);
1 P: [0 E7 G! e u- I0 F5 R( N7 } - ) C7 v; O. Z+ c0 t+ r
- if ((ret != NX_SUCCESS) || (server_status == NX_FALSE))1 @8 l o8 h% X* w1 v! P* R
- {
; D1 d' f4 P8 Q1 _; K2 {8 g - /* We do not have a valid update. */6 e" B4 a2 z! F+ W7 P
- Error_Handler();% C( O, O) ^ i0 @" p, S* c
- }% g0 z; x1 f2 ?) B8 w" n
- /* We have a valid update. Get the SNTP Client time. */
1 J7 H5 e5 K; v6 N g$ V( h - ret = nx_sntp_client_get_local_time_extended(&SntpClient, ¤t_time, &fraction, NX_NULL, 0);
# q/ w* E9 Z( `
4 V& H. A' L0 X3 F7 P$ O- I- /* take off 70 years difference */' \+ t+ l# E2 K3 d9 {6 ]
- current_time -= EPOCH_TIME_DIFF;8 I( Y& l6 r$ `6 v7 }7 _
& V, B6 g ?9 {9 v6 Y7 \/ ^9 x- }
2 M" E: e7 N! F" r - else
- G( R2 t1 L6 A' q( K - {9 i3 v% z6 o& T+ K
- //Error_Handler();$ w! A7 Y, D! N+ h. q
- }
复制代码 5、编译程序运行。可以看到已经连接到了测试 MQTT 服务器了。
) _$ Z$ m" k) W# `, e7 \# m
8 Q* O( K# L9 ?# M: _7 y
0 s/ t4 L+ j/ ]8 Y2 \ D7 r- W N9 R" C5 E5 L$ z9 `$ J9 p1 T
来源:EEWORLD论坛网友 bigbat 版权归原作者所有4 G/ I9 w# E+ U, a, h3 Z
# S# |3 z7 c3 S
$ y' Z# t% L0 G& Z- ~; Y
7 q3 u8 a( z( T3 r0 B' o1 d1 } |