0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用小凌派开发板wifi进行tcp通信的步骤

电子发烧友开源社区 来源:HarmonyOS官方合作社区 作者:HarmonyOS官方合作社 2022-05-16 09:35 次阅读

在开发过程中想要与开发板进行通信一般使用串口通信,当开发板使用串口与pc通信还需要专门的串口转换工具才行,小凌派开发板自带wifi功能。因此与pc通信时可以使用wifi功能进行tcp通信这样就不需要专门的转换工具非常方便。

在使用小凌派开发板wifi进行tcp通信的步骤

1、要确定pc机所连接路由的wifi名称和密码,通过修改代码使小凌派连接到与pc同一网络

修改文件device/rockchip/rk2206/sdk_liteos/board/src/config_network.c 中的SSID 即wifi名称,和PASSWORD 即wifi密码。

#define SSID          "凌智电子"#define PASSWORD        "********"

(左右移动查看全部内容)

2、确认小凌派wifi功能是否开启

查看device/rockchip/rk2206/sdk_liteos/board/main.c 文件是否调用ExternalTaskConfigNetwork();

3、确认小凌派开发板与开发板在同一网段

在修改以上配置后先编译烧录程序然后查看log确认小凌派开发板获取到的ip地址。

6aa1fc74-d4b0-11ec-bce3-dac502259ad0.png

在确认pc的ip地址,在控制台输入ipconfig

6ad1b1f8-d4b0-11ec-bce3-dac502259ad0.png

可以看到两个ip地址都是点2网段,说明已经在同一局域网。

4、 修改wifi_tcp 例程中服务地址及端口

#define OC_SERVER_IP  "192.168.2.49"#define SERVER_PORT   6666

(左右移动查看全部内容)


这个ip地址即PC的ip地址,修改后重新编译烧录程序。

5、 pc上打开两个网络调试工具,一个客户端和一个服务端,并设置ip地址和端口号:
服务端 ip地址:0.0.0.0
端口号:6666


客户端ip地址:192.168.2.50 (之前查看到小凌派的ip地址)
端口号:6666

6b07a196-d4b0-11ec-bce3-dac502259ad0.png

6 、查看log等待小凌派的tcp客户端和服务端任务启动

6b4d6384-d4b0-11ec-bce3-dac502259ad0.png

可以看到客户端连接地址192.168.2.49:6666 即pc的ip地址:服务端监听端口为6666,这表示小凌派tcp客户端和服务端任务都已经启动。

7、 在pc网络调试助手点击启动客户端和服务端

6b7abe4c-d4b0-11ec-bce3-dac502259ad0.png

可以观察到网络调试助手服务端有设备连接成功并且接收到了调试数据。网络调试助手的客户端也显示连接成功。

8、 使用网络调试助手发送数据

6bc6f848-d4b0-11ec-bce3-dac502259ad0.png

可以查看log发现小凌派开发板已经可以正常收发数据了,这样就可以通过使用wifi与pc进行通信。

接下来分析一下代码的工作流程

首先包含必要的头文件:

#include "ohos_init.h"#include "cmsis_os2.h"#include "los_task.h"#include "lz_hardware.h"#include "config_network.h"#include "lwip/tcp.h"#include "lwip/ip_addr.h"#include "lwip/priv/tcp_priv.h"#include "lwip/stats.h"#include "lwip/inet_chksum.h"

(左右移动查看全部内容)

这些定义主要是 ip地址和端口号以及缓存大小

#define LOG_TAG  "tcp"#define OC_SERVER_IP  "192.168.2.49"#define SERVER_PORT 6666#define BUFF_LEN  256

(左右移动查看全部内容)

这部分是获取wifi连接信息,通过查询wifi连接信息确认wifi是否连接成功。只有wifi连接成功了才能进行tcp通信

