Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
博流_BL61x_BL808
BL808 RT-Thread Wi-Fi 驱动适配
发布于 2023-11-30 23:58:04 浏览:774
订阅该版
[tocm] BL808 WiFi 属于 SOC 单芯片型无线 MCU,片上集成 WiFi 功能,移植 RT-Thread 过程中,需要使用 RT-Thread wlan 框架。 RT-Thread wlan 框架是用于管理 Wi-Fi 驱动设备的框架,对下连接具体的 Wi-Fi 驱动,控制 Wi-Fi 的连接断开、扫描等操作,对上为应用提供统一的 Wi-Fi 控制接口。 wlan 框架主要有 3 部分组成: - dev 驱动接口层:为 wlan 框架提供统一的接口调用。 - manage 管理层:为用户提供 Wi-Fi 扫描,链接,断线重连等功能。 - protocol 协议:负责处理 Wi-Fi 产生的数据流,如 lwip。 使用了 wlan 驱动框架之后,Wi-Fi 驱动只需要关注 Wi-Fi 的连接、断开、扫描等动作,并通过 event 将相关动作告知 wlan 框架,由 wlan 框架根据收到的 event 管理 lwip。 ## 1、使能 wlan 驱动 在 Linux 下 执行如下命令,并开启 wlan 驱动。 ```shell $ scons --menuconfig RT-Thread Components ---> Device Drivers ---> [*] Using Wi-Fi framework ---> ``` 开启 wlan 驱动后,默认会选中 lwip。 如 WiFi SOC 类芯片,原厂 SDK 中已经有线程管理 WiFi 数据收发,可关闭 lwip 中的 Rx thread 和 Tx thread,以节省系统资源。 ```shell Network ---> -*- LwIP: light weight TCP/IP stack ---> [*] Not use Rx thread [*] Not use Tx thread ``` ## 2、wlan 驱动框架适配 ### 初始化 通过 rt_wlan_dev_register() 注册 STATION 和 AP 设备,并将 wlan 设备接口函数注册进对应设备。 ```c static const struct rt_wlan_dev_ops ops = { .wlan_init = drv_wlan_init, .wlan_mode = drv_wlan_mode, .wlan_scan = drv_wlan_scan, .wlan_join = drv_wlan_join, .wlan_softap = drv_wlan_softap, .wlan_disconnect = drv_wlan_disconnect, .wlan_ap_stop = drv_wlan_ap_stop, .wlan_ap_deauth = drv_wlan_ap_deauth, .wlan_scan_stop = drv_wlan_scan_stop, .wlan_get_rssi = drv_wlan_get_rssi, .wlan_set_powersave = drv_wlan_set_powersave, .wlan_get_powersave = drv_wlan_get_powersave, .wlan_cfg_promisc = drv_wlan_cfg_promisc, .wlan_cfg_filter = drv_wlan_cfg_filter, .wlan_cfg_mgnt_filter = drv_wlan_cfg_mgnt_filter, .wlan_set_channel = drv_wlan_set_channel, .wlan_get_channel = drv_wlan_get_channel, .wlan_set_country = drv_wlan_set_country, .wlan_get_country = drv_wlan_get_country, .wlan_set_mac = drv_wlan_set_mac, .wlan_get_mac = drv_wlan_get_mac, .wlan_recv = drv_wlan_recv, .wlan_send = drv_wlan_send, }; int rt_hw_wifi_init(void) { rt_err_t ret = RT_EOK; static struct rt_wlan_device wlan0; static struct rt_wlan_device wlan1; memset(&wifi_sta, 0, sizeof(wifi_sta)); ret = rt_wlan_dev_register(&wlan0, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta); wifi_sta.wlan = &wlan0; memset(&wifi_ap, 0, sizeof(wifi_ap)); ret |= rt_wlan_dev_register(&wlan1, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap); wifi_ap.wlan = &wlan1; return ret; } INIT_DEVICE_EXPORT(rt_hw_wifi_init); ``` ### 启动设备 在 main.c 中 加入 rt_wlan_set_mode 分别设置 STATION 和 AP 模式。 ```c int main(void) { rt_kprintf("Hello, RISC-V!\n"); /* set wifi work mode */ rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION); rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP); return 0; } ``` ### 接口实现 - 在 STATION 模式下,至少需要实现连接路由器 `drv_wlan_join()` 和断开路由器 `drv_wlan_disconnect()` 这 2 个函数。 - 在 AP 模式下,至少要实现 AP 开启 `drv_wlan_softap` 和 AP 关闭 `drv_wlan_ap_stop()` 这 2个函数。 这 4 个函数可以按照芯片 SDK 上的接口对应实现即可。 ### event 管理 在实现以上接口用,需要在 Wi-Fi 触发对应事件后,通过 event 通知 wlan 驱动框架。 - 在 STATION 模式下,当连接路由器成功后,通过 `rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_CONNECT, RT_NULL)` 函数通知 wlan 框架 station 已经连接路由成功。当断开路由器后,通过 `rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_DISCONNECT, RT_NULL)` 函数通过 wlan 框架 station 已经断开路由器。 wlan 框架在收到 RT_WLAN_DEV_EVT_CONNECT 时间后会通过 dhcp 服务获取 IP。 - 在 AP 模式下,开启软 AP 成功后,通过 `rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_START, RT_NULL)` 函数通知 wlan 框架 AP 模式开启成功。关闭软 AP 成功后,通过 `rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_STOP, RT_NULL)` 函数通知 wlan 框架软 AP 关闭。 wlan 框架在收到 RT_WLAN_DEV_EVT_AP_START 时间后会开启 DHCP_SERVER 服务。 采用了 RT-Thread wlan 驱动框架后,芯片 SDK 只需要负责管理 WiFi 相关的连接服务,而不需要管理 lwip 协议栈, ### 数据收发 上面说到 wlan 框架在收到对应的 evnet 后,负责启动 lwip 中的对应服务。 - wlan 框架通过 `drv_wlan_send()` 函数将需要发送的网络数据包发输出去。针对WiFi 而言,需要通过判断设备是 station 还是 ap 后,将对应的数据包发送给 WiFi 。 ```c static int drv_wlan_send(struct rt_wlan_device *wlan, void *buff, int len) { if (wlan->user_data == &wifi_sta) bl_wifi_tx(0, (struct pbuf *)buff); else bl_wifi_tx(1, (struct pbuf *)buff); return RT_EOK; } ``` - WiFi 设备接收到数据后,通过 `rt_wlan_dev_report_data()` 函数,将数据传递给 wlan 框架,wlan 框架会进一步通过 lwip 做进一步处理。 ```c int bl_wifi_rx(uint8_t idx, struct pbuf *p) { rt_err_t ret = RT_EOK; if (idx == 0) ret = rt_wlan_dev_report_data(wifi_sta.wlan, p, p->tot_len); else ret = rt_wlan_dev_report_data(wifi_ap.wlan, p, p->tot_len); return ret; } ``` ### 其他必须实现的接口 - mac相关 主要实现 mac 地址读取和写入。 ```c static rt_err_t drv_wlan_set_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[]) { wifi_mgmr_sta_mac_set(mac); return RT_EOK; } ``` ```c static rt_err_t drv_wlan_get_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[]) { wifi_mgmr_sta_mac_get(mac); return RT_EOK; } ``` - Wi-Fi scan ```c static rt_err_t drv_wlan_scan(struct rt_wlan_device *wlan, struct rt_scan_info *scan_info) { int channel_input_num = 0; uint8_t channel_input[MAX_FIXED_CHANNELS_LIMIT] = {0}; const char *ssid = NULL; uint8_t bssid[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; uint8_t scan_mode = SCAN_ACTIVE; uint32_t duration_scan_us = 0; if (scan_info != NULL && scan_info->ssid.len > 0) { ssid = scan_info->ssid.val; } if (wifi_mgmr_scan_adv(wlan, wifi_scan_complete_callback, channel_input, channel_input_num, bssid, ssid, scan_mode, duration_scan_us) != 0) return -RT_ERROR; return RT_EOK; } ```
4
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
燕十三
这家伙很懒,什么也没写!
文章
12
回答
15
被采纳
0
关注TA
发私信
相关文章
1
BL808编译rt-thread下载润了,但也就止于此
2
求助rt-smart在适配riscv64虚拟地址和物理地址映射关系
3
BL808 rt-smart 运行hello.elf报错
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
19
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
6
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部