(十)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_EXT
    bool
    #更改为
    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.a
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_debug.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/sdio_sif_esp.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/spi_sif_esp.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_io.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_file.o
  CC [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.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_ext.o
  CC [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: here
         case 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: here
         case SIP_AMPDU_TX_OPERATIONAL:
         ^~~~
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_mac80211.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_utils.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp_pm.o
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/testmode.o
  LD [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp8089-spi.o
  MODPOST 1 modules
  CC [M]  /home/project01/pro01/new_kernel/linux-5.7.1/spiwifi/ESP8089-SPI-github/esp8089-spi.mod.o
  LD [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>; //PE7
            interrupt= <136>; //PE8
            debug= <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.conf

udhcpc -i wlan0

ping 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 传文件


  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kashine

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值