mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-06-17 11:54:24 +08:00
feat(bootloader): Support to trigger test app in bootloader
This commit is contained in:
@ -119,31 +119,40 @@ config BOOTLOADER_DATA_FACTORY_RESET
|
|||||||
default "nvs"
|
default "nvs"
|
||||||
help
|
help
|
||||||
Allows customers to select which data partitions will be erased while factory reset.
|
Allows customers to select which data partitions will be erased while factory reset.
|
||||||
|
|
||||||
Specify the names of partitions as a comma-delimited with optional spaces for readability. (Like this: "nvs, phy_init, ...")
|
Specify the names of partitions as a comma-delimited with optional spaces for readability. (Like this: "nvs, phy_init, ...")
|
||||||
Make sure that the name specified in the partition table and here are the same.
|
Make sure that the name specified in the partition table and here are the same.
|
||||||
Partitions of type "app" cannot be specified here.
|
Partitions of type "app" cannot be specified here.
|
||||||
|
|
||||||
config BOOTLOADER_APP_TEST
|
config BOOTLOADER_APP_TEST
|
||||||
bool "GPIO triggers boot from test app partition"
|
bool "GPIO triggers boot from test app partition"
|
||||||
default N
|
default n
|
||||||
depends on TARGET_PLATFORM_ESP32
|
|
||||||
help
|
help
|
||||||
Allows to run the test app from "TEST" partition.
|
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.
|
A boot from "test" partition will occur if there is a GPIO input pulled low while device starts up.
|
||||||
See settings below.
|
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
|
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||||
int "Number of the GPIO input to boot TEST partition"
|
int "Number of the GPIO input to boot TEST partition"
|
||||||
depends on BOOTLOADER_APP_TEST
|
depends on BOOTLOADER_APP_TEST
|
||||||
range 0 39
|
range 0 15
|
||||||
default 18
|
default 2
|
||||||
help
|
help
|
||||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
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.
|
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||||
(factory or OTA[x]).
|
(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
|
config BOOTLOADER_HOLD_TIME_GPIO
|
||||||
int "Hold time of GPIO for reset/test mode (seconds)"
|
int "Hold time of GPIO for reset/test mode (seconds)"
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "bootloader_config.h"
|
#include "bootloader_config.h"
|
||||||
#include "bootloader_init.h"
|
#include "bootloader_init.h"
|
||||||
#include "bootloader_utility.h"
|
#include "bootloader_utility.h"
|
||||||
|
#include "bootloader_common.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
@ -97,6 +98,11 @@ static int selected_boot_partition(const bootloader_state_t *bs)
|
|||||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||||
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
|
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");
|
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) {
|
if (bs->test.offset != 0) {
|
||||||
boot_index = TEST_APP_INDEX;
|
boot_index = TEST_APP_INDEX;
|
||||||
return boot_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");
|
ESP_LOGE(TAG, "Test firmware is not found in partition table");
|
||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// Customer implementation.
|
// Customer implementation.
|
||||||
|
@ -2,6 +2,8 @@ PROVIDE ( ets_memcpy = 0x400018b4 );
|
|||||||
|
|
||||||
PROVIDE ( SPIRead = 0x40004b1c );
|
PROVIDE ( SPIRead = 0x40004b1c );
|
||||||
|
|
||||||
|
PROVIDE ( gpio_input_get = 0x40004cf0 );
|
||||||
|
|
||||||
PROVIDE ( xthal_get_ccount = 0x4000dd38 );
|
PROVIDE ( xthal_get_ccount = 0x4000dd38 );
|
||||||
PROVIDE ( uart_div_modify = 0x400039d8 );
|
PROVIDE ( uart_div_modify = 0x400039d8 );
|
||||||
PROVIDE ( ets_io_vprintf = 0x40001f00 );
|
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 <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <xtensa/hal.h>
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
|
#include "rom/gpio.h"
|
||||||
|
|
||||||
#include "bootloader_config.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)
|
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);
|
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
|
#endif
|
||||||
|
@ -151,4 +151,23 @@
|
|||||||
SET_PERI_REG_MASK(PIN_NAME, (((FUNC & BIT2) << 2) | (FUNC & 0x3)) << PERIPHS_IO_MUX_FUNC_S); \
|
SET_PERI_REG_MASK(PIN_NAME, (((FUNC & BIT2) << 2) | (FUNC & 0x3)) << PERIPHS_IO_MUX_FUNC_S); \
|
||||||
} while (0)
|
} 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_
|
#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