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

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

3天内不再提示

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

福州市凌睿智捷电子有限公司 2024-08-08 08:23 次阅读

实验内容

本示例将演示如何在小凌派-RK2206开发板上使用WiFi-AP模式(即将RK2206作为WiFi路由器),实现与PC端进行TCP通信

程序设计

API设计

FlashInit()

头文件:

//device/rockchip/rk2206/adapter/include/lz_hadware.h

函数描述:

unsigned int FlashInit(void);

作用描述:

初始化RK2206的Flash。

参数描述:

返回值:

LZ_HARDWARE_SUCCESS为成功,反之为失败。

VendorSet()

头文件:

//device/rockchip/rk2206/adapter/include/lz_hadware.h

实际定义在:

//device/rockchip/rk2206/adapter/include/lz_hardware/vendor.h

函数描述:

unsigned int VendorSet(VendorID id, unsigned char *buf, int len);

作用描述:

在Flash区域中设置WiFi相关参数。

参数描述:

名字描述
id配置的参数,例如:VENDOR_ID_WIFI_SSID:设备作为终端,连接WiFi路由器的SSID,32字节 + '\0'VENDOR_ID_WIFI_PASSWD:设备作为终端,连接WiFi路由器的密钥,64字节 + '\0'VENDOR_ID_WIFI_ROUTE_SSID:设备作为WiFi路由器,配置SSID,32字节 + '\0'VENDOR_ID_WIFI_ROUTE_PASSWD:设备作为WiFi路由器,配置密钥,64字节 + '\0'VENDOR_ID_WIFI_MODE:配置设备作为终端或WiFi路由器,3字节 + '\0'
buf配置内容字符串
len配置内容字符串长度

返回值:

LZ_HARDWARE_SUCCESS为成功,反之为失败。

SetApModeOff()

头文件:

/device/rockchip/rk2206/sdk_liteos/board/include/config_network.h

函数描述:

WifiErrorCode SetApModeOff();

作用描述:

关闭WiFi-AP模式。

参数描述:

返回值:

0为成功,反之为失败。

SetApModeOn()

头文件:

/device/rockchip/rk2206/sdk_liteos/board/include/config_network.h

函数描述:

WifiErrorCode SetApModeOn();

作用描述:

开启WiFi-AP模式。

参数描述:

返回值:

0为成功,反之为失败。

软件设计

整个例程主要分为2个部分:

配置RK2206为WiFi-AP模式

创建TCP服务端,监听并等待TCP客户端

配置WiFi-AP模式

该任务主要分为如下几个步骤:

(1)配置WiFi相关参数

首先,定义几个WiFi相关参数,并予以赋值。

