• Home
Name Date Size #Lines LOC

..--

BUILD.gnD12-May-2024889 2521

README_zh.mdD12-May-202414.8 KiB480365

wifi_udp_example.cD12-May-202410.1 KiB311218

README_zh.md

1# 小凌派-RK2206开发板基础外设开发——wifi-udp通信
2
3本示例将演示如何在小凌派-RK2206开发板上使用wifi进行udp通信
4
5![小凌派-RK2206开发板](../../docs/figures/lockzhiner-rk2206.jpg)
6
7## WiFi ssid 和密码设置
8
9修改文件 ``device/soc/rockchip/rk2206/sdk_liteos/platform/network/config_network.c`` 中的SSID WiFi名称,PASSWORD WiFi密码 连接到与pc同一网络
10
11```c
12#define SSID                    "凌智电子"
13#define PASSWORD                "88888888"
14```
15
16确认main文件 ``device/soc/rockchip/rk2206/sdk_liteos/platform/main/main.c`` wifi功能已开启
17
18```c
19ExternalTaskConfigNetwork();
20```
21
22### 查看小凌派获取到的IP地址和网关
23
24图如下所示:
25![wifi ip地址](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp1.png)
26
27### 确认pc与小凌派在同一局域网,查看PC的IP地址和网关
28
29在控制台输入 ``ipconfig``
30图如下所示:
31![pc ip地址](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp2.png)
32网关都是 ``192.168.2.1``表示在同一局域网
33
34修改wifi_udp例程中 服务地址及端口号后重新编译烧录程序
35
36```c
37#define  OC_SERVER_IP      "192.168.2.49"   //pc IP地址 此地址为上一步查询到的地址每个人的地址可能不一样需要根据自己的修改
38#define  SERVER_PORT        6666            //端口号
39#define  CLIENT_LOCAL_PORT  8888
40```
41
42pc上打开两个网络调试工具一个客户端一个服务端,并设置IP地址和端口号
43![pc 网络调试工具](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp3.png)
44
45用网络调试助手点击启动客户端和服务端
46![网络调试工具 start](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp4.png)
47
48查看log 等待小凌派的udp客户端和服务端任务启动
49![udp start](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp5.png)
50
51修改网络调试工具字符集编码
52![网络调试工具字符集修改](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp6.png)
53
54然后就可以通过网络调试工具与小凌派通信了
55![网络调试工具 udp_msg](/vendor/lockzhiner/lingpi/docs/figures/wifi_udp/udp7.png)
56
57## 程序设计
58
59### API分析
60
61#### 头文件
62
63```c
64#include "lz_hardware.h"
65#include "config_network.h"
66#include "lwip/tcp.h"
67#include "lwip/ip_addr.h"
68#include "lwip/priv/tcp_priv.h"
69#include "lwip/stats.h"
70#include "lwip/inet_chksum.h"
71```
72
73#### socket()
74
75```c
76int socket(int domain, int type, int protocol);
77```
78
79**描述:**
80
81创建套接字
82**参数:**
83
84| 名字     | 描述                                              |
85| :------- | :------------------------------------------------ |
86| domai    | 协议类型,一般为AF_INET                           |
87| type     | socket类型                                        |
88| protocol | 用来指定socket所使用的传输协议编号,通常设为0即可 |
89
90**返回值:**
91
92返回大于0为成功,反之为失败
93
94#### bind()
95
96```c
97int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
98```
99
100**描述:**
101
102绑定地址端口号
103
104**参数:**
105
106| 名字    | 描述                                                         |
107| :------ | :----------------------------------------------------------- |
108| sockfd  | socket描述符                                                 |
109| my_addr | 是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针 |
110| addrlen | 常被设为sizeof(struct sockaddr)                              |
111
112**返回值:**
113
114返回大于0为成功,反之为失败
115
116#### connect()
117
118```c
119int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
120```
121
122**描述:**
123
124仅仅用于表示确定了另一方的地址
125
126**参数:**
127
128| 名字      | 描述                             |
129| :-------- | :------------------------------- |
130| sockfd    | 目的服务器的socket描述符         |
131| serv_addr | 包含目的机器ip地址和端口号的指针 |
132| addrlen   | sizeof(struct sockaddr)          |
133
134**返回值:**
135
136返回大于0为成功,反之为失败
137
138#### sendto()
139
140```c
141int sendto(int sockfd, const void *msg, int len, int flags, struct sockaddr * to int *tolen);
142```
143
144**描述:**
145
146发送消息
147
148**参数:**
149
150| 名字   | 描述                       |
151| :----- | :------------------------- |
152| sockfd | 用来传输数据的socket描述符 |
153| msg    | 要发送数据的指针           |
154| len    | 要发送的数据长度(字节)   |
155| flags  | 0                          |
156| to     | 目的socket描述符           |
157| tolen  | 目的socket描述符长度       |
158
159**返回值:**
160
161发送成功返回发送字节数,失败返回值小于0
162
163#### recvfrom()
164
165```c
166int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr * from int *fromlen);
167```
168
169**描述:**
170
171接收消息
172
173**参数:**
174
175| 名字    | 描述                   |
176| :------ | :--------------------- |
177| sockfd  | 接收数据的socket描述符 |
178| buf     | 存放数据的缓冲区       |
179| len     | 缓冲的长度(字节)     |
180| flags   | 0                      |
181| from    | 来自socket描述符       |
182| fromlen | 来自socket描述符长度   |
183
184**返回值:**
185
186接收成功返回大于0,失败返回值小于0
187
188#### lwip_close()
189
190```c
191int lwip_close(int sockfd);
192```
193
194**描述:**
195
196关闭套接字
197
198**参数:**
199
200| 名字   | 描述           |
201| :----- | :------------- |
202| sockfd | 要关闭的套接字 |
203
204**返回值:**
205
206发送成功返回发送字节数,失败返回值小于0
207
208### 主要代码分析
209
210创建客户端任务 socket-->connect-->send-->recv-->lwip_close
211
212```c
213int wifi_udp_client(void)
214{
215    int client_fd, ret;
216    struct sockaddr_in serv_addr, local_addr;
217
218    while(1)
219    {
220        client_fd = socket(AF_INET, SOCK_DGRAM, 0);//AF_INET:IPV4;SOCK_DGRAM:UDP
221        if (client_fd < 0)
222        {
223            printf("create socket fail!\n");
224            return -1;
225        }
226
227        /*设置调用close(socket)后,仍可继续重用该socket。调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。*/
228        int flag = 1;
229        ret = setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
230        if (ret != 0) {
231            printf("[CommInitUdpServer]setsockopt fail, ret[%d]!\n", ret);
232        }
233
234        memset(&local_addr, 0, sizeof(local_addr));
235        local_addr.sin_family = AF_INET;
236        local_addr.sin_addr.s_addr = wifiinfo.ipAddress;
237        local_addr.sin_port = htons(CLIENT_LOCAL_PORT);
238        //绑定本地ip端口号
239        ret = bind(client_fd, (struct sockaddr*)&local_addr, sizeof(local_addr));
240
241        memset(&serv_addr, 0, sizeof(serv_addr));
242        serv_addr.sin_family = AF_INET;
243        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
244        // serv_addr.sin_addr.s_addr = inet_addr(OC_SERVER_IP);  //指定ip接收
245        serv_addr.sin_port = htons(SERVER_PORT);
246
247        udp_client_msg_handle(client_fd, (struct sockaddr*)&serv_addr);
248
249        LOS_Msleep(1000);
250    }
251
252    return 0;
253}
254```
255
256连接服务端,并发送消息和接收消息
257
258```c
259void udp_client_msg_handle(int fd, struct sockaddr* dst)
260{
261    socklen_t len = sizeof(*dst);
262
263    struct sockaddr_in client_addr;
264    int cnt = 0,count = 0;
265    printf("[udp client] remote addr:%s port:%u\n", inet_ntoa(((struct sockaddr_in*)dst)->sin_addr), ntohs(((struct sockaddr_in*)dst)->sin_port));
266    connect(fd, dst, len);
267    getsockname(fd, (struct sockaddr*)&client_addr,&len);
268    printf("[udp client] local  addr:%s port:%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
269
270    while (1)
271    {
272        char buf[BUFF_LEN];
273        printf("[udp client]------------------------------------------------\n");
274        printf("[udp client] waitting server message!!!\n");
275        // count = recv(fd, buf, BUFF_LEN, 0);       //接收来自server的信息
276        count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&client_addr, &len);       //recvfrom是阻塞函数,没有数据就一直阻塞
277        if(count == -1)
278        {
279            printf("[udp client] No server message!!!\n");
280        }
281        else
282        {
283            printf("[udp client] remote addr:%s port:%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
284            printf("[udp client] rev:%s\n", buf);
285        }
286        memset(buf, 0, BUFF_LEN);
287        sprintf(buf, "UDP TEST cilent send:%d", ++cnt);
288        // count = send(fd, buf, strlen(buf), 0);                      //发送数据给server
289        count = sendto(fd, buf, strlen(buf), 0, (struct sockaddr*)&client_addr, len);        //发送信息给client
290        printf("[udp client] send:%s\n", buf);
291        printf("[udp client] client sendto msg to server %dbyte,waitting server respond msg!!!\n", count);
292
293        LOS_Msleep(100);
294    }
295    lwip_close(fd);
296}
297```
298
299创建服务端任务 socket-->bind-->listen-->accept-->recv-->send-->close
300
301```c
302int wifi_udp_server(void)
303{
304    int server_fd, ret;
305
306    while(1)
307    {
308        server_fd = socket(AF_INET, SOCK_DGRAM, 0); //AF_INET:IPV4;SOCK_DGRAM:UDP
309        if (server_fd < 0)
310        {
311            printf("create socket fail!\n");
312            return -1;
313        }
314
315        /*设置调用close(socket)后,仍可继续重用该socket。调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。*/
316        int flag = 1;
317        ret = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
318        if (ret != 0) {
319            printf("[CommInitUdpServer]setsockopt fail, ret[%d]!\n", ret);
320        }
321
322        struct sockaddr_in serv_addr = {0};
323        serv_addr.sin_family = AF_INET;
324        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址
325        // serv_addr.sin_addr.s_addr = wifiinfo.ipAddress;
326        serv_addr.sin_port = htons(SERVER_PORT);       //端口号,需要网络序转换
327        /* 绑定服务器地址结构 */
328        ret = bind(server_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
329        if (ret < 0)
330        {
331            printf("socket bind fail!\n");
332            lwip_close(server_fd);
333            return -1;
334        }
335        printf("[udp server] local  addr:%s,port:%u\n", inet_ntoa(wifiinfo.ipAddress), ntohs(serv_addr.sin_port));
336
337        udp_server_msg_handle(server_fd);   //处理接收到的数据
338        LOS_Msleep(1000);
339    }
340}
341```
342
343连接客户端,并发送消息和接收消息
344
345```c
346void udp_server_msg_handle(int fd)
347{
348    char buf[BUFF_LEN];  //接收缓冲区
349    socklen_t len;
350    int cnt = 0, count;
351    struct sockaddr_in client_addr = {0};
352    while (1)
353    {
354        memset(buf, 0, BUFF_LEN);
355        len = sizeof(client_addr);
356        printf("[udp server]------------------------------------------------\n");
357        printf("[udp server] waitting client msg\n");
358        count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&client_addr, &len);       //recvfrom是阻塞函数,没有数据就一直阻塞
359        if (count == -1)
360        {
361            printf("[udp server] recieve data fail!\n");
362            LOS_Msleep(3000);
363            break;
364        }
365        printf("[udp server] remote addr:%s port:%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
366        printf("[udp server] rev client msg:%s\n", buf);
367        memset(buf, 0, BUFF_LEN);
368        sprintf(buf, "I have recieved %d bytes data! recieved cnt:%d", count, ++cnt);
369        printf("[udp server] send msg:%s\n", buf);
370        sendto(fd, buf, strlen(buf), 0, (struct sockaddr*)&client_addr, len);        //发送信息给client
371    }
372    lwip_close(fd);
373}
374```
375
376## 编译调试
377
378### 修改 BUILD.gn 文件
379
380修改 `vendor/lockzhiner/lingpi/sample` 路径下 BUILD.gn 文件,指定 `b8_wifi_udp` 参与编译。
381
382```r
383"b8_wifi_udp",
384```
385
386在主目录下输入编译命令。
387
388```shell
389hb build -f
390```
391
392### 运行结果
393
394示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,串口显示如下:
395
396```c
397[MAIN:D]Main: enter ...
398entering kernel init...
399hilog will init.
400[IOT:D]IotInit: start ....
401[MAIN:D]Main: LOS_Start ...
402Entering scheduler
403[config_network:D]rknetwork SetApModeOff start ...
404
405[config_network:D]rknetwork AP is inactive
406
407[config_network:D]rknetwork SetApModeOff end ...
408
409hiview init success.[FLASH:I]FlashInit: blockSize 4096, blockStart 0, blockEnd 8388608
410[config_network:D]rknetwork SetWifiModeOn
411
412wifi_udp_example start ....
413[config_network:D]rknetwork g_wificonfig.ssid 凌智电子
414
415[config_network:D]rknetwork g_wificonfig.psk 88888888
416
417[wifi_api:D]ip=192.168.2.10 gw=192.168.2.1 mask=255.255.255.0
418[wifi_api:D]HWADDR (10:dc:b6:90:00:00)
419[bcore_device:E]start bb ...
420[WIFI_DEVICE:E]GetLocalWifiIp: netif get fail
421
422[bcore_device:E]start bb done
423[wifi_api:D]netif setup ...
424[config_network:D]rknetwork EnableWifi done
425
426[config_network:D]rknetwork SetWifiScan after g_wificonfig.bssid:
427
428[wifi_api_internal:D]Connect to (SSID=凌智电子)
429[wifi_api_internal:D]derive psk ...
430[IOT:D]IotProcess: start ....
431[wifi_api_internal:D]derive psk done
432[wifi_api_internal:D]recovery process ...
433[wifi_api_internal:D]AP BSSID (30:5f:77:80:80:b0)
434[udp:D]rknetwork IP (192.168.2.48)
435[udp:D]network GW (192.168.2.1)
436[udp:D]network NETMASK (255.255.255.0)
437[WIFI_DEVICE:E]l o num:0 127.0.0.1
438[WIFI_DEVICE:E]w l num:1 192.168.2.48
439[udp:D]set network GW
440[udp:D]network GW (192.168.2.1)
441[udp:D]network NETMASK (255.255.255.0)
442[config_network:I]ConnectTo (凌智电子) done
443[config_network:D]rknetwork IP (192.168.2.48)
444[config_network:D]network GW (192.168.2.1)
445[config_network:D]network NETMASK (255.255.255.0)
446[WIFI_DEVICE:E]l o num:0 127.0.0.1
447[WIFI_DEVICE:E]w l num:1 192.168.2.48
448[config_network:D]set network GW
449[config_network:D]network GW (192.168.2.1)
450[config_network:D]network NETMASK (255.255.255.0)
451[udp client] remote addr:0.0.0.0 port:6666
452[udp client] local  addr:192.168.2.48 port:8888
453[udp server] local  addr:192.168.2.48,port:6666
454[udp client]------------------------------------------------
455[udp server]------------------------------------------------
456[udp client] waitting server message!!!
457[udp server] waitting client message!!!
458[udp client] remote addr:192.168.2.49 remote port:6666
459[udp client] rev:凌智电子udp连接客户端
460[udp client] send:UDP TEST cilent send:1
461[udp client] client sendto msg to server 22byte,waitting server respond msg!!!
462[udp client]------------------------------------------------
463[udp client] waitting server message!!!
464[udp server] remote addr:192.168.2.49 port:8888
465[udp server] rev:凌智电子udp连接服务端
466[udp server] send:I have recieved 30 bytes data! recieved cnt:1
467[udp server]------------------------------------------------
468[udp server] waitting client message!!!
469
470
471当log中出现以下信息表示小凌派的tcp客户端和服务端任务已启动
472```c
473[tcp client] connect:50<192.168.2.49:6666>
474[tcp server] listen:51<0.0.0.0:6666>
475```
476
477此时用网络调试助手查看并收发消息。
478![网络调试工具 tcp_msg](/vendor/lockzhiner/lingpi/docs/figures/wifi_tcp/2022-05-09_15-00-15tcp_msg.png)
479
480