此篇博客用来介绍 ESP32-C3 如何在上电后 50 ms 内控制 GPIO 输出。当前使用的 IDF 为 release/v4.3,commit 为 6be10fab0
。
请注意,修改 bootloader 可能会导致风险。故修改 bootloader 后需要进行测试来保证稳定性
首先进入到 bootloader_start.c,将以下代码
#include "soc/soc.h"
#include "soc/gpio_periph.h"
#include "hal/gpio_hal.h"
gpio_dev_t *hw = &GPIO;
hw->enable_w1ts.enable_w1ts = (0x1 << 18);
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[18], 1);
hw->out_w1ts.out_w1ts = (0x1 << 18);
放入 API call_start_cpu0()
中,如下:
static int select_partition_number(bootloader_state_t *bs);
static int selected_boot_partition(const bootloader_state_t *bs);
#include "soc/soc.h"
#include "soc/gpio_periph.h"
#include "hal/gpio_hal.h"
/*
* We arrive here after the ROM bootloader finished loading this second stage bootloader from flash.
* The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
* We do have a stack, so we can do the initialization in C.
*/
void __attribute__((noreturn)) call_start_cpu0(void)
{
// 1. Hardware initialization
if (bootloader_init() != ESP_OK) {
bootloader_reset();
}
gpio_dev_t *hw = &GPIO;
hw->enable_w1ts.enable_w1ts = (0x1 << 18);
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[18], 1);
hw->out_w1ts.out_w1ts = (0x1 << 18);
上述示例能在 bootloader 阶段将 GPIO18 设置为输出高电平。此时通过逻辑分析仪检测可以发现从芯片上电 EN 拉高到 GPIO18 被拉高的时间为 58 ms。如下:
此时将设置 GPIO18 为高电平输出的代码挪到 API call_start_cpu0()
开始处:
#include "soc/soc.h"
#include "soc/gpio_periph.h"
#include "hal/gpio_hal.h"
/*
* We arrive here after the ROM bootloader finished loading this second stage bootloader from flash.
* The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset.
* We do have a stack, so we can do the initialization in C.
*/
void __attribute__((noreturn)) call_start_cpu0(void)
{
gpio_dev_t *hw = &GPIO;
hw->enable_w1ts.enable_w1ts = (0x1 << 18);
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[18], 1);
hw->out_w1ts.out_w1ts = (0x1 << 18);
// 1. Hardware initialization
if (bootloader_init() != ESP_OK) {
bootloader_reset();
}
此时通过逻辑分析仪检测可以发现从芯片上电 EN 拉高到 GPIO18 被拉高的时间被缩短到了 28 ms。如下:
此时即可满足上电后 50 ms 内控制 GPIO 输出。