我的项目在以前的应用主要是 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() 函数。- 9 ] E+ k0 A3 s9 V
- /**
) n1 D- A0 ]6 c- O2 N - * @brief The application entry point.. F/ Q* k r0 K
- * @retval int
) P3 t, e; B5 u+ P, u Q% } - */* Y' D7 o$ C3 K; D
- int main(void)
: z, M! e! L2 @7 r6 x - {
5 w B/ W! O: [7 q) q+ u1 a - /* USER CODE BEGIN 1 */- s* |+ ]1 n5 K# p! }/ F( i$ r
- /* USER CODE END 1 */
; z; p3 i x9 X! } - /* MCU Configuration--------------------------------------------------------*/+ d" y3 g4 A+ u3 O6 k
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
5 i- L0 W+ e: d( Q8 A - HAL_Init();
7 M& k" ~" k! ?' p0 |1 n) l/ W - /* USER CODE BEGIN Init */, T$ s' X2 \: b" g+ d
- /* USER CODE END Init */9 z$ b3 R$ z) v. Y4 a5 [# C0 \0 U7 W
- /* Configure the system clock */% Z" D/ v0 m) T O
- SystemClock_Config();+ N0 u4 c# [2 j' A, @7 {3 _
- /* USER CODE BEGIN SysInit */
* q- M$ D3 j% \ t2 [( f - /* USER CODE END SysInit */
3 |) {- g. o: A7 n! } - /* Initialize all configured peripherals */3 n! U' R9 i/ H$ w1 z; i/ ?
- MX_GPIO_Init();/ U8 D6 t" x# `( R$ L
- MX_ICACHE_Init();9 A( c* `- _( P- A) c7 s
- MX_ETH_Init();3 V0 t" ~! b; L- a9 a
- MX_USART3_UART_Init();
) Y; L% L2 W3 C- ?% j9 H - MX_RTC_Init();
6 b( P( s3 I3 w3 A! V4 _ - /* USER CODE BEGIN 2 */
# y5 |* x+ z c4 Z% z/ @% j6 H - /* USER CODE END 2 */1 G8 E( O9 B8 p* V" }3 P1 S
- MX_ThreadX_Init();( q9 I+ w$ j0 z9 i
- /* We should never get here as control is now taken by the scheduler */
7 e7 l. v. e2 u& X - /* Infinite loop */, z( m3 E& z. f6 G4 q- S
- /* USER CODE BEGIN WHILE */
3 _% Q9 j' n: v% N4 ` - while (1); ?$ m* z) w$ a6 \" Y% _5 a# i
- {' _( X7 m+ ]* S3 [
- /* USER CODE END WHILE */
+ _- h& Q i$ R - /* USER CODE BEGIN 3 */
1 S9 A3 F- L2 Q& s% a, F: a+ O - }- Z$ C9 l% f) N
- /* USER CODE END 3 */
9 }$ q' V+ E3 X+ x: O - }
复制代码 可以看到程序非常简洁,微软的建议是将硬件的初始化尽可能的放在 main.C 中进行,这里放入 printf 的设置。不要放入太多的逻辑代码,应用的初始化尽可能在 tx_application_define 函数中进行。这里的初始化过程被封装到 status = MX_NetXDuo_Init(memory_ptr) 中了,在这个 MX_NetXDuo_Init 函数中在进行线程的初始化。主要有三个线程和一个回调函数。
; ~8 D0 h8 Z0 D- /* Private function prototypes -----------------------------------------------*/3 B2 q8 t4 E) n) G" {* g
- static VOID App_Main_Thread_Entry (ULONG thread_input);
' j* k; ?5 r0 q0 O( r" \ - static VOID ip_address_change_notify_callback(NX_IP *ip_instance, VOID *ptr);& K6 ?7 o" r" O$ Z
- /* USER CODE BEGIN PFP */
! f. k. e& {; E2 c+ n - static VOID App_SNTP_Thread_Entry(ULONG thread_input);
5 U6 Q, P, ~0 r4 W, m% }2 h" y - static VOID App_Link_Thread_Entry(ULONG thread_input);
复制代码 来源:EEWORLD论坛网友 bigbat 版权归原作者所有5 A# T0 R/ R5 H: V4 U7 Q' ]/ S9 V# n. d+ L
: c" G5 L! k, }, J2 M0 {0 I2 l4 T3 a G |