【填坑】ESP32 bootloader初探(上)

前言

大名鼎鼎的乐鑫ESP8266 WIFI模组你应该不陌生,不用我多说了。在这之后乐鑫还更迭了更多高性能的芯片型号,比如这次我要记录的ESP32-C3,搭载近期很火的RISC-V指令集处理器,支持2.4G wifi、BLE-5,拥有丰富应用场景。

是的,它很好。至少硬件很强大,不过再牛批的硬件也需要众多开发者的实践经验来不断完善它的生态。在动手这次开发之前,我对ESP32的认识仅限于乐鑫的另一款型号ESP8266,三年前在eclipse中编译运行过应用层,用已经下载调试好的基线和代码,我也完完全全不会想到,这将是又一段难忘的含泪填坑经历。

文章比较长,分上下两篇。 结合起来阅读,对你认识bootloader开发帮助更大。
文中有多处可以点击的跳转链接,都是我的辛酸开发史总结后,会对你有帮助的内容,根据需要跳转查看吧。

>> 注意 <<: 本文不是详细开发步骤的教程。只记录我在开发Bootloader过程,从头到尾遇到的问题点和解决办法以及一些启发。真的不知道怎么着手的新手盆友,建议移步官方的“ESP-IDF 编程指南”来入门,点这里去看。无论如何,感谢你花时间在这篇文章上。

好了,开始吧。


这次开发需要的材料:

硬件:ESP32-C3-WROOM-02开发板,USB连接线
软件:ESP-IDF V4.4.2,Ubuntu16.04,ESP DOWNLOAD TOOL等
ESP32-C3开发板开发板各组件介绍


背景

我这次的开发工作,如标题所说。在一个少有ESP32开发者踏足的区域 —— Bootloader。会这么说是因为后来了解到这次的开发任务做的事情,在乐鑫官方人员那里都未曾试过(至少没有发布过版本,或许因为需求太少?),对我这半路接手项目的人而言,更是全新的体验。

此次开发的功能主要是在Boot中,与外部MCU进行串口通讯,完成数据内容的协议解析并在flash中存储一些有用的数据给应用层使用。既然涉及通讯,当然也考虑一些超时重试,用到了定时器。

主要难点包括外设在boot怎么使用、如何添加自己的代码到boot固件运行起来、如何分配自定义分区并在boot使用、资源占用调整等等内容,计划在boot的工作两周工作日内完成,实际要多花一周时间…


准备工作

编译环境

这次用的是Ubuntu16.04,很经典的版本,没什么好说,就是能用、好用而已。

  • 有个点值得一提,就是一定要预留给你的虚拟机镜像存放编译用的代码足够的硬盘空间。对于我这种笔记本只有原装256G固态,C、D盘全红的情况,只能寄希望于移动硬盘的救济。 虽然虚拟机有时反应慢点,好歹能跑,凑合。
    • 但这里坑就坑在我使用的虚拟机镜像,也是多年前制作好专门用来编译代码的,安装了很多其他工具链的东西,当时分配了总共20G硬盘空间,仅剩下2、3G能存放新加入的东西。捉襟见肘,十分痛苦。要引以为戒。

讲完编译用的虚拟机,来到开发中编译的对象—— 基线代码。这可有的一说了。


基线代码

基线的选择

别用太老的,这点很重要(比如两三年前的那种)。基线代码更迭不频繁,但功能改动较多,修复的bug也很重要。我这次一上手用的还是多年前,从其他工程师那沿用下来的基线,是IDF V4.0 。 当然了,通常在公司里,从别人那接手的项目不会冒然更换基线再修改移植,而是从已经通过原来功能验证的基线着手。这也就是第一个坑所在,一上来我就掉进去了。在老基线遇到的问题,浪费我一周时间,教训惨痛。

  • 在Github的基线下方,Readme内容如下图,可以查看到各型号支持的基线与维护周期等内容 => 点这里去看看

各ESP32芯片支持的基线

