Hi everyone!
I am currently trying to tackle the following problem: I have two apps installed on my ESP32, e.g., on the factory and ota_0 partitions, and I want to select the app to boot based on the state of some given GPIO pin. I have searched the documentation for options and found the following: Apparently one could install one app in a 'test' partition and then there is some mechanism by which the test partition is booted if some GPIO is set. However, documentation on that is sparse and I did not really understand it. Do I need to overwrite the second stage bootloader (at 0x001000 I think?) to achieve the desired behaviour?
Alternatively, the following would work too: Always boot the factory app and then this app decided on whether to boot the ota_0 app based on the state of a GPIO pin. I did not find anything regard booting one app out of the other, however.
It is very important that the ota_0 app is completely agnostic to this whole process, i.e., that this would work with any binary installed in the ota_0 partition.
This problem feels like a standard problem to me, but I could not find much on the internet. I am still new to the ESP-IDF and I might just be lacking some keyword to look for. Any help is greatly appreciated!
Best,
Hrox
Bootloader: Selecting app based on GPIO input
Re: Bootloader: Selecting app based on GPIO input
Now that we have bootloader_components, I think you could wrap bootloader_utility_get_selected_boot_partition for a fairly simple and clean solution. eg. (untested):
project_dir/bootloader_components/bootloader_select/bootloader_select.c:
project_dir/bootloader_components/bootloader_select/CMakeLists.txt:
project_dir/bootloader_components/bootloader_select/bootloader_select.c:
Code: Select all
#include "soc/gpio_periph.h"
#include "soc/gpio_struct.h"
#include "soc/io_mux_reg.h"
#include "hal/gpio_ll.h"
#include "esp_rom_gpio.h"
#include "bootloader_common.h"
#include "bootloader_config.h"
#define BOOTLOADER_SELECT_GPIO 25
int __real_bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs);
static bool bootloader_select_is_button_pushed(void)
{
esp_rom_gpio_pad_pullup_only(BOOTLOADER_SELECT_GPIO);
esp_rom_gpio_pad_select_gpio(BOOTLOADER_SELECT_GPIO);
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[BOOTLOADER_SELECT_GPIO]);
return (gpio_ll_get_level(&GPIO, BOOTLOADER_SELECT_GPIO) == 0);
}
int __wrap_bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
{
if(bootloader_common_get_reset_reason(0) != DEEPSLEEP_RESET)
{
if(bootloader_select_is_button_pushed())
{
return FACTORY_INDEX;
}
}
return __real_bootloader_utility_get_selected_boot_partition(bs);
}
void __attribute__((section("/DISCARD/"))) bootloader_select_include() {}
Code: Select all
idf_component_register(
SRCS "bootloader_select.c"
REQUIRES hal bootloader_support
)
idf_build_set_property(LINK_OPTIONS "-Wl,--wrap=bootloader_utility_get_selected_boot_partition" APPEND)
idf_build_set_property(LINK_OPTIONS "-Wl,--require-defined=__wrap_bootloader_utility_get_selected_boot_partition" APPEND)
idf_build_set_property(LINK_OPTIONS "-Wl,--require-defined=bootloader_select_include" APPEND)
Re: Bootloader: Selecting app based on GPIO input
Thank you for the fast answer! I have to admit, I do not have much experience with the esp-idf/components lib, since I have been mostly using the Arduino framework together with PlatformIO. Is there any documentation available regarding the functions and macros you have used in the example code or will I just have to read the headers and source code? Thanks in advance
Who is online
Users browsing this forum: cdollar, Majestic-12 [Bot] and 120 guests