本文章基于 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天线部分处理并不符合要求,所以信号会有影响。

实物如下:

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

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/1qTTgBndBvmssCdeqXHI3Pg
提取码:fw52

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

1. 硬件设计

1.1 接线表

F1C200S ESP8266Ex ESP-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 处理内核不支持警告

使用

  1. make ARCH=arm CROSS_COMPILE=arm-linux-

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

  1. #make ARCH=arm CROSS_COMPILE=arm-linux-
  2.  
  3. *** WARNING: This kernel lacks wireless extensions.
  4. Wireless drivers will not work properly.
  5.  
  6. make -C /home/twzy/linuxCard/kernel/linux-5.7.1/ M=/home/twzy/linuxCard/Driver/ESP8089-SPI
  7. make[1]: 进入目录“/home/twzy/linuxCard/kernel/linux-5.7.1
  8. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.o
  9. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.o
  10. In file included from ./include/linux/mm_types.h:12:0,
  11. from ./include/linux/mmzone.h:21,
  12. from ./include/linux/gfp.h:6,
  13. from ./include/linux/slab.h:15,
  14. from ./include/linux/crypto.h:19,
  15. from ./include/crypto/hash.h:11,
  16. from ./include/linux/uio.h:10,
  17. from ./include/linux/socket.h:8,
  18. from ./include/linux/compat.h:15,
  19. from ./include/linux/ethtool.h:17,
  20. from ./include/linux/netdevice.h:37,
  21. from /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:17:
  22. /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c: 在函数‘esp_pub_init_all’中:
  23. ./include/linux/completion.h:54:2: 警告: ISO C90 不允许混合使用声明和代码 [-Wdeclaration-after-statement]

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

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

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

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

在内核目录使用

  1. make ARCH=arm CROSS_COMPILE=arm-linux-

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

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

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

  1. config WIRELESS_EXT
  2. bool

更改为

  1. config WIRELESS_EXT
  2. def_bool y