使用老基线我这里遇到三个情况:

  1. 提问不方便。 什么意思?无论是团队内部追溯早期版本记录,还是遇到困难咨询论坛,都无法获得很准确或可靠的答复,一是该基线官方已经不再维护。二是我的团队在早期也没有建立完备的版本管理和文档记录工作,更是无从查起。这对于很多开发者来说都是非常头疼的事,所以一定一定要做好归档工作。
  2. 操作方法在新基线不全适用。 这里说的是之后我切换到了新基线,发现原来在老基线上做法OK的事情,到了新基线不能用了。比如我修改了分区配置,在新基线上用了老基线的修改方法导致固件运行有各种问题。
  3. 老基线有缺陷。这很显然了,是代码都会多少出现点问题,只要在特定情况下就会显现出来。
    • 这第3点,以前我一直不以为然,觉得就算是老基线怎么说也是当时的发布版本,稳定性上面肯定还好啦。 应该说这话没错,一般场景下完全OK。但就拿我这次要在boot中使用外设为例,修改好的boot代码怎么也跑不起来,达不到预期效果。但一字不差放到新基线的boot上,运行没有问题… 哎,换了基线后为开发前选择的老基线着实郁闷好一阵。

基线的获取

三种途径:

  1. Github 代码库:但Github在国内访问,无论下载zip还是Git命令拉取,速度你懂得… 真感人 T.T
    • 不建议使用Github自带的下载zip到本地的方式,这样下不了基线里包含的各种Submodule组件,编译不通过而且要补全很费时费力。我已经踩过这个坑,没等全部submodule下载完,先放弃了。
    • 如果不介意Github网速问题,有两种方式能够获取完整的基线
      1. 使用Git命令拉取到本地。最好是直接在linux中拷贝仓库地址,先拉取基线,然后用“git submodule update --init --recursive” 更新submodule,解决上一条提到的下载zip到本地出现的问题。 => 点这里去试试
      2. 根据代码库提交的tags,选择一个版本(右侧的Unverify是说作者没有对该tags签名认证,不放心则不选择就行),根据需要下载zip或tar.gz文件到本地。此时压缩包中的基线,就是带有完整Submodule代码的,可放心编译使用。 => 点这里去看看
  2. Gitee 代码库
    • 这是国内的代码库站点,网速很给力 => 看看怎么下载
    • 不想费劲阅读的,直接拷贝下面这四条命令到自己的linux用户目录,依次运行即可:
      git clone https://gitee.com/EspressifSystems/esp-gitee-tools.git
      git clone --single-branch --branch release/v4.4 https://gitee.com/EspressifSystems/esp-idf.git
      cd esp-gitee-tools
      ./submodule-update.sh ../esp-idf
      • 以上四步会把IDF V4.4基线拉取到linux目录下,并且通过submodule脚本更新好所有缺失的组件。可以根据需要修改命令中的基线版本号,没有相应目录去创建就行。
  • 可以发现,以上两个方法基本是通过运行git命令拉取的,这也是在linux编译开发的推荐做法,不会遗漏IDF基线内的众多submodule组件,省心、可靠。
  1. 离线安装工具
    • 这是一款在windows安装的软件,包含了所有在windows编译环境的依赖文件。相当于通过安装,把相应的ESP-IDF基线编译环境整个解压到本地 => 点这里去下载
      • 我这次没在windows下编译运行,对该途径没有更深入的尝试。
  • 说的有点多,要实在搞不懂怎么办?墙裂建议你去查阅官方的 “ESP-IDF 编程指南 ” 第二步 =》 点这里。左上角选好自己的型号和基线,跟着一步步完成配置吧。
    在这里插入图片描述

bootloader 初看

搞定了以上编译工程所需的基本要素。终于来到此次开发任务的主战场 —— Bootloader

上战场首先要熟悉地形吧。boot文件结构如何,开发中需要注意什么,怎么让自己的代码跑起来,我又该怎么动手?别急,我们一起来了解下。

