我的项目在以前的应用主要是 FreeRTOS+lwIP 的组合,这个组合能用但不好用,其中问题也较多。例如,断线重连问题,从检测到重连的时间较长,往往中断50秒或更久,希望找到一个靠谱的 TCP/IP 协议栈。STM32H563ZI 板卡有 ThreadX 和 NETX 的组合支持,我们一起来测试一下。 首先从已有例程开始,选择 Nx_SNTP_Client,该例程是 NTP 服务器对时的应用。这个应用非常实用,在与实时时钟的相关应用中,多数都需要校时任务。首先打开 Nx_SNTP_Client.ioc 文件。 可以看到应用支持,ThreadX 和 NETX 的应用,应用层支持 DNS 和 SNTP 应用,相比以前使用过lwIP的DNS,步骤简洁很多。底层支持 DHCP、ICMP、TCP,比 lwIP 的 DHCP 稳定快捷,lwIP 的 DHCP 应用有时会出现长时间无法获得IP、需不停检测和重试的情况。硬件接口设置就很简单了接口选 RMII,PHY 设置 LAN8742,MAC 地址 00:80:E1:00:00:00 (这是测试地址,应用中最好修改一下)硬件开启全局中断。还有串口设置,还有 printf 设置,注意编译时选择 microLIB 库,要不无法收到串口信息。下面来分析应用,Main.C 基本上不需要动,主要是硬件程序化和 MX_ThreadX_Init() 函数。- ' v2 u* M5 Q, }9 w; v9 g
- /**
1 S& F1 R) m) w4 g. w {$ g - * @brief The application entry point." ^5 j: s9 L& G) L! Z
- * @retval int% [: L$ P! d# q- c) J
- */
, j* I5 R* R) w* S% C - int main(void). C* B. [1 s5 [( c
- {
2 c5 o2 l) m. A# n' Z - /* USER CODE BEGIN 1 */
@; Q8 l' Q& Z6 R# m# p - /* USER CODE END 1 */2 [. Q5 ^, m& ~/ R, a: x, I8 C
- /* MCU Configuration--------------------------------------------------------*/2 M( t* S- a% g/ N: r2 }- w
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
q" z" _( g8 P# c2 j# f - HAL_Init();
# s. J% Z/ A, q - /* USER CODE BEGIN Init */
- n+ C# ^+ O4 z3 J$ i' ]' F3 u - /* USER CODE END Init */
: A0 D5 J) M, n7 }3 m9 @4 X' r - /* Configure the system clock */
2 U$ i% f# C" ]5 i# ? - SystemClock_Config();
4 B( F- F4 R F. C- o - /* USER CODE BEGIN SysInit *// ]; N, A) u) N8 } b; U* w6 B
- /* USER CODE END SysInit */
$ k+ R2 {* u' l* M2 V# h& e; K; g! ?% a - /* Initialize all configured peripherals */
# W0 I: u3 H3 U# ] - MX_GPIO_Init();
. u1 y/ E+ Q& k$ u" U - MX_ICACHE_Init();
/ c- ]5 T# G6 l, n - MX_ETH_Init();
/ m( p; A7 t" P+ Y3 B& d - MX_USART3_UART_Init();
7 g* r1 g q3 J2 x) a' Q0 s - MX_RTC_Init();
8 C! ^8 ]. P8 ~ R* ?6 R& o, _ - /* USER CODE BEGIN 2 */
3 Q3 |' J: D% s$ b" }# H% }2 @6 L - /* USER CODE END 2 */
. U- o. Q* V/ k - MX_ThreadX_Init();
! R7 n3 t% V% h' w; w1 U( s- G - /* We should never get here as control is now taken by the scheduler */
+ U; M9 K+ ]& R8 y- D - /* Infinite loop */; n/ O$ f8 p4 p/ \2 @9 A6 `' \
- /* USER CODE BEGIN WHILE *// u; h" L$ i" r" n4 M2 }
- while (1)# Q* \2 L4 x' G. \7 [ i
- {
* m1 m: n |* a4 {! @ - /* USER CODE END WHILE */
- ~8 r+ s6 y3 y1 W* r - /* USER CODE BEGIN 3 */
1 F Q/ @/ o; }5 o+ z6 | - }
\: V: Q' C3 k0 |0 _ G9 f - /* USER CODE END 3 */8 {8 | y' N, r' m z
- }
复制代码 可以看到程序非常简洁,微软的建议是将硬件的初始化尽可能的放在 main.C 中进行,这里放入 printf 的设置。不要放入太多的逻辑代码,应用的初始化尽可能在 tx_application_define 函数中进行。这里的初始化过程被封装到 status = MX_NetXDuo_Init(memory_ptr) 中了,在这个 MX_NetXDuo_Init 函数中在进行线程的初始化。主要有三个线程和一个回调函数。
/ |3 n; V9 z! y" P% v- /* Private function prototypes -----------------------------------------------*/. C4 d$ p$ n2 m& H5 M
- static VOID App_Main_Thread_Entry (ULONG thread_input);! g1 R" B6 i% i3 u, ?
- static VOID ip_address_change_notify_callback(NX_IP *ip_instance, VOID *ptr);5 T2 z2 ]! P6 E2 |, y. q( e
- /* USER CODE BEGIN PFP */( Q% P, B6 b6 B1 v6 f, P
- static VOID App_SNTP_Thread_Entry(ULONG thread_input);
9 J7 a# {5 U4 y - static VOID App_Link_Thread_Entry(ULONG thread_input);
复制代码 来源:EEWORLD论坛网友 bigbat 版权归原作者所有7 i) r0 f: P- V) y; H' h' p
- M( J5 @' X& a/ A8 _( k) c' L+ ] |