02 ESP32-Environment Setup-Compilation And Programming

一、官方文档

环境搭建的步骤,乐鑫官方都有比较详细的文档,可以直接参考.本文对一些概念进行进一步的学习和探讨.

官方推荐使用Make(ESP-IDF v3.2)或CMake(ESP-IDF v3.3)命令行的方式编译和烧写程序,灵活性更高,参考:

对于不熟悉命令行操作,喜欢使用集成开发环境的开发者,也提供了IDE的配置指导:

二、学习笔记

1. 自动切换启动模式的软件方案探究

1.1. 安装串口驱动

在第一节我们提到,V2的开发板使用CP2102实现USB转串口的通信(乐鑫原厂开发板大多使用该芯片,其他品牌开发板有些使用CH340),这款芯片在windows10系统中可以自动安装驱动,保持电脑联网,插入设备即可,在Ubuntu16.04、18.04中实测也是可以直接使用的.如果遇到驱动问题,可以在SILABS官网下载.CP210x USB to UART Bridge VCP Drivers

Windows系统可以从设备管理器,查看驱动是否成功安装.Linux系统可以使用dmeg指令查看,可以查找到如下信息,其中ttyUSB0就是我们刷固件要用到的端口号.

username@dd111:~$ dmesg
[ 3106.111239] usb 1-10: new full-speed USB device number 5 using xhci_hcd
[ 3106.241340] usb 1-10: New USB device found, idVendor=10c4, idProduct=ea60
[ 3106.241350] usb 1-10: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3106.241357] usb 1-10: Product: CP2102 USB to UART Bridge Controller
[ 3106.241363] usb 1-10: Manufacturer: Silicon Labs
[ 3106.241369] usb 1-10: SerialNumber: 0001
[ 3106.242743] cp210x 1-10:1.0: cp210x converter detected
[ 3106.242985] usb 1-10: cp210x converter now attached to ttyUSB0

1.2. 安装esptool.py

$ pip install esptool

官方esp-idf在进行make flash操作时,也是使用了这个工具

1.3. 查看esptool.py源代码

esptool.py:A serial utility to communicate & flash code to Espressif ESP8266 & ESP32 chips.

我们先进行一下芯片擦除操作,找一些线索

username@dd111:~$ sudo esptool.py --port /dev/ttyUSB0 erase_flash #可以不设置 --port, 默认为/dev/ttyUSB0
esptool.py v2.7 #esptool版本号
Serial port /dev/ttyUSB0 #操作的端口号 
Connecting...... #尝试连接,与bootloader通信
Detecting chip type... ESP32 #检测到ESP32
Chip is ESP32D0WDQ5 (revision 0) #芯片型号
Features: WiFi, BT, Dual Core, Coding Scheme None #该型号配置
Crystal is 40MHz #晶振频率
MAC: 30:ae:a4:80:05:10 #硬件MAC地址
Uploading stub...
Running stub... 
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 1.1s
Hard resetting via RTS pin...

擦除的过程,我们没有对硬件进行任何操作,esptool.py完成了Download boot模式的启动(相当于按住boot,然后点击EN).

根据输出信息顺藤摸瓜,终于在esptool.py文件中发现了实现这个机制的关键代码:

    def _setDTR(self, state):
        self._port.setDTR(state)

    def _setRTS(self, state):
        self._port.setRTS(state)
        # Work-around for adapters on Windows using the usbser.sys driver:
        # generate a dummy change to DTR so that the set-control-line-state
        # request is sent with the updated RTS state and the same DTR state
        self._port.setDTR(self._port.dtr)
        # issue reset-to-bootloader:
        # RTS = either CH_PD/EN or nRESET (both active low = chip in reset
        # DTR = GPIO0 (active low = boot to flasher)
        #
        # DTR & RTS are active low signals,
        # ie True = pin @ 0V, False = pin @ VCC.
        if mode != 'no_reset':
            self._setDTR(False)  # IO0=HIGH
            self._setRTS(True)   # EN=LOW, chip in reset
            time.sleep(0.1)
            if esp32r0_delay:
                # Some chips are more likely to trigger the esp32r0
                # watchdog reset silicon bug if they're held with EN=LOW
                # for a longer period
                time.sleep(1.2)
            self._setDTR(True)   # IO0=LOW
            self._setRTS(False)  # EN=HIGH, chip out of reset
            if esp32r0_delay:
                # Sleep longer after reset.
                # This workaround only works on revision 0 ESP32 chips,
                # it exploits a silicon bug spurious watchdog reset.
                time.sleep(0.4)  # allow watchdog reset to occur
            time.sleep(0.05)
            self._setDTR(False)  # IO0=HIGH, done