文件结构

  • 在IDF V4.4.2的根目录,component中有两个boot相关的文件夹“bootloader”、“bootloader_support”,内部结构如下图。 其中bootloader_support中的mycode,是我添加的boot自定义代码主要所在位置。
    boot在基线中的文件结构
  • 想对ESP32-C3的bootloader有更全面详细的了解,找官方的“ESP-IDF 编程指南”吧 => 点这里

特点

bootloader固件独立于应用层app。在开发上有几个注意事项:

  1. 固件大小
    • 不像在应用层,动辄几百K的固件都妥妥能运行。ESP32对boot的二进制文件,绝对大小限制为0x10000,也就是最大64KB。默认则是32KB,不够时的调整方法有三个:
      1. 调整编译boot固件的优化等级
      2. 降低boot日志输出级别
      3. 调整menuconfig的CONFIG_PARTITION_TABLE_OFFSET
      • 关于以上三个调整大小的方法,在这里先不展开,想知道官方更多详细说明的,可以查阅“ESP-IDF 编程指南 - 引导加载程序大小” 章节 => 点这里。 后续会深入到boot去开发。涉及分区修改时,我会再提到调整boot大小相关的内容。
    • 在我的开发后期,时不时boot固件会编译超过64KB,也挺蛋疼,提示如下:
      boot编译超过64KB的错误提示
  2. 大多数功能无法使用
    • 在IDF中,应用层很容易调用各种driver接口让外设工作或操作系统调度起来。像定时器、串口、IIS这样的外设,其实他们的使用接口内部都含有freertos的组件,比如动态申请空间、各种信号量完成的上锁机制等等。而在boot中,其一无法使用操作系统(固件大小的限制也不允许),其二外设无法直接调用现成的应用层接口工作。包括各种初始化、让外设工作的接口,只能自己搞定。 这一点会在后面详细说到,是在bootloader开发要重点解决的问题之一。
      • 当然,除非你用不到硬件上的任何外设啦。:)

怎么改

我们自己的代码,怎么加入到原来boot中让它生效,怎么输出库给到我们的客户让他也能使用?

修改后通过什么方式生效

  • 首先要说明的是官方建议的bootloader开发方式,有以下两种:
    1. 通过钩子函数。扩展原来的bootloader流程,打个补丁。
    2. 通过覆盖bootloader。重写一个bootloader,覆盖原来bootloader的逻辑来运行。
    • 可以发现,这两种方式一个针对小改动需求,一个针对大改动的需要。
    • “ESP-IDF 编程指南”怎么说自定义bootloader呢? => 点这里看看。指南中提到的custom_bootloader?点这里
  • 你尽可以去探索一下这两种方式的差别。我这里要说的,是第二种方式,但严格来说又不是这两者其一。
    • 既没有使用钩子函数打补丁,也没有新建main文件夹在一个叫booloader_components的文件夹中。我认为这应该是老基线的bootloader产物,被保留到了新基线中。
    • 我的方式,在上面说【文件结构】时已经提到,就是直接把代码放在自己创建的mycode文件夹中。

怎么添加自己的功能

如果在应用层开发,会做些什么?

  1. 嗯,你会在component目录下新建自己功能名的文件夹
  2. 之后呢?不知道了… 那就看看component其他组件都放了啥吧。哦,有CMakeLists.txt,component.mk,还有代码目录。那咱们依葫芦画瓢,也放上这些东西。
  3. 然后?既然有Cmake的东西,那就看看里面都说了啥。哦,原来里面就是设置好了要编译哪些源文件,头文件目录在哪里,还有配置好编译选项啊,库路径什么的。
  • 是的,这些东西在bootloader里面都有,方法类似。就我的开发方式而言,mycode放在bootloader_support目录下之后,里面的源文件、头文件、库这些的,都跟应用层开发一样。该在CMakeLists.txt加什么就加。
    • 这跟在boot还是在app其实就没啥关系,是CMake这种跨平台编译方式的基本操作。
      在这里插入图片描述

