mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-18 04:09:36 +08:00
feat(bootloader): Support to trigger test app in bootloader
This commit is contained in:
@ -126,24 +126,33 @@ config BOOTLOADER_DATA_FACTORY_RESET
|
||||
|
||||
config BOOTLOADER_APP_TEST
|
||||
bool "GPIO triggers boot from test app partition"
|
||||
default N
|
||||
depends on TARGET_PLATFORM_ESP32
|
||||
default n
|
||||
help
|
||||
Allows to run the test app from "TEST" partition.
|
||||
A boot from "test" partition will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
|
||||
config BOOTLOADER_APP_TEST_IN_OTA_1
|
||||
depends on BOOTLOADER_APP_TEST && TARGET_PLATFORM_ESP8266
|
||||
bool "Put test app in the ota_1 partition"
|
||||
default y
|
||||
help
|
||||
For the small SPI Flash solution, there maybe no enough space for the test app partition.
|
||||
By enable this option, test app will locate in ota_1 partition by default.
|
||||
After ota, the test app will be erased and re-write as new app.
|
||||
|
||||
If you disable this, make sure there has a test app partition in you partition table CVS.
|
||||
|
||||
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||
int "Number of the GPIO input to boot TEST partition"
|
||||
depends on BOOTLOADER_APP_TEST
|
||||
range 0 39
|
||||
default 18
|
||||
range 0 15
|
||||
default 2
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a test app, this GPIO must be pulled low on reset.
|
||||
To trigger a test app(the second ota firmware), this GPIO must be pulled low on reset.
|
||||
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||
(factory or OTA[x]).
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
config BOOTLOADER_HOLD_TIME_GPIO
|
||||
int "Hold time of GPIO for reset/test mode (seconds)"
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_init.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
@ -97,6 +98,11 @@ static int selected_boot_partition(const bootloader_state_t *bs)
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
|
||||
ESP_LOGI(TAG, "Detect a boot condition of the test firmware");
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST_IN_OTA_1
|
||||
/* In this case, test bin will locate in ota_1 by default.
|
||||
This is the solution for small Flash. */
|
||||
return 1;
|
||||
#else
|
||||
if (bs->test.offset != 0) {
|
||||
boot_index = TEST_APP_INDEX;
|
||||
return boot_index;
|
||||
@ -104,6 +110,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
|
||||
ESP_LOGE(TAG, "Test firmware is not found in partition table");
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
// Customer implementation.
|
||||
|
@ -2,6 +2,8 @@ PROVIDE ( ets_memcpy = 0x400018b4 );
|
||||
|
||||
PROVIDE ( SPIRead = 0x40004b1c );
|
||||
|
||||
PROVIDE ( gpio_input_get = 0x40004cf0 );
|
||||
|
||||
PROVIDE ( xthal_get_ccount = 0x4000dd38 );
|
||||
PROVIDE ( uart_div_modify = 0x400039d8 );
|
||||
PROVIDE ( ets_io_vprintf = 0x40001f00 );
|
@ -165,11 +165,23 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "crc.h"
|
||||
|
||||
#include "rom/gpio.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_common.h"
|
||||
|
||||
static const char *TAG = "bootloader_common";
|
||||
|
||||
static inline uint32_t esp_log_early_timestamp()
|
||||
{
|
||||
return xthal_get_ccount() / (80 * 1000);
|
||||
}
|
||||
|
||||
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
@ -181,4 +193,24 @@ bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
return s->ota_seq != UINT32_MAX && s->crc == bootloader_common_ota_select_crc(s);
|
||||
}
|
||||
|
||||
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec)
|
||||
{
|
||||
gpio_pad_select_gpio(num_pin);
|
||||
gpio_pad_pullup(num_pin);
|
||||
|
||||
uint32_t tm_start = esp_log_early_timestamp();
|
||||
if (GPIO_INPUT_GET(num_pin) == 1) {
|
||||
ESP_LOGD(TAG, "gpio %d input %x", num_pin, GPIO_INPUT_GET(num_pin));
|
||||
return GPIO_NOT_HOLD;
|
||||
}
|
||||
do {
|
||||
if (GPIO_INPUT_GET(num_pin) != 0) {
|
||||
ESP_LOGD(TAG, "gpio %d input %x", num_pin, GPIO_INPUT_GET(num_pin));
|
||||
return GPIO_SHORT_HOLD;
|
||||
}
|
||||
} while (delay_sec > ((esp_log_early_timestamp() - tm_start) / 1000L));
|
||||
ESP_LOGD(TAG, "gpio %d input %x", num_pin, GPIO_INPUT_GET(num_pin));
|
||||
return GPIO_LONG_HOLD;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -151,4 +151,23 @@
|
||||
SET_PERI_REG_MASK(PIN_NAME, (((FUNC & BIT2) << 2) | (FUNC & 0x3)) << PERIPHS_IO_MUX_FUNC_S); \
|
||||
} while (0)
|
||||
|
||||
#define PERIPHS_GPIO_MUX_REG(i) \
|
||||
(i==0) ? PERIPHS_IO_MUX_GPIO0_U: \
|
||||
(i==1) ? PERIPHS_IO_MUX_U0TXD_U: \
|
||||
(i==2) ? PERIPHS_IO_MUX_GPIO2_U: \
|
||||
(i==3) ? PERIPHS_IO_MUX_U0RXD_U: \
|
||||
(i==4) ? PERIPHS_IO_MUX_GPIO4_U: \
|
||||
(i==5) ? PERIPHS_IO_MUX_GPIO5_U: \
|
||||
(i==6) ? PERIPHS_IO_MUX_SD_CLK_U: \
|
||||
(i==7) ? PERIPHS_IO_MUX_SD_DATA0_U: \
|
||||
(i==8) ? PERIPHS_IO_MUX_SD_DATA1_U: \
|
||||
(i==9) ? PERIPHS_IO_MUX_SD_DATA2_U: \
|
||||
(i==10)? PERIPHS_IO_MUX_SD_DATA3_U: \
|
||||
(i==11)? PERIPHS_IO_MUX_SD_CMD_U: \
|
||||
(i==12)? PERIPHS_IO_MUX_MTDI_U: \
|
||||
(i==13)? PERIPHS_IO_MUX_MTCK_U: \
|
||||
(i==14)? PERIPHS_IO_MUX_MTMS_U: \
|
||||
(i==15)? PERIPHS_IO_MUX_MTDO_U: \
|
||||
PAD_XPD_DCDC_CONF
|
||||
|
||||
#endif //_PIN_MUX_H_
|
||||
|
102
components/esp8266/include/rom/gpio.h
Normal file
102
components/esp8266/include/rom/gpio.h
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_GPIO_H_
|
||||
#define _ROM_GPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp8266/pin_mux_register.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup gpio_apis, uart configuration and communication related apis
|
||||
* @brief gpio apis
|
||||
*/
|
||||
|
||||
/** @addtogroup gpio_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define GPIO_INPUT_GET(gpio_no) ((gpio_input_get() >> (gpio_no)) & BIT0)
|
||||
|
||||
/**
|
||||
* @brief Change GPIO(0-15) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
|
||||
* There is no particular ordering guaranteed; so if the order of writes is significant,
|
||||
* calling code should divide a single call into multiple calls.
|
||||
*
|
||||
* @param uint32_t set_mask : the gpios that need high level.
|
||||
*
|
||||
* @param uint32_t clear_mask : the gpios that need low level.
|
||||
*
|
||||
* @param uint32_t enable_mask : the gpios that need be changed.
|
||||
*
|
||||
* @param uint32_t disable_mask : the gpios that need diable output.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
|
||||
|
||||
/**
|
||||
* @brief Sample the value of GPIO input pins(0-31) and returns a bitmask.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0.
|
||||
*/
|
||||
uint32_t gpio_input_get(void);
|
||||
|
||||
/**
|
||||
* @brief Select pad as a gpio function from IOMUX.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~15
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void gpio_pad_select_gpio(uint32_t gpio_num)
|
||||
{
|
||||
uint32_t gpio_mux_reg = PERIPHS_GPIO_MUX_REG(gpio_num);
|
||||
|
||||
if (gpio_num == 0 || gpio_num == 2 || gpio_num == 4 || gpio_num == 5) {
|
||||
PIN_FUNC_SELECT(gpio_mux_reg, 0);
|
||||
} else {
|
||||
PIN_FUNC_SELECT(gpio_mux_reg, 3);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pull up the pad from gpio number.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~15
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void gpio_pad_pullup(uint32_t gpio_num)
|
||||
{
|
||||
uint32_t gpio_mux_reg = PERIPHS_GPIO_MUX_REG(gpio_num);
|
||||
|
||||
PIN_PULLUP_EN(gpio_mux_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ROM_GPIO_H_ */
|
Reference in New Issue
Block a user