再次编译:

  1. $ make ARCH=arm CROSS_COMPILE=arm-linux-
  2. make -C /home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf M=/home/twzy/linuxCard/Driver/ESP8089-SPI
  3. make[1]: Entering directory '/home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf'
  4. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_debug.o
  5. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/sdio_sif_esp.o
  6. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.o
  7. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_io.o
  8. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_file.o
  9. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.o
  10. In file included from ./include/linux/mm_types.h:12:0,
  11. from ./include/linux/mmzone.h:21,
  12. from ./include/linux/gfp.h:6,
  13. from ./include/linux/slab.h:15,
  14. from ./include/linux/crypto.h:19,
  15. from ./include/crypto/hash.h:11,
  16. from ./include/linux/uio.h:10,
  17. from ./include/linux/socket.h:8,
  18. from ./include/linux/compat.h:15,
  19. from ./include/linux/ethtool.h:17,
  20. from ./include/linux/netdevice.h:37,
  21. from /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:17:
  22. /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c: In function esp_pub_init_all’:
  23. ./include/linux/completion.h:54:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  24. struct completion work = COMPLETION_INITIALIZER(work)
  25. ^
  26. ./include/linux/completion.h:74:43: note: in expansion of macro DECLARE_COMPLETION
  27. # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
  28. ^~~~~~~~~~~~~~~~~~
  29. /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:81:2: note: in expansion of macro DECLARE_COMPLETION_ONSTACK
  30. DECLARE_COMPLETION_ONSTACK(complete);
  31. ^~~~~~~~~~~~~~~~~~~~~~~~~~
  32. In file included from /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_main.c:221:0:
  33. /home/twzy/linuxCard/Driver/ESP8089-SPI/eagle_fw1.h: In function esp_download_fw’:
  34. /home/twzy/linuxCard/Driver/ESP8089-SPI/eagle_fw1.h:8:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  35. static u8 eagle_fw1[] =
  36. ^~~~~~
  37. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_sip.o
  38. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_ext.o
  39. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_ctrl.o
  40. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_mac80211.o
  41. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_utils.o
  42. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp_pm.o
  43. CC [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/testmode.o
  44. LD [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.o
  45. Building modules, stage 2.
  46. MODPOST 1 modules
  47. CC /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.mod.o
  48. LD [M] /home/twzy/linuxCard/Driver/ESP8089-SPI/esp8089-spi.ko
  49. make[1]: Leaving directory '/home/twzy/DVPM_linux-5.2/linux-nano-5.2-tf'

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

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

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

2.3 修改设备树

找到设备树
suniv-f1c100s.dtsi文件
在pio分组添加

  1. spi0_pc_pins: spi0-pc-pins {
  2. pins = "PC0","PC1","PC2","PC3";
  3. function = "spi0";
  4. };

在soc分组下添加

  1. spi0: spi@1c05000 {
  2. compatible = "allwinner,suniv-spi",
  3. "allwinner,sun8i-h3-spi";
  4. reg = <0x01c05000 0x1000>;
  5. interrupts = <10>;
  6. clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;
  7. clock-names = "ahb", "mod";
  8. resets = <&ccu RST_BUS_SPI0>;
  9. status = "disabled";
  10. #address-cells = <1>;
  11. #size-cells = <0>;
  12. };

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

  1. &spi0 {
  2. pinctrl-names = "default";
  3. pinctrl-0 = <&spi0_pc_pins>;
  4. status = "okay";
  5. };

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 命令加载驱动

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

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

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

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

加载depmod

  1. # cd /lib/modules/5.7.1/
  2. # ls
  3. esp8089-spi.ko
  4. # depmod
  5. # ls
  6. esp8089-spi.ko modules.alias modules.dep modules.symbols

加载驱动

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

日志中我们发现

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

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

2.5 驱动修改适配

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

  1. struct spi_device* sif_platform_new_device(void) {
  2. master = spi_busnum_to_master(esp_board_spi_devices[0].bus_num);
  3. spi = spi_new_device( master, esp_board_spi_devices );
  4. if(!spi)
  5. printk("esp8089_spi: FAILED to create slave\n");
  6. if(spi_setup(spi))
  7. printk("esp8089_spi: FAILED to setup slave\n");
  8. return spi;
  9. }

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

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

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

  1. static struct spi_board_info esp_board_spi_devices[] = {
  2. {
  3. .modalias = "ESP8089_0",
  4. .max_speed_hz = MAX_SPEED_HZ,
  5. .bus_num = 1,
  6. .chip_select = 0,
  7. .mode = 0,
  8. },
  9. };

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之后(此处不知这种解释是否符合理)

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

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

  1. static struct spi_board_info esp_board_spi_devices[] = {
  2. {
  3. .modalias = "ESP8089_0",
  4. .max_speed_hz = MAX_SPEED_HZ,
  5. .bus_num = 0, //fix here
  6. .chip_select = 0,
  7. .mode = SPI_MODE_3, //fix here
  8. },
  9. };

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

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

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

中断脚

复位脚

2.6 内核编译配置

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

  1. CONFIG_SPI=y
  2. CONFIG_SPI_MASTER=y
  3. CONFIG_SPI_SUN4I=y
  4. CONFIG_SPI_SPIDEV=y
  5. CONFIG_SPI_SUN6I=y

执行结果如下,

  1. # cd /lib/modules/5.7.1/
  2. # modprobe esp8089-spi
  3. [ 29.008363] esp8089_spi: loading out-of-tree module taints kernel.
  4. [ 29.025084] esp8089_spi: EAGLE DRIVER VER bdf5087c3deb
  5. [ 29.631516] esp8089_spi: try to use 0
  6. [ 29.637763] esp8089_spi: esp_spi_dummy_probe enter
  7. [ 29.644630] esp8089_spi: register board OK
  8. [ 29.650529] esp8089_spi: sem_timeout = 0
  9. [ 29.872020] esp8089_spi: ESP8089 power up OK
  10. [ 29.878555] esp8089_spi: esp_spi_probe ENTER
  11. [ 29.884786] esp8089_spi: esp_setup_spi
  12. [ 29.890336] esp8089_spi: sif_spi_protocol_init
  13. [ 29.896621] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
  14. [ 29.907012] esp8089_spi: fail_count = 0
  15. [ 30.024997] rx:[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
  16. [ 30.135388] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
  17. [ 30.145770] esp8089_spi: fail_count = 1
  18. [ 30.265689] rx:[0xff],[0x09],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
  19. [ 30.376023] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1559
  20. [ 30.386385] esp8089_spi: fail_count = 2
  21. [ 30.507530] rx:[0xff],[0xff],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
  22. [ 31.116845] esp8089_spi: /home/twzy/linuxCard/Driver/ESP8089-SPI/spi_sif_esp.c, 1578
  23. [ 31.143207] rx:[0xff],[0xff],[0x01],[0x10],[0xff],[0xff],[0x00],[0xff],[0xff],[0xff]
  24.  
  25. ………………
  26.  
  27. [ 38.628868] rx:[0xff],[0x00],[0x01],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff],[0xff]
  28. [ 39.659517] esp8089_spi: esp_pub_init_all
  29. [ 39.665431] esp8089_spi: esp_download_fw
  30. [ 40.095380] esp8089_spi: sif_platform_irq_init enter
  31. [ 50.402011] resetting event timeout
  32. [ 50.407306] esp8089_spi: esp_init_all failed: -110
  33. [ 50.413944] esp8089_spi: first error exit
  34. [ 50.419686] esp8089_spi: esp_spi_probe EXIT
  35. [ 50.425909] esp8089_spi: sem_timeout = 0
  36. [ 50.431610] esp8089_spi: esp_spi_init err 0
  37. #

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

2.7 处理重置超时检测

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

在声明变量:

  1. extern struct task_struct *sif_irq_thread;

修改sip_poll_bootup_event函数

  1. sip_poll_bootup_event(struct esp_sip *sip)
  2. {
  3. int ret = 0;
  4.  
  5. esp_dbg(ESP_DBG_TRACE, "polling bootup event... \n");
  6.  
  7. if (gl_bootup_cplx)
  8. ret = wait_for_completion_timeout(gl_bootup_cplx, 2 * HZ);
  9.  
  10. esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);
  11. if (ret <= 0) {
  12. esp_dbg(ESP_DBG_ERROR, "bootup event timeout\n");
  13. //修改了一下代码
  14. //return -ETIMEDOUT;
  15. sip->epub->wait_reset = 0;
  16. wake_up_process(sif_irq_thread);
  17. 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");
  18. msleep(50);
  19. }
  20.  
  21. if(sif_get_ate_config() == 0){
  22. ret = esp_register_mac80211(sip->epub);
  23. }
  24.  
  25. #ifdef TEST_MODE
  26. ret = test_init_netlink(sip);
  27. if (ret < 0) {
  28. esp_sip_dbg(ESP_DBG_TRACE, "esp_sdio: failed initializing netlink\n");
  29. return ret;
  30. }
  31. #endif
  32.  
  33. atomic_set(&sip->state, SIP_RUN);
  34. esp_dbg(ESP_DBG_TRACE, "target booted up\n");
  35.  
  36. return ret;
  37. }

修改sip_poll_resetting_event函数

  1. sip_poll_resetting_event(struct esp_sip *sip)
  2. {
  3. int ret = 0;
  4.  
  5. esp_dbg(ESP_DBG_TRACE, "polling resetting event... \n");
  6.  
  7. if (gl_bootup_cplx)
  8. ret = wait_for_completion_timeout(gl_bootup_cplx, 10 * HZ);
  9.  
  10. esp_dbg(ESP_DBG_TRACE, "******time remain****** = [%d]\n", ret);
  11. if (ret <= 0) {
  12. esp_dbg(ESP_DBG_ERROR, "resetting event timeout\n");
  13.  
  14. //修改了一下代码
  15. //return -ETIMEDOUT;
  16. sip->epub->wait_reset = 0;
  17. wake_up_process(sif_irq_thread);
  18. 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");
  19. msleep(50);
  20. }
  21.  
  22. esp_dbg(ESP_DBG_TRACE, "target resetting %d %p\n", ret, gl_bootup_cplx);
  23.  
  24. return 0;
  25. }

2.8 加载驱动

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

  1. ifconfig wlan0 up

启动网卡
使用

  1. ifconfig

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

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

3. 将代码编译到内核

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

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

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

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

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

  1. source "drivers/staging/esp8089/Kconfig"

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

  1. obj-$(CONFIG_ESP8089) += esp8089/

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

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

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

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

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

配置如下:
suniv-f1c100s.dtsi

  1. spi0:spi@1c05000 {
  2. compatible = "allwinner,suniv-spi", "allwinner,sun8i-h3-spi";
  3. reg = <0x01c05000 0x1000>;
  4. interrupts = <10>;
  5. clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;
  6. clock-names = "ahb", "mod";
  7. resets = <&ccu RST_BUS_SPI0>;
  8. status = "disabled";
  9. #address-cells = <1>;
  10. #size-cells = <0>;
  11. pinctrl-names = "default";
  12. pinctrl-0 = <&spi0_pins>;
  13. };

suniv-f1c100s-licheepi-nano.dts

  1. &spi0 {
  2. status = "okay";
  3. esp8089@0 {
  4. status = "okay";
  5. compatible = "boss,esp8089";
  6. spi-cpol;
  7. spi-cpha;
  8. reg = <0>;
  9. spi-max-frequency = <30000000>;
  10. reset= <135>; //PE7
  11. interrupt= <136>; //PE8
  12. debug= <0>;
  13. };
  14.  
  15. };

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

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

这样就不用再手动modprobe

4. 连接互联网

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

进入根目录执行

  1. make menuconfig

进入如下菜单:

  1. Target packages -> Networking applications

选中

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

等软件

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

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

  1. ifconfig

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

  1. vi /etc/wpa_supplicant.conf

输入内容:

  1. network={
  2. ssid="我的热点"
  3. psk="我的密码"
  4. }

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

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

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

  1. udhcpc -i wlan0

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

联网成功。

总结

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

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

小白自制Linux开发板 四. 通过SPI使用ESP8266做无线网卡的更多相关文章

  1. 小白自制Linux开发板 二. u-boot移植

    上一篇:小白自制Linux开发板 一. 瞎抄原理图与乱画PCB  中我们做了一个小型而没用的开发板,用的是Licheepi Nano的镜像,那从本篇开始我们开始自己构建它的灵魂吧. 我们都知道,PC在 ...

  2. 小白自制Linux开发板 三. Linux内核与文件系统移植

    上一篇完成了uboot的移植,但是想要愉快的在开发板上玩耍还需要移植Linux内核和文件系统. 1.Linux内核 事实上对于F1C100S/F1C200S,Linux官方源码已经对licheepi ...

  3. 小白自制Linux开发板 六. SPI TFT屏幕修改与移植

    本文章参考:https://www.bilibili.com/read/cv9947785?spm_id_from=333.999.0.0 本篇通过SPI接口,使用ST7789V TFT焊接屏(13p ...

  4. 小白自制Linux开发板 一. 瞎抄原理图与乱画PCB

    因为墨云是基于高中物理水平的电路知识来学习.而且此前也就玩过树莓派.Esp8266之类的开发板,水平基础趋近于零,所以在写这个系列的时候抱着记录的心态.还望不足之处还望大佬们指正. <论语> ...

  5. 小白自制Linux开发板 八. Linux音频驱动配置

    不知不觉小白自制开发板系列已经到第八篇了,本篇要配置的是音频驱动,也算是硬件部分的最后一片了,积攒的文章也差不多全放完了,后续更新可能会放缓,还请见谅. 对于F1C200s是自带了多媒体处理功能的,所 ...

  6. 小白自制Linux开发板(第二季 V3s篇) 一. 换个核心再来一次

    1.前言 大家心心念念(个人认为)的小白自制开发板全新系列正式来了,之前我们使用全志的F1C200s芯片制作了一个小电脑,众所周知,调试很艰难,坑也很多,以至于墨云到现在还是没找到对应的补救方案,为了 ...

  7. 小白自制Linux开发板 九. 修改开机Logo

    许久不见啊,今天我们继续来修改我们的系统. 通过前面的几篇文章我们已经能轻松驾驭我们的开发板了,但是现在都是追求个性化的时代,我们在开发板上打上了自己的Logo,那我们是否可以改变开机启动的Logo呢 ...

  8. 小白自制Linux开发板 十. NES游戏玩起来

    本篇基于我们制作的Debian文件系统而展开,而且我们这会玩一些高级的操作方式--用我们的小电脑进行程序编译.   所以本篇操作全部都在我们个的开发板上完成.   1. 开发环境搭建 首先安装gcc, ...

  9. 小白自制Linux开发板 番外篇 一 modprobe加载驱动问题(转载整理)

    使用modprobe加载驱动 转载地址:https://blog.csdn.net/qq_39101111/article/details/78773362 前面我们提到,modprobe并不需要指定 ...

随机推荐

  1. 回调与Promise

    Promise 对象就是用于表示一个异步操作的最终状态(成功或失败).它的流程就是在什么状态下需要执行什么样的操作. resolve简单理解就是一步操作执行成功后的回调函数 then是Promise对 ...

  2. vscode 1.32.x按下鼠标左键无法拖曳选择,而旧一点的版本1.30.2可以

    最近升级vscode后,无法通过鼠标左键选择文本,恢复到旧版本1.30.2就可以了. 另外:1.32.x和1.31.1都不正常 进一步测试发现:在中文输入法下(无论中英输入模式),都有问题:切换到纯英 ...

  3. 第一次实战:XX漫画的XSS盲打

    第一次实战:XX漫画的XSS盲打 XSS盲打 盲打是一种惯称的说法,就是不知道有没有XSS漏洞存在的情况下,不顾一切的输入XSS代码在留言啊投诉窗口啊之类的地方,尽可能多的尝试XSS的语句,就叫盲打. ...

  4. python opencv cv2 imshow threading 多线程

    除了线程同步,还需要注意的是「窗口处理」要放在主线程 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys import threadin ...

  5. uni-app 入门小白纯徒手编写组件 hello-popup

    我的需求是:弹出框顶部有 title,底部有确认和取消按钮.这两部分固定,中间部分 content 的高度随自身内容会动态增长,但是它最大高度不能超过父节点 bg 的 80%,而父节点 bg 的高度也 ...

  6. 剑指 Offer 14- II. 剪绳子 II

    剑指 Offer 14- II. 剪绳子 II 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]... ...

  7. ☕【Java技术指南】「并发编程专题」Fork/Join框架基本使用和原理探究(基础篇)

    前提概述 Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行. 我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一 ...

  8. NAT-T下的端口浮动

    1. IKE端口浮动 IPsec在隧道建立第一第二阶段主要进行加密方式.加密策略等信息的协商,这部分功能是通过IKE协议来实现的. IKE协议默认端口为500,但是如果IPsec隧道传输路径上存在NA ...

  9. 装配Bean的三种方式

    一.装配Bean就是在xml写一个Bean标签:装配完Bean,还需要读取xml配置文件创建Spring容器来创建对象: 1.new 实现类方式 正常的三种创建Bean容器的方法都可以根据装配的Bea ...

  10. go中如果想要实现别人写的接口,如何保证确实实现了那个接口而不是错过了什么?

    在类型的实现方法上定义通用代码指令 var _ 要实现的接口  = (receiver类型)(nil) 比如要定义一个web处理程序 type  handler_def struct{} var _ ...