zoukankan      html  css  js  c++  java
  • 小白自制Linux开发板 四. 通过SPI使用ESP8266做无线网卡

    本文章基于 WhyCan Forum(哇酷开发者社区)

    https://whycan.com/t_4149.html
    https://whycan.com/t_5870.html
    整理而成。

    为了尊重原作者和其他贡献者,所以该篇涉及到的部分代码和资料只提供原贴资源链接。

    前言

    前几次我们一起完成了那个小小开发板的设计,并且成功运行自己移植的Linux系统,但是,那个小板并没有什么用,接下来这几篇我们一起来做点有意思的事情吧。

    首先改变一下电路设计,随着小板的完成,我需要添加各种功能,但是因为每种功能设计的时候都心里没底,需要做专门的验证板来进行实验,那我就不得不将soc以及电源相关的容阻器件进行重新焊接,不但费时费力,还容易造成相关元件损坏(别问我怎么知道的)。所以这里依然借(bai)鉴(piao)大佬们的思路,分为核心板和底板两部分。

    核心板主要承载soc以及核心供电相关的一些元件,通过M.2接口引出除了TV部分codec之外的大部分引脚,原理图如下:

    核心板的pcb使用4层设计,尺寸大概是2.2mm*4mm,效果图如下:

     

    为啥起名叫SnailCard的呢,因为这个板子用的核心确实很慢就像蜗牛一样,还因为我们家那个小祖宗喜欢蜗牛^_^

    底板的原理图如下

     底板使用两层设计,我们看到底板的资源十分丰富,除了本篇讲的ESP-12F(esp8266的模组)无线网卡,还有TFT屏幕、使用FE8.1扩展的usb接口、音频接口等,后续的文章会以此进行说明,另外供电与串口部分改为了Type-C 口,与时俱进嘛。

    效果如如下:

     需要注意的是,ESP12-F的铁皮外壳和里面的Flash芯片我们到时候会去掉,这里的WIFI天线部分处理并不符合要求,所以信号会有影响。

    需要注意一下底板Gerber文件打样处理,焊接元件的时候,两个USB之间钽电容画反了,所以需要注意正负极反过来

    否则会爆炸吆!!

    实物如下:

     

     核心板、底板硬件资料下载:

    https://files.cnblogs.com/files/twzy/SnailCard%E7%A1%AC%E4%BB%B6.zip

    需要注意一下:

    1. 核心板中各两个json文件分别对应原理图和pcb图,底板因为原来的PCB图改动过,所以只给出了原理图;
    2. zip文件为最终生成的Gerber文件,该文件可以直接提供给厂家生产pcb;
    3. 核心板打样一定选择厚度为0.8mm

    测试镜像文件:

    链接:https://pan.baidu.com/s/1uG4MTF008DliohcKo6IuqQ
    提取码:xnpz

    前期分享的那个镜像文件是有问题的,使用新的替换。

     现在嘉立创、捷配等一系列PCB厂商都开启了免费打样并且包邮的活动,所以还在等什么。

    1. 硬件设计

    1.1 接线表

    F1C200SESP8266ExESP-12F
    SPI-MOSI SDIO_CMD(GPIO 11) ESP_CS
    SPI-MISO SDIO_DATA_0(GPIO 7) ESP_MISO
    SPI-CS SDIO_DATA_3(GPIO 10) ESP_GPIO10
    WIFI_INT(PE8) SDIO_DATA_1(GPIO 8) ESP_MOSI
    SPI-CLK SDIO_CLK(GPIO 6) ESP_CLK
    WIFI_RESET(PE7) CHOP_PU ESP_EN(RST)

    1. 如果是用是Exp8266芯片,请参考第一列和第二列,使用ESP-12F模块请参考第一列和第三例
    2. 如果使用ESP-12F模块,请务必去掉模块中的Flash芯片

    1.2 电位

    该图来源于驱动参考文档,另外不同于nodeMCU模组,这里的GPIO15 需要拉高,GPIO2需要拉低

    1.3 个人接线图

    F1c100s/F1c200s 引脚图(注意此图中元件为自制的核心板,所以引脚标号与原始标号不一致,使用对应元件名称即可。)
    SOC引脚

    核心板引脚

    使用SPI0作为通信接口
    使用PE7引脚作为复位引脚
    使用PE8引脚作为中断引脚

    ESP12-F引脚

    这里使用ESP-12F 重置使用使能引脚(EN)来控制(官网推荐)。

    这是其中某次的成品图(后来这部分无论核心板还底板都有过调整,但是软件部分都是一样的)

    2. 驱动配置

    esp8089-spi的驱动代码地址
    https://github.com/notabucketofspam/ESP8089-SPI/

    如果无法现在可以通过这个网址下载:

    https://whycan.cn/files/members/3907/ESP8089-SPI_20200509.7z

    【注意:这部分代码是编译成独立的驱动文件,手动加载才能运行,如果想直接集成在内核可以直接下载 3节的代码】

    项目说明文档中说,可以使用ESP8266或者ESP8089都是可以的。只不过ESP8266需要把SPI flash拆掉

    2.1 编译配置

    接下来修改驱动项目的KBUILD,指向 Linux-5.7.1内核源码目录。

    2.2 处理内核不支持警告

    使用

    make ARCH=arm CROSS_COMPILE=arm-linux-

    编译驱动时候出现这个警告需要处理一下命令进行编译,得来如下结果:

    #make ARCH=arm CROSS_COMPILE=arm-linux-
    
    *** WARNING: This kernel lacks wireless extensions.
    Wireless drivers will not work properly.
    
    
    make -C /home/twzy/linuxCard/kernel/linux-5.7.1/ M=/home/twzy/linuxCard/Driver/ESP8089-SPI
    make[1]: 进入目录“/home/twzy/linuxCard/kernel/linux-5.7.1”
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/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/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:17:
    /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c: 在函数‘esp_pub_init_all’中:
    ./include/linux/completion.h:54:2: 警告: ISO C90 不允许混合使用声明和代码 [-Wdeclaration-after-statement]

    先分析一下这部分警告信息

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

    那么我们就去搜一下。进行分析。
    查看esp8089-spi的Makefile,发现这么一句话,

    config_check:
        @if [ -z "$(CONFIG_WIRELESS_EXT)$(CONFIG_NET_RADIO)" ]; then 
            echo; echo; 
            echo "*** WARNING: This kernel lacks wireless extensions."; 
            echo "Wireless drivers will not work properly."; 
            echo; echo; 
        fi

    在内核目录使用

    make ARCH=arm CROSS_COMPILE=arm-linux-

    然后按下/键,进行搜索CONFIG_WIRELESS_EXT
    找到

    Symbol: WIRELESS_EXT [=n ]
     │ Type  : bool 
     │   Defined at net/wireless/Kconfig:2 
     │   Depends on: NET [=y] && WIRELESS [=y]

    然后在kernel/net/wireless/Kconfig中找WIRELESS_EXT

    config WIRELESS_EXT
        bool

    更改为

    config WIRELESS_EXT
        def_bool y

    再次编译:

    $ make ARCH=arm CROSS_COMPILE=arm-linux-
    make -C /home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf M=/home/twzy/linuxCard/Driver/ESP8089-SPI
    make[1]: Entering directory '/home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf'
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_debug.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/sdio_sif_esp.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_io.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_file.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/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/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:17:
    /home/twzy/linuxCard/Driver/ESP8089-SPI/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/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:81:2: note: in expansion of macro ‘DECLARE_COMPLETION_ONSTACK’
      DECLARE_COMPLETION_ONSTACK(complete);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:221:0:
    /home/twzy/linuxCard/Driver/ESP8089-SPI/eagle_fw1.h: In function ‘esp_download_fw’:
    /home/twzy/linuxCard/Driver/ESP8089-SPI/eagle_fw1.h:8:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
     static u8 eagle_fw1[] =
     ^~~~~~
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_sip.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_ext.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_ctrl.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_mac80211.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_utils.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_pm.o
      CC [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/testmode.o
      LD [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.o
      Building modules, stage 2.
      MODPOST 1 modules
      CC      /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.mod.o
      LD [M]  /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.ko
    make[1]: Leaving directory '/home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf'

    没有刚才的提示信息了就OK了,

    其他的警告都是不在最开始声明变量的警告,可以忽略。

    需要注意处理完成这个后内核也需要同步更新

    2.3 修改设备树

    找到设备树
    suniv-f1c100s.dtsi文件
    在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>;
            };

    suniv-f1c100s-licheepi-nano.dts文件下添加

    &spi0 {
            pinctrl-names = "default";
            pinctrl-0 = <&spi0_pc_pins>;
            status = "okay";
    };

    2.4 处理驱动加载问题

    将生成的 esp8089-spi.ko驱动文件放置到 TF卡rootfs 分区 /lib/modules/5.7.1文件夹下,如果没有需要手动mkdir创建了文件夹,另外将重新编译过的Linux内核zImage与设备树dtb文件也更新一下

    运行开发板,进入/lib/modules/5.7.1文件夹,如果将esp8089-spi.ko放置到其他文件夹下执行会报如下类似的错误,最后的数字是Linux内核版本,根据提示建立对应文件夹即可
    执行modprobe esp8089-spi.ko 命令加载驱动

    # modprobe esp8089-spi.ko
    modprobe: can't change directory to '5.7.1': No such file or directory

    将驱动放入对应的文件夹下
    再次modprobe esp8089-spi.ko

    # modprobe esp8089-spi.ko
    modprobe: can't open 'modules.dep': No such file or directory

    这里需要我们重新取编译编译文件系统
    处理方法如下:
    https://www.cnblogs.com/twzy/p/15126656.html

    加载depmod

    # cd /lib/modules/5.7.1/
    # ls
    esp8089-spi.ko
    # depmod
    # ls
    esp8089-spi.ko   modules.alias    modules.dep      modules.symbols

    加载驱动

    # modprobe esp8089-spi.ko
    [   59.630001] esp8089_spi: loading out-of-tree module taints kernel.
    [   59.682075] esp8089_spi: EAGLE DRIVER VER bdf5087c3deb
    [   60.305428] esp8089_spi: FAILED to find master
    [   60.328536] esp8089_spi: FAILED to create slave
    [   60.351455] Unable to handle kernel NULL pointer dereference at virtual address                                                            000001a8
    [   60.396146] pgd = (ptrval)
    [   60.417170] [000001a8] *pgd=83254831, *pte=00000000, *ppte=00000000
    [   60.460005] Internal error: Oops: 17 [#1] ARM
    [   60.482718] Modules linked in: esp8089_spi(O+)
    [   60.505401] CPU: 0 PID: 122 Comm: modprobe Tainted: G           O      5.7.1
    [   60.550047] Hardware name: Allwinner suniv Family
    [   60.572839] PC is at spi_setup+0x4/0x164
    [   60.594988] LR is at sif_platform_new_device+0x38/0x88 [esp8089_spi]
    [   60.636851] pc : [<c0423420>]    lr : [<bf00023c>]    psr: 60000013
    
         …………
    
    [   61.895790] [<c0423420>] (spi_setup) from [<00000000>] (0x0)
    [   61.940327] Code: ebff0d15 eafffff9 c080caa4 e92d4030 (e59031a8)
    [   61.985796] ---[ end trace b39325ed7e1d8da4 ]---
    Segmentation fault

    日志中我们发现

    [   60.305428] esp8089_spi: FAILED to find master
    [   60.328536] esp8089_spi: FAILED to create slave

    所以我们要找到注册master 和 slave 的位置。

    2.5 驱动修改适配

    当我们通过日志内容找到文件 spi_stub.c 后,
    一起来修改吧:

    struct spi_device* sif_platform_new_device(void) {
      master = spi_busnum_to_master(esp_board_spi_devices[0].bus_num);
      spi = spi_new_device( master, esp_board_spi_devices );
      if(!spi)
        printk("esp8089_spi: FAILED to create slave
    ");
      if(spi_setup(spi))
        printk("esp8089_spi: FAILED to setup slave
    ");
      return spi;
    }

     知道注册函数,以及注册结构体

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

    其中,esp_board_spi_devices[]为代码前面定义的结构体

    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设备,由dts解析得到,dts会指定spi slave 挂载在哪个bus num下,由bus num就可以得到对应的spi master 了

    因为我们使用的spi0
    所以将bus_num改为0之后(此处不知这种解释是否符合理)

    # modprobe esp8089-spi
    [   11.554796] esp8089_spi: loading out-of-tree module taints kernel.
    [   11.606600] esp8089_spi: EAGLE DRIVER VER bdf5087c3deb
    [   12.230317] esp8089_spi: esp_spi_dummy_probe enter
    [   12.254156] sun6i-spi 1c05000.spi: chipselect 0 already in use
    [   12.296718] esp8089_spi: FAILED to create slave
    [   12.342262] Unable to handle kernel NULL pointer dereference at virtual addre               ss 000001a8
    [   12.387280] pgd = (ptrval)

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

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

    另外我们顺便修改一下频率,改为30Mhz:

    //#define SPI_FREQ (10000000)
    //#define SPI_FREQ (20000000)                             //  1. 22.5Mhz     2. 45Mhz
    #define SPI_FREQ (30000000)                             //  1. 22.5Mhz     2. 45Mhz

    另外还要修改中断脚复位脚,还是在spi_stub.c文件中:

    中断脚

    复位脚

     

    2.6 内核编译配置

    再修改内核编译文件.config,用于启用相关SPI功能。

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

    执行结果如下, 

    # cd /lib/modules/5.7.1/
    # modprobe esp8089-spi
    [   29.008363] esp8089_spi: loading out-of-tree module taints kernel.
    [   29.025084] esp8089_spi: EAGLE DRIVER VER bdf5087c3deb
    [   29.631516] esp8089_spi: try to use 0
    [   29.637763] esp8089_spi: esp_spi_dummy_probe enter
    [   29.644630] esp8089_spi: register board OK
    [   29.650529] esp8089_spi: sem_timeout = 0
    [   29.872020] esp8089_spi: ESP8089 power up OK
    [   29.878555] esp8089_spi: esp_spi_probe ENTER
    [   29.884786] esp8089_spi: esp_setup_spi
    [   29.890336] esp8089_spi: sif_spi_protocol_init
    [   29.896621] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
    [   29.907012] esp8089_spi: fail_count = 0
    [   30.024997] rx:[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
    [   30.135388] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
    [   30.145770] esp8089_spi: fail_count = 1
    [   30.265689] rx:[0xff],[0x09],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
    [   30.376023] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
    [   30.386385] esp8089_spi: fail_count = 2
    [   30.507530] rx:[0xff],[0xff],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
    [   31.116845] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1578
    [   31.143207] rx:[0xff],[0xff],[0x01],[0x10],[0xff],[0xff],[0x00],[0xff],[0xff],[0xff]
    
      ………………
       
    [   38.628868] rx:[0xff],[0x00],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
    [   39.659517] esp8089_spi: esp_pub_init_all
    [   39.665431] esp8089_spi: esp_download_fw
    [   40.095380] esp8089_spi: sif_platform_irq_init enter
    [   50.402011] resetting event timeout
    [   50.407306] esp8089_spi: esp_init_all failed: -110
    [   50.413944] esp8089_spi: first error exit
    [   50.419686] esp8089_spi: esp_spi_probe EXIT
    [   50.425909] esp8089_spi: sem_timeout = 0
    [   50.431610] esp8089_spi: esp_spi_init err 0
    # 

    通过日志发现,Esp8266固件已经下载进去了,但是出现了重置超时问题。

    2.7 处理重置超时检测

    这里使用这种方式暂时屏蔽超时检测
    修改esp_sip.c文件

    在声明变量:

    extern struct task_struct *sif_irq_thread;

    修改sip_poll_bootup_event函数

    sip_poll_bootup_event(struct esp_sip *sip)
    {
        int ret = 0;
    
            esp_dbg(ESP_DBG_TRACE, "polling bootup event... 
    ");
    
        if (gl_bootup_cplx)
            ret = wait_for_completion_timeout(gl_bootup_cplx, 2 * HZ);
    
        esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]
    ", ret);
        if (ret <= 0) {
            esp_dbg(ESP_DBG_ERROR, "bootup event timeout
    ");
           //修改了一下代码
               //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
    ");
                msleep(50);
        }    
    
        if(sif_get_ate_config() == 0){
            ret = esp_register_mac80211(sip->epub);
        }
    
    #ifdef TEST_MODE
            ret = test_init_netlink(sip);
            if (ret < 0) {
                    esp_sip_dbg(ESP_DBG_TRACE, "esp_sdio: failed initializing netlink
    ");
            return ret;
        }
    #endif
            
        atomic_set(&sip->state, SIP_RUN);
            esp_dbg(ESP_DBG_TRACE, "target booted up
    ");
    
        return ret;
    }

    修改sip_poll_resetting_event函数

    sip_poll_resetting_event(struct esp_sip *sip)
    {
        int ret = 0;
    
            esp_dbg(ESP_DBG_TRACE, "polling resetting event... 
    ");
    
        if (gl_bootup_cplx)
            ret = wait_for_completion_timeout(gl_bootup_cplx, 10 * HZ);
    
        esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]
    ", ret);
        if (ret <= 0) {
            esp_dbg(ESP_DBG_ERROR, "resetting event timeout
    ");
    
                  //修改了一下代码
                   //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
    ");
                   msleep(50);
        }    
          
            esp_dbg(ESP_DBG_TRACE, "target resetting %d %p
    ", ret, gl_bootup_cplx);
    
        return 0;
    }

    2.8 加载驱动

    完成编写后,重新加载驱动
    使用命令:

    ifconfig wlan0 up 

    启动网卡
    使用

    ifconfig

    命令即可看到wlan0已经成功启动

    此时可以使用iw相关wifi工具连接网络进行测试。
    但是iw在连接有密码的wifi太不好操作了。

    3. 将代码编译到内核

    通过上面的方式我们完成了驱动的开发,本节将我们通过另外一片帖子提供的代码,进行修改后打包到我们的系统中。

    下载可以打包到Linux内核的ESP8266驱动包

    下载地址1

    https://whycan.com/files/members/5526/esp8089.zip

    下载地址2

    https://files.cnblogs.com/files/twzy/esp8089.zip

    这里修改了部分配置信息,以便于打包进入内核

    把该文件解压到内核源码/driver/staging/
    修改内核源码/driver/staging/下的Kconfig文件,添加:

    source "drivers/staging/esp8089/Kconfig"

    修改内核源码/driver/staging/下的Makefile

    obj-$(CONFIG_ESP8089)           += esp8089/

    接着返回内核源码所在目录,输入:

    make menuconfig   #(buildroot请输入 make linux-menuconfig)

    然后选中ESP8089,里面选中SPI编译即可。

    [Device Drivers]
            ->[Staging drivers]
                    ->[<*>   Extend for NetWork Using ESP_8266EX/8089] 
                           ->[<*>   Compile SPI-Mode-ESP_8266EX/8089 module in kernel]

    此时我们还需要修改设备树,

    配置如下:
    suniv-f1c100s.dtsi

    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_pins>;
         };

    suniv-f1c100s-licheepi-nano.dts

    &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>;
            };
            
    };

    请根据实际情况进行修改reset和interrupt。
    更新内核文件和设备树,

    编译后在加载过程中出现一些第2节遇到的问题,可以返回去修改当前代码即可(比如那个重启超时处理的代码)

    这样就不用再手动modprobe

    4. 连接互联网

    内核驱动部分已经完成了,那么开始安装应用层的软件吧。进入buildroot,我们需要重新制作文件系统,增加网络相关组件。

    进入根目录执行

    make menuconfig

    进入如下菜单:

    Target packages -> Networking applications

    选中

    • wireless tools     --无线管理工具
    • wpa_supplicant  --连接无线网络
    • dhcpcd               --获取IP地址

    等软件

     选中对应选项后,退出配置界面进行编译文件系统写入TF卡,最后开发板上电以后进入系统,

    我们首先看看wlan0是否已经被创建,使用如下命令:

    ifconfig

    然后用以下命令配置WIFI的SSID和密码

    vi /etc/wpa_supplicant.conf

    输入内容:

    network={
      ssid="我的热点"
      psk="我的密码"
    }

    退出vi回到命令行,后执行如下命令连接wifi

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

     此处表示WIFI已经正确连入路由器,那接下来启动dhcp自动获取IP吧:

    udhcpc -i wlan0

     已经获取到IP地址了,那么现在开始愉快的玩啥吧。

     联网成功。

    总结

    本篇存在多次制作驱动、内核以及文件系统的操作,通篇下来不是很连贯,而且细节部分过于分散,这是因为本篇是在作者在调试网卡过程中不断输出的,所以出现多次返工的问题。还望读者海涵谅解。

    到目前为止网卡驱动已经制作完成,并且已经成功启动网卡,并且连接了网络,但是因为Buildroot软件生成的最小文件系统组件太少了,我们还没发使用apt、ssh等组件(当然可以直接在Buildroot中构建),这样距离当一个真正的小电脑还有点远,所以下一篇我们来一起移植Debian吧。


     本篇有个遗留问题:

    开发板接受数据正常,通过ssh进行访问操作都正常 ,但是只要大量发送数据,比如作为Web服务器被访问,wifi就挂了

    root@SnailCard:~# dmesg |grep wlan0
    [  241.525691] wlan0: authenticate with 78:44:fd:7e:02:88
    [  241.531292] wlan0: send auth to 78:44:fd:7e:02:88 (try 1/3)
    [  241.742250] wlan0: send auth to 78:44:fd:7e:02:88 (try 2/3)
    [  241.755538] wlan0: authenticated
    [  241.772270] wlan0: associate with 78:44:fd:7e:02:88 (try 1/3)
    [  241.982257] wlan0: associate with 78:44:fd:7e:02:88 (try 2/3)
    [  241.998657] wlan0: RX AssocResp from 78:44:fd:7e:02:88 (capab=0x1411 status=0 aid=1)
    [  242.009522] wlan0: associated
    [  242.014791] wlan0: Limiting TX power to 20 (20 - 0) dBm as advertised by 78:44:fd:7e:02:88
    [  572.506851] wlan0: authenticate with 78:44:fd:7e:02:88   #在这里开始作为Web服务器被访问
    [  572.514157] wlan0: send auth to 78:44:fd:7e:02:88 (try 1/3)
    [  572.725587] wlan0: send auth to 78:44:fd:7e:02:88 (try 2/3)
    [  572.935684] wlan0: send auth to 78:44:fd:7e:02:88 (try 3/3)
    [  573.145784] wlan0: authentication with 78:44:fd:7e:02:88 timed out

    墨云正在苦恼中……



    NetAnalyzer下载地址

    NetAnalzyer交流群:39753670 (PS 只提供交流平台,群主基本不说话^_^)

    [转载请保留作者信息  作者:冯天文 ]


  • 相关阅读:
    onLoad和DomContentLoad的区别
    懒加载和预加载区别
    各大浏览器特点
    移动端适配
    清除浮动的方法
    rem的计算
    粗结MySql数据库基础知识点之一
    单例模式(饿汉式单例模式与懒汉式单例模式)
    关于ajax技术
    浅谈EL与JSTL
  • 原文地址:https://www.cnblogs.com/twzy/p/15160808.html
Copyright © 2011-2022 走看看