【STM32F429】第11章 ThreadX NetXDUO之UDP客戶端/伺服器
最新教程下載:http://www.armbbs.cn/forum.php?mod=viewthread&tid=104619
第11章 ThreadX NetXDUO之UDP客戶端/伺服器
本章節為大家講解NetXDUO的UDP客戶端實現,學習本章節前,務必要優先學習第10章UDP傳輸控制協議基礎知識。有了這些基礎知識之後,再搞本章節會有事半功倍的效果。
11.1 初學者重要提示
11.2 UDP的API函式
11.3 UDP的實現方法
11.4 網路除錯助手和板子的除錯操作步驟
11.5 實驗例程說明
11.6 總結
11.1 初學者重要提示
1、 學習本章節前,務必保證已經學習了第10章的基礎知識。
2、 本章要掌握的函式稍多,可以先學會基本的使用,然後再深入瞭解這些函式使用時的注意事項,爭取達到熟練使用。
3、 ThreadX NetXDUO的UDP Socket資料包申請和釋放問題
- 函式nx_udp_socket_receive 會申請一個NX_PACKET資料包用於接收,如果使用者不使用了必須使用函式nx_packet_release釋放。
- 使用函式nx_udp_socket_send必須有申請好的NX_PACKET資料包,可以使用函式nx_packet_allocate申請,也可以使用nx_udp_socket_receive申請的。
特別要注意的地方來了,函式nx_udp_socket_send呼叫後會釋放nx_packet_allocate或者nx_udp_socket_receive申請的資料包。無需使用者再去呼叫函式nx_packet_release釋放。
11.2 UDP的API函式
11.2.1 函式nx_system_initialize
函式原型:
VOID nx_system_initialize(VOID);
函式描述:
NetXDUO初始化,所有其它功能呼叫之前必須優先呼叫此函式。
11.2.2 函式nx_packet_pool_create
函式原型:
UINT nx_packet_pool_create( NX_PACKET_POOL *pool_ptr, CHAR *name, ULONG payload_size, VOID*memory_ptr, ULONG memory_size);
函式描述:
此函式用於資料包記憶體池建立
函式引數:
- 第1個引數是記憶體池控制塊的地址。
- 第2個引數是記憶體池名字。
- 第3個引數是記憶體池中每個資料包的位元組數。 此值必須至少為 40 個位元組,並且還必須可以被 4 整除。
- 第4個引數是記憶體池中資料地址,此地址必須ULONG對齊。
- 第5個引數是記憶體池大小。
- 返回值:
- NX_SUCCESS:(0x00) 建立記憶體池成功。
- NX_PTR_ERROR:(0x07) 第1個引數地址無效。
- NX_SIZE_ERROR:(0x09) 第5個引數記憶體池大小無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
使用舉例:
/* 建立記憶體池 */ status = nx_packet_pool_create(&pool_0, /* 記憶體池控制塊 */ "NetX Main Packet Pool",/* 記憶體池名 */ 1536, /* 記憶體池每個資料包大小,單位位元組此值必須至少為 40 個位元組,並且還必須可以被 4 整除 */ (ULONG*)(((int)packet_pool_area + 15) & ~15) ,/* 記憶體池地址,此地址必須ULONG對齊 */ NX_PACKET_POOL_SIZE); /* 記憶體池大小 */
11.2.3 函式nx_ip_create
函式原型:
UINT nx_ip_create( NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask, NX_PACKET_POOL *default_pool, VOID (*ip_network_driver)(NX_IP_DRIVER *), VOID *memory_ptr, ULONG memory_size, UINT priority);
函式描述:
此函式使用使用者提供的 IP 地址,資料包記憶體記憶體池和網路驅動程式建立 IP 例項。注意,直到 IP任務執行之後,才會呼叫網路驅動。
函式引數:
- 第1個引數是建立IP例項的控制塊指標。
- 第2個引數是IP例項的名字。
- 第3個引數是IP地址。
- 第4個引數是子網掩碼
- 第5個引數是記憶體池地址。
- 第6個引數是網絡卡驅動地址。
- 第7個引數是IP任務棧地址
- 第8個引數是IP任務棧大小,單位位元組。
- 第9個引數是IP任務優先順序。
- 返回值
- NX_SUCCESS:(0x00) 建立 IP 例項成功。
- NX_NOT_IMPLEMENTED:(0x4A) 未正確配置 NetX Duo 庫。
- NX_PTR_ERROR:(0x07) IP控制塊地址、網路驅動函式指標、記憶體池地址或任務棧地址無效。
- NX_SIZE_ERROR:(0x09) 提供的任務棧大小太小。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_IP_ADDRESS_ERROR:(0x21) 提供的 IP 地址無效。
- NX_OPTION_ERROR:(0x21) 提供的 IP 任務優先順序無效。
使用舉例:
/* 例化IP */ status = nx_ip_create(&ip_0, /* IP例項控制塊 */ "NetX IP Instance 0", /* IP例項名 */ IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3), /* IP地址 */ 0xFFFFFF00UL, /* 子網掩碼 */ &pool_0, /* 記憶體池 */ nx_driver_stm32h7xx, /* 網絡卡驅動 */ (UCHAR*)AppTaskNetXStk, /* IP任務棧地址 */ sizeof(AppTaskNetXStk), /* IP任務棧大小,單位位元組 */ APP_CFG_TASK_NETX_PRIO); /* IP任務優先順序 */
11.2.4 函式nx_arp_enable
函式原型:
UINT nx_arp_enable( NX_IP *ip_ptr, VOID *arp_cache_memory, ULONG arp_cache_size);
函式描述:
此函式用於使能ARP地址解析。
函式引數:
- ip_ptr:IP例項地址。
- arp_cache_memory:ARP快取地址。
- arp_cache_size:每個 ARP 條目均為 52 個位元組,因此,ARP 條目總數是52位元組整數倍。
- 返回值
- NX_SUCCESS:(0x00) 啟用 ARP 成功。
- NX_PTR_ERROR:(0x07) IP例項地址或ARP快取地址無效。
- NX_SIZE_ERROR:(0x09) 使用者提供的 ARP 快取記憶體太小。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_ALREADY_ENABLED:(0x15) 此元件已啟用。
使用舉例:
int32_t tcp_sock; tcp_sock = netTCP_GetSocket (tcp_cb_server); if (tcp_sock > 0) { res = netTCP_Listen (tcp_sock, PORT_NUM); } if(netTCP_SendReady(tcp_sock) == true ) { }
11.2.5 函式nx_ip_fragment_enable
函式原型:
UINT nx_ip_fragment_enable(NX_IP *ip_ptr);
函式描述:
此函式用於啟用 IPv4 和 IPv6 資料包分段和重組功能。建立 IP 任務時,此服務會自動禁用。
函式引數:
- 第1個引數是IP例項地址。
- 返回值
- NX_SUCCESS:(0x00) 啟用 IP 分段成功。
- NX_PTR_ERROR:(0x07) IP 例項地址無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_NOT_ENABLED:(0x14) IP 分段功能未編譯到 NetX Duo 中。
使用舉例:
/* 使能fragment */ status = nx_ip_fragment_enable(&ip_0);
11.2.6 函式nx_udp_enable
函式原型:
UINT nx_udp_enable(NX_IP *ip_ptr);
函式描述:
此函式用於使能UDP元件。
函式引數:
- 第1個引數是IP例項地址。
- 返回值
- NX_SUCCESS:(0x00) 啟用 UDP 成功。
- NX_PTR_ERROR:(0x07) IP 指標無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_ALREADY_ENABLED:(0x15) 此元件已啟用。
使用舉例:
/* 使能UDP */ status = nx_udp_enable(&ip_0);
11.2.7 函式nx_udp_socket_create
函式原型:
UINT nx_udp_socket_create( NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name, ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG queue_maximum);
函式描述:
此函式用於建立UDP Socket。
函式引數:
1、 第1個引數是IP例項指標。
2、 第2個引數是UDP Socket指標。
3、 第3個引數是UDP Socket名字。
4、 第4個引數是傳輸服務型別,支援的引數如下:
- NX_IP_NORMAL (0x00000000)
- NX_IP_MIN_DELAY (0x00100000)
- NX_IP_MAX_DATA (0x00080000)
- NX_IP_MAX_RELIABLE (0x00040000)
- NX_IP_MIN_COST (0x00020000)
5、 第5個引數是指定是否允許進行 IP 分段。 如果指定 NX_FRAGMENT_OKAY (0x0),則允許進行 IP 分段。如果指定 NX_DONT_FRAGMENT (0x4000),則會禁止進行 IP 分段。
6、 第6個引數是指定一個 8 位的值,用於定義此資料包在被丟棄之前可通過的路由器數目。 預設值由 NX_IP_TIME_TO_LIVE 指定。
7、 第7個引數是支援的UDP Socket報文最大數目。達到最大值後,接收到每個新資料包時,都會釋放最早的 UDP 資料包。
8、 返回值
- NX_SUCCESS:(0x00) 建立 UDP Socket成功。
- NX_OPTION_ERROR:(0x0A) 服務型別、分段或生存時間選項無效。
- NX_PTR_ERROR:(0x07) IP 或Socket指標無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_NOT_ENABLED (0x14) 尚未啟用此元件。
使用舉例:
/* 建立UDP socket */ ret = nx_udp_socket_create(&ip_0, /* IP例項控制塊 */ &UDPSocket, /* UDP控制塊 */ "UDP Server Socket", /* UDP名 */ NX_IP_NORMAL, /* IP服務型別 */ NX_FRAGMENT_OKAY, /* 使能IP分段 */ NX_IP_TIME_TO_LIVE, /*用於定義此資料包在被丟棄之前可通過的路由器數目 */ 512); /* 支援的報文數 */
11.2.8 函式nx_udp_socket_bind
函式原型:
UINT nx_udp_socket_bind( NX_UDP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
函式描述:
此函式用於為建立的UDP Socket繫結埠。如果設定的埠號還不可用,可以設定等待時間。
函式引數:
1、 第1個引數是UDP Socket指標。
2、 第2個引數是繫結的埠,範圍1 -65535。如果設定為NX_ANY_PORT(0x0000),則會搜尋一個可用埠號。
3、 第3個引數是埠號不可用時,等待時間定義:
- NX_NO_WAIT (0x00000000)
- NX_WAIT_FOREVER (0xFFFFFFFF)
- 等待時間:(0x00000001 到 0xFFFFFFFE),單位是ThreadX系統時鐘節拍。
4、 返回值
- NX_SUCCESS:(0x00) 繫結UDP Socket成功。
- NX_ALREADY_BOUND:(0x22) 此UDP Socket已與另一 UDP 埠繫結。
- NX_PORT_UNAVAILABLE:(0x23) 埠已與其他Socket繫結。
- NX_NO_FREE_PORTS:(0x45) 沒有可用的埠。
- NX_WAIT_ABORTED:(0x1A) 已通過呼叫 tx_thread_wait_abort 中止請求。
- NX_INVALID_PORT:(0x46) 埠無效。
- NX_PTR_ERROR:(0x07) Socket指標無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_NOT_ENABLED:(0x14) 此元件尚未啟用。
使用舉例:
/* UDP Socket繫結埠 */ ret = nx_udp_socket_bind(&UDPSocket, DEFAULT_PORT, TX_WAIT_FOREVER); if (ret != NX_SUCCESS) { Error_Handler(__FILE__, __LINE__); }
11.2.9 函式nx_packet_data_retrieve
函式原型:
UINT nx_packet_data_retrieve( NX_PACKET *packet_ptr, VOID *buffer_start, ULONG *bytes_copied);
函式描述:
此函式用於將提供的資料包中的資料複製到提供的緩衝區。複製的實際位元組數由形參bytes_copied 所指向的儲存單元返回。
注意,此函式不會更改該資料包的內部狀態。檢索的資料仍存在於該資料包中。
函式引數:
- 第1個引數是指向源資料包的指標
- 第2個引數是目的資料包的地址。
- 第3個引數是最終複製的位元組數儲存地址。
- 返回值,返回以下幾種狀態值:
- NX_SUCCESS:(0x00)複製資料包資料成功。
- NX_INVALID_PACKET:(0x12) 資料包無效。
- NX_PTR_ERROR:(0x07) 形參地址無效。
注意事項:
目標緩衝區的大小必須足以容納該資料包的內容。否則記憶體會損壞,導致不可預知的結果。
使用舉例:
/* 獲取客戶端發來的資料 */ nx_packet_data_retrieve(data_packet, /* 接收到的資料包 */ data_buffer, /* 解析出資料 */ &bytes_read); /* 資料大小 */
11.2.10 函式nx_packet_data_extract_offset
函式原型:
UINT nx_packet_data_extract_offset( NX_PACKET *packet_ptr, ULONG offset, VOID *buffer_start, ULONG buffer_length, ULONG *bytes_copied);
函式描述:
此函式將NetX Duo 資料包中的資料複製到指定緩衝區中,可以指定要複製的資料偏移位置。實際複製的位元組數在 bytes_copied 中返回。此函式不會從資料包中刪除資料,也不會調整前置指標或其他內部狀態資訊。
函式引數:
- 第1個引數是資料包指標。
- 第2個引數是資料包的偏移地址。
- 第3個引數是複製後要儲存的緩衝地址。
- 第4個引數是要複製的位元組數。
- 第5個引數是實際複製的位元組數
- 返回值,返回以下幾種狀態值:
- NX_SUCCESS:(0x00)複製資料包資料成功。
- NX_PACKET_OFFSET_ERROR (0x53)提供了無效的偏移值。
- NX_PTR_ERROR:(0x07) 形參地址無效。
注意事項:
目標緩衝區的大小必須足以容納該資料包的內容。否則記憶體會損壞,導致不可預知的結果。
使用舉例:
/* 將UDP資料包中的資料複製到緩衝data_buffer */ nx_packet_data_extract_offset(RecPacket, /* 資料包 */ 0, /* 資料包地址偏移 */ data_buffer, /* 目標緩衝 */ sizeof(data_buffer), /* 目標緩衝大小 */ &bytes_read); /* 資料複製的位元組數 */
11.2.11 函式nx_udp_socket_receive
函式原型:
UINT nx_udp_socket_receive( NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
函式描述:
此函式用於從指定的Socket接收UDP資料,如果指定的Socket上沒有已經排隊的資料,則呼叫方會根據提供的等待選項引數掛起。
函式引數:
1、 第1個引數是UDP Socket指標
2、 第2個引數是UDP資料包指標。
3、 第3個引數是Socket佇列上沒有資料時的處理:
- NX_NO_WAIT (0x00000000)。
- NX_WAIT_FOREVER (0xFFFFFFFF)。
- 以時鐘週期為單位的超時值(0x00000001 到 0xFFFFFFFE)。
4、 返回值:
- NX_SUCCESS:(0x00) 接收Socket資料成功。
- NX_NOT_BOUND:(0x24) Socket未繫結。
- NX_NO_PACKET:(0x01) 未收到任何資料。
- NX_WAIT_ABORTED:(0x1A) 通過呼叫 tx_thread_wait_abort 中止掛起。
- NX_PTR_ERROR:(0x07) Socket指標或返回資料包指標無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_NOT_ENABLED:(0x14) 此元件尚未啟用。
注意事項:
- 如果返回了 NX_SUCCESS,則應用程式負責:不再需要收到資料包時將其釋放。
使用舉例:
/* 接收資料 */ ret = nx_udp_socket_receive(&UDPSocket, &RecPacket, TX_WAIT_FOREVER);
11.2.12 函式nx_udp_socket_send
函式原型:
UINT nx_udp_socket_send( NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG ip_address, UINT port);
函式描述:
此函式用於UDP Socket資料傳送。注意,無論 UDP 資料報是否已成功傳送,此服務都會立即返回。。
函式引數:
- 第1個引數是UDP Socket控制代碼。
- 第2個引數是UDP資料包指標。
- 第3個引數是目標地址。
- 第4個引數是目標埠號,範圍1到65535。
- 返回值,返回以下幾種狀態值:
- NX_SUCCESS:(0x00) Socket傳送成功。
- NX_NOT_BOUND:(0x24) Socket未與任何埠繫結。
- NX_NO_INTERFACE_ADDRESS:(0x50) 找不到合適的傳出介面。
- NX_TX_QUEUE_DEPTH:(0x49) 已達到最大傳輸佇列深度。
- NX_OVERFLOW:(0x03) 資料包追加指標無效。
- NX_UNDERFLOW:(0x02) 資料包前置指標無效。
- NX_PTR_ERROR:(0x07) 套接字指標無效。
- NX_CALLER_ERROR:(0x11) 此服務的呼叫方無效。
- NX_NOT_ENABLED:(0x14) 此元件尚未啟用。
使用舉例:
/* 傳送資料包到UDP傳送端 */ ret = nx_udp_socket_send(&UDPSocket, TraPacket, source_ip_address, source_port);
11.2.13 函式nx_packet_release
函式原型:
UINT nx_packet_release(NX_PACKET *packet_ptr);
函式描述:
此函式用於釋放資料包,包括連結到指定資料包的任何其他資料包。如果有其他任務在等待這個資料包,則該任務會獲得該資料包並繼續執行。
函式引數:
- 第1個引數是資料包地址。
- 返回值,返回以下幾種狀態值:
- NX_SUCCESS:(0x00) 釋放資料包成功。
- NX_PTR_ERROR:(0x07) 資料包指標無效。
- NX_UNDERFLOW:(0x02) 預置指標小於有效負載開始位置。
- NX_OVERFLOW:(0x03) 追加指標大於有效負載結束位置。
注意事項:
應用程式必須防止多次釋放同一資料包,否則會導致不可預知的結果。
11.3 UDP的實現方法
11.3.1 NetXDUO初始化
建立UDP前,要初始化NetX,建立記憶體池,例化IP:
/* ********************************************************************************************************* * 函 數 名: NetXTest * 功能說明: TCPnet應用 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void NetXTest(void) { UINT status; UINT ret; ULONG socket_state; UINT old_priority; NX_PACKET *data_packet; ULONG bytes_read; ULONG peer_ip_address; ULONG peer_port; /* 初始化NetX */ nx_system_initialize(); /* 建立記憶體池 */ status = nx_packet_pool_create(&pool_0, /* 記憶體池控制塊 */ "NetX Main Packet Pool",/* 記憶體池名 */ 1536, /* 記憶體池每個資料包大小,單位位元組此值必須至少為 40 個位元組,並且還必須可以被 4 整除 */ (ULONG*)(((int)packet_pool_area + 15) & ~15) ,/* 記憶體池地址,此地址必須ULONG對齊 */ NX_PACKET_POOL_SIZE); /* 記憶體池大小 */ /* 檢測建立是否失敗 */ if (status) error_counter++; /* 例化IP */ status = nx_ip_create(&ip_0, /* IP例項控制塊 */ "NetX IP Instance 0", /* IP例項名 */ IP_ADDRESS(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3), /* IP地址 */ 0xFFFFFF00UL, /* 子網掩碼 */ &pool_0, /* 記憶體池 */ nx_driver_stm32h7xx, /* 網絡卡驅動 */ (UCHAR*)AppTaskNetXStk, /* IP任務棧地址 */ sizeof(AppTaskNetXStk), /* IP任務棧大小,單位位元組 */ APP_CFG_TASK_NETX_PRIO); /* IP任務優先順序 */ /* 檢測建立是否失敗 */ if (status) error_counter++; /* 使能ARP,並提供ARP快取 */ status = nx_arp_enable(&ip_0, /* IP例項控制塊 */ (void *)arp_space_area, /* ARP快取地址 */ sizeof(arp_space_area)); /* 每個 ARP 條目均為 52 個位元組,因此,ARP 條目總數是52位元組整數倍 */ /* 使能fragment */ status = nx_ip_fragment_enable(&ip_0); /* 檢測使能成功 */ if (status) error_counter++; /* 使能TCP */ status = nx_tcp_enable(&ip_0); /* 檢測使能成功 */ if (status) error_counter++; /* 使能UDP */ status = nx_udp_enable(&ip_0); /* 檢測使能成功 */ if (status) error_counter++; /* 使能ICMP */ status = nx_icmp_enable(&ip_0); /* 檢測使能成功 */ if (status) error_counter++; /* NETX初始化完畢後,重新設定優先順序 */ tx_thread_priority_change(netx_thread_ptr, APP_CFG_TASK_NETX_PRIO1, &old_priority); tx_thread_priority_change(&AppTaskNetXProTCB, APP_CFG_TASK_NetXPro_PRIO1, &old_priority); /* 省略 */ }
程式末尾務優先順序做了特別處理,建立的時候先設定為低優先順序,檢測到網線正常連線並初始了網路後將優先順序設定到正常水平。
11.3.2 UDP實現
下面是建立UDP:
/* ********************************************************************************************************* * 函 數 名: NetXTest * 功能說明: TCPnet應用 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void NetXTest(void) { /* 省略 */ /* 建立UDP socket */ ret = nx_udp_socket_create(&ip_0, /* IP例項控制塊 */ &UDPSocket, /* UDP控制塊 */ "UDP Server Socket", /* UDP名 */ NX_IP_NORMAL, /* IP服務型別 */ NX_FRAGMENT_OKAY, /* 使能IP分段 */ NX_IP_TIME_TO_LIVE, /* 用於定義此資料包在被丟棄之前可通過的路由器數目 */ 512); /* 支援的報文數 */ if (ret != NX_SUCCESS) { Error_Handler(__FILE__, __LINE__); } /* UDP Socket繫結埠 */ ret = nx_udp_socket_bind(&UDPSocket, DEFAULT_PORT, TX_WAIT_FOREVER); if (ret != NX_SUCCESS) { Error_Handler(__FILE__, __LINE__); } /* 省略 */ }
11.3.3 UDP迴環通訊實現
迴環的意思就是電腦端網路助手傳送資料給板子後,板子再將資料返回。為了方便大家使用,本例子將接收資料包和傳送資料包分別做了定義:
/* ********************************************************************************************************* * 函 數 名: NetXTest * 功能說明: TCPnet應用 * 形 參: 無 * 返 回 值: 無 ********************************************************************************************************* */ void NetXTest(void) { /* 省略 */ /* 接收資料 */ ret = nx_udp_socket_receive(&UDPSocket, &RecPacket, TX_WAIT_FOREVER); if (ret == NX_SUCCESS) { /* 將UDP資料包中的資料複製到緩衝data_buffer */ nx_packet_data_extract_offset(RecPacket, /* 資料包 */ 0, /* 資料包地址偏移 */ data_buffer, /* 目標緩衝 */ sizeof(data_buffer), /* 目標緩衝大小 */ &bytes_read); /* 資料複製的位元組數 */ /* 獲取遠端埠和IP */ nx_udp_source_extract(RecPacket, &source_ip_address, &source_port); /* 列印接收到資料 */ PRINT_DATA(source_ip_address, source_port, data_buffer); /* 釋放資料包 */ nx_packet_release(RecPacket); /* 申請傳送資料包 */ ret = nx_packet_allocate(&pool_0, &TraPacket, NX_UDP_PACKET, TX_WAIT_FOREVER); if (ret) { Error_Handler(__FILE__, __LINE__); } sprintf((char *)sendbuf, "sendbuf = %d\r\n", count++); /*將要傳送的資料附加到TraPacket */ ret = nx_packet_data_append(TraPacket, (VOID *)sendbuf, strlen((char *)sendbuf), &pool_0, TX_WAIT_FOREVER); if (ret) { Error_Handler(__FILE__, __LINE__); } /* 傳送資料包到UDP傳送端 */ ret = nx_udp_socket_send(&UDPSocket, TraPacket, source_ip_address, source_port); } } /* 省略 */ }
11.4 網路除錯助手和板子的除錯操作步驟
我們這裡使用下面這款除錯助手,當然,任何其它網路除錯助手均可,不限制:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=1568 。
11.4.1 測試使用的DM916X網口並注意跳線帽
測試時,網線要插到DM916X網口上:
特別注意此處跳線帽的位置,要短接PG11:
11.4.2 RJ45網路變壓器插座上綠燈和黃燈現象
各種網絡卡、交換機等網路裝置都不一樣,一般來講:綠燈分為亮或不亮(代表網路速度),黃燈分為閃爍或不閃爍(代表是否有資料收發)。
綠燈:長亮代表100M; 不亮代表10M。
黃燈:長亮代表無資料收發; 閃爍代表有資料收發。
也有些千兆網絡卡的燈以顏色區分,不亮代表10M / 綠色代表100M / 黃色代表1000M。現在10M的網路基本看不到了,如果一個燈長亮,基本可以說明100M網路或更高,而另一個燈時而閃爍,那代表有資料收發,具體要看網路裝置了。甚至有些低等網絡卡如TP-LINK,只有一個燈,亮代表連通,閃爍代表資料收發。
對於開發板上面的RJ45網路變壓器插座上面的燈而言,綠燈代表資料收發,長亮的話表示無資料收發,閃爍代表有資料收發。黃燈代表網路速度,長亮代表100M,不亮代表10M。
11.4.3 第1步,設定板子IP地址
我們這裡使用使用固定IP(或者說靜態IP一個意思),設定也比較省事。我們這裡以開發板和電腦直連的方式進行說明,即通過一根網線直接將開發板的網口和電腦端的網口連線起來即可。如果大家使用的是筆記本,強烈推薦測試期間將筆記本的WIFI網路禁止,各種代理軟體和虛擬網絡卡也暫時關閉。等測試完畢了再逐一開啟,檢視是否有問題。
對於固定IP方式,也可以接到路由器或者交換機上面測試,特別注意板子設定的IP地址不要跟路由器或者交換機上其它裝置的IP衝突了,測試階段還是建議採用電腦直連方式,跑通了再跑其它方式。
在檔案demo_dm9162_netx.h中設定IP地址,具體配置如下(大家更新自己的情況修改):
/* ********************************************************************************************************* * IP相關 ********************************************************************************************************* */ #define DEFAULT_PORT 1000 /* TCP伺服器監聽埠號 */ #define IP_ADDR0 192 #define IP_ADDR1 168 #define IP_ADDR2 28 #define IP_ADDR3 245
11.4.4 第2步,設定電腦IP地址
一定要將電腦端的IP地址設定到跟開發板在一個IP段,即都是192.168.28.X。第2步中已經將開發板的IP設定為192.168.28.245,我們這裡就將電腦的IP設定為192.168.28.221。我這裡是WIN7 64bit系統。
(1)右擊桌面上的“網路”圖示,選擇屬性。
(2)彈出的介面中選項“本地連線”
(3)選擇“屬性(P)”
(4)雙擊“Internet協議版本4(TCP/Ipv4)”選項。
(5)配置IP地址、子網掩碼和預設閘道器,DNS無需配置,記得點選確定
(6)點選了“確定”按鈕後,退回到之前的介面,這裡的“確定”按鈕不要忘了點選:
11.4.5 第3步,測試ping是否成功
下載例程到開發板,然後ping 192.168.28.245,檢視是否連線上。
(1)WIN+R組合鍵開啟“執行”視窗,輸入cmd。
(2)輸入ping 192.168.28.245後,回車,也是可以的。
收發相同,沒有資料丟失,說明ping命令也是成功的。
11.4.6 第5步,網路除錯助手建立UDP伺服器
- 開啟除錯助手,點選左上角建立伺服器:
- 彈出如下介面,指定IP設定為192.168.28.245,一定要跟第2步設定的板子端IP地址一致,埠號1000,最後點選確定:
- 建立後的介面效果如下:
11.4.7 第6步,連線板子端的UDP Socket
點選連線UDP Socket:
正常連線後效果:
11.4.8 第5步,UDP迴環測試
板子和網路除錯助手建立連線後就可以相互收發資料了。
板子端接收到字元做了個簡單的展示(波特率115200,資料位8,奇偶校驗位無,停止位1):
11.5 實驗例程
配套例子:
V6-2404_ThreadX NetXDUO UDP
實驗目的:
- 學習ThreadX NetXDUO UDP實現
實驗內容:
- 共建立瞭如下幾個任務,通過按下按鍵K1可以通過串列埠列印任務堆疊使用情況
======================================================
OS CPU Usage = 1.31%
=======================================================
任務優先順序 任務棧大小 當前使用棧 最大棧使用 任務名
Prio StackSize CurStack MaxStack Taskname
2 4092 303 459 App Task Start
30 1020 303 303 App Task STAT
31 1020 87 71 App Task IDLE
5 4092 311 551 App Msp Pro
7 4092 303 719 App Task UserIF
6 4092 255 359 App NETX Pro
3 4092 415 535 NetX IP Instance 0
0 1020 191 235 System Timer Thread
串列埠軟體可以使用SecureCRT或者H7-TOOL RTT檢視列印資訊。
App Task Start任務 :啟動任務,這裡用作BSP驅動包處理。
App Task MspPro任務 :訊息處理。
App Task UserIF任務 :按鍵訊息處理。
App Task COM任務 :這裡用作LED閃爍。
System Timer Thread任務:系統定時器任務
操作說明:
- 由於程式使用了DWT時鐘週期計數器,程式下載後,請將板子重新上電使用,防止DWT時鐘週期計數器沒有正常復位。
- NetX網路協議棧操作:
(1) 預設IP地址192.168.28.245,在demo_dm9162_netx.c開頭定義,使用者可根據需要修改。
(2) 可以在電腦端用網路除錯軟體建立TCP伺服器,埠號1001。
(3) 實現了一個簡單的迴環通訊,使用者使用上位機發送的資料,然後板子返回另外的資料。
串列埠列印資訊方式(AC5,AC6和IAR):
波特率 115200,資料位 8,奇偶校驗位無,停止位 1
11.6 總結
本章節就為大家講解這麼多,希望大家多做測試,爭取可以熟練掌握這些API函式的使用。
微信公眾號:armfly_com 安富萊論壇:www.armbbs.cn 安富萊淘寶:https://armfly.taobao.com