如何为 esp32 编译和配置及烧写 MicroPython 固件。
MicroPython 在 esp-idf (esp32) 上编译固件
esp32 编译 micropython 的固件相关的资料应该很多吧,我也会出一篇,但会额外讲一些 linux 的东西的。
资料将按照以下顺序进行说明。
- 什么是 esp-idf ?
- 配置 esp32 工具链
- 准备 micropython 仓库
- 建立 micropython for esp32 固件
注意,以下操作截图全部在 linux 下完成(but 我在虚拟机,方便截图),顺便一提,我写的资料,并不会考虑开发新手,如果有问题可以评论解答,但我是不会在写的内容中照顾他人的,随心所欲,但是有问题欢迎来提。
什么是 esp-idf ?
esp-idf 就是 esp32 的官方标准 SDK 支持,进入仓库看下 readme 即可,但在这里并非必要了解的知识。
往下看前请先准备 esp-idf 的官方文档,进入 快速开始 一章,按步骤开始部署开发环境。
配置 esp32 交叉编译工具链
因为在电脑上写的程序将要编译运行在 esp32 上,所以这必然就需要交叉编译工具链,所以写代码先需要先配置好编译环境。
值得一提的是官方的配置文档(/get-started/linux-setup)写的流程很好,所以照着做就行,但要注意的是,它们都是在 i686(i386) 或 ARM64 上的机器上跑的二进制(bin)文件,如果需要在类似树莓派的 arm linux 上编译,则需要重新编译工具链了。
请准备一台 linux 按上述官方配置文档配置完成后,在命令行下输入 xtensa-esp32-elf 然后按 tab 键补全系统命令,确认配置完成,如下图。

注意工具链相关的文件需要绑定到系统全局下,作为命令(符号)给 makefile 接入。
所以记得在 linux 环境变量里添加路径,例如配置文档里讲的,至此编译环境已经建立,注意,不同版本的 idf 可能会变更 工具链 ,所以编译出错的时候不妨检查检查 esp-idf 和 工具链 是否匹配。
export PATH="$HOME/esp/xtensa-esp32-elf/bin:$PATH";
至于如果你想编译工具链,可以继续看官方文档 从零开始设置 Linux 环境下的工具链 ,可喜可贺的是如今都有中文了鸭,上述我们设置的是编译后的二进制版本,如果想学习工具链的本质,就要亲自试试编译工具链了。
交叉编译工具链源码仓库 在这里 ,是很值得学习的开源代码呢。
准备 micropython 仓库
看到这里,我希望你已经按上述的文档和步骤,成功搭建 esp32 的编译环境和获取 esp-idf 源码。
如果发现 git clone 很慢,记得在尾巴添加 --depth=1 的命令,让它不要获取历史提交(commit),这样下载就会快很多了。
- 准备好工具链
xtensa-esp32-elf。 - 准备好开发 SDK 的仓库 esp-idf 。
- 看一眼 esp32 目录下的 readme.md 。
通过下述命令获取 micropython 的仓库。
$ git clone https://github.com/micropython/micropython --depth=1
接着编译一下 mpy-coress ,用来给 Python 文件预编译为 bytecode 到固件里的工具链。
$ make -C mpy-cross
然后初始化一下相关的子仓库。
$ git submodule init lib/berkeley-db-1.xx
$ git submodule update
最后在编译(make)一下。
$ cd ports/esp32
$ make
此时编译就开始了,会有如下滚动信息。

