Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
WIFI模块
树莓派Pico
设备驱动
Pico W 基于 C/C++ SDK 适配 RT-Thread Wi-Fi 经验总结
发布于 2023-11-22 23:03:19 浏览:567
订阅该版
[tocm] ## Pico W 基于 C/C++ SDK 适配 RT-Thread Wi-Fi 经验总结 软件包地址:[cyw43439-RTT ](https://github.com/Z8MAN8/cyw43439-RTT) ## 前言: Pico W 作为 Raspberry Pi Pico 的衍生版本,主要增加了无线通信的功能,通过搭载 CYW43439 无线芯片,支持 2.4 GHz Wi-Fi 4 及蓝牙5.0 ,其余和 Raspberry Pi Pico 基本相同,外部引脚也相互兼容。 也可以参考我之前文章中介绍的使用 Clion 搭建开发调试下载环境,同样适用。这里需要注意的一点是,当你首次烧录使板载 LED 闪烁的程序时,开发板可能没有相应的现象,这可能不是你下载失败了,也不是你的开发板是坏的,而是 Pico W 的板载 LED 由无线模块控制,想要使其闪烁需要参照官方 Pico-Example 中 Pico W 的具体示例:[pico w/wifi/blink](https://github.com/raspberrypi/pico-examples/tree/master/pico_w/wifi/blink) ## 准备工作 开发环境搭建完成后,接下来就可以根据树莓派官方的 SDK 和 Example 调一调程序,逐渐梳理清楚逻辑和各模块之间的依赖关系。例如先运行一个最简单的 Wi-Fi scan 的示例程序,其主要逻辑是先 `cyw43_arch_init()` 初始化模块,再通过 `cyw43_arch_enable_sta_mode()` 使能为 STA 模式,最后使用`cyw43_wifi_scan()` 开始扫描并注册扫描完成回调函数打印扫描结果,整体的逻辑和 API 还是很简洁明了的。 主要依赖于英飞凌提供的 cyw43-driver 驱动库,接下来我们开始通过分析 Cmake 文件确定各模块之间的调用关系和对一些宏定义的依赖关系。以下是一部分我通过 Cmake 文件大致整理的关系图: ![依赖关系](https://oss-club.rt-thread.org/uploads/20231122/94f93d71df8e158f4295e4b7b4ea02d6.png.webp) 通过这样的关系图,我们能更直观快速的将官方的 SDK 和 Example 等 Cmake 工程移植为 RT-Thread 所使用的 Scons 工程。 ## 开始开发 主要有以下三种类型:`poll` , `threadsafe_background`, `freertos` 。poll 是需要用户定期调用的,并且不保证线程安全性;threadsafe_background 和 freertos 能够保证线程安全性,threadsafe_background 不使用 RTOS,通过**低优先级的 ISR** 实现调度同步,freertos 是通过专门的**线程**处理调动同步。 一开始我选择的是基于 `threadsafe_background` 进行开发,通过参照以上 Cmake 关系图很快就成功在 RT-Thread 的 Bsp 中复现了 Wi-Fi scan 示例程序。但是开发后续需要使用 lwip 的功能时,与 RT-Thread 就产生了很多冲突。 想要更好的适配 RT-Thread 还是得按照 RTOS 的来,于是开始复现官方提供的基于 FreeRTOS 的,首先想到的是使用 RT-Thread 的 FreeRTOS 兼容层软件包,在 menuconfig 中使能即可: ![menuconfig配置.png](https://oss-club.rt-thread.org/uploads/20231122/2553f0bf6cf31e4cb59fcdda2311eb5f.png) 引入兼容层后大部分报错消失了,但报错没有 `portCHECK_IF_IN_ISR` 的相关实现,在 FreeRTOS 的源码中查找发现其为 RP2040 特有的实现。其是用于判断上下文环境是否处于中断中,改为 RT-Thread 中的检测中断 nest 是否大于 0 即可。 成功编译下载程序后,却因为定时器进入了 `hardfault` ,检查发现 FreeRTOS 兼容层中的 portMAX_DEALY 对接错了,不是 RT_TICK_MAX ,应该为 RT_TICK_MAX / 2 - 1(韦东山老师在rtt开发者大会上专门讲解过 RTT 优雅的定时器算法,感兴趣可以看看)这个问题目前已经修复了。 之后程序还是进入 `hardfault` ,一直 debug 对比代码没有发现问题,再次分析对比 FreeRTOS 和 RT-Thread 之间的差异,两者的优先级等级和数值的关系是相反的,检查发现 `async_context_task` 线程的优先级为 `tskIDLE_PRIORITY + 4` 在 FreeRTOS 中优先级比空闲线程高4,但在 RT-Thread 中因为优先级太低,得不到调度,造成死锁问题。解决办法是将其线程优先级提高。 ## 移植 RT-Thread 以上的示例程序跑通以后,就开始将 wifi freertos 的相关的文件移植为 RT-Thread 。主要包含以下内容: 1. **替换头文件:** - 用 RT-Thread 的头文件替换 FreeRTOS 的头文件。 2. **修改任务创建和管理:** - 使用 RT-Thread 的任务创建和管理 API 替代 FreeRTOS 的任务 API。 - 注意 RT-Thread 的任务入口函数参数和返回值的差异。 3. **修改互斥锁:** - 替换 `xSemaphoreCreateRecursiveMutex` 为 RT-Thread 提供的互斥锁创建 API。 - 替换 `xSemaphoreTakeRecursive` 和 `xSemaphoreGiveRecursive` 为 RT-Thread 互斥锁的 API。 4. **替换定时器:** - 使用 RT-Thread 的软定时器或者实时时钟服务替代 FreeRTOS 定时器。 5. **任务通知:** - 替换 FreeRTOS 的任务通知 API 为 RT-Thread 的事件和信号量等。 6. **任务挂起和唤醒:** - 替换 FreeRTOS 的 `vTaskSuspend` 和 `vTaskResume` 为 RT-Thread 的任务挂起和唤醒 API 主要涉及 `async_context_rtthread`,`cyw43_arch`,`cyw43_arch_rtthread`,`lwip_rtthread`这些文件,基础的移植完成后,就可以开始将其对接到 RT-Thread 的 Wi-Fi 设备驱动框架了,主要参考 [rw007](https://github.com/RT-Thread-packages/rw007) 和 [cyw43012-RTT ](https://github.com/Guozhanxin/cyw43012-RTT) 的对接。需要使能 RT-Thread 的 lwip 和 SAL 等组件。需要注意的一点是 RT-Thread 的 lwip 组件使能后,已经包含了 lwip 的初始化,`cyw43_arch_init()` 中的 lwip 初始化相关注释即可,否则重复初始化会因为完成量无法获取造成阻塞。 ```c #if CYW43_LWIP // ok &= lwip_rtthread_init(context); #endif ``` ``` // 重复初始化信号量无法获取造成阻塞 bool lwip_rtthread_init(async_context_t *context) { RT_ASSERT(!lwip_context); lwip_context = context; static bool done_lwip_init; if (!done_lwip_init) { done_lwip_init = true; rt_sem_t init_sem = rt_sem_create("lwip_init_sem", 0, RT_IPC_FLAG_PRIO); tcpip_task_blocker = rt_sem_create("tcpip_task_blocker", 0, RT_IPC_FLAG_PRIO); tcpip_init(tcpip_init_done, init_sem); // 阻塞在信号量获取 rt_sem_take(init_sem, RT_TICK_MAX / 2 - 1); rt_sem_delete(init_sem); } else { rt_sem_release(tcpip_task_blocker); } return true; } ``` 运行过程中可能会报错提示 lwip 线程栈空间不足,在 menuconfig 中适当改大即可 ![调整lwip.png](https://oss-club.rt-thread.org/uploads/20231122/ee37fad98eb5f1687f977652f22676db.png.webp) 对接完成后测试功能,使能为 STA 模式,日志中显示 mac 地址 ![mac地址.png](https://oss-club.rt-thread.org/uploads/20231122/f169cb73ae5113ae8d30005ab4599dc7.png) 扫描附近ap ![WiFi scan.png](https://oss-club.rt-thread.org/uploads/20231122/c8a7c89339dd393464302132a4457226.png) 连接ap并成功ping通 ![ping通.png](https://oss-club.rt-thread.org/uploads/20231122/7e4f614bd6af52387ca43c5674fb33cd.png) 测试ap功能,使能为AP模式,设置名称及pwd,可以使用手机成功连接。 ## 注意事项 - 使用pico w的无线模块需要使用一些相关的宏定义,如无线模块的引脚定义等,其定义在 picow.h 中。但程序默认包含的是 pico.h 。可以通过定义宏 `PICO_CONFIG_HEADER=boards/pico_w.h` 进行切换。 - 吞吐量还未进行测试。 - 目前基于 C/C++ SDK 的开发案例较少,推荐直接阅读官方文档。 - 在对接设备驱动框架 `wifi_join` 方法时苦恼于 ap 的 channel 和 bssid 没有正常传递,查看源码发现使能 RT_WLAN_JOIN_SCAN_BY_MGNT 这个宏可以先扫描ap,并传递包含 channel 和 bssid 的 info,但要将以下改为rt_memcpy ![RT_WLAN_JOIN_SCAN_BY_MGNT.jpg](https://oss-club.rt-thread.org/uploads/20231122/80dfbbfa764bf3b1cf63126ec4a20af2.jpg) 个人理解,没有找到其他的说明和用例。(不过最后发现,连接ap没有 channel 和 bssid 也行,直接设置为 RT_NULL ) 觉得不错的话就给项目点个 star 吧! 软件包地址:[cyw43439-RTT ](https://github.com/Z8MAN8/cyw43439-RTT) ## Ref: - https://www.raspberrypi.com/documentation/pico-sdk - https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf - https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf
5
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
螺丝松掉的人
这家伙很懒,什么也没写!
文章
42
回答
0
被采纳
0
关注TA
发私信
相关文章
1
让成员函数能作为rt_device中的回调函数
2
关于设备配置时延时的处理
3
rt_device_set_rx_indicate设置的回调如何传递参数?
4
关于 输入捕获 驱动的
5
关于设备驱动的迷茫与疑惑
6
关于rtthread中各种驱动的问题
7
drv_hwtimer 和hwtimer关系是啥?
8
RTT有没有接口文档,可以用于写一些自己创建的设备的这些文档?
9
i2c设备驱动为什么没有速率设置
10
UART设备中断接收及轮询发送
推荐文章
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
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部