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

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

3天内不再提示

简析esp32的wifi驱动如何被集成进Zephyr的驱动

ZephyrProject 来源:ZephyrProject 作者:ZephyrProject 2021-06-01 10:41 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

分析Zephyr ESP32 WIFI驱动的实现可以更为清晰的掌握esp32 wifi在zephyr上的使用,本文主要分析esp32的wifi驱动如何被集成进Zephyr的驱动,并不涉及esp32 wifi驱动本身API的说明。

框架

目前ESP32 wifi在zephyr上的实现框架如下图

93deaa3e-c240-11eb-9e57-12bb97331649.png

1. esp_private:

esp提供的wifi驱动,不开源,属于zephyr的外部module,其API头文件在moduleshalespressifcomponentsesp_wifiincludeesp_private内

2. adapter

esp提供的zephyr wifi适配层,对esp_private进行封装专门为zephyr用,属于zephyr的外部module,其代码放在moduleshalespressifzephyradaptersrcwifi

3. esp_wifi_drv:

Zephyr中的esp32 wifi驱动,调用adapter,和L2 ethernet进行对接。明明是wifi,不封装为L2 wifi, 而封装为L2 ethernet,这可能是目前zephyr对L2 wifi的抽象还不完备,目前只支持offload wifi。

这部分是后文的主要分析内容,代码在zephyrdriverswifiesp32src

4. L2 ethernet

Zephyr L2 ethernet,提供ethernet初始化/配置/收发功能, 代码在zephyrsubsys etl2ethernet,本文不做分析

esp_wifi_drv

zephyr的esp32 wifi驱动可以分为初始化,收,发三部分来分析:

初始化

主要是完成L2的初始化,注册入device初始化函数eth_esp32_dev_init和iface的初始化函数eth_esp32_init已经L2的发送函数eth_esp32_send

1

2

static const struct ethernet_api eth_esp32_apis = {

.iface_api.init= eth_esp32_init,

.send = eth_esp32_send,

};

NET_DEVICE_DT_INST_DEFINE(0,

eth_esp32_dev_init, NULL,

ð_data, NULL, CONFIG_ETH_INIT_PRIORITY,

ð_esp32_apis, ETHERNET_L2,

NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);

使用NET_DEVICE_DT_INST_DEFINE注册后,在系统启动时kernel的POST_KERNEL阶段调用eth_esp32_dev_init,在net初始化阶段调用eth_esp32_init.

eth_esp32_dev_init代码如下,主要是调用hal中提供的一系列初始化和启动函数,让wifi启动,值得注意的是当CONFIG_ESP32_WIFI_STA_AUTO=y时,zephyr驱动会自动去帮你用配置好的CONFIG_ESP32_WIFI_SSID和CONFIG_ESP32_WIFI_PASSWORD去连接Wifi。

如果没有配置,就需要在应用代码中直接调用esp hal的API进行连接,另外就是zephyr目前并没有将esp32 wifi的scan/connect/disconnect做到L2 WIFI内进行管理,可以参考Zephyr网络管理模块分析-注册请求机制, 这边部分也需要在应用中直接调用esp hal的API进行管理。

static int eth_esp32_dev_init(const struct device *dev)

{

esp_timer_init();

esp_event_init();

wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();

esp_err_t ret = esp_wifi_init(&config);

ret |= esp_supplicant_init();

ret |= esp_wifi_start();

//安装配置进行WIFI连接

if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO)) {

wifi_config_t wifi_config = {

.sta = {

.ssid = CONFIG_ESP32_WIFI_SSID,

.password = CONFIG_ESP32_WIFI_PASSWORD,

},

};

ret = esp_wifi_set_mode(WIFI_MODE_STA);

ret |= esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);

ret |= esp_wifi_connect();

}

if (ret != ESP_OK) {

LOG_ERR(“Connect failed”);

}

return ret;

}

网络初始化, 完成ethernet iface注册,并注册数据接收callback,

static void eth_esp32_init(struct net_if *iface)

{

const struct device *dev = net_if_get_device(iface);

struct esp32_wifi_runtime *dev_data = DEV_DATA(dev);

dev_data-》iface = iface;

esp32_wifi_iface = iface;

//从ESP32读出MAC地址,设置给zephyr的iface

/* Start interface when we are actually connected with WiFi network */

net_if_flag_set(iface, NET_IF_NO_AUTO_START);

esp_read_mac(dev_data-》mac_addr, ESP_MAC_WIFI_STA);

/* Assign link local address. */

net_if_set_link_addr(iface,

dev_data-》mac_addr, 6, NET_LINK_ETHERNET);

//进行ethernet初始化

ethernet_init(iface);

//注册接收数据的callback,当hal esp32 wifi驱动收到网络封包后会调用eth_esp32_rx

esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);

}

数据接收

前面的代码可以看到注册的callback是eth_esp32_rx,hal esp32 wifi驱动收到网络封包后会调用eth_esp32_rx,eth_esp32_rx会将网络封包直接转发给IP层

static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)

