(十)WiFi驱动--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>

本文主要是介绍(十)WiFi驱动--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、ESP-12F作无线网卡 

二、模块化WiFi驱动

1、无线驱动源码下载

2、无线驱动源码适配

3、设备树修改

4、模块驱动加载

📌 模块驱动加载命令

📌 驱动加载、遇到的问题、解决方法

📌 驱动问题解决  

5、启动网卡

6、连接互联网

7、apt-get命令测试

8、文件传输

三、内核WiFi驱动

1、内核驱动代码下载

2、设备树修改

3、内核无线驱动源码修改

4、无线网卡测试

四、参考内容


一、ESP-12F作无线网卡 

本文重点参考众人拾柴-F1C200S通过SPI使用ESP8089或ESP8266做无线网卡和四. 通过SPI使用ESP8266做无线网卡。通过使用去掉Flash的ESP-12F作为F1C200s的无线网卡,使F1C200s获得访问外网的能力。本文配置无线网卡驱动,在对ESP-12F复位之后,利用F1C200s通过SPI通信将固件下载到ESP-12F,并通过SPI接口进行网络数据传输(我的理解,如有错误,欢迎评论区指正)。至于本文的硬件电路,详见本专栏的第一篇文章。

Linux驱动有两种运行方式,第一种就是将驱动编译进Linux内核中,这样当Linux内核启动的时候就会自动运行驱动程序。第二种就是将驱动编译成模块(Linux下模块扩展名为.ko),在Linux内核启动以后使用“insmod”命令或“modprobe”命令加载驱动模块。在调试驱动的时候一般都选择将其编译为模块,这样我们修改驱动以后只需要编译一下驱动代码即可,不需要编译整个 Linux 代码。

再次强调:如果使用ESP-12F模块,请务必去掉模块中的Flash芯片!


二、模块化WiFi驱动

本节首先下载ESP8089无线驱动源码(ESP12-F同样适用),对源码进行修改后编译生成模块化驱动(.ko文件),在Debian文件系统中加载该驱动,解决加载过程中出现的一系列问题,最终配置网络,成功ping通百度。

驱动的移植工作主要是:

  • 配置复位引脚,完成对ESP-12F的复位;
  • 配置SPI通信,完成固件下载与网络通信;
  • 配置中断引脚,辅助通信。

1、无线驱动源码下载

在此处ESP8089-SPI/README.md at master · notabucketofspam/ESP8089-SPI · GitHub下载esp8089无线网卡驱动,(是的我们又是用的别人写好的驱动,慢慢来吧,先按照步骤做出来现象,后面理解原理),并在Linux5.7.1源码根目录创建spiwifi文件夹,将下载的源码放到该文件夹中。

2、无线驱动源码适配

首先修改无线驱动项目的KBUILD使其指向 Linux-5.7.1内核构建树的路径(内核源码目录)。KBUILD变量主要用来生成一些和汇编有关的文件(Kconfig是图形界面的描述文件)。并且添加架构和交叉编译器信息,至于本文为何使用arm-linux-gnueabi-编译器,怎么和迪卡、墨云等人的不同,原因见这里F1C200s无线网卡问题源码编译?。

# modify by kashine 5
# KBUILD ?= $(shell readlink -f /lib/modules/$(KVERS_UNAME)/build)
KBUILD ?= /home/project01/pro01/new_kernel/linux-5.7.1/
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-gnueabi-

修改KBUILD、ARCH、CROSS_COMPILE之后,使用make命令进行编译。然而并没有像迪卡那样报错:

*** WARNING: This kernel lacks wireless extensions.
Wireless drivers will not work properly.

为了不影响后续的操作,我们同样进行对内核源码目录中的/net/wireless/Kconfig文件开头部分进行以下修改

config WIRELESS_EXTbool#更改为def_bool y