大致是这样的流程,但要注意的是我这里只是简化了操作,接着说一下下述几个注意点。
注意看 micropython/port/esp32 的 readme.md 。
有如下内容:
Setting up the toolchain and ESP-IDF
------------------------------------
There are two main components that are needed to build the firmware:
- the Xtensa cross-compiler that targets the CPU in the ESP32 (this is different to the compiler used by the ESP8266)
- the Espressif IDF (IoT development framework, aka SDK)
The ESP-IDF changes quickly and MicroPython only supports a certain version. The
git hash of this version can be found by running `make` without a configured
`ESPIDF`. Then you can fetch only the given esp-idf using the following command:
$ git clone https://github.com/espressif/esp-idf.git
$ git checkout <Current supported ESP-IDF commit hash>
$ git submodule update --init --recursive
所以没事多看 readme ,比看一般人的博客强多了,所以我这里主要是交待一些编译的方法和常见错误的坑。
上述的意思很简单,就是 micropython 依赖于 esp-idf ,但是需要切换 esp-idf 的版本,也就是说随着 micropython 不一定会支持最新的 esp-idf 代码,如果出现错误,你需要通过 git checkout 切换版本号。
命令格式示范:git checkout <Current supported ESP-IDF commit hash>
而尾巴的<hash> 存放在 Makefile 文件中的,如下内容。
# the git hash of the currently supported ESP IDF version
ESPIDF_SUPHASH := 6b3da6b1882f3b72e904cc90be67e9c4e3f369a9
所以在 esp-idf 的目录下有如下操作(注意和 readme 有点点不同鸭)
$ cd esp-idf
$ git checkout 6b3da6b1882f3b72e904cc90be67e9c4e3f369a9
$ git submodule update --init --recursive
那么现在就可以继续编译 esp32 的 micropython 了。
此时注意,虽然前面说过直接 make 是可以,但实际上官方的做法是额外在 ports/esp32 里准备一个 makefile ,并且区别于 Makefile 文件(Linux 文件区分大小写),按 readme 所述填下列内容即可。
ESPIDF = <path to root of esp-idf repository> # such as ESPIDF = /root/esp-idf
BOARD = GENERIC
# PORT = /dev/ttyUSB0
# FLASH_MODE = qio
# FLASH_SIZE = 4MB
# CROSS_COMPILE = xtensa-esp32-elf-
include Makefile
注意这里可以指定填写你的 ESP-IDF 路径,这样做的好处就是不需要添加到系统环境变量中了,所以你可以同时拥有许多份不同工程用的 esp-idf 仓库,并且此时 make 命令调用的是 makefile ,接着 makefile 末尾将会调用 Makefile(即 include Makefile),其他内容可以选填(# 为注释),相当于预先为 Makefile 的执行载入环境变量。
此时就开始编译固件吧,编译成功如下图:

此时常用命令有如下(查阅 readme 可知):
- 打开串口收发,组合 Ctrl + A 和 Ctrl + Q 退出串口(需要安装 picocom )
$ picocom -b 115200 /dev/ttyUSB0
- 擦除 esp32 中 flash 。
$ make erase
- 编译后烧录 micropython 固件。
$ make deploy
- 清理编译结果。
$ make clean
- 组合命令,烧录完固件后打开串口。
$ make deploy && picocom -b 115200 /dev/ttyUSB0
如下图运行结果:

顺手输入了 print('hello esp32') ,值得注意的是,这里也支持 tab 补全操作多多体验吧。
额外的信息
为什么固件只有一个 firmware.bin 文件?
固件编译后的 firmware.bin 文件产生在 port/esp32/build 文件夹,它是通过 makeimg.py 合成的,看一下就知道发生了什么。
import sys
OFFSET_BOOTLOADER = 0x1000
OFFSET_PARTITIONS = 0x8000
OFFSET_APPLICATION = 0x10000
files_in = [
('bootloader', OFFSET_BOOTLOADER, sys.argv[1]),
('partitions', OFFSET_PARTITIONS, sys.argv[2]),
('application', OFFSET_APPLICATION, sys.argv[3]),
]
file_out = sys.argv[4]
cur_offset = OFFSET_BOOTLOADER
with open(file_out, 'wb') as fout:
for name, offset, file_in in files_in:
assert offset >= cur_offset
fout.write(b'\xff' * (offset - cur_offset))
cur_offset = offset
with open(file_in, 'rb') as fin:
data = fin.read()
fout.write(data)
cur_offset += len(data)
print('%-12s% 8d' % (name, len(data)))
print('%-12s% 8d' % ('total', cur_offset))
可以得知,firmware.bin 是由 bootloader + partitions + application 而来的一个单独的 bin ,即为固件,所以只需要在 0x1000 起始位置烧入 esp32 的 flash 里就可以运行 micropython 了。
如何编译 8M spiflash 的固件?
此外我们还需要知道如何编译带 SPIRAM 固件,通常来说,只需要修改 makefile 的 BOARD = GENERIC_SPIRAM。
ESPIDF = <path to root of esp-idf repository> # such as ESPIDF = /root/esp-idf
BOARD = GENERIC_SPIRAM
include Makefile
不过你也可能会遇到一些问题,比如我修改了编译工具链里的一些头文件才编译通过的,所以得做好准备随时修改源码的准备趴。
至于我遇到了什么问题,唔,改一下编译中的文件之间的符号关系就好了。
编译后运行可以看到 Found 64MBit SPI RAM device ,然后查看 gc.mem_free() 可以看到 3997 * 4096 Byte,也就是 4M RAM ,如下图(带有 SPIRAM 的固件)。

下图就是对照的无 Flash 固件,可以看到 111 * 1024 的,用的是内部的 RAM (小于 384 KB)。

结语
最后,如果遇到在本文的流程下出现编译问题,可以留言,也可以直接问我。
如何为 esp32 编译和配置及烧写 MicroPython 固件。的更多相关文章
- esp32(M5STACK)程序烧写(Ubuntu)
由于我们的开发环境在Ubuntu上,所以介绍一下如何在Ubuntu上烧写esp32的程序 首先下载esptools pip install esptool 擦除 sudo es ...
- 在windows 下使用eclipse进行编译和烧写
eclipse IDE是一款开源的前端编程软件,它提供了编写,编译和调试ESP-IDF项目的图形集成开发环境. 首先在https://www.obeo.fr/en/eclipse-download?I ...
- UBoot的编译与烧写
每当我们学习任何编译语言之前,第一节课都是介绍我们要学习的是什么,以及编译语言和工具,最后写一个小程序编译并运行就算入门,也就是所谓的"Hello, world!".这里也不例外, ...
- 编译 Linux 3.5 内核烧写 Android 4.2.2 到 Tiny4412 开发板
. . . . . 昨天已经编译了 Android 4.2.2 的源码,详见<Ubuntu 14.04 编译 Android 4.2.2 for Tiny4412>一文. 今天我们继续剩下 ...
- sd卡脱机烧写系统的方法(测试成功)
一.sd卡烧写系统的基本思路: (1)把uboot.bin烧写到sd卡 (2)把image整个文件夹复制到sd卡 (3)开发板从sd卡启动,就开始自动烧写到nandflash中了. 二.烧写uboot ...
- 【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410
作者 : 万境绝尘 转载请著名出处 终于拿到板子了, 嵌入式开发正式开启. 板子型号 : 三星 S3C6410 基于ARM11, 指令集基于arm6指令集; 为毛不是 Cortext A9的板子; 烧 ...
- 烧写uboot和openwrt固件ARxx系列
以AR9331为例. 1.用烧录器将uboot烧写到flash中 (AR9331_U-Boot_Oolite-v1-v20170713.bin) 2.登录:192.168.1.1网页烧写uboot ...
- 8元电调调参教程(使用Arduino Uno)| BLHeli无刷电调的固件烧写及调参
前言 淘某上有款8元电调,性价比很高,但是需要简单设置一下 1.材料清单 (1)Arduino UNO开发板 (2)BLHeliSuite 16.7.14.9.0.1 调参软件及固件已上传Gitee: ...
- VS Code 与 ESP32 官方SDK配置
开发基于 ESP XXX 微控制器应用,最简单的环境搭建方案是像 MicroPython.CircuitPython.NanoFramework 等,下载固件,直接开刷:或者基于 Arduino 的开 ...
随机推荐
- Python接口测试-模块引用与映射
PyCharm中发现模块引用老是有各种问题 可以用映射来解决,例如需要调用登录模块里面的东西的时,可以这样处理: 登录模块:1-login.py import this import requests ...
- Android省电和提高效率
一.Android省电开发之性能优化 电量优化 Android应用开发中的网络.定位.传感器等都是比较耗电的特性,我们应该正确使用API来有效降低应用的耗电量. 1.BroadcastReceiver ...
- ubuntu如何删除刚添加的源?
答: sudo add-apt-repository -r <source_url> 如: sudo add-apt-repository -r ppa:linaro-maintainer ...
- mybatis之动态SQL操作之插入
1) 根据条件,插入一个学生 /** * 持久层*/ public class StudentDao { /** * 动态SQL--插入 */ public void dynaSQLwithInse ...
- consul ocelot
consul配置完成后 新建.netcoreapi项目, nuget安装ocelot 添加多个配置文件,.netcore中会自动合并为一个文件,global配置总的配置,其他为各个项目的配置 Serv ...
- React Native安卓代码混淆和打包
一上午就整了个React Native的打包,中间还遇到各种问题,这里还是记录下吧: 文档链接: http://reactnative.cn/docs/0.45/signed-apk-android. ...
- Cell中实现多图展示
实现的效果如下: 主要实现代码如下: // // DetailCell.m // Floral // // Created by 思 彭 on 16/9/21. // Copyright © 2016 ...
- Java数组(4):数组实用功能
Java标准类库的System.arraycopy()方法,及在java.utils.Arrays类中一套用于数组的static方法,都是操纵数组实用功能.下面分别介绍. (1) 数组的复制 (2) ...
- 【笔记】Docker入门
这个文章讲的比较透彻,就不复制粘贴了 <Docker从入门到实践>阅读笔记 Docker安装 环境 root@fudonghai:~# uname -a Linux fudonghai - ...
- HTML5 a标签的down属性进行图片下载
a标签中的down属性时HTML5新增的属性,此属性指示浏览器下载URL而不是导航到URL,因此将提示用户将其保存为本地文件.目前该属性的兼容性如下: 具体代码实现: /* 主要原理:利用a标签的do ...