int get_wifi_info(WifiLinkedInfo *info){  int ret = -1;  int gw, netmask;  memset(info, 0, sizeof(WifiLinkedInfo));  unsigned int retry = 15;  while (retry) {    if (GetLinkedInfo(info) == WIFI_SUCCESS) {      if (info->connState == WIFI_CONNECTED) {        if (info->ipAddress != 0) {          LZ_HARDWARE_LOGD(LOG_TAG, "rknetwork IP (%s)", inet_ntoa(info->ipAddress));          if (WIFI_SUCCESS == GetLocalWifiGw(&gw)) {            LZ_HARDWARE_LOGD(LOG_TAG, "network GW (%s)", inet_ntoa(gw));          }          if (WIFI_SUCCESS == GetLocalWifiNetmask(&netmask)) {            LZ_HARDWARE_LOGD(LOG_TAG, "network NETMASK (%s)", inet_ntoa(netmask));          }          if (WIFI_SUCCESS == SetLocalWifiGw()) {            LZ_HARDWARE_LOGD(LOG_TAG, "set network GW");          }          if (WIFI_SUCCESS == GetLocalWifiGw(&gw)) {            LZ_HARDWARE_LOGD(LOG_TAG, "network GW (%s)", inet_ntoa(gw));          }          if (WIFI_SUCCESS == GetLocalWifiNetmask(&netmask)) {            LZ_HARDWARE_LOGD(LOG_TAG, "network NETMASK (%s)", inet_ntoa(netmask));          }          ret = 0;          goto connect_done;        }      }    }    LOS_Msleep(1000);    retry--;  }
connect_done:  return ret;}

(左右移动查看全部内容)

这部分是tcp服务端接收消息处理,先进入accept()会处于阻塞状态,即没有客户端连接时一直阻塞。单客户端连接后又进入接收数据状态,此状态也是阻塞状态。

没有数据时一直阻塞,不过需要注意的是在此状态下当客户端断开连接时recv会返回-1,接收到pc客户端的消息后通过send()发响应消息给PC客户端。