前面我们提到需要对ESP12F进行复位,并且需要中断支持,一方面需要配置设备树,另一方面需要对驱动源码进行修改。在无线驱动源码目录中的spi_stub.c文件中进行如下修改,管脚编号对应关系为:PA0 -- 0;PB0 -- 32;PC0 -- 64;PD0 -- 96;PE0 -- 128。

修改完成以后,使用重新编译,编译输出log如下,警告可以忽略(变量声明位置不合适):

make -C /home/project01/pro01/new_kernel/linux-5.7.1/ M=/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github
make[1]: Entering directory '/home/project01/pro01/new_kernel/linux-5.7.1'AR      /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/built-in.aCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_debug.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/sdio_sif_esp.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_io.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_file.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_main.o
In file included from ./include/linux/mm_types.h:12:0,from ./include/linux/mmzone.h:21,from ./include/linux/gfp.h:6,from ./include/linux/slab.h:15,from ./include/linux/crypto.h:19,from ./include/crypto/hash.h:11,from ./include/linux/uio.h:10,from ./include/linux/socket.h:8,from ./include/linux/compat.h:15,from ./include/linux/ethtool.h:17,from ./include/linux/netdevice.h:37,from /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_main.c:17:
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_main.c: In function ‘esp_pub_init_all’:
./include/linux/completion.h:54:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]struct completion work = COMPLETION_INITIALIZER(work)^
./include/linux/completion.h:74:43: note: in expansion of macro ‘DECLARE_COMPLETION’# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)^~~~~~~~~~~~~~~~~~
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_main.c:81:2: note: in expansion of macro ‘DECLARE_COMPLETION_ONSTACK’DECLARE_COMPLETION_ONSTACK(complete);^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_main.c:221:0:
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/eagle_fw1.h: In function ‘esp_download_fw’:
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/eagle_fw1.h:8:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]static u8 eagle_fw1[] =^~~~~~CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_sip.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ext.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.o
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.c: In function ‘sip_send_ampdu_action’:
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.c:479:29: warning: this statement may fall through [-Wimplicit-fallthrough=]action->ssn = ssn;~~~~~~~~~~~~^~~~~
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.c:480:9: note: herecase SIP_AMPDU_RX_STOP:^~~~
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.c:481:31: warning: this statement may fall through [-Wimplicit-fallthrough=]action->index = index;~~~~~~~~~~~~~~^~~~~~~
/home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ctrl.c:482:9: note: herecase SIP_AMPDU_TX_OPERATIONAL:^~~~CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_mac80211.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_utils.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_pm.oCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/testmode.oLD [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp8089-spi.oMODPOST 1 modulesCC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp8089-spi.mod.oLD [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp8089-spi.ko
make[1]: Leaving directory '/home/project01/pro01/new_kernel/linux-5.7.1'

 3、设备树修改

添加SPI管脚复用spi0结点,注意在dtsi中未对spi0进行使能。

// 在pio分组添加
spi0_pc_pins: spi0-pc-pins {pins = "PC0","PC1","PC2","PC3";function = "spi0";};// 在soc分组下添加
spi0:spi@1c05000 {compatible = "allwinner,suniv-spi","allwinner,sun8i-h3-spi";reg = <0x01c05000 0x1000>;interrupts = <10>;clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;clock-names = "ahb", "mod";resets = <&ccu RST_BUS_SPI0>;status = "disabled";#address-cells = <1>;#size-cells = <0>;pinctrl-names = "default";pinctrl-0 = <&spi0_pc_pins>;
};

在dts文件中对spi0结点进行使能,为什么没有添加中断复位引脚呢?因为我们下载的源码是板级描述文件大概意思是,驱动源码和设备树没有关系,直接在代码中获取硬件信息),直接在源码中指定即可,也就是上一小节指定的中断和复位引脚。

&spi0 {status = "okay";
};

需要注意的一点是,我们需要在使能SPI驱动配置,在.config中保证如下驱动处于使能状态:

CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_SUN4I=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_SUN6I=y

此处有个坑,我们在配置.config文件的时候,一定要删除对应的注释,比如我们要配置使能CONFIG_SPI_ALTERA,那么一定要将对应的注释“CONIFG_SPI_ALTERA is not set"删除,否则可能无法成功使能对应驱动。详见warning: override: reassigning to symbol 问题解决。

 4、模块驱动加载

将编译产生的esp8089-spi.ko驱动文件拷贝到Debian根文件系统(TF卡rootfs分区)的/lib/modules/5.7.1文件夹下,如果文件夹路径不存在需要手动创建对应的文件夹,文件夹名字一定要下配置正确,5.7.1是内核版本号,需要根据实际情况修改,当然,重新编译过的Linux内核镜像文件设备树文件也需要更新。注意:本文直接使用的Debian根文件系统,因为buildroot制作的根文件系统各种命令都缺,而buildroot编译过于繁琐耗时。

📌 模块驱动加载命令

更新对应的文件之后,上电启动,使用ls命令可以看到我们编译产生的驱动文件。我们首先说明模块驱动的加载方式:

驱动编译完成以后扩展名为.ko,有两种命令可以加载驱动模块:insmod和modprobe。 insmod 命令不能解决模块的依赖关系,比如 drv.ko 依赖 first.ko 这个模块,就必须先使用insmod 命令加载 first.ko 这个模块,然后再加载 drv.ko 这个模块。而modprobe 会分析模块的依赖关系,然后会将所有的依赖模块都加载到内核中,modprobe 命令默认会去/lib/modules/<kernel-version>目录中查找模块。

另外有一点需要注意,使用modprobe命令之前需要使用depmod命令,depmod命令可检测模块的相依性,供modprobe在安装模块时使用。

📌 驱动加载、遇到的问题、解决方法

进入/lib/modules/5.7.1文件夹,使用depmod命令检测驱动模块相依性,但是会报错如下,提示没有对应的文件(挠头,怎么会没有文件呢?)。

参考这个博客depmod: ERROR: could not open directory /lib/modules/5.2.0-licheepi-zero+: No such file or dir,将内核中的modules.order和modules.builtin这两个文件拷贝到根文件系统的/lib/modules/5.7.1文件夹中,这两个文件在内核源码根目录下,如下图所示:

复制完成,重新上电启动,在/lib/modules/5.7.1文件夹使用depmod命令不再出现报错,使用depmod完成模块相依性检测后,通过modprobe命令加载驱动,需注意的是,以下两个命令只有后者才可以正常执行。

modprobe esp-8089.ko # 无法正常运行
modprobe esp-8089    # 可正常运行

📌 驱动问题解决  

modprobe执行成功,但是我们的驱动并没有正确加载,细心的朋友可以发现在加载完驱动之后,打印出以下信息,这说明我们的驱动代码既没有找到SPI主设备,有没有创建SPI从设备,这显然是不允许的,因为SPI是我们进行无线通信的基础。

esp8089_spi: FAILED to find master
esp8089_spi: FAILED to create slave

 经过迪卡大佬的排查,发现是无线驱动代码中spi_stub.c文件出错:

struct spi_device* sif_platform_new_device(void) {master = spi_busnum_to_master(esp_board_spi_devices[0].bus_num);if(!master)printk("esp8089_spi: FAILED to find master\n");// 报错spi = spi_new_device( master, esp_board_spi_devices );if(!spi)printk("esp8089_spi: FAILED to create slave\n");// 报错printk("esp8089_spi: I will go dead\n");if(spi_setup(spi))printk("esp8089_spi: FAILED to setup slave\n"); printk("esp8089_spi: I am OK\n");return spi;
}

也就是说下面的代码出了问题:

master = spi_busnum_to_master(esp_board_spi_devices[0].bus_num);

其中,esp_board_spi_devices[]spi_stub.c文件前面定义的结构体:

static struct spi_board_info esp_board_spi_devices[] = {{.modalias = "ESP8089_0",.max_speed_hz = MAX_SPEED_HZ,.bus_num = 1,.chip_select = 0,.mode = 0,},
};

迪卡分析:

bus_num就是1;spi_busnum_to_master(1)研究一下;每个master都对应一个bus num。
注册spi slave设备(ESP-12F SPI),由dts解析得到,dts会指定spi slave挂载在哪个bus num下,由bus num就可以得到对应的spi master 了。(可能不合理,但能跑)

 将bus_num改为0后,重新编译无线驱动代码并上电运行,打印信息如下:

奇怪不奇怪,我们的spi0分明没有作为其他设备的通信接口,但是报错信息提示我们片选地址已被使用。 

墨云分析:

可见spi_master已经注册成功,但是chipselect 0 already in use,说明当前配置SPI0,中片选为0的地址已经被使用,实时上我们并未链接其他设备,所以怀疑是其他问题,通过查找资料SPI通信模式分为4中模式,经过逐一测试发现SPI_MODE_3也就是(4)可用。

根据墨云的分析对无线驱动代码spi_stub.c文件中的代码进行修改如下:

static struct spi_board_info esp_board_spi_devices[] = {{.modalias = "ESP8089_0",.max_speed_hz = MAX_SPEED_HZ,.bus_num = 0,// modify by kashine 5.chip_select = 0,.mode = SPI_MODE_3,// modify by kashine 5},
};

修改后重新编译,上电后加载esp-8089驱动。注意,如果使用我的硬件电路,一定要注意,如果屏幕较大,并且同时使用无线模块,可能导致供电不足,现象是屏幕熄灭、串口关闭,解决办法是除串口USB之外,利用USB HUB扩展的USB接口增加一个USB供电。模块驱动加载日志如下所示:

root@likaiqin-virtual-machine:/lib/modules/5.7.1# modprobe esp8089-spi
[  128.493238] esp8089_spi: loading out-of-tree module taints kernel.
[  128.508273] esp8089_spi: EAGLE DRIVER VER bdf5087c3deb
[  129.114478] esp8089_spi: esp_spi_dummy_probe enter
[  129.120111] esp8089_spi: register board OK
[  129.124623] esp8089_spi: sem_timeout = 0
[  129.340023] esp8089_spi: ESP8089 power up OK
[  129.345448] esp8089_spi: esp_spi_probe ENTER
[  129.350322] esp8089_spi: esp_setup_spi
[  129.354477] esp8089_spi: sif_spi_protocol_init
[  129.359437] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1559
[  129.370920] esp8089_spi: fail_count = 0
[  129.498009] rx:[0x00],[0x00],[0x00],[0x00],[0x00],[0x00],[0x00],[0x00],[0x00],[0x00]
[  129.606625] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1559
[  129.618134] esp8089_spi: fail_count = 1
[  129.733228] rx:[0x3f],[0x09],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  129.841860] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1559
[  129.853379] esp8089_spi: fail_count = 2
[  130.054228] rx:[0xff],[0xff],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  130.661815] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1578
[  130.679097] rx:[0xff],[0xff],[0x01],[0x10],[0xff],[0xff],[0x00],[0xff],[0xff],[0xff]
[  131.186870] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1591
[  131.230265] rx:[0xff],[0xff],[0x00],[0x90],[0xff],[0xff],[0x00],[0xff],[0xff],[0xff]
[  131.751505] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1603
[  131.795833] rx:[0xff],[0x00],[0x02],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  132.317567] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1617
[  132.363805] rx:[0xff],[0x00],[0x03],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  132.886662] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1630
[  132.935628] rx:[0xff],[0x00],[0x02],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  133.459909] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1643
[  133.512035] rx:[0xff],[0x00],[0x03],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  134.037354] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  134.091882] rx:[0xff],[0xff],[0x00],[0x00],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  134.617589] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  134.672142] rx:[0xff],[0xff],[0x00],[0x25],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  135.198185] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  135.254763] rx:[0xff],[0xff],[0x00],[0x10],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  135.780766] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  135.834891] rx:[0xff],[0xff],[0x00],[0x12],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  136.361421] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  136.416215] rx:[0xff],[0xff],[0x00],[0x00],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  136.942723] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  136.997550] rx:[0xff],[0xff],[0x00],[0x06],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  137.523992] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  137.578214] rx:[0xff],[0xff],[0x00],[0x00],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  138.104701] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1655
[  138.159169] rx:[0xff],[0xff],[0x00],[0x00],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  138.685676] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1668
[  138.740390] rx:[0xff],[0x00],[0x00],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  138.767739] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1681
[  138.834001] rx:[0xff],[0x00],[0x02],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  138.861304] esp8089_spi: /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.c, 1694
[  138.963902] rx:[0xff],[0x00],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
[  139.998233] esp8089_spi: esp_pub_init_all
[  140.021398] esp8089_spi: esp_download_fw
[  140.459848] esp8089_spi: sif_platform_irq_init enter
[  150.889369] resetting event timeout
[  150.910574] esp8089_spi: esp_init_all failed: -110
[  150.932966] esp8089_spi: first error exit
[  150.954067] esp8089_spi: esp_spi_probe EXIT
[  150.975268] esp8089_spi: sem_timeout = 0
[  150.995481] esp8089_spi: esp_spi_init err 0
root@likaiqin-virtual-machine:/lib/modules/5.7.1# 