{

struct net_pkt *pkt;

if (esp32_wifi_iface == NULL) {

LOG_ERR(“network interface unavailable”);

return ESP_FAIL;

}

//为封包分配内存

pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len,

AF_UNSPEC, 0, K_NO_WAIT);

if (!pkt) {

LOG_ERR(“Failed to get net buffer”);

return ESP_FAIL;

}

//将封包数据从驱动搬运到pkt内

if (net_pkt_write(pkt, buffer, len) 《 0) {

LOG_ERR(“Failed to write pkt”);

goto pkt_unref;

}

//将封包抓发给IP层

if (net_recv_data(esp32_wifi_iface, pkt) 《 0) {

LOG_ERR(“Failed to push received data”);

goto pkt_unref;

}

//通知esp驱动封包数据已经使用完

esp_wifi_internal_free_rx_buffer(eb);

return ESP_OK;

pkt_unref:

net_pkt_unref(pkt);

return ESP_FAIL;

}

数据发送

数据发送的API在初始化时将eth_esp32_send注册进ethernet_api的send, IP层在呼叫L2的send时会找到ethernet_send进行发送,ethernet_send调用就是eth_esp32_send

static int ethernet_send(struct net_if *iface, struct net_pkt *pkt)

{

。。。

//这里api-》send就是注册的eth_esp32_send

ret = net_l2_send(api-》send, net_if_get_device(iface), iface, pkt);

。。。

}

static inline int net_l2_send(net_l2_send_t send_fn,

const struct device *dev,

struct net_if *iface,

struct net_pkt *pkt)

{

net_capture_pkt(iface, pkt);

return send_fn(dev, pkt);

}

static int eth_esp32_send(const struct device *dev, struct net_pkt *pkt)

{

const int pkt_len = net_pkt_get_len(pkt);

//找到frame

/* Read the packet payload */

if (net_pkt_read(pkt, DEV_DATA(dev)-》frame_buf, pkt_len) 《 0) {

return -EIO;

}

//使用hal esp32 wifi进行发送

/* Enqueue packet for transmission */

esp_wifi_internal_tx(ESP_IF_WIFI_STA, (void *)DEV_DATA(dev)-》frame_buf, pkt_len);

LOG_DBG(“pkt sent %p len %d”, pkt, pkt_len);

return 0;

}

待确认

Wifi的帧结构是802.11, 其帧结构和ethernet不一样,现在直接将hal esp32 wifi和zephyr ethernet对接,应该是esp做了相应的转换,具体如何,待确认。

编辑:jq

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

    关注

    12

    文章

    1990

    浏览量

    88698
  • API
    API
    +关注

    关注

    2

    文章

    2474

    浏览量

    67004
  • WIFI
    +关注

    关注

    82

    文章

    5531

    浏览量

    214384
  • ESP
    ESP
    +关注

    关注

    0

    文章

    198

    浏览量

    36705
  • 开源
    +关注

    关注

    3

    文章

    4343

    浏览量

    46435

原文标题:Zephyr ESP32 wifi驱动简析