模拟BOOT按键被按下

            self._setDTR(False) 
            self._setRTS(True)   #DTR=0,RTS=1,IO0=0(相当于BOOT按键被按下)

模拟EN按键被按下

            self._setDTR(True)   # IO0=LOW
            self._setRTS(False)  # DTR=1,RTS=0,EN=0(硬件复位)

这段代码在esp.connect()中调用,也就是esptool.py尝试连接时,就将ESP32设置成了Download boot模式.

2. menuconfig作用与原理探究

2.1. ESP-IDF menuconfig作用

make menuconfig 提供了图形化、交互式的配置环境,在Linux编程中用于配置内核.ESP-IDF也提供了这个功能,可用于:

  1. 选择通信参数(串口号 波特率 烧写速度等)

  2. 配置Bootloader

  3. 配置组件参数

  4. 配置编译器(优化等级,屏蔽warning等)

  5. 配置自定义参数

2.2. 如何进入menuconfig?

只需要在工程目录下:

make menuconfig
使用键盘操作进入 Component config ---> Wi Fi --->

2.3. menuconfig修改了什么?

menuconfig操作完成之后,会在工程根目录下自动生成==sdkconfig==文件,之前的sdkconfig被重新命名为sdkconfig.old,用于恢复上一次的配置.同目录下还存在一个sdkconfig.defaults文件,用于保存初始配置.

sdkconfig会被编译系统进一步编译成sdkconfig.h,该文件保存在工程目录->build->include->sdkconfig.h 会被构建系统添加到全局头文件搜索路径.

sdkconfig也可以手动修改,但是要注意,不能在menuconfig图形界面启动时修改,图形界面上的修改会覆盖掉当前手动修改的内容.

2.4. menuconfig添加自定义选项

menuconfig生成的sdkconfig文件中具有一系列的宏定义,可以在工程文件中作为全局宏定义使用,那么我们是否能把自己的宏定义,添加到menuconfig选项中呢,答案是可以的.

menuconfig的自定义菜单项保存在当前工程的==Kconfig.projbuild==文件中,可以按照以下示例编写.我们这里定义了一个一级菜单“TEST Configuration”,二级菜单(宏定义变量名)“TEST_GPIO”,范围定义为0-34,默认为5,还可以添加help说明文件.

menu "TEST Configuration"

config TEST_GPIO
    int "TEST GPIO number"
    range 0 34
    default 5
    help
        test menuconfig

endmenu

效果如下:

2.4. 为什么使用make调用menuconfig?

虽然make常常被用于编译,但它不等同于编译命令.更广泛的可以理解为对一组命令(makefile)的调用.在ESP-IDF中包含了很多脚本工具,比如esptool.py、idf.py、idf_monitor.py等,每一个工具都有自己的指令集合,make对其做了进一步的封装,简化了使用.

例如:

make flash

其实相当于:

先调用gcc命令将代码编译成bin,再使用esptool烧写程序

sudo esptool.py --port /dev/ttyUSB0 erase_flash

如果添加自定义make参数,需要将命令参数添加到到makefile中的 .PHONY中,防止与文件名冲突(makefile 默认target为文件)

3. makefile包含哪些内容?

ESP工具链的make指令功能繁多,但是因为层级关系比较分明,makefile并不复杂,最小的makefile可以只有两行:

PROJECT_NAME := myProject
include $(IDF_PATH)/make/project.mk
  • PROJECT_NAME是最终bin文件的名称

  • ==project.mk==用来管理系统定义的一系列make指令,project.mk中又调用了其他工具的makefile,如调用project_config.mk来支持make menuconfig,该文件一般不需要修改.

构建系统 (传统 GNU Make)

最后更新于