bootloader初看完,你应该对它有些基本了解了。接下来,我们进入重头戏,看看bootloader里我是怎么搞定外设使用的。 => 【填坑】ESP32 bootloader初探(下)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/40762.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32初级入门

1.下载的时候如果出现不能下载&#xff0c;那是因为没复位&#xff0c;在出现connect时按住板子上的boot按键&#xff0c;出进度了然后松开&#xff0c;就会正常下载。 2.点灯和uno一样&#xff0c;直接在setup里面设置管脚模式&#xff0c;在loop里面赋值就行&#xff0c;根本…

ESP32 Secure Boot和Flash加密

ESP32的代码是存在外部Flash中&#xff0c;如果不加密&#xff0c;很容易被窃取代码。 ESP32的secure boot和flash加密是两个功能&#xff0c;但是要配合一起使用&#xff0c;其加密效果才好。 一、初次加密。 这里只写可重复烧写的加密方式&#xff0c;其加密步骤如下&…

ESP32修改BootLoader:在boot中添加GPIO和IIC驱动方式

ESP32修改BootLoader&#xff1a;在boot中添加GPIO和IIC驱动方式 1. ESP Bootloader简介 ESP32有着强大的引导加载程序&#xff08;Bootloader&#xff09;功能&#xff1a; 主要执行以下任务&#xff1a; 内部模块的最小化初始配置&#xff1b; 根据分区表和 ota_data&#…

ESP32 基础篇: 启动时 rst cause 和 boot mode