文章出处:【微信号:ZephyrProject,微信公众号:ZephyrProject】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    乐鑫科技新品ESP32-H4亮点速递!

    的技术潜力。产品主要规格产品特性与适用场景1超低功耗ESP32-H4内部集成的DC-DC模块可高效管理电源,降低系统功耗,延长设备续航时间。同时,该设计使芯片能够
    的头像 发表于 04-16 18:05 304次阅读
    乐鑫科技新品<b class='flag-5'>ESP32</b>-H4亮点速递!

    新国标ESP32-C3充电宝驱屏方案,启明云端乐鑫代理及方案商

    破局。该方案的亮点如下:功能集成:乐鑫科技ESP32-C3芯片方案,集成Wi-Fi和蓝牙。直接驱动屏幕实时显示电池健康度、使用次数等重要参数,让用户对充电宝状态一
    的头像 发表于 03-17 18:19 422次阅读
    新国标<b class='flag-5'>ESP32</b>-C3充电宝驱屏方案,启明云端乐鑫代理及方案商

    ESP32/ESP8266开发板单向一对多ESP-NOW无线通信

    通过ESP-NOW无线通信协议实现ESP32开发板向多个ESP32/ESP 8266开发板发送数据。
    的头像 发表于 03-13 09:23 280次阅读
    <b class='flag-5'>ESP32</b>/<b class='flag-5'>ESP</b>8266开发板单向一对多<b class='flag-5'>ESP</b>-NOW无线通信

    ESP32驱动TFmini-S红外激光测距ToF模块进行测距

    本文介绍了TFmini-S红外激光测距ToF模块的基本特性,然后用ESP32开发板驱动TFmini-S模块进行测距,并在串口助手上显示出测距数据。
    的头像 发表于 03-06 14:43 331次阅读
    <b class='flag-5'>ESP32</b><b class='flag-5'>驱动</b>TFmini-S红外激光测距ToF模块进行测距

    ESP32 驱动瀚海微SD NAND 完整方案 + FAT/FAT32 驱动核心区别

    ESP32 驱动 SD NAND 的核心是基于SDIO 接口(SD NAND 主流通信方式,兼容 SPI 但速率更高),借助乐鑫官方esp-idf框架的SDMMC 驱动库实现,无需额外
    的头像 发表于 02-02 11:38 790次阅读
    <b class='flag-5'>ESP32</b> <b class='flag-5'>驱动</b>瀚海微SD NAND 完整方案 + FAT/FAT32 <b class='flag-5'>驱动</b>核心区别

    ESP32蓝牙驱动MAX98357对音频音乐播放

    本文介绍了MAX98357音频模块的基本特性,并利用ESP32的蓝牙功能程序驱动此模块,最后用手机蓝牙连接ESP32播放手机音乐
    的头像 发表于 12-19 19:55 3206次阅读
    <b class='flag-5'>ESP32</b>蓝牙<b class='flag-5'>驱动</b>MAX98357对音频音乐播放

    ESP8266和ESP32开发板常见的2种下载方式

    ESP32ESP8266是性价比很高而且使用较为广泛的的Wi-Fi模块,在物联网(IoT)领域的DIY项目中可以首先考虑这2款产品。 两款芯片都属于32位处理器。ESP32是低功耗双核80MHz
    的头像 发表于 11-10 20:30 1365次阅读
    <b class='flag-5'>ESP</b>8266和<b class='flag-5'>ESP32</b>开发板常见的2种下载方式

    低成本开源!用乐鑫科技ESP32-S3开发板轻松驱动无刷电机,保姆级教程来了!

    想用ESP32-S3开发板驱动无刷电机却不知从何下手?本教程将手把手教你完成从硬件连接到软件编程的全流程,无论你是新手还是有一定经验的开发者,都能轻松掌握!本教程代码已全部开源!后台私信关键词
    的头像 发表于 11-06 18:03 1113次阅读
    低成本开源!用乐鑫科技<b class='flag-5'>ESP32</b>-S3开发板轻松<b class='flag-5'>驱动</b>无刷电机,保姆级教程来了!

    乐鑫ESP32-C6和ESP32-C61究竟该如何选择?一文读懂本质区别

    乐鑫科技推出的ESP32-C6和ESP32-C61均支持Wi-Fi6,但定位不同。ESP32-C6是多协议枢纽,集成Wi-Fi6、蓝牙5、Zigbee和Thread,适合智能家居网关和
    的头像 发表于 10-28 14:17 2631次阅读
    乐鑫<b class='flag-5'>ESP32</b>-C6和<b class='flag-5'>ESP32</b>-C61究竟该如何选择?一文读懂本质区别

    ESP32驱动SPIFFS进行文件操作

    本篇文章介绍如何在ESP32开发板上使用SPIFFS(SPI Flash File System)进行文件操作。看下如何初始化SPIFFS文件系统、读取文件、列出文件、删除文件,并查看存储的剩余空间。
    的头像 发表于 08-05 18:11 4481次阅读
    <b class='flag-5'>ESP32</b><b class='flag-5'>驱动</b>SPIFFS进行文件操作

    zephyr设备驱动程序模型

        1:Zephyr 内核支持多种设备驱动程序。驱动程序是否可用取决于board 和驱动程序。 Zephyr 设备模型为配置作为系统一部
    的头像 发表于 07-29 10:34 839次阅读
    <b class='flag-5'>zephyr</b>设备<b class='flag-5'>驱动</b>程序模型

    ESP32开发板元件资料

    ESP32开发板元件
    发表于 07-21 14:47 17次下载

    用SPI玩转WiFi,RT-Thread ESP-Hosted驱动深度适配指南 | 技术集结

    还在为MCU的WiFi连接方案发愁?RT-Thread社区开源ESP-Hosted驱动,通过标准SPI接口即可实现,并且该仓库已整理成RT-Thread软件包。RT-ThreadESP-Hosted
    的头像 发表于 07-09 19:03 1889次阅读
    用SPI玩转<b class='flag-5'>WiFi</b>,RT-Thread <b class='flag-5'>ESP</b>-Hosted<b class='flag-5'>驱动</b>深度适配指南 | 技术集结

    基于ESP32C3的智能小车设计

    你有没有想过,从零开始亲手制作一辆坚固耐用的遥控越野车?今天,小编就带你走进一个融合机械、电子与物联网的精彩DIY项目——一款由 Seeed Studio XIAO ESP32C3 强力驱动的 3D打印4x4 RC漫游车!
    的头像 发表于 06-04 11:11 2836次阅读
    基于<b class='flag-5'>ESP32</b>C3的智能小车设计

    ESP32驱动MFRC522 RFID模块读写IC卡数据

    本文将介绍ESP32开发板驱动MFRC522 RFID模块,读取RFID卡原始数据、获取RFID卡的UID,并将个人数据添加到RFID卡中。
    的头像 发表于 05-28 15:52 1760次阅读
    <b class='flag-5'>ESP32</b><b class='flag-5'>驱动</b>MFRC522 RFID模块读写IC卡数据