ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS

在之前的文章中,我描述了新的esp32芯片,并解释了如何设置开发环境,包括使用一种可选的图形IDE,Eclipse。

在开始开发程序之前,您需要了解框架的三个关键组件:flash,bootloader和FreeRTOS操作系统。但别担心!在本篇文章的最后,您将编写,编译并执行您的第一个程序(即使是“最小化”),并从下一个教程开始,我们将一起处理更复杂的示例。

Flash

正如我在本教程的第一篇文章中所写的,esp32芯片需要一个外部闪存来存储程序,数据,配置参数......

外部存储器通过SPI总线连接到芯片,支持的容量高达16Mb。官方Espressif模块(ESP-WROOM-32)包含由GigaDevice(GD25Q32)制造的4Mb闪存:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第1张图片

闪存可以存储不同的元素:程序,数据...因此它被分成多个部分(分区)。闪存中的列表分区,大小和位置存储在内存本身(地址0x8000),它被称为分区表。

默认情况下定义了两种分区类型:

  • app (type 0) – partition that contains an application (program)包含应用程序(程序)的分区
  • data (type 1) – partition that contains data 包含数据的分区

在编写新程序时,开发人员可以根据程序的特定需求决定如何组织闪存。 esp-idf框架提供两种预先配置的内存布局,您可以从配置菜单中进行选择:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第2张图片

您还可以使用make partition_table命令显示项目的分区表:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第3张图片

I在上面的屏幕截图中,您可以看到对应于最简单配置的分区表布局(单工厂应用程序,无OTA):

  • a data partition (named “nvs“) with a size of 24Kb starting from address 0x9000
  • a data partition (named “phy_init“) with a size of 4Kb starting from address 0xf000
  • an app partition (named “factory“) with a size of 1Mb starting from address 0x10000

Bootloader

为了更好地理解为什么将闪存划分为分区,我必须描述esp32引导加载程序的工作原理,即如何启动应用程序以及如何上载新固件。

在esp32 ROM内存中有一个小程序,名为第一阶段启动加载程序。该程序在芯片的每次复位时执行:它配置对外部闪存的访问,并且如果需要,存储来自串行/ USB端口的新数据(闪存过程)。一旦完成,它将访问闪存(地址为0x1000)并加载并执行第二阶段启动加载程序。

即使esp-idf框架的标准行为是使用此第二阶段启动加载程序,也可以开发一个独立应用程序,该应用程序存储在闪存的地址0x8000处,由第一阶段启动加载程序直接执行。

第二阶段引导加载程序读取地址为0x8000的分区表并搜索应用程序分区。它根据otadata分区的内容决定执行哪个应用程序:如果此分区为空或不存在,则引导加载将执行存储在出厂分区中的应用程序。这允许实施无线(OTA)应用程序更新过程:将新版本的应用程序发送到esp32芯片;该版本存储在新的应用程序分区中。一旦上传完成,分区的ID被保存在otadata中并且芯片被重新启动;引导程序将执行新版本:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第4张图片

FreeRTOS

esp-idf框架基于FreeRTOS实时操作系统。在像esp32这样的“小型”芯片上工作时谈论操作系统可能听起来很奇怪......但您不必认为FreeRTOS是Windows,Linux或MacOS等操作系统。嵌入式操作系统提供的主要功能(由于其内部调度程序)是多任务处理,即能够并行运行不同任务。我们知道微处理器内核可以一次执行一条指令:由于调度程序在其任务之间快速切换,似乎不同的应用程序同时运行。

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第5张图片

(FreeRTOS中不同的任务状态)

实时操作系统的设计是为了确保任务调度是确定性的:您可以预测其调度程序的行为。 FreeRTOS允许开发人员为每个任务定义优先级:调度程序使用优先级值来定义不同任务的执行模式。

Our first program

我们来编写我们的第一个使用esp-idf框架的程序。这个程序在我的Github仓库中可用,将成为所有下一个教程的基础。

首先,我们必须包含一些库:

esp-flash07

stdio.h库(Standard I / O)用于输入/输出函数(printf ...),两个freertos头文件用于定义和执行不同的任务。

每个程序都从app_main()开始执行:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第6张图片

在app_main()中,使用xTaskCreate方法创建一个新任务。此方法需要以下参数:指向包含任务代码的函数(&loop_task)的指针,任务名称(“loop_task”),要分配给任务的堆栈内存大小(以字为单位) ,任务的附加参数(NULL),任务的优先级(5)和指针 - 可选 - 来检索任务的处理程序(NULL)。

一旦创建任务,FreeRTOS调度程序将根据不同的任务和优先级执行任务。

该任务具有以下代码:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第7张图片

这是一个连续的循环,每秒打印一个句子Hello World!“。 vTaskDelay方法将任务暂停指定的刻度数。 portTICK_RATE_MS常量定义一个刻度的持续时间(以毫秒为单位);如果你因此将1000分为这个常数,你会在一秒钟内得到滴答的数量。

Additional files

为了能够编译你的项目,你需要添加一些额外的文件:

  • a Makefile in the main folder of your project that contains the name of the project and an include for the main makefile of the framework:项目主文件夹中的Makefile,其中包含项目的名称和框架的主makefile的include:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第8张图片

  • a component.mk file – it can be empty – in the folder where the source code is saved into to tell the compiler to process the files in that folder:一个component.mk文件 - 它可以是空的 - 在保存源代码的文件夹中告诉编译器处理该文件夹中的文件:

ESP-IDF库开发教程之(4)--FLASH、BootLoader和FreeRTOS_第9张图片

Test

当程序准备就绪时,您可以按照上一篇文章中的说明编译并加载到主板上:

make
make flash

如果一切正常,当用串行仿真器连接到电路板时,应该看到:

esp-flash12

你可能感兴趣的:(ESP32,ESP32开发之旅)