本文参考 ESP32 技术参考手册 和 ESP32-WROOM-32 datasheet 简介 在 ESP32 启动时, ROM CODE 会读取 GPIO 状态和 rst cause 状态, 进而决定 ESP32 工作模式。 通过了解和掌握 rst cause 和 boot mode, 有助于定位某些系统问题。 例如: ESP32 启动时会有如下打印: rst:0x1 (…

微信小程序 自动对对联

微信小程序 自动对对联 微信扫描二维码体验吧

使用scoped让样式只对当前页面其作用时/deep/ 可以使其对子组件起作用

官方文档https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles 使其样式只对当前页面起作用 影响到里面的子组件

uniapp-微信小程序,对子组件实现onShow效果

背景&#xff1a;使用uni-app开发一个微信小程序&#xff0c;使用的vue子组件&#xff0c;发现在子组件里面不能使用onShow生命周期&#xff0c;但是可以在page里面可以调用&#xff0c;需要在使用uni.navigateBack()返回后&#xff0c;该组件能请求接口数据刷新 解决&#xf…

基于强化学习的大规模多任务机器人训练

发布人:Google 机器人团队高级研究员 Karol Hausman 和研究员 Yevgen Chebotar 通用机器人要想发挥最大的作用,就需要能够完成一系列的任务,如清洁、维护和运送。但是,使用离线强化学习 (RL)(智能体使用以前收集的数据开展训练,在试验和错误中学习的一种方法)来训练,即…

数据库MySQL详解

全网最详细MySQL教程&#xff0c;应付大学考试、考研复试、求职笔试应该说是完全足够的&#xff0c; 有兴趣的朋友可以看我的MySQL专栏&#xff0c;都是MySQL原理和底层一点的东西&#xff0c;可能比一般的面试文都深入。 本文篇幅较长&#xff0c;笔误之处在所难免&#xff0c…

关于对Vue中slot插槽理解

关于slot插槽理解 1.何时需要使用插槽 在开发中&#xff0c;我们需要将共性内容抽取到组件中&#xff0c;将不同的暴露为插槽。 插槽的益处便是&#xff0c;一旦预留了插槽&#xff0c;使用者便可以根据自己的需求来决定插槽中插入的的内容2. slot的基本使用 <div idapp&…

记录一次 AGP 调研过程中的思考,我从一个事故搞出了一个故事!

背景 看过我博客的老铁应该知道&#xff0c;我在 18 年五月写过一个小 gradle 插件https://github.com/yanbober/app-tiny-R-gradle-plugin&#xff0c;其作用就是将 app 生成的 R 常量进行内联操作。对&#xff0c;就是前不久很火的滴滴 booster 和字节跳动 ByteX 提供的 R 资…

hive中对子查询如in,exists等支持情况和使用

案例情况&#xff1a;同事使用公司数据探查跑一段代码&#xff0c;部分代码如下&#xff0c;报错&#xff0c;显示不支持in内的子查询。但是直接用虚拟机去跑的话代码没有任何报错&#xff0c;也出结果&#xff0c;很奇怪。 SELECT t1.SIGN_CODE AS bus_src,t1.ORGANIZATI…

overflow属性对before、after伪元素的影响

div中有before伪元素&#xff0c;如图&#xff1a; 当该div内容增多时&#xff0c;添加了纵向滚动条的样式&#xff0c;如下&#xff1a; max-height:300px; overflow: auto; 随后伪元素就消失了&#xff0c;如图&#xff0c;小箭头不见了。 overflow的说明&#xff1a; http…

如何提升对编程的兴趣,在编程中找到快乐?

上周有同学和我交流&#xff0c;问我怎么能在编程中找到快乐&#xff0c;提升编程的兴趣。 今天正好又是周末&#xff0c;对于这个问题&#xff0c;小编就要祭出大招了。 首先&#xff0c;打开浏览器&#xff0c;访问一个神奇的地址&#xff1a; https://github.com/ 。 对的…

一个会对对联的AI项目

编辑文章 声明&#xff1a;本文首发微信公众号【菜鸟要飞】&#xff0c;如有转载&#xff0c;请标明出处&#xff01; 快过年了&#xff0c;贴对联是必不可少的传统风俗。不知道各位读者有没有自己写过对联呢&#xff1f;写对联可不是一件简单的事情&#xff0c;如果不是满腹…

字符串匹配算法知多少?

文章目录 BF算法RK算法编辑器中的全局替换方法&#xff1a;BM算法坏字符好后缀规则代码实现 KMP算法 一说到字符串匹配算法&#xff0c;不知道会有多少小伙伴不由自主的想起那个kmp算法呢&#xff1f; 想到是很正常的&#xff0c;谁让它那么优秀呢。 BF算法 不要被事物的表面…

量化股票查询代码是什么?

量化股票查询代码是什么&#xff1f;接下来用一些代码来分析一下&#xff0c;如下&#xff1a; 做空95&#xff1a;HHV((HIGHLOWOPEN2*CLOSE)/5H-L,5),COLORBLUE;做空68: HHV((HIGH-LOWOPEN2*CLOSE)/5*2-L,5),COLORRED&#xff1b; 平衡点&#xff1a;LLV((HIGHLOWOPEN2*CLOSE…

voipdiscount免费拨打全球电话(无需手机注册)

我测试过了的&#xff0c;能给我手机打通&#xff0c;我也给无题打了的感觉还不错。现推荐给大家&#xff01; voipdiscount免费拨打全球电话&#xff08;无需手机注册&#xff09;通话效果极好到www.voipdiscount.com下载一个软件voipdiscount,申请一个用户&#xff08;不需手…

企业使用虚拟码号的优势!

其实用不用隐私码号&#xff0c;或者怎么用隐私码号&#xff0c;是和企业的基本业务场景有关的。我们在这将近5年的服务过程中&#xff0c;遇上的行业千差万别&#xff0c;需求也是完全不同。如果非要总结一些优势的话&#xff0c;那么简单的做个应用场景分类。 隐私码号&#…

VOS网络电话如何注册IMS

IMS注册需要IMS方提供账号的注册信息 比如 用户名称&#xff1a;862584372919 认证密码&#xff1a;123456 服务器地址&#xff1a;ims.jx.chinamobile.com 认证用户&#xff1a;862584372919 SIP代理&#xff1a;172.16.5.144 第一步: 在vos的业务管理—>注册管理中按下图…