void tcp_server_msg_handle(int fd){  char buf[BUFF_LEN]; //接收缓冲区  socklen_t client_addr_len;  int cnt = 0, count;  int client_fd;  struct sockaddr_in client_addr = {0};    printf("waitting for client connect...
");  /* 监听socket 此处会阻塞 */  client_fd = accept(fd, (struct sockaddr*)&client_addr, &client_addr_len);  // client_fd = lwip_accept(fd, (struct sockaddr*)&client_addr, &client_addr_len);  printf("[tcp server] accept <%s:%d>
", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));  while (1)  {    memset(buf, 0, BUFF_LEN);    printf("-------------------------------------------------------
");    printf("[tcp server] waitting client msg
");    count = recv(client_fd, buf, BUFF_LEN, 0);    //read是阻塞函数,没有数据就一直阻塞    // count = lwip_read(client_fd, buf, BUFF_LEN); //read是阻塞函数,没有数据就一直阻塞    if (count == -1)    {      printf("[tcp server] recieve data fail!
");      LOS_Msleep(3000);      break;    }    printf("[tcp server] rev client msg:%s
", buf);    memset(buf, 0, BUFF_LEN);    sprintf(buf, "I have recieved %d bytes data! recieved cnt:%d", count, ++cnt);    printf("[tcp server] send msg:%s
", buf);    send(client_fd, buf, strlen(buf), 0);    //发送信息给client    // lwip_write(client_fd, buf, strlen(buf)); //发送信息给client  }  lwip_close(client_fd);  lwip_close(fd);}

(左右移动查看全部内容)

这部分是tcp服务端任务代码,服务端处理流程

socket-->bind-->listen-->accept-->recv-->send-->lwip_close

先通过socket()接口打开一个服务端socket文件,然后设置需要绑定的服务端ip地址及端口号。在进行监听,需要注意的是此处监听不会处于阻塞态。

int wifi_server(void* arg){  int server_fd, ret;
  while(1)  {    server_fd = socket(AF_INET, SOCK_STREAM, 0);     //AF_INET:ipv4;SOCK_STREAM:TCP    // server_fd = lwip_socket(AF_INET, SOCK_STREAM, 0); //AF_INET:IPV4;SOCK_STREAM:TCP    if (server_fd < 0)    {      printf("create socket fail!
");      return -1;    }
    /*设置调用close(socket)后,仍可继续重用该socket。调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。*/    int flag = 1;    ret = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));    if (ret != 0) {      printf("[CommInitTcpServer]setsockopt fail, ret[%d]!
", ret);    }        struct sockaddr_in serv_addr = {0};    serv_addr.sin_family = AF_INET;    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址    // serv_addr.sin_addr.s_addr = inet_addr(OC_SERVER_IP); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址    serv_addr.sin_port = htons(SERVER_PORT);    //端口号,需要网络序转换    /* 绑定服务器地址结构 */    ret = bind(server_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));    // ret = lwip_bind(server_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));    if (ret < 0)    {      printf("socket bind fail!
");      lwip_close(server_fd);      return -1;    }    /* 监听socket 此处不阻塞 */    ret = listen(server_fd, 64);    // ret = lwip_listen(server_fd, 64);    if(ret != 0)    {      printf("socket listen fail!
");      lwip_close(server_fd);      return -1;    }    printf("[tcp server] listen:%d<%s:%d>
",server_fd, inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port));    tcp_server_msg_handle(server_fd);  //处理接收到的数据    LOS_Msleep(1000);  }}

(左右移动查看全部内容)

这部分是tcp客户端的接收消息处理函数,先进行尝试连接pc机的服务端,如果失败则延迟5秒后重新连接直到连接成功。

连接成功后先发消息给PC的服务端,然后进入接收状态,此状态是阻塞态。当接收到pc的消息后进入循环发送状态。

void tcp_client_msg_handle(int fd, struct sockaddr* dst){  socklen_t len = sizeof(*dst);
  int cnt = 0, count = 0;  while (connect(fd, dst, len) < 0)  {    printf("connect server faiLED...%d
", ++count);    lwip_close(fd);    LOS_Msleep(5000);    fd = socket(AF_INET, SOCK_STREAM, 0); //AF_INET:IPV4;SOCK_STREAM:TCP  }    while (1)  {    char buf[BUFF_LEN];    sprintf(buf, "TCP TEST cilent send:%d", ++cnt);    count = send(fd, buf, strlen(buf), 0);           //发送数据给server    // count = lwip_write(fd, buf, strlen(buf));          //发送数据给server    printf("------------------------------------------------------------
");    printf("[tcp client] send:%s
", buf);    printf("[tcp client] client sendto msg to server %d,waitting server respond msg!!!
", count);    memset(buf, 0, BUFF_LEN);    count = recv(fd, buf, BUFF_LEN, 0);    //接收来自server的信息    // count = lwip_read(fd, buf, BUFF_LEN);   //接收来自server的信息    if(count == -1)    {      printf("[tcp client] recieve data fail!
");      LOS_Msleep(3000);      break;    }    printf("[tcp client] rev:%s
", buf);  }  lwip_close(fd);}

(左右移动查看全部内容)

这部分代码是tcp客户端代码,客户端处理流程:socket-->connect-->send-->recv-->lwip_close

先通过socket()接口创建客户端的socket文件。然后设置客户端连接PC服务端的ip地址及端口号。在进行connect连接。

int wifi_client(void* arg){  int client_fd, ret;  struct sockaddr_in serv_addr;    while(1)  {    client_fd = socket(AF_INET, SOCK_STREAM, 0);//AF_INET:IPV4;SOCK_STREAM:TCP    if (client_fd < 0)    {      printf("create socket fail!
");      return -1;    }
    /*设置调用close(socket)后,仍可继续重用该socket。调用close(socket)一般不会立即关闭socket,而经历TIME_WAIT的过程。*/    int flag = 1;    ret = setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));    if (ret != 0) {      printf("[CommInitTcpServer]setsockopt fail, ret[%d]!
", ret);    }        memset(&serv_addr, 0, sizeof(serv_addr));    serv_addr.sin_family = AF_INET;    serv_addr.sin_addr.s_addr = inet_addr(OC_SERVER_IP);    serv_addr.sin_port = htons(SERVER_PORT);    printf("[tcp client] connect:%d<%s:%d>
",client_fd, inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port));            tcp_client_msg_handle(client_fd, (struct sockaddr*)&serv_addr);        LOS_Msleep(1000);  }
  return 0;}

(左右移动查看全部内容)

这部分是tcp创建客户端和服务端任务,可以看到在创建客户端和服务端任务前先阻塞判断wifi的连接状态。只有wifi连接成功后才创建客户端和服务端任务

void wifi_process(void *args){  unsigned int threadID_client, threadID_server;  unsigned int ret = LOS_OK;    WifiLinkedInfo info;
  while(get_wifi_info(&info) != 0) ;
  CreateThread(&threadID_client, wifi_client, NULL, "client@ process");  CreateThread(&threadID_server, wifi_server, NULL, "server@ process");}

(左右移动查看全部内容)

这部分是创建wifi tcp 通信任务主要是为了使用APP_FEATURE_INIT(wifi_tcp_example);这样当OpenHarmony初始化完成后会自动执行此任务。

void wifi_tcp_example(void){  unsigned int ret = LOS_OK;  unsigned int thread_id;  TSK_INIT_PARAM_S task = {0};  printf("%s start ....
", __FUNCTION__);
  task.pfnTaskEntry = (TSK_ENTRY_FUNC)wifi_process;  task.uwStackSize = 10240;  task.pcName = "wifi_process";  task.usTaskPrio = 24;  ret = LOS_TaskCreate(&thread_id, &task);  if (ret != LOS_OK)  {    printf("Falied to create wifi_process ret:0x%x
", ret);    return;  }}APP_FEATURE_INIT(wifi_tcp_example);

(左右移动查看全部内容)

原文标题:基于小凌派RK2206鸿蒙开发板wifi-tcp通信实验

文章出处:【微信公众号:HarmonyOS官方合作社区】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • WIFI
    +关注

    关注

    81

    文章

    5297

    浏览量

    203660
  • 开发板
    +关注

    关注

    25

    文章

    5040

    浏览量

    97420
  • TCP通信
    +关注

    关注

    0

    文章

    146

    浏览量

    4222

原文标题:基于小凌派RK2206鸿蒙开发板wifi-tcp通信实验

文章出处:【微信号:HarmonyOS_Community,微信公众号:电子发烧友开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于小RK2206开发板wifi-tcp通信实验

    需要专门的转换工具非常方便。一、在使用小开发板wifi进行tcp
    发表于 05-13 09:20

    每周精选 | 小RK2206开发板wifi-tcp通信实验,Markdown编辑器有奖体验活动

    开发板进行通信一般使用串口通信,当开发板使用串口与pc通信还需要专门的串口转换工具才行。而小
    发表于 05-13 10:25

    【小RK2206开发板试用体验】小手势应用之原力控制星球大战BB-8机器人

    在上一篇文章中,我分享了 小隔空操作迪文COF智能屏 ,这次再给大家分享一个更有趣的智能手势应用----小RK2206开发板赋予你原
    发表于 05-24 10:56

    基于小RK2206开发板wifi-udp通信实验

    显示,这些消息是不断被覆盖的,使用udp就高效的多。一、在使用小开发板wifi进行udp通信
    发表于 05-31 10:12

    如何在小RK2206开发板上使用wifi进行tcp通信

    文件,指定 b7_wifi_tcp 参与编译。"b7_wifi_tcp",在主目录下输入编译命令。hb build -f运行结果示例代码编译烧录代码后,按下开发板的RESET按键
    发表于 08-12 16:50

    基于开发板的FastDeploy适配

    )目前,我已将FastDeploy适配到开发板上,可用于目标检测、人脸检测、人脸识别、人脸对齐、图像分割、OCR等领域,这将大大提高
    发表于 02-16 09:43

    NXP iMX6ULL开发板WIFI接口功能测试

    : iMX6ULL开发板上电,启动Linux系统。 步骤2: 连接USB WIFI到飞iMX6ULL开发板的USB Host接口
    的头像 发表于 05-05 17:02 2427次阅读

    基于小RK2206开发板所制作的简易示波器

    基于OpenHarmony + 小RK2206开发板制作的简易示波器,实时采集波形,实时计算并实时显示对应的波形。OpenHarmony实时性较高,稳定性好,瑞芯微RK2206芯片接口丰富
    的头像 发表于 05-06 17:09 1812次阅读
    基于小<b class='flag-5'>凌</b><b class='flag-5'>派</b>RK2206<b class='flag-5'>开发板</b>所制作的简易示波器

    利用小开发板自带的wifi功能来进行tcp通信的教程

    与pc通信时可以使用wifi功能进行tcp通信这样就不需要专门的转换工具非常方便。 一、在使用小
    的头像 发表于 05-13 15:05 2733次阅读
    利用小<b class='flag-5'>凌</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b>自带的<b class='flag-5'>wifi</b>功能来<b class='flag-5'>进行</b><b class='flag-5'>tcp</b><b class='flag-5'>通信</b>的教程

    用小开发板wifi进行udp通信的教程

    显示,这些消息是不断被覆盖的,使用udp就高效的多。   一、在使用小开发板wifi进行udp通信
    的头像 发表于 05-31 16:43 3425次阅读
    用小<b class='flag-5'>凌</b><b class='flag-5'>派</b><b class='flag-5'>开发板</b><b class='flag-5'>wifi</b><b class='flag-5'>进行</b>udp<b class='flag-5'>通信</b>的教程

    树莓Pico开发板扩展ESP01S无线WiFi模块通信实践

    介绍树莓Pico开发板扩展ESP01S无线模块建立WiFi连接,并采用AT命令和MicroPython语言实现树莓Pico与手机之间的WiFi
    发表于 05-31 15:59 3次下载
    树莓<b class='flag-5'>派</b>Pico<b class='flag-5'>开发板</b>扩展ESP01S无线<b class='flag-5'>WiFi</b>模块<b class='flag-5'>通信</b>实践

    基于小RK2206开发板wifi-udp通信实验

    显示,这些消息是不断被覆盖的,使用udp就高效的多。一、在使用小开发板wifi进行udp通信
    的头像 发表于 06-01 10:33 870次阅读
    基于小<b class='flag-5'>凌</b><b class='flag-5'>派</b>RK2206<b class='flag-5'>开发板</b><b class='flag-5'>wifi</b>-udp<b class='flag-5'>通信</b>实验

    -RK2206开发板:UART控制案例

    -RK2206开发板:UART控制案例一、简介通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART。它将要传输的资料在串行
    的头像 发表于 06-14 11:12 1038次阅读
    小<b class='flag-5'>凌</b><b class='flag-5'>派</b>-RK2206<b class='flag-5'>开发板</b>:UART控制案例

    基于小RK2206开发板wifi-tcp通信实验

    与pc通信时可以使用wifi功能进行tcp通信这样就不需要专门的转换工具非常方便。一、在使用小
    的头像 发表于 06-14 11:10 1316次阅读
    基于小<b class='flag-5'>凌</b><b class='flag-5'>派</b>RK2206<b class='flag-5'>开发板</b><b class='flag-5'>wifi-tcp</b><b class='flag-5'>通信</b>实验

    基于OpenHarmony轻量级操作系统实现RK2206 WiFi-AP模式通信开发案例

    实验内容本示例将演示如何在小-RK2206开发板上使用WiFi-AP模式(即将RK2206作为WiFi路由器),实现与PC端
    的头像 发表于 08-08 08:23 421次阅读
    基于OpenHarmony轻量级操作系统实现RK2206 <b class='flag-5'>WiFi</b>-AP模式<b class='flag-5'>通信</b><b class='flag-5'>开发</b>案例