void wifi_process(void *args){ unsigned int threadID_client, threadID_server; unsigned int ret = LOS_OK; WifiLinkedInfo info; uint8_t wifi_mode[4]; // 注意:wifi_mode字符串长度为4, 不能超过4 uint8_t mac_address[6]; // 注意:mac_address字符串长度为6, 不能超过6 uint8_t route_ssid[WIFI_MAX_SSID_LEN]; // config_network.h有定义该宏定义 uint8_t route_passwd[WIFI_MAX_KEY_LEN]; // config_network.h有定义该宏定义

// 配置WiFi模式字符串 memset(wifi_mode, 0, sizeof(wifi_mode)); snprintf(wifi_mode, sizeof(wifi_mode), "AP"); // 配置MAC地址字符串 memset(mac_address, 0, sizeof(mac_address)); mac_address[0] = 0x00; mac_address[1] = 0xdc; mac_address[2] = 0xb6; mac_address[3] = 0x90; mac_address[4] = 0x11; mac_address[5] = 0x00; // 配置route_ssid和route_passwd memset(route_ssid, 0, WIFI_MAX_SSID_LEN); snprintf(route_ssid, sizeof(route_ssid), WIFI_SSID); memset(route_passwd, 0, WIFI_MAX_KEY_LEN); snprintf(route_passwd, sizeof(route_passwd), WIFI_PASSWORD); ......}

注意:上述wifi_mode、mac_address、route_ssid和route_passwd都有严格的字符串长度定义。

(2)写入Flash

将之前定义好的WiFi相关参数写入到Flash。

void wifi_process(void *args){ ........ // Flash初始化 FlashInit(); // 配置RK2206为WiFi-AP模式,并设置WiFi路由器的SSID和密码 VendorSet(VENDOR_ID_WIFI_MODE, wifi_mode, sizeof(wifi_mode)); // 配置为Wifi AP模式 VendorSet(VENDOR_ID_MAC, mac_address, sizeof(mac_address)); // 配置MAC地址 VendorSet(VENDOR_ID_WIFI_SSID, route_ssid, sizeof(route_ssid)); // 配置WiFi路由器的SSID VendorSet(VENDOR_ID_WIFI_PASSWD, route_passwd, sizeof(route_passwd)); // 配置WiFi路由器的密码 ......}

注意:

在调用VendorSet()之前必须调用FlashInit(),初始化Flash相关操作,否则VendorSet()无效。

VendorSet()第1个参数在vendor.h有定义。

(3)重启WiFi-AP模式

void wifi_process(void *args){ ........ // 开启WiFi-AP模式 SetApModeOff(); SetApModeOn(); ......}

TCP服务端

首先,在wifi_process()调用CreateThread()创建1个线程,运行wifi_tcp_server()

void wifi_process(void *args){ ........ // 创建TCP服务端线程 CreateThread(&threadID_server, wifi_tcp_server, NULL, "tcp_server");}

其次,运行TCP服务端,绑定IP地址和端口号,监听端口,等待TCP客户端连接

int wifi_tcp_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!\n"); 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]!\n", 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!\n"); 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!\n"); lwip_close(server_fd); return -1; } printf("[tcp server] listen:%d<%s:%d>\n", server_fd, inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port)); tcp_server_msg_handle(server_fd); // 处理接收到的数据 LOS_Msleep(1000); }}

最后,tcp_server_msg_handle()负责与TCP客户端进行实际通信。

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...\n"); /* 监听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>\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); while (1) { memset(buf, 0, BUFF_LEN); printf("-------------------------------------------------------\n"); printf("[tcp server] waitting client msg\n"); 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!\n"); LOS_Msleep(3000); break; } printf("[tcp server] rev client msg:%s\n", 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\n", buf); send(client_fd, buf, strlen(buf), 0); // 发送信息给client // lwip_write(client_fd, buf, strlen(buf)); //发送信息给client } lwip_close(client_fd); lwip_close(fd);}

编译调试

修改BUILD.gn文件

修改 vendor/lockzhiner/rk2206/sample 路径下 BUILD.gn 文件,指定 wifi_ap_example 参与编译。

"./b14_wifi_ap:wifi_ap_example",

修改 device/lockzhiner/rk2206/sdk_liteos 路径下 Makefile 文件,添加 -lwifi_ap_example 参与编译。

app_LIBS = -lwifi_ap_example

运行结果

示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,显示如下:

entering kernel init...hilog will init.[IOT:D]IotInit: start ....[MAIN:D]Main: LOS_Start ...Entering scheduler[IOT:D]IotProcess: start ....wifi_ap_example start ....[FLASH:I]FlashInit: blockSize 4096, blockStart 0, blockEnd 8388608[config_network:D]rknetwork SetApModeOff start ...

[config_network:D]rknetwork AP is inactive

[config_network:D]rknetwork SetApModeOff end ...

[config_network:D]rknetwork SetApModeOn start ...

[FLASH:E]FlashInit: id 0, controller has already been initialized[config_network:D]rknetwork EnableHotspot ...

[wifi_api:D]ip=192.168.2.10 gw=192.168.2.1 mask=255.255.255.0[wifi_api:D]HWADDR (00b611:00)[bcore_device:E]start bb ...[bcore_device:E]start bb done[wifi_api:D]netif setup ...[wifi_api_internal:D]Start AP (SSID=rk2206_nano channel=1)[wifi_api_internal:D]derive psk ...[wifi_api_internal:D]derive psk done[wifi_dhcp:D]lann_ipaddr:192.168.2.1[wifi_dhcp:D]lann_mask:255.255.255.0[config_network:D]rknetwork EnableHotspot done[tcp server] listen:50<0.0.0.0:6666>waitting for client connect...

注意:设备WiFi路由器IP地址为192.168.2.10。

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

    关注

    18

    文章

    6032

    浏览量

    135978
  • 操作系统
    +关注

    关注

    37

    文章

    6818

    浏览量

    123322
  • OpenHarmony
    +关注

    关注

    25

    文章

    3721

    浏览量

    16302
收藏 人收藏

    评论

    相关推荐

    基于Openharmony轻量级操作系统的分布式数据管理开发案

    实验内容本例程演示如何在小凌派-RK2206开发板上使用OpenHarmony轻量级操作系统进行KvStore(即分布式数据管理)数据读写。
    的头像 发表于 08-07 08:23 964次阅读
    基于<b class='flag-5'>Openharmony</b><b class='flag-5'>轻量级</b><b class='flag-5'>操作系统</b>的分布式数据管理<b class='flag-5'>开发案</b>例

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

    实验内容 本示例将演示如何在小凌派-RK2206开发板上使用WiFi-AP模式(即将RK2206作为Wi
    发表于 08-07 15:50

    首发!成功移植OpenHarmony到瑞芯微RK2206开发板,2022年2月即将开源~

    、CapSense、I2S、PDM、i8080显示接口、相机串行接口等,使产品开发更加简单多样。凌智RK2206开发板搭载OpenHarmony操作
    发表于 12-15 18:30

    轻量系统开发套件介绍:凌睿智捷 | 小凌派-RK2206 开发板套件

    凌睿智捷 | 小凌派-RK2206 开发板套件是由福州市凌睿智捷电子有限公司出品,主控器为瑞芯微高性能、高性价比的RK2206芯片,搭载OpenHarmony
    发表于 04-21 13:39

    【小凌派RK2206开发板试用体验】开发环境搭建

    非常感谢发烧友william hill官网 和凌智电子,为我和孩子提供此产品小凌派RK2206开发板感谢大佬们的指导。小凌派-RK2206是一款由福州市凌睿智捷电子有限公司专为HarmonyOS系统打造的Har
    发表于 06-02 09:55

    RK2206开发板搭载OpenHarmony操作系统简介

    1、小凌派-RK2206开发板简介小凌派-RK2206开发板主控器为瑞芯微高性能、高性价比的RK2206芯片,搭载
    发表于 07-28 17:28

    RK2206开发板搭载OpenHarmony操作系统

    OTG、I2C、UART、PWM、SPI、CapSense、I2S、PDM、i8080显示接口、相机串行接口等,使产品开发更加简单多样。凌智RK2206开发板搭载OpenHarmony
    发表于 09-07 17:15

    一款小凌派RK2206开发的智能电子宠物展示

    一款小凌派RK2206开发的智能电子宠物,OpenHarmony轻量级操作系统设计。以房间内声源,物体,无线信号,人等为研究对象,组成一体多
    发表于 01-31 09:53

    【新书推荐】《OpenHarmony嵌入式系统原理与应用--基于RK2206芯片(微课视频版)》

    OpenHarmony可以基于同-·套系统能力,适配多种终端形态,是一款面向未来、面向全场景的分布式操作系统。本书以 OpenHarmony 为主题,详细讲解了基于瑞芯微
    发表于 03-23 18:30

    好书推荐|《OpenHarmony嵌入式操作原理与应用》

    OpenHarmony嵌入式操作原理与应用》一书以物联网应用为切入点,以瑞芯微 RK2206芯片为核心控制器,详细讲解了 OpenHarmony(开源鸿蒙)
    发表于 03-25 16:01

    OpenHarmony嵌入式系统原理与应用——基于RK2206芯片(微课视频版)》学习记录1 环境配置与源码编译

    OpenHarmony编程模型:OpenHarmony支持多进程和多线程编程,进程和线程的管理由操作系统内核负责。线程间通信可以使用信号量、消息队列等方式。
    发表于 06-25 11:26

    好书推荐|《OpenHarmony嵌入式操作原理与应用》

    OpenHarmony嵌入式操作原理与应用》一书以物联网应用为 主题,通过瑞芯微 RK2206芯片为核心控制器,搭配几个互联网的应用项目讲解,能让用户能对OpenHarmony(开源
    发表于 06-27 23:12

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

    RK2206开发板而做的简易示波器开发。 本开发以瑞芯微RK2206芯片 + OpenHarmony
    的头像 发表于 05-06 17:09 1812次阅读
    基于小凌派<b class='flag-5'>RK2206</b><b class='flag-5'>开发</b>板所制作的简易示波器

    OpenHarmony开源鸿蒙大赛作品集:基于RK2206开发板20+成熟应用案例!

    -RK2206开发板,主控器为瑞芯微高性能、高性价比的RK2206芯片,搭载OpenHarmony操作系统,内置
    的头像 发表于 02-21 16:35 3161次阅读

    好书推荐|《OpenHarmony嵌入式操作原理与应用》

    OpenHarmony嵌入式操作原理与应用》一书以物联网应用为切入点,以瑞芯微RK2206芯片为核心控制器,详细讲解了OpenHarmony(开源鸿蒙)
    的头像 发表于 04-03 09:50 1011次阅读
    好书推荐|《<b class='flag-5'>OpenHarmony</b>嵌入式<b class='flag-5'>操作</b>原理与应用》