kopia lustrzana https://github.com/espressif/esp-idf
support for console redirection to other UART
This change adds a set of menuconfig options to set custom UART#, baud rate, and pins, for console output. Setting happens in bootloader startup code for PRO CPU, and in application startup code for APP CPU. Ref. TW8146pull/154/head
rodzic
6dc77bc55c
commit
b3f6cd08db
|
@ -23,6 +23,8 @@
|
|||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
|
@ -31,6 +33,8 @@
|
|||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
|
@ -62,7 +66,7 @@ void set_cache_and_start_app(uint32_t drom_addr,
|
|||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
static void uart_console_configure(void);
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
|
@ -224,6 +228,7 @@ static bool ota_select_valid(const esp_ota_select_entry_t *s)
|
|||
|
||||
void bootloader_main()
|
||||
{
|
||||
uart_console_configure();
|
||||
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
|
||||
|
||||
esp_image_header_t fhdr;
|
||||
|
@ -616,3 +621,63 @@ void print_flash_info(const esp_image_header_t* phdr)
|
|||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t get_apb_freq(void)
|
||||
{
|
||||
// Get the value of APB clock from RTC memory.
|
||||
// The value is initialized in ROM code, and updated by librtc.a
|
||||
// when APB clock is changed.
|
||||
// This value is stored in RTC_CNTL_STORE5_REG as follows:
|
||||
// RTC_CNTL_STORE5_REG = (freq >> 12) | ((freq >> 12) << 16)
|
||||
uint32_t apb_freq_reg = REG_READ(RTC_CNTL_STORE5_REG);
|
||||
uint32_t apb_freq_l = apb_freq_reg & 0xffff;
|
||||
uint32_t apb_freq_h = apb_freq_reg >> 16;
|
||||
if (apb_freq_l == apb_freq_h && apb_freq_l != 0) {
|
||||
return apb_freq_l << 12;
|
||||
} else {
|
||||
// fallback value
|
||||
return APB_CLK_FREQ_ROM;
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
{
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_num = CONFIG_CONSOLE_UART_NUM;
|
||||
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
|
||||
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
|
||||
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
||||
// Wait for it to be printed.
|
||||
uart_tx_wait_idle(0);
|
||||
// Switch to the new UART (this just changes UART number used for
|
||||
// ets_printf in ROM code).
|
||||
uart_tx_switch(uart_num);
|
||||
// Set new baud rate
|
||||
uart_div_modify(uart_num, (((uint64_t) get_apb_freq()) << 4) / uart_baud);
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
|
||||
// Change pin mode for GPIO1/3 from UART to GPIO
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
|
||||
// Route GPIO signals to/from pins
|
||||
// (arrays should be optimized away by the compiler)
|
||||
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
|
||||
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
|
||||
const uint32_t tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
#endif // CONFIG_CONSOLE_UART_NONE
|
||||
}
|
||||
|
|
|
@ -138,6 +138,64 @@ config NEWLIB_STDOUT_ADDCR
|
|||
is usually done by an added CR character. Enabling this will make the
|
||||
standard output code automatically add a CR character before a LF.
|
||||
|
||||
choice CONSOLE_UART
|
||||
prompt "UART for console output"
|
||||
default CONSOLE_UART_DEFAULT
|
||||
help
|
||||
Select whether to use UART for console output (through stdout and stderr).
|
||||
- Default is to use UART0 on pins GPIO1(TX) and GPIO3(RX).
|
||||
- If "Custom" is selected, UART0 or UART1 can be chosen,
|
||||
and any pins can be selected.
|
||||
- If "None" is selected, there will be no console output on any UART, except
|
||||
for initial output from ROM bootloader. This output can be further suppressed by
|
||||
bootstrapping GPIO13 pin to low logic level.
|
||||
|
||||
config CONSOLE_UART_DEFAULT
|
||||
bool "Default: UART0, TX=GPIO1, RX=GPIO3"
|
||||
config CONSOLE_UART_CUSTOM
|
||||
bool "Custom"
|
||||
config CONSOLE_UART_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
choice CONSOLE_UART_NUM
|
||||
prompt "UART peripheral to use for console output (0-1)"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
default CONSOLE_UART_CUSTOM_NUM_0
|
||||
help
|
||||
Due of a ROM bug, UART2 is not supported for console output
|
||||
via ets_printf.
|
||||
|
||||
config CONSOLE_UART_CUSTOM_NUM_0
|
||||
bool "UART0"
|
||||
config CONSOLE_UART_CUSTOM_NUM_1
|
||||
bool "UART1"
|
||||
endchoice
|
||||
|
||||
config CONSOLE_UART_NUM
|
||||
int
|
||||
default 0 if CONSOLE_UART_DEFAULT || CONSOLE_UART_NONE
|
||||
default 0 if CONSOLE_UART_CUSTOM_NUM_0
|
||||
default 1 if CONSOLE_UART_CUSTOM_NUM_1
|
||||
|
||||
config CONSOLE_UART_TX_GPIO
|
||||
int "UART TX on GPIO#"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
range 0 33
|
||||
default 19
|
||||
|
||||
config CONSOLE_UART_RX_GPIO
|
||||
int "UART RX on GPIO#"
|
||||
depends on CONSOLE_UART_CUSTOM
|
||||
range 0 39
|
||||
default 21
|
||||
|
||||
config CONSOLE_UART_BAUDRATE
|
||||
int "UART console baud rate"
|
||||
depends on !CONSOLE_UART_NONE
|
||||
default 115200
|
||||
range 1200 4000000
|
||||
|
||||
config ULP_COPROC_ENABLED
|
||||
bool "Enable Ultra Low Power (ULP) Coprocessor"
|
||||
default "n"
|
||||
|
|
|
@ -33,7 +33,7 @@ void esp_set_cpu_freq(void)
|
|||
|
||||
// freq will be changed to 40MHz in rtc_init_lite,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
|
||||
|
||||
rtc_init_lite(XTAL_AUTO);
|
||||
cpu_freq_t freq = CPU_80M;
|
||||
|
@ -54,7 +54,7 @@ void esp_set_cpu_freq(void)
|
|||
|
||||
// freq will be changed to freq in rtc_set_cpu_freq,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
|
||||
|
||||
rtc_set_cpu_freq(freq);
|
||||
ets_update_cpu_frequency(freq_mhz);
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
#include "esp_coexist.h"
|
||||
#include "trax.h"
|
||||
|
||||
#define STRINGIFY(s) STRINGIFY2(s)
|
||||
#define STRINGIFY2(s) #s
|
||||
|
||||
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
||||
void start_cpu0_default(void) IRAM_ATTR;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
|
@ -97,9 +100,6 @@ void IRAM_ATTR call_start_cpu0()
|
|||
"wsr %0, vecbase\n" \
|
||||
::"r"(&_init_start));
|
||||
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
|
||||
|
||||
/* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */
|
||||
|
@ -145,6 +145,15 @@ void IRAM_ATTR call_start_cpu1()
|
|||
|
||||
cpu_configure_region_protection();
|
||||
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
uart_tx_switch(CONFIG_CONSOLE_UART_NUM);
|
||||
#endif
|
||||
|
||||
ESP_EARLY_LOGI(TAG, "App cpu up.");
|
||||
app_cpu_started = 1;
|
||||
start_cpu1();
|
||||
|
@ -164,7 +173,7 @@ void start_cpu0_default(void)
|
|||
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
|
||||
#endif
|
||||
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||
uart_div_modify(CONFIG_CONSOLE_UART_NUM, (APB_CLK_FREQ << 4) / CONFIG_CONSOLE_UART_BAUDRATE);
|
||||
#if CONFIG_BROWNOUT_DET
|
||||
esp_brownout_init();
|
||||
#endif
|
||||
|
@ -177,10 +186,16 @@ void start_cpu0_default(void)
|
|||
esp_setup_time_syscalls();
|
||||
esp_vfs_dev_uart_register();
|
||||
esp_reent_init(_GLOBAL_REENT);
|
||||
const char* default_uart_dev = "/dev/uart/0";
|
||||
#ifndef CONFIG_CONSOLE_UART_NONE
|
||||
const char* default_uart_dev = "/dev/uart/" STRINGIFY(CONFIG_CONSOLE_UART_NUM);
|
||||
_GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r");
|
||||
_GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w");
|
||||
_GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w");
|
||||
#else
|
||||
_GLOBAL_REENT->_stdin = (FILE*) &__sf_fake_stdin;
|
||||
_GLOBAL_REENT->_stdout = (FILE*) &__sf_fake_stdout;
|
||||
_GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr;
|
||||
#endif
|
||||
do_global_ctors();
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
esp_crosscore_int_init();
|
||||
|
|
Ładowanie…
Reference in New Issue