从上面的驱动加载日志中可以就看出两个信息一个是固件下载成功,一个是超时问题。

针对超时问题,采用迪卡的屏蔽操作,相当于强制跳过超时警告执行。修改无线驱动源码的esp_sip.c文件如下:

extern struct task_struct *sif_irq_thread;// 声明变量
sip_poll_bootup_event(struct esp_sip *sip)
{int ret = 0;esp_dbg(ESP_DBG_TRACE, "polling bootup event... \n");if (gl_bootup_cplx)ret = wait_for_completion_timeout(gl_bootup_cplx, 2 * HZ);esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);if (ret <= 0) {esp_dbg(ESP_DBG_ERROR, "bootup event timeout\n");// modify by kashine 5// return -ETIMEDOUT;sip->epub->wait_reset = 0;wake_up_process(sif_irq_thread);esp_dbg(ESP_DBG_ERROR, "for unknow reason,we may not be informed the boot/rst complete event, assume it completed and continue here\n");msleep(50);}    if(sif_get_ate_config() == 0){ret = esp_register_mac80211(sip->epub);}
sip_poll_resetting_event(struct esp_sip *sip)
{int ret = 0;esp_dbg(ESP_DBG_TRACE, "polling resetting event... \n");if (gl_bootup_cplx)ret = wait_for_completion_timeout(gl_bootup_cplx, 10 * HZ);esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);if (ret <= 0) {esp_dbg(ESP_DBG_ERROR, "resetting event timeout\n");// modify by kashine 5// return -ETIMEDOUT;sip->epub->wait_reset = 0;wake_up_process(sif_irq_thread);esp_dbg(ESP_DBG_ERROR, "for unknow reason,we may not be informed the boot/rst complete event, assume it completed and continue here\n");msleep(50);}    esp_dbg(ESP_DBG_TRACE, "target resetting %d %p\n", ret, gl_bootup_cplx);

修改完成,重新编译上电启动,加载驱动后, 输出日志如下(部分):

 5、启动网卡

至此,需要加载esp8089无线驱动,然后使用命令ifconfig wlan0 up启动网卡:

使用ifconfig查看网卡:

 6、连接互联网

Debian根文件系统制作的时候,我们已经安装了对应的网络组件,此处我们使用组件wpa_supplicant连接wifi,wifi为我的手机热点。在Debian根文件系统的/etc目录下创建配置文件,并按照以下格式输入wifi信息:

vi /etc/wpa_supplicant.conf
network={ssid="wifi名称"psk="wifi密码"
}

然后执行如下指令进行wifi连接:

wpa_supplicant -B -d -i wlan0 -c /etc/wpa_supplicant.conf

执行udhcpc -i wlan0命令,获取IP地址:

 ping一下百度试试:

7、apt-get命令测试

之前我们在制作Debian根文件系统的时候,安装过evtest触摸屏测试软件,现在我们把它卸载掉,然后重新安装,以此测试apt-get安装软件是否正常。首先使用dpkg --list查看是否安装了evtest软件。

如果安装了evtest软件,使用apt-get remove命令卸载在卸载过程中,弹出了一堆的报错信息如下,我们来分析一下,systemd-journal invoked oom-killer,提示进程被杀掉,OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,防止内存耗尽而自动把该进程杀掉。这样看应该是内核检测到系统内存不足、挑选并杀掉某个进程。

为什么会内存不足呢?DDR有64M,我们在制作根文件系统的时候添加了swap分区,将一部分硬盘作为虚拟内存,使用free命令查看一下内存的使用情况,咦,swap分区怎么是0?后来发现我多次制作根文件系统,在重新制作根文件系统的时候没有添加swap分区。

按照Debian根文件系统制作博客的教程重新建立swap分区如下:

重新卸载evtest软件,不再报错。

 使用dpkg --list命令查看是否成功卸载,发现不存在evtest软件,正常卸载。

重新安装evtest软件,正常安装。至此,F1C200s无线网卡驱动完成,可以直接使用apt-get命令安装软件了,不必在Ubuntu下使用qemu模拟器安装。

8、文件传输

如何在虚拟机中的Ubuntu和我们的开发板之间传输文件呢?

首先保证我们的物理机、Ubuntu虚拟机、开发板在同一个热点的同一个网段下,可以相互ping通,如下图所示,这里我就不再赘述,详细内容参考linux开发板访问互联网 笔记本win10中虚拟机_Kashine的博客-CSDN博客。

为了防止混淆,使用vi /etc/hostname命令修改主机名,将主机Ubuntu命名为Ubuntu,开发板命名为:Debian。

Debian和Ubuntu都要打开允许ssh以root登录, 使用 vi /etc/ssh/sshd_config命令打开文件写入PermitRootLogin yes,如果未使能服务端SSH服务配置了root用户登录策略,会产生“Permission denied, please try again.”的报错提示。

配置完成后,使用如下命令进入Debian:

#ssh root@Debian ip
ssh root@192.168.180.164

 可以在Ubuntu中控制Debian播放mp3文件或者是mp4文件:

跑题了,跑题了,怎么放音乐看视频去了,大年初一可以放松一下,哈哈。来看文件传输,首先使用exit命令退出上面的远程访问。如果欲将Ubuntu中的文件复制到Debian中,应该怎么操作呢?在Debian中使用指令scp root@192.168.180.164(Ubuntu的ip):/Ubuntu中文件路径 /拷贝到Debian中的位置可以将Ubuntu中文件拷贝到Debian中。可以看到传输速度为734.4KB/s还可以吧,说的过去,整个过程不消耗流量哦(我是用的手机热点)。

 scp root@192.168.180.59:/mnt/hgfs/Desktop/opencv3.4.13bit32.rar ./

至此, 本文的需求全部解决,至于墨云所说开发板只要大量发送数据,比如作为Web服务器被访问,wifi就挂了,本文测试了在Ubuntu下将Debian中的文件拷贝到Ubuntu,也就是开发板发送数据,并未出现报错或者wifi断开的情况。

我错了我错了,又试了一次,wifi挂了。

Debian接收数据经过连续多次测试正常。

经连续多次测试发现发送数据也没有问题,bug无法复现,可能是发送的文件太小,随缘解决吧。

至此,无线网卡功能全部实现,但我们发现每次上电之后都需要加载驱动,很是麻烦,能不能直接将驱动编译到内核呢?当然可以。 


三、内核WiFi驱动

1、内核驱动代码下载

首先在F1C200S修改ESP8089源码,由原来板极描述文件改为设备树,一键配置

或者墨云提供的下载链接https://files.cnblogs.com/files/twzy/esp8089.zip(复制到地址栏下载)下载内核wifi驱动代码源码,其实此源码大部分和上面模块化驱动相同,只是此处使用设备树获取设备信息,将驱动文件直接编译到内核。下载的代码也是在上面的基础上修改而来的,详见第一个链接。

2、设备树修改

设备树修改如下:

&spi0 {status = "okay";   esp8089@0 {status = "okay";compatible = "boss,esp8089";spi-cpol;spi-cpha;reg = <0>;spi-max-frequency = <30000000>;reset= <135>; //PE7interrupt= <136>; //PE8debug= <0>;}; 
};
spi0:spi@1c05000 {compatible = "allwinner,suniv-spi","allwinner,sun8i-h3-spi";reg = <0x01c05000 0x1000>;interrupts = <10>;clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;clock-names = "ahb", "mod";resets = <&ccu RST_BUS_SPI0>;status = "disabled";#address-cells = <1>;#size-cells = <0>;pinctrl-names = "default";pinctrl-0 = <&spi0_pc_pins>;
};

3、内核无线驱动源码修改

首先将内核无线驱动源码复制到内核源码的/drivers/staging/目录下,因为我们使用的是SPI0,因此无线驱动源码中的spi_stub.c文件需要修改如上一小节所示。

然后在spi_stub.c文件对我们使用的管脚进行修改,需要修改吗?是不需要的,我们之前对管脚进行修改是因为我们用的spi_stub.c文件中的变量描述硬件信息,现在我们使用设备树描述硬件设备信息,我们下载的代码中已经集成设备树解析函数,因此我们无需再次在代码中指定硬件信息。

加入防止超时的代码:

extern struct task_struct *sif_irq_thread;

修改完成使用make命令进行编译,发现以下错误,提示的意思是函数本来是void类型,结果我们按照有返回值的形式使用函数,esp_debug.c文件中的内容进行修改:

 esp_debug.c文件修改完成如下所示,重新使用make命令编译内核,不再报错。

4、无线网卡测试

编译完成,更新内核镜像文件,上电启动,内核自动加载无线驱动,无需手动modprobe esp8089.ko,进入Debian系统后,依次输入如下命令:

ifconfig wlan0 up #启动网卡
ifconfig #查看现有网卡vi /etc/wpa_supplicant.conf # 配置WiFi信息network={ssid="热点"psk="密码"
}wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.confudhcpc -i wlan0ping www.baidu.com

成功ping通百度,此次连接的不是手机热点,而是WiFi,延迟略微降低。对于文件传输等请自行测试,本文不再赘述。


四、参考内容

1. 众人拾柴-F1C200S通过SPI使用ESP8089或ESP8266做无线网卡 / 全志 SOC / WhyCan Forum(哇酷开发者社区)

2. 小白自制Linux开发板 四. 通过SPI使用ESP8266做无线网卡 - 淡墨青云 - 博客园

3. [ESP8089-SPI移植支持设备树]F1C200S修改ESP8089源码,由原来板极描述文件改为设备树,一键配置。

4. i.MX6ULL Linux阿尔法开发板 — 正点原子资料下载中心 1.0.0 文档

5. depmod: ERROR: could not open directory /lib/modules/5.2.0-licheepi-zero+: No such file or dir

6.modprobe: FATAL: Module xxx.ko not found in directory /lib/modules/$(uname -r)_SoldierJazz2021的博客-CSDN博客

7.warning: override: reassigning to symbol 问题解决_爱就是恒久忍耐的博客-CSDN博客_reassigning to symbol

8.腾讯云的轻量应用服务器修改主机名hostname的方法 - 知乎

9.使用ssh 连接linux 并传送文件_SIXTOME的博客-CSDN博客_linux ssh 传文件


这篇关于(十)WiFi驱动--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/155025

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