服务器显示rl112,【RL-TCPnet网络教程】第13章 RL-TCPnet之TCP服务器(下)
第13章??????RL-TCPnet之TCP服務器(下)
本章節為大家講解RL-TCPnet的TCP服務器實現,學習本章節前,務必要優先學習第12章TCP傳輸控制協議基礎知識。有了這些基礎知識之后,再搞本章節會有事半功倍的效果。
本章教程含STM32F407開發板和STM32F429開發板。
13.1?初學者重要提示
13.2 TCP服務器API函數
13.3 TCP配置說明(Net_Config.c)
13.4 TCP調試說明(Net_Debug.c)
13.5 TCP服務器的實現方法
13.6?網絡調試助手和板子的調試操作步驟
13.7?實驗例程說明(裸機)
13.8?實驗例程說明(RTX)
13.9??????總結
13.7實驗例程說明(裸機)
13.7.1STM32F407開發板實驗
?配套例子:
V5-1008_RL-TCPnet實驗_TCP服務器(裸機)
實驗目的:
1.學習RL-TCPnet的TCP服務器創建和數據收發。
實驗內容:
1.強烈推薦將網線接到路由器或者交換機上面測試,因為已經使能了DHCP,可以自動獲取IP地址。
2.創建了一個TCP
Server,而且使能了局域網域名NetBIOS,用戶只需在電腦端ping
armfly就可以獲得板子的IP地址,端口號1001。
3.用戶可以在電腦端用網絡調試軟件創建TCP
Client連接此服務器端。
4.按鍵K1按下,發送8字節的數據給TCPClient。
5.按鍵K2按下,發送1024字節的數據給TCPClient。
6.按鍵K3按下,發送5MB字節的數據給TCPClient。
實驗操作:
詳見本章節13.6小節。
配置向導文件設置(Net_Config.c):
詳見本章節13.3小節。
調試文件設置(Net_Debug.c):
詳見本章節13.4小節。
程序設計:
主函數初始化
在main.c文件實現:
int main (void)
{
bsp_Init();
TCPnetTest();
}
硬件外設初始化
硬件外設的初始化是在
bsp.c文件實現:
voidbsp_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitUart();
bsp_InitKey();
bsp_InitLed();
bsp_InitTimer();
}
RL-TCPnet功能測試
這里專門創建了一個app_tcpnet_lib.c文件用于RL-TCPnet功能的測試,主要功能是創建了一個TCP
Server。
#if 1
#define printf_debug printf
#else
#define printf_debug(...)
#endif
#definePORT_NUM
1001
uint8_tsocket_tcp;
U16 tcp_callback(U8 soc, U8 evt, U8 *ptr, U16
par)
{
char buf[50];
uint16_t i;
if (soc != socket_tcp)
{
return (0);
}
switch (evt)
{
case TCP_EVT_CONREQ:
sprintf(buf,"遠程客戶端請求連接IP:%d.%d.%d.%d", ptr[0],
ptr[1], ptr[2], ptr[3]);
printf_debug("IP:%s? port:%d\r\n", buf,
par);
return (1);
case TCP_EVT_ABORT:
break;
case TCP_EVT_CONNECT:
printf_debug("Socket isconnected to remote peer\r\n");
break;
case TCP_EVT_CLOSE:
printf_debug("Connection hasbeen closed\r\n");
break;
case TCP_EVT_ACK:
break;
case TCP_EVT_DATA:
printf_debug("Data length =%d\r\n", par);
for(i = 0; i < par; i++)
{
printf_debug("ptr[%d] =%d\r\n", i, ptr[i]);
}
break;
}
return (0);
}
uint8_tTCP_StatusCheck(void)
{
uint8_t res;
switch (tcp_get_state(socket_tcp))
{
case TCP_STATE_FREE:
case TCP_STATE_CLOSED:
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res= %d\r\n", res);
break;
case TCP_STATE_LISTEN:
break;
case TCP_STATE_CONNECT:
return (__TRUE);
default:
break;
}
return (__FALSE);
}
voidtcpnet_poll(void)
{
if(bsp_CheckTimer(0))
{
timer_tick ();
}
main_TcpNet ();
}
voidTCPnetTest(void)
{
int32_t ulCount;
uint8_t *sendbuf;
uint8_t tcp_status;
uint16_t maxlen;
uint8_t res;
uint8_t ucKeyCode;
init_TcpNet ();
socket_tcp = tcp_get_socket(TCP_TYPE_SERVER | TCP_TYPE_KEEP_ALIVE,
0, 10, tcp_callback);
if(socket_tcp != 0)
{
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res =%d\r\n", res);
}
bsp_StartAutoTimer(0, 100);
while (1)
{
tcpnet_poll();
tcp_status = TCP_StatusCheck();
ucKeyCode = bsp_GetKey();
if ((ucKeyCode
!=KEY_NONE)&&(tcp_status ==
__TRUE))
{
switch (ucKeyCode)
{
case
KEY_DOWN_K1:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 8;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen = tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='1';
sendbuf[1] ='2';
sendbuf[2] ='3';
sendbuf[3] ='4';
sendbuf[4] ='5';
sendbuf[5] ='6';
sendbuf[6] ='7';
sendbuf[7] ='8';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount > 0);
break;
case
KEY_DOWN_K2:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 1024;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount >
0);
break;
case
KEY_DOWN_K3:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 5*1024*1024;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount > 0);
break;
default:
break;
}
}
}
}
13.7.2STM32F429開發板實驗
配套例子:
V6-1008_RL-TCPnet實驗_TCP服務器(裸機)
實驗目的:
1.學習RL-TCPnet的TCP服務器創建和數據收發。
實驗內容:
1.強烈推薦將網線接到路由器或者交換機上面測試,因為已經使能了DHCP,可以自動獲取IP地址。
2.創建了一個TCP
Server,而且使能了局域網域名NetBIOS,用戶只需在電腦端ping
armfly就可以獲得板子的IP地址,端口號1001。
3.用戶可以在電腦端用網絡調試軟件創建TCP
Client連接此服務器端。
4.按鍵K1按下,發送8字節的數據給TCPClient。
5.按鍵K2按下,發送1024字節的數據給TCPClient。
6.按鍵K3按下,發送5MB字節的數據給TCPClient。
實驗操作:
詳見本章節13.6小節。
配置向導文件設置(Net_Config.c):
詳見本章節13.3小節。
調試文件設置(Net_Debug.c):
詳見本章節13.4小節。
程序設計:
主函數初始化
在main.c文件實現:
int main (void)
{
bsp_Init();
TCPnetTest();
}
硬件外設初始化
硬件外設的初始化是在
bsp.c文件實現:
voidbsp_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitUart();
bsp_InitKey();
bsp_InitLed();
bsp_InitTimer();
}
RL-TCPnet功能測試
這里專門創建了一個app_tcpnet_lib.c文件用于RL-TCPnet功能的測試,主要功能是創建了一個TCP
Server。
#if 1
#define printf_debug printf
#else
#define printf_debug(...)
#endif
#definePORT_NUM
1001
uint8_tsocket_tcp;
U16 tcp_callback(U8 soc, U8 evt, U8 *ptr, U16
par)
{
char buf[50];
uint16_t i;
if (soc != socket_tcp)
{
return (0);
}
switch (evt)
{
case TCP_EVT_CONREQ:
sprintf(buf, "遠程客戶端請求連接IP: %d.%d.%d.%d",
ptr[0],ptr[1], ptr[2], ptr[3]);
printf_debug("IP:%s? port:%d\r\n", buf,
par);
return (1);
case TCP_EVT_ABORT:
break;
case TCP_EVT_CONNECT:
printf_debug("Socket isconnected to remote peer\r\n");
break;
case TCP_EVT_CLOSE:
printf_debug("Connection hasbeen closed\r\n");
break;
case TCP_EVT_ACK:
break;
case TCP_EVT_DATA:
printf_debug("Data length =%d\r\n", par);
for(i = 0; i < par; i++)
{
printf_debug("ptr[%d] =%d\r\n", i, ptr[i]);
}
break;
}
return (0);
}
uint8_tTCP_StatusCheck(void)
{
uint8_t res;
switch (tcp_get_state(socket_tcp))
{
case TCP_STATE_FREE:
case TCP_STATE_CLOSED:
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res= %d\r\n", res);
break;
case TCP_STATE_LISTEN:
break;
case TCP_STATE_CONNECT:
return (__TRUE);
default:
break;
}
return (__FALSE);
}
voidtcpnet_poll(void)
{
if(bsp_CheckTimer(0))
{
timer_tick ();
}
main_TcpNet ();
}
voidTCPnetTest(void)
{
int32_t ulCount;
uint8_t *sendbuf;
uint8_t tcp_status;
uint16_t maxlen;
uint8_t res;
uint8_t ucKeyCode;
init_TcpNet ();
socket_tcp = tcp_get_socket(TCP_TYPE_SERVER | TCP_TYPE_KEEP_ALIVE,
0, 10, tcp_callback);
if(socket_tcp != 0)
{
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res =%d\r\n", res);
}
bsp_StartAutoTimer(0, 100);
while (1)
{
tcpnet_poll();
tcp_status = TCP_StatusCheck();
ucKeyCode = bsp_GetKey();
if ((ucKeyCode
!=KEY_NONE)&&(tcp_status ==
__TRUE))
{
switch (ucKeyCode)
{
case
KEY_DOWN_K1:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 8;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen = tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='1';
sendbuf[1] ='2';
sendbuf[2] ='3';
sendbuf[3] ='4';
sendbuf[4] ='5';
sendbuf[5] ='6';
sendbuf[6] ='7';
sendbuf[7] ='8';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount > 0);
break;
case
KEY_DOWN_K2:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 1024;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount >
0);
break;
case
KEY_DOWN_K3:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
ulCount = 5*1024*1024;
do
{
tcpnet_poll();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
ulCount -=maxlen;
if(ulCount <0)
{
maxlen =ulCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(ulCount > 0);
break;
default:
break;
}
}
}
}
13.8實驗例程說明(RTX)
13.8.1STM32F407開發板實驗
配套例子:
V5-1009_RL-TCPnet實驗_TCP服務器(RTX)
實驗目的:
1.學習RL-TCPnet的TCP服務器創建和數據收發。
實驗內容:
1.強烈推薦將網線接到路由器或者交換機上面測試,因為已經使能了DHCP,可以自動獲取IP地址。
2.創建了一個TCP
Server,而且使能了局域網域名NetBIOS,用戶只需在電腦端ping
armfly就可以獲得板子的IP地址,端口號1001。
3.用戶可以在電腦端用網絡調試軟件創建TCP
Client連接此服務器端。
4.按鍵K1按下,發送8字節的數據給TCPClient。
5.按鍵K2按下,發送1024字節的數據給TCPClient。
6.按鍵K3按下,發送5MB字節的數據給TCPClient。
實驗操作:
詳見本章節13.6小節。
配置向導文件設置(Net_Config.c):
詳見本章節13.3小節。
調試文件設置(Net_Debug.c):
詳見本章節13.4小節。
RTX配置:
RTX配置向導詳情如下:
Task
Configuration
(1)Number of concurrent running tasks
允許創建6個任務,實際創建了如下5個任務:
AppTaskUserIF任務 :按鍵消息處理。
AppTaskLED任務:LED閃爍。
AppTaskMsgPro任務 :按鍵檢測。
AppTaskTCPMain任務:RL-TCPnet測試任務。
AppTaskStart任務:啟動任務,也是最高優先級任務,這里實現RL-TCPnet的時間基準更新。
(2)Number of tasks with user-provided stack
創建的5個任務都是采用自定義堆棧方式。
(3)Run in privileged mode
設置任務運行在非特權級模式。
RTX任務調試信息:
程序設計:
任務棧大小分配:
staticuint64_t AppTaskUserIFStk[1024/8];
staticuint64_t
AppTaskLEDStk[1024/8];
staticuint64_t
AppTaskMsgProStk[1024/8];
staticuint64_t AppTaskTCPMainStk[2048/8];
staticuint64_t
AppTaskStartStk[1024/8];
將任務棧定義成uint64_t類型可以保證任務棧是8字節對齊的,8字節對齊的含義就是數組的首地址對8求余等于0。如果不做8字節對齊的話,部分C語言庫函數、浮點運算和uint64_t類型數據運算會出問題。
系統棧大小分配:
RTX初始化:
int main (void)
{
bsp_Init();
os_sys_init_user
(AppTaskStart,
5,
&AppTaskStartStk,
sizeof(AppTaskStartStk));
while(1);
}
硬件外設初始化
硬件外設的初始化是在
bsp.c文件實現:
voidbsp_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
bsp_InitDWT();
bsp_InitUart();
bsp_InitKey();
bsp_InitLed();
}
RTX任務創建:
static void AppTaskCreate (void)
{
HandleTaskUserIF=
os_tsk_create_user(AppTaskUserIF,
1,
&AppTaskUserIFStk,
sizeof(AppTaskUserIFStk));
HandleTaskLED
=os_tsk_create_user(AppTaskLED,
2,
&AppTaskLEDStk,
sizeof(AppTaskLEDStk));
HandleTaskMsgPro=
os_tsk_create_user(AppTaskMsgPro,
3,
&AppTaskMsgProStk,
sizeof(AppTaskMsgProStk));
HandleTaskTCPMain
=
os_tsk_create_user(AppTaskTCPMain,
4,
&AppTaskTCPMainStk,
sizeof(AppTaskTCPMainStk));
}
五個RTX任務的實現:
__task void AppTaskUserIF(void)
{
uint8_tucKeyCode;
while(1)
{
ucKeyCode= bsp_GetKey();
if(ucKeyCode != KEY_NONE)
{
switch(ucKeyCode)
{
caseKEY_DOWN_K1:
printf("K1鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit0被設置\r\n");
os_evt_set(KEY1_BIT0,
HandleTaskTCPMain);
break;
caseKEY_DOWN_K2:
printf("K2鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit1被設置\r\n");
os_evt_set(KEY2_BIT1, HandleTaskTCPMain);
break;
caseKEY_DOWN_K3:
printf("K3鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit2被設置\r\n");
os_evt_set(KEY3_BIT2, HandleTaskTCPMain);
break;
default:
break;
}
}
os_dly_wait(20);
}
}
__task void AppTaskLED(void)
{
constuint16_t usFrequency = 500;
os_itv_set(usFrequency);
while(1)
{
bsp_LedToggle(2);
os_itv_wait();
}
}
__task void AppTaskMsgPro(void)
{
while(1)
{
bsp_KeyScan();
os_dly_wait(10);
}
}
__task void AppTaskTCPMain(void)
{
while(1)
{
TCPnetTest();
}
}
__task void AppTaskStart(void)
{
init_TcpNet();
AppTaskCreate();
os_itv_set(100);
while(1)
{
os_itv_wait();
timer_tick();
}
}
RL-TCPnet功能測試
這里專門創建了一個app_tcpnet_lib.c文件用于RL-TCPnet功能的測試,主要功能是創建了一個TCP
Server。
#include"includes.h"
#if 1
#define printf_debug printf
#else
#define printf_debug(...)
#endif
#definePORT_NUM
1001
uint8_tsocket_tcp;
U16 tcp_callback(U8 soc, U8 evt, U8 *ptr, U16
par)
{
char buf[50];
uint16_t i;
if (soc != socket_tcp)
{
return (0);
}
switch (evt)
{
case TCP_EVT_CONREQ:
sprintf(buf, "遠程客戶端請求連接IP: %d.%d.%d.%d",
ptr[0],ptr[1], ptr[2], ptr[3]);
printf_debug("IP:%s? port:%d\r\n", buf,
par);
return (1);
case TCP_EVT_ABORT:
break;
case TCP_EVT_CONNECT:
printf_debug("Socket isconnected to remote peer\r\n");
break;
case TCP_EVT_CLOSE:
printf_debug("Connection hasbeen closed\r\n");
break;
case TCP_EVT_ACK:
break;
case TCP_EVT_DATA:
printf_debug("Data length =%d\r\n", par);
for(i = 0; i < par; i++)
{
printf_debug("ptr[%d] =%d\r\n", i, ptr[i]);
}
break;
}
return (0);
}
uint8_tTCP_StatusCheck(void)
{
uint8_t res;
switch (tcp_get_state(socket_tcp))
{
case TCP_STATE_FREE:
case TCP_STATE_CLOSED:
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res= %d\r\n", res);
break;
case TCP_STATE_LISTEN:
break;
case TCP_STATE_CONNECT:
return (__TRUE);
default:
break;
}
return (__FALSE);
}
voidTCPnetTest(void)
{
int32_t iCount;
uint8_t *sendbuf;
uint8_t tcp_status;
uint16_t maxlen;
uint8_t res;
OS_RESULT xResult;
const uint16_t usMaxBlockTime = 2;
socket_tcp = tcp_get_socket(TCP_TYPE_SERVER|TCP_TYPE_KEEP_ALIVE, 0,
10, tcp_callback);
if(socket_tcp != 0)
{
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res =%d\r\n", res);
}
while (1)
{
main_TcpNet();
tcp_status = TCP_StatusCheck();
if((os_evt_wait_or(0xFFFF,usMaxBlockTime) ==
OS_R_EVT)&&(tcp_status ==
__TRUE))
{
xResult = os_evt_get ();
switch (xResult)
{
case
KEY1_BIT0:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 8;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen =iCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='1';
sendbuf[1] ='2';
sendbuf[2] ='3';
sendbuf[3] ='4';
sendbuf[4] ='5';
sendbuf[5] ='6';
sendbuf[6] = '7';
sendbuf[7] ='8';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount > 0);
break;
case
KEY2_BIT1:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 1024;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen =iCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] = 'c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount >
0);
break;
case
KEY3_BIT2:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 5*1024*1024;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen= iCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount > 0);
break;
default:
break;
}
}
}
}
13.8.2STM32F429開發板實驗
配套例子:
V6-1009_RL-TCPnet實驗_TCP服務器(RTX)
實驗目的:
1.學習RL-TCPnet的TCP服務器創建和數據收發。
實驗內容:
1.強烈推薦將網線接到路由器或者交換機上面測試,因為已經使能了DHCP,可以自動獲取IP地址。
2.創建了一個TCP
Server,而且使能了局域網域名NetBIOS,用戶只需在電腦端ping
armfly就可以獲得板子的IP地址,端口號1001。
3.用戶可以在電腦端用網絡調試軟件創建TCP
Client連接此服務器端。
4.按鍵K1按下,發送8字節的數據給TCPClient。
5.按鍵K2按下,發送1024字節的數據給TCPClient。
6.按鍵K3按下,發送5MB字節的數據給TCPClient。
實驗操作:
詳見本章節13.6小節。
配置向導文件設置(Net_Config.c):
詳見本章節13.3小節。
調試文件設置(Net_Debug.c):
詳見本章節13.4小節。
RTX配置:
RTX配置向導詳情如下:
Task
Configuration
(1)Number of concurrent running tasks
允許創建6個任務,實際創建了如下5個任務:
AppTaskUserIF任務
:按鍵消息處理。
AppTaskLED任務:LED閃爍。
AppTaskMsgPro任務 :按鍵檢測。
AppTaskTCPMain任務:RL-TCPnet測試任務。
AppTaskStart任務:啟動任務,也是最高優先級任務,這里實現RL-TCPnet的時間基準更新。
(2)Number of tasks with user-provided stack
創建的5個任務都是采用自定義堆棧方式。
(3)Run in privileged mode
設置任務運行在非特權級模式。
RTX任務調試信息:
程序設計:
任務棧大小分配:
staticuint64_t AppTaskUserIFStk[1024/8];
staticuint64_t
AppTaskLEDStk[1024/8];
staticuint64_t
AppTaskMsgProStk[1024/8];
staticuint64_t AppTaskTCPMainStk[2048/8];
staticuint64_t
AppTaskStartStk[1024/8];
將任務棧定義成uint64_t類型可以保證任務棧是8字節對齊的,8字節對齊的含義就是數組的首地址對8求余等于0。如果不做8字節對齊的話,部分C語言庫函數、浮點運算和uint64_t類型數據運算會出問題。
系統棧大小分配:
RTX初始化:
int main (void)
{
bsp_Init();
os_sys_init_user
(AppTaskStart,
5,
&AppTaskStartStk,
sizeof(AppTaskStartStk));
while(1);
}
硬件外設初始化
硬件外設的初始化是在
bsp.c文件實現:
voidbsp_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
SystemCoreClockUpdate();
bsp_InitDWT();
bsp_InitUart();
bsp_InitKey();
bsp_InitExtIO();
bsp_InitLed();
}
RTX任務創建:
static void AppTaskCreate (void)
{
HandleTaskUserIF=
os_tsk_create_user(AppTaskUserIF,
1,
&AppTaskUserIFStk,
sizeof(AppTaskUserIFStk));
HandleTaskLED =os_tsk_create_user(AppTaskLED,
2,
&AppTaskLEDStk,
sizeof(AppTaskLEDStk));
HandleTaskMsgPro=
os_tsk_create_user(AppTaskMsgPro,
3,
&AppTaskMsgProStk,
sizeof(AppTaskMsgProStk));
HandleTaskTCPMain
=
os_tsk_create_user(AppTaskTCPMain,
4,
&AppTaskTCPMainStk,
sizeof(AppTaskTCPMainStk));
}
五個RTX任務的實現:
__task void AppTaskUserIF(void)
{
uint8_tucKeyCode;
while(1)
{
ucKeyCode= bsp_GetKey();
if(ucKeyCode != KEY_NONE)
{
switch(ucKeyCode)
{
caseKEY_DOWN_K1:
printf("K1鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit0被設置\r\n");
os_evt_set(KEY1_BIT0,
HandleTaskTCPMain);
break;
caseKEY_DOWN_K2:
printf("K2鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit1被設置\r\n");
os_evt_set(KEY2_BIT1, HandleTaskTCPMain);
break;
caseKEY_DOWN_K3:
printf("K3鍵按下,直接發送事件標志給任務AppTaskTCPMain,bit2被設置\r\n");
os_evt_set(KEY3_BIT2, HandleTaskTCPMain);
break;
default:
break;
}
}
os_dly_wait(20);
}
}
__task void AppTaskLED(void)
{
constuint16_t usFrequency = 500;
os_itv_set(usFrequency);
while(1)
{
bsp_LedToggle(2);
os_itv_wait();
}
}
__task void AppTaskMsgPro(void)
{
while(1)
{
bsp_KeyScan();
os_dly_wait(10);
}
}
__task void AppTaskTCPMain(void)
{
while(1)
{
TCPnetTest();
}
}
__task void AppTaskStart(void)
{
init_TcpNet();
AppTaskCreate();
os_itv_set(100);
while(1)
{
os_itv_wait();
timer_tick ();
}
}
RL-TCPnet功能測試
這里專門創建了一個app_tcpnet_lib.c文件用于RL-TCPnet功能的測試,主要功能是創建了一個TCP
Server。
#include"includes.h"
#if 1
#define printf_debug printf
#else
#define printf_debug(...)
#endif
#definePORT_NUM
1001
uint8_tsocket_tcp;
U16 tcp_callback(U8 soc, U8 evt, U8 *ptr, U16
par)
{
char buf[50];
uint16_t i;
if (soc != socket_tcp)
{
return (0);
}
switch (evt)
{
case TCP_EVT_CONREQ:
sprintf(buf, "遠程客戶端請求連接IP: %d.%d.%d.%d",
ptr[0],ptr[1], ptr[2], ptr[3]);
printf_debug("IP:%s? port:%d\r\n", buf,
par);
return (1);
case TCP_EVT_ABORT:
break;
case TCP_EVT_CONNECT:
printf_debug("Socket isconnected to remote peer\r\n");
break;
case TCP_EVT_CLOSE:
printf_debug("Connection hasbeen closed\r\n");
break;
case TCP_EVT_ACK:
break;
case TCP_EVT_DATA:
printf_debug("Data length =%d\r\n", par);
for(i = 0; i < par; i++)
{
printf_debug("ptr[%d] =%d\r\n", i, ptr[i]);
}
break;
}
return (0);
}
uint8_tTCP_StatusCheck(void)
{
uint8_t res;
switch (tcp_get_state(socket_tcp))
{
case TCP_STATE_FREE:
case TCP_STATE_CLOSED:
res = tcp_listen (socket_tcp,PORT_NUM);
printf_debug("tcp listen res= %d\r\n", res);
break;
case TCP_STATE_LISTEN:
break;
case TCP_STATE_CONNECT:
return (__TRUE);
default:
break;
}
return (__FALSE);
}
voidTCPnetTest(void)
{
int32_t iCount;
uint8_t *sendbuf;
uint8_t tcp_status;
uint16_t maxlen;
uint8_t res;
OS_RESULT xResult;
const uint16_t usMaxBlockTime = 2;
socket_tcp = tcp_get_socket(TCP_TYPE_SERVER|TCP_TYPE_KEEP_ALIVE, 0,
10, tcp_callback);
if(socket_tcp != 0)
{
res = tcp_listen (socket_tcp, PORT_NUM);
printf_debug("tcp listen res =%d\r\n", res);
}
while (1)
{
main_TcpNet();
tcp_status = TCP_StatusCheck();
if((os_evt_wait_or(0xFFFF,usMaxBlockTime) ==
OS_R_EVT)&&(tcp_status ==
__TRUE))
{
xResult = os_evt_get ();
switch (xResult)
{
case
KEY1_BIT0:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 8;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen =iCount + maxlen;
}
sendbuf= tcp_get_buf(maxlen);
sendbuf[0] ='1';
sendbuf[1] ='2';
sendbuf[2] ='3';
sendbuf[3] ='4';
sendbuf[4] ='5';
sendbuf[5] ='6';
sendbuf[6] ='7';
sendbuf[7] ='8';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount > 0);
break;
case
KEY2_BIT1:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 1024;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen = iCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount >
0);
break;
case
KEY3_BIT2:
printf_debug("tcp_get_state(socket_tcp)= %d\r\n",
tcp_get_state(socket_tcp));
iCount = 5*1024*1024;
do
{
main_TcpNet();
if (tcp_check_send(socket_tcp) == __TRUE)
{
maxlen =tcp_max_dsize (socket_tcp);
iCount -=maxlen;
if(iCount <0)
{
maxlen= iCount + maxlen;
}
sendbuf =tcp_get_buf(maxlen);
sendbuf[0] ='a';
sendbuf[1] ='b';
sendbuf[2] ='c';
sendbuf[3] ='d';
sendbuf[4] ='e';
sendbuf[5] ='f';
sendbuf[6] ='g';
sendbuf[7] ='h';
tcp_send(socket_tcp, sendbuf, maxlen);
}
}while(iCount > 0);
break;
default:
break;
}
}
}
}
13.9總結
本章節就為大家講解這么多,希望大家多做測試,爭取可以熟練掌握這些API函數的使用。
總結
以上是生活随笔為你收集整理的服务器显示rl112,【RL-TCPnet网络教程】第13章 RL-TCPnet之TCP服务器(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 裸服务器证书,使用SSH证书远程登陆你的
- 下一篇: STP文件服务器,综合监控stp服务器