ESP32

ESP-IDF Programming Guide, v2
ESP-IDF Programming Guide, latest
hackaday ESP32 Hands-On: Awesome Promise

Twitter: ESP32.net, Projekte ansehen

Tensilica(Cadence Design Systems) Xtensa (configurable cores)

Das Espressif IoT Development Framework ist ein auf FreeRTOS und lwIP basiertes Entwicklungssystem für den ESP32.

ESP-IDF, multicore & freeRTOS confusion
To sum up my assumptions about ESP32 I make, when asking this question:

  • ESP32 contains two identical cores, one is PRO_CPU and the second is APP_CPU.
  • Application entry points on both CPUs (start_cpu0 and start_cpu1) are weak functions.
  • However some useful parts of ESP-IDF are written or configured to use FreeRTOS synchronisation and locking primitives.
  • ESP-IDF is build on top FreeRTOS. That means that handling of WiFi and other stuff is handled as RTOS task.
  • ESP-IDF is the lowest-possible API officially supported

The Internet of Things with ESP32
ESP32 Overview

Installation

Standard Setup of Toolchain for Linux

sudo usermod -a -G dialout $USER && \
sudo apt-get install git wget make libncurses-dev \
flex bison gperf python python-serial && \
wget https://bootstrap.pypa.io/get-pip.py && \
sudo python get-pip.py && \
sudo pip install pyserial && \
mkdir -p ~/Arduino/hardware/espressif && \
cd ~/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32/tools/ && \
python get.py

Emulator / Simulator (QEMU)

Xtensa on QEMU
Features/Xtensa
Olof Astrand github.com/Ebiroll/qemu_esp32, Add tensilica esp32 cpu and a board to qemu and dump the rom to learn more about esp-idf

Shop

WEMOS LOLIN32 V1.0.0

Battery Jack / Akku Buchse

It has two jacks: one for a battery and one for an USB plug that can be used to charge the battery. The charging circuit is built around a TP5410 Lipo charger. One therefore would expect a standard LiPo cell connector on the board but the LiPo cell connector on the board is an XH2.54 connector, whereas most LiPo cells come with a JST-PH connector. Another disappointment was that it came with male headers only. Apparently it is thought this shield should come on top of every other possible shield.

There is still no technical information but it seems possible to charge the battery from the micro USB port. The connector is not specified but it looks identical to that of the shield battery (presentation), connector JST XH2-2.54mm. The dedicated page of the Wiki is under construction.

The Wemos LoLin32 has the particularity to propose a connector for LiPo battery. The connector is JST XH2-2.54mm. It has a key that prevents reverse polarity.

La Wemos LoLin32 a la particularité de proposer un connecteur pour batterie LiPo. Le connecteur est de type JST XH2-2.54mm. Il dispose d’un détrompeur qui empêche l’inversion de polarité.

SourceCode

Espressif IoT Development Framework
Hello World Example
Arduino core for ESP32 WiFi chip
Espconn based on lwip on esp32

Hardware

Espressif ESP32 WROVER KIT, Adafruit
LOLIN32 – A wifi&bluetooth board based ESP-32

FreeRTOS

  • FreeRTOS 8.2.0 Custom ESP32
  • FreeRTOS 9.0.0 Latest Release

Configuration
Customisation7
FreeRTOS is customised using a configuration file called FreeRTOSConfig.h. Every FreeRTOS application must have a FreeRTOSConfig.h header file in its pre-processor include path. FreeRTOSConfig.h tailors the RTOS kernel to the application being built. It is therefore specific to the application, not the RTOS, and should be located in an application directory, not in one of the RTOS kernel source code directories.

ESP32 (4) – Flash, bootloader and FreeRTOS

vTaskDelay

Naming Conventions

Coding Standard and Style Guide

Variables:

  • Variables of type uint32_t are prefixed ul, where the 'u' denotes 'unsigned' and the 'l denotes 'long'.
  • Variables of type uint16_t are prefixed us, where the 'u' denotes 'unsigned' and the 's' denotes 'short'.
  • Variables of type uint8_t are prefixed uc, where the 'u' denotes 'unsigned' and the 'c' denotes 'char'.
  • Variables of non stdint types are prefixed x. Examples include BaseType_t and TickType_t, which are portable layer defined typedefs for the natural or most efficient type for the architecture and the type used to hold the RTOS tick count respectively.
  • Unsigned variables of non stdint types have an additional prefix u. For example variables of type UBaseType_t (unsigned BaseType_t) are prefixed ux.
  • Variables of type size_t are also prefixed x.
  • Enumerated variables are prefixed e
  • Pointers have an additional prefixed p, for example a pointer to a uint16_t will have prefix pus.
  • In line with MISRA guides, unqualified standard char types are only permitted to hold ASCII characters and are prefixed c.
  • In line with MISRA guides, variables of type char * are only permitted to hold pointers to ASCII strings and are prefixed pc.

Functions

  • Same as variables.
  • File scope static (private) functions are prefixed with prv.
  • API functions are prefixed with their return type, as per the convention defined for variables, with the addition of the prefix v for void.
  • API function names start with the name of the file in which they are defined. For example vTaskDelete() is defined in tasks.c, and has a void return type.

RTOS Task Notifications

untested functions in freertos
ESP32: Untested FreeRTOS function “ulTaskNotifyTake”
=> Don’t use Task Notifications, use

  • Queue (for mailbox)
  • Counting Semaphore
  • EventGroups (for bitmask based flag events)
xTaskNotify()
xTaskNotifyWait()
resp.

xTaskNotifyGive()
ulTaskNotifyTake() 

Ethernet

ESP32 Monster board, Ether, CAN, OLED all in one
>ESP32 Monster board, Pinout & schematic
GRANDE ESP32 Monster board
kodera2t/ESP32_OLED_LAN8720_sample
Enabling Ethernet On The ESP32
Ethernet on ESP32 using LAN8720
WaveShare Ethernet
WaveShare Wiki – LAN8720 ETH Board
WaveShare Wiki – DP83848 Ethernet Board
ESP32-EVB: Development-Board mit WLAN und Ethernet
Olimex ESP32-EVB
An ESP32 board with ethernet support (LAN8720A)
espressif/esp-idf » Add LAN8720 phy support
[info] ESP32-EVB board for IoT with Ethernet 100Mb interface..

ROM

These are the steps to build newlib used in ESP32 ROM and ESP-IDF
ESP32 ROM update

MMU

Help in understanding the address mapping

Bluetooth

Wikipedia: Bluetooth stack
Android Bluetooth
BlueZ vs Bluedroid bluetooth stack
Bluedroid stack in android

Bluetooth classic Example

Bluetooth classic

It’s definitely not hardware. They’re using a Riviera Waves/CEVA IP core for at least the controller if not the modem side, per their and CEVA’s press releases. That’s full function to 4.1/4.2 as a dual mode device. The problem, apparently, is that they’re implementing the full embedded profile design which means it kind-of skips the HCI being propagated through a channel and you don’t have a raw HCI edge, only an API. Definitely annoying since they claim full support on the chip. That equates to all the hooks to drive that hardware fully, which is very definitely NOT the case.

  • Riviera Waves/CEVA IP
BLE   = Bluetooth Low Energy
BT    = Bluetooth Classic
BTDM  = Bluetooth Dual Mode (BTDM)

BTE   = Bluetooth Embedded System
BTA   = Bluetooth Application Layer

VHCI

/** @brief esp_vhci_host_callback
 *  used for vhci call host function to notify what host need to do
 */
typedef struct esp_vhci_host_callback {
    void (*notify_host_send_available)(void);               /*!< callback used to notify that the host can send packet to controller */
    int (*notify_host_recv)(uint8_t *data, uint16_t len);   /*!< callback used to notify that the controller has a packet to send to the host*/
} esp_vhci_host_callback_t;


/** @brief esp_vhci_host_register_callback
 * register the vhci referece callback, the call back
 * struct defined by vhci_host_callback structure.
 * @param callback esp_vhci_host_callback type variable
 */
void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);

I2S

Interfacing an audio codec with ESP32, June 7, 2017
FreeRTOS Event Groups – quick reference notes

Kolban

Channel: t Technical Tutorials
ESP32 Technical Tutorials: BLE and C++
github.com/nkolban/esp32-snippets/cpp_utils

Bluedroid

typedef struct {
    void (* btc_call)(btc_msg_t *msg);
    void (* btc_cb)(btc_msg_t *msg);
} btc_func_t;

static btc_func_t profile_tab[BTC_PID_NUM] = {
    [BTC_PID_MAIN_INIT] = {btc_main_call_handler,       NULL                    },
    [BTC_PID_DEV]       = {btc_dev_call_handler,        NULL                    },
    [...]
};

esp-idf/components/bt/include/bt.h                         esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
esp-idf/components/bt/bluedroid/hci/hci_hal_h4.c           transmit_data(type, uint8_t *data, uint16_t length)
esp-idf/components/bt/bluedroid/hci/hci_hal_h4.c           interface
esp-idf/components/bt/bluedroid/hci/hci_hal_h4.c           hci_hal_h4_get_interface()
esp-idf/components/bt/bluedroid/hci/hci_layer.c            hci_layer_get_interface()
esp-idf/components/bt/bluedroid/main/bte_main.c            bte_main_boot_entry(bluedroid_init_done_cb_t cb)
esp-idf/components/bt/bluedroid/btc/core/btc_main.c        btc_init_bluetooth(void)
esp-idf/components/bt/bluedroid/btc/core/btc_main.c        btc_main_call_handler(btc_msg_t *msg)
esp-idf/components/bt/bluedroid/btc/core/btc_task.c        profile_tab[BTC_PID_NUM]

esp-idf/components/bt/bluedroid/btc/core/btc_task.c        profile_tab[msg.pid].btc_call(&msg);
esp-idf/components/bt/bluedroid/btc/core/btc_task.c        btc_task(void *arg)
esp-idf/components/bt/bluedroid/btc/core/btc_task.c        btc_init(void)
esp-idf/components/bt/bluedroid/api/esp_bt_main.c          esp_bluedroid_init(void)
esp-idf/examples/bluetooth/gatt_server/main/gatts_demo.c   app_main()
esp-idf/components/esp32/cpu_start.c                       main_task(void* args)

Future vs. Thread

Context of future_t object correct in ESP32?

An Introduction to Lock-Free Programming
Acquire and Release Semantics
Semaphores and Threadpools in Java
Tasks parallel ausführen mit Java Future
Java 8 Concurrency Tutorial: Threads and Executors
Interface Future
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready.

Futures
The future access to parallelism as supported by the hardware and operating system. In contrast to thread, which provides concurrency for arbitrary computations without parallelism, future provides parallelism for limited computations. A future executes its work in parallel (assuming that support for parallelism is available) until it detects an attempt to perform an operation that is too complex for the system to run safely in parallel. Similarly, work in a future is suspended if it depends in some way on the current continuation, such as raising an exception.

“Safe” parallel execution of a future means that all operations provided by the system must be able to enforce contracts and produce results as documented. “Safe” does not preclude concurrent access to mutable data that is visible in the program. For example, a computation in a future might use set! to modify a shared variable, in which case concurrent assignment to the variable can be visible in other futures and threads. Furthermore, guarantees about the visibility of effects and ordering are determined by the operating system and hardware—which rarely support, for example, the guarantee of sequential consistency that is provided for thread-based concurrency. At the same time, operations that seem obviously safe may have a complex enough implementation internally that they cannot run in parallel.

Arduino

Sparkfun ESP32 Thing Hookup Guide
makeEspArduino – A makefile for ESP8266 and ESP32 Arduino projects

Deep-Sleep

System API » Deep Sleep
API Guides » Deep Sleep Wake Stubs

YouTube

pcbreflux’s ESP32 Playlist

Andreas Spiess

#149 ESP32 Deep Sleep, RTC Memory, “Secret” LoLin Pins

Tutorials

ESP-IDF Programming Guide
Get Started (ESP IDF, official, latest)

Debug

OpenOCD README
ESP32 JTAG

# Check if user is in group "plugdev"
$ groups
andreas adm dialout cdrom sudo dip video plugdev lpadmin sambashare wireshark

# Copy OpenOCD rules to udev and restart
$ sudo cp ./share/openocd/contrib/99-openocd.rules /etc/udev/rules.d
$ sudo service udev restart

$ bin/openocd -s share/openocd/scripts -f interface/ftdi/tumpa.cfg -f board/esp-wroom-32.cfg
Open On-Chip Debugger 0.10.0-dev-ga859564 (2017-07-24-16:16)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
none separate
adapter speed: 20000 kHz
force hard breakpoints
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
Info : esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
[...]
>>> start GDB <<<
[...]
Info : accepting 'gdb' connection on tcp/3333
Info : Target halted. PRO_CPU: PC=0x400D12B4 (active)    APP_CPU: PC=0x00000000 
esp32: target state: halted
Info : Use core0 of target 'esp32'
Info : Target halted. PRO_CPU: PC=0x40091D07 (active)    APP_CPU: PC=0x400D12B4 
Info : Auto-detected flash size 4096 KB
Info : Using flash size 4096 KB
Info : Set current thread to 0x00000000, old= 0x00000000
Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
Info : esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
Info : esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
Info : Target halted. PRO_CPU: PC=0x5000004B (active)    APP_CPU: PC=0x00000000 
esp32: target state: halted
Info : esp32: Core was reset (pwrstat=0x1F, after clear 0x0F).
Info : Target halted. PRO_CPU: PC=0x40000400 (active)    APP_CPU: PC=0x40000400 
esp32: target state: halted
Info : Target halted. PRO_CPU: PC=0x400D171F (active)    APP_CPU: PC=0x400850A4 

$ xtensa-esp32-elf-gdb -x gdbinit build/blink.elf 
GNU gdb (crosstool-NG crosstool-ng-1.22.0-61-gab8375a) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-build_pc-linux-gnu --target=xtensa-esp32-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from build/blink.elf...done.
0x400d12b4 in esp_vApplicationIdleHook () at /home/andreas/esp32/esp-idf/components/esp32/./freertos_hooks.c:52
52	        asm("waiti 0");
JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
Target halted. PRO_CPU: PC=0x5000004B (active)    APP_CPU: PC=0x00000000 
esp32: target state: halted
esp32: Core was reset (pwrstat=0x1F, after clear 0x0F).
Target halted. PRO_CPU: PC=0x40000400 (active)    APP_CPU: PC=0x40000400 
esp32: target state: halted
Hardware assisted breakpoint 1 at 0x400d171f: file /home/andreas/esp32/apps/blink/main/./blink.c, line 43.
0x0:	0x00000000
Target halted. PRO_CPU: PC=0x400D171F (active)    APP_CPU: PC=0x400850A4 
[New Thread 1073413728]
[New Thread 1073413372]
[New Thread 1073433120]
[New Thread 1073431992]
[New Thread 1073410212]
[New Thread 1073408748]
[New Thread 1073411340]
[Switching to Thread 1073411776]

Temporary breakpoint 1, app_main () at /home/andreas/esp32/apps/blink/main/./blink.c:43
43	    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
(gdb) 

(gdb) b blink.c:33
Breakpoint 2 at 0x400d16fe: file /home/andreas/esp32/apps/blink/main/./blink.c, line 33.
(gdb) continue
Continuing.
Target halted. PRO_CPU: PC=0x400D16FE (active)    APP_CPU: PC=0x400850A4 
[New Thread 1073434248]
[Switching to Thread 1073434248]

Breakpoint 2, blink_task (pvParameter=0x0) at /home/andreas/esp32/apps/blink/main/./blink.c:33
33	        gpio_set_level(BLINK_GPIO, 0);
(gdb) n
Target halted. PRO_CPU: PC=0x400D1700 (active)    APP_CPU: PC=0x400850A4 
Target halted. PRO_CPU: PC=0x400D1703 (active)    APP_CPU: PC=0x400850A4 
Target halted. PRO_CPU: PC=0x400DCA58 (active)    APP_CPU: PC=0x400850A4 
Target halted. PRO_CPU: PC=0x400D1706 (active)    APP_CPU: PC=0x400850A4 
34	        vTaskDelay(1000 / portTICK_PERIOD_MS);
(gdb) n
Target halted. PRO_CPU: PC=0x400D1709 (active)    APP_CPU: PC=0x400850A4 
Target halted. PRO_CPU: PC=0x40084458 (active)    APP_CPU: PC=0x400850A4 
Target halted. PRO_CPU: PC=0x400D170C (active)    APP_CPU: PC=0x400D12B4 
36	        gpio_set_level(BLINK_GPIO, 1);
(gdb) n
Target halted. PRO_CPU: PC=0x400D170E (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x400D1710 (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x400DCA58 (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x400D1713 (active)    APP_CPU: PC=0x400D12B4 
37	        vTaskDelay(1000 / portTICK_PERIOD_MS);
(gdb) n
Target halted. PRO_CPU: PC=0x400D1716 (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x40084458 (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x400D1719 (active)    APP_CPU: PC=0x400D12B4 
Target halted. PRO_CPU: PC=0x400D16FE (active)    APP_CPU: PC=0x400D12B4

(gdb) layout asm
   6──────────────────────────────────────────────────────────────────────────────
B+ <0x400d16fe <blink_task+18>              movi.n a11, 0
   <0x400d1700 <blink_task+20>              movi   a10, 5 
   <0x400d1703 <blink_task+23>              call8  0x400dca58 <gpio_set_level>
   <0x400d1706 <blink_task+26>              movi   a10, 100
   <0x400d1709 <blink_task+29>              call8  0x40084458 <vTaskDelay>
   <0x400d170c <blink_task+32>              movi.n a11, 1
   <0x400d170e <blink_task+34>              movi.n a10, 5
   <0x400d1710 <blink_task+36>              call8  0x400dca58 <gpio_set_level>
   <0x400d1713 <blink_task+39>              movi   a10, 100
   <0x400d1716 <blink_task+42>              call8  0x40084458 <vTaskDelay>
   <0x400d1719 <blink_task+45>              j      0x400d16fe <blink_task+18>

(gdb) tui enable
(gdb) tui disable

$ bin/openocd -s share/openocd/scripts -f interface/ftdi/tumpa.cfg -f board/esp-wroom-32.cfg
Open On-Chip Debugger 0.10.0-dev-ga859564 (2017-07-24-16:16)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
none separate
adapter speed: 20000 kHz
force hard breakpoints
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
Info : esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
Info : esp32: Debug controller was reset (pwrstat=0xE5, after clear 0x5F).

$ bin/openocd -s share/openocd/scripts -f interface/ftdi/tumpa.cfg -f board/esp-wroom-32.cfg
Open On-Chip Debugger 0.10.0-dev-ga859564 (2017-07-24-16:16)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
none separate
adapter speed: 20000 kHz
force hard breakpoints
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi_tdo_sample_edge falling"
Info : clock speed 20000 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: esp32.cpu0: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : esp32: Debug controller was reset (pwrstat=0xFF, after clear 0xFF).
Info : esp32: Core was reset (pwrstat=0xFF, after clear 0xFF).
Error: cpu0: esp32_fetch_all_regs (line 163): DSR (FFFFFFFF) indicates target still busy!
Error: cpu0: esp32_fetch_all_regs (line 163): DSR (FFFFFFFF) indicates DIR instruction generated an exception!
Error: cpu0: esp32_fetch_all_regs (line 163): DSR (FFFFFFFF) indicates DIR instruction generated an overrun!
Error: cpu0: esp32_fetch_all_regs (line 190): DSR (FFFFFFFF) indicates target still busy!
Error: cpu0: esp32_fetch_all_regs (line 190): DSR (FFFFFFFF) indicates DIR instruction generated an exception!
Error: cpu0: esp32_fetch_all_regs (line 190): DSR (FFFFFFFF) indicates DIR instruction generated an overrun!
Error: Exception reading pc!
Info : Target halted. PRO_CPU: PC=0x00000000             APP_CPU: PC=0x00000000 (active)
Error: cpu0: xtensa_write_memory (line 696): DSR (FFFFFFFF) indicates target still busy!
Error: cpu0: xtensa_write_memory (line 696): DSR (FFFFFFFF) indicates DIR instruction generated an exception!
Error: cpu0: xtensa_write_memory (line 696): DSR (FFFFFFFF) indicates DIR instruction generated an overrun!
Warn : esp32: Failed writing 4 bytes at address 0x3FF5F064, data - a1, 3a, d8, 50, a1, 3a, d8, 50

$ xtensa-esp32-elf-gdb -x gdbinit build/app-template.elf 
GNU gdb (crosstool-NG crosstool-ng-1.22.0-61-gab8375a) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-build_pc-linux-gnu --target=xtensa-esp32-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from build/app-template.elf...done.
0x400da440 in ieee80211_send_mgmt ()
JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
esp32: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
Target halted. PRO_CPU: PC=0x5000004B (active)    APP_CPU: PC=0x00000000 
esp32: target state: halted
esp32: Core was reset (pwrstat=0x1F, after clear 0x0F).
Target halted. PRO_CPU: PC=0x40000400 (active)    APP_CPU: PC=0x40000400 
esp32: target state: halted
Hardware assisted breakpoint 1 at 0x400f49f8: file /home/andreas/esp32/apps/myapp/main/./main.c, line 15.
0x0:	0x00000000

Debugging – OpenOCD setup for ESP32
TIAO USB Multi-Protocol Adapter (JTAG, SPI, I2C, Serial) (FT2232H)
TIAO USB Multi Protocol Adapter User’s Manual
Flyswatter2 (FT2232H)
FT2232H – Hi-Speed Dual USB UART/FIFO IC

ESP32 – building the toolchain for Linux (Ubuntu)

Hands-On the Hot New WeMos ESP-32 Breakout
mikrocontroller.net/articles/ESP32
ESP32 – building the toolchain for Linux (Ubuntu)
ESP32 (8) – tcp connection
Enginursday: First Impressions of the ESP32
exploreembedded.com – Wiki
exploreembedded.com – Hello World with ESP32 Explained
ESP32 – FIRST STEPS

Closed-Source Libraries

./esp-idf/components/bt/lib/libbtdm_app.a
./esp-idf/components/newlib/lib/libm.a
./esp-idf/components/newlib/lib/libc_nano.a
./esp-idf/components/newlib/lib/libg.a
./esp-idf/components/newlib/lib/libc.a
./esp-idf/components/esp32/libhal.a
./esp-idf/components/esp32/lib/libnet80211.a
./esp-idf/components/esp32/lib/libwpa2.a
./esp-idf/components/esp32/lib/libwps.a
./esp-idf/components/esp32/lib/libwpa.a
./esp-idf/components/esp32/lib/libsmartconfig.a
./esp-idf/components/esp32/lib/libphy.a
./esp-idf/components/esp32/lib/libcore.a
./esp-idf/components/esp32/lib/libcoexist.a
./esp-idf/components/esp32/lib/librtc.a
./esp-idf/components/esp32/lib/libpp.a

Books

SparkFun ESP32 Thing Development Workshop, von Agus Kurniawan
Kolban’s book on ESP32, von Neil Kolban

Dual-Core and Tasks

Task Switching
FreeRTOS is currently configured to use one of the timers built into the CPU core (CCOMPARE0).

ESP-IDF, multicore & freeRTOS confusion

Getting started with FreeRtos
Also don’t call vTaskStartScheduler(), this function is called before app_main starts. In fact, app_main runs within a FreeRTOS task already.

Use of dual core
The second core is normally enabled. You can disable it using the sdkconfig file, which you would normally ‘edit’ by running ‘make menuconfig’. If you start up a task using the FreeRTOS xTaskCreate function, FreeRTOS will automatically run the task on any of the two CPUs, whichever one is free. You can also ‘pin’ a task to one single CPU by using xTaskCreatePinnedToCore.

xTaskCreatePinnedToCore()
xTaskCreate()

Arguments:
TaskFunction_t         pxTaskCode,
const char * const     pcName,
const uint32_t         usStackDepth,
void * const           pvParameters,
UBaseType_t            uxPriority,
TaskHandle_t * const   pxCreatedTask,
const BaseType_t       xCoreID = { 0, 1, tskNO_AFFINITY }
typedef struct {
    const char* filename;
    bool write;
    size_t word_count;
    int seed;
    SemaphoreHandle_t done;
    int result;
} read_write_test_arg_t;

#define READ_WRITE_TEST_ARG_INIT(name, seed_) \
        { \
            .filename = name, \
            .seed = seed_, \
            .word_count = 8192, \
            .write = true, \
            .done = xSemaphoreCreateBinary() \
        }

static void read_write_task(void* param)
{
    read_write_test_arg_t* args = (read_write_test_arg_t*) param;

    [...]
}

[...]

void test_fatfs_concurrent(const char* filename_prefix)
{
    char names[4][64];
    for (size_t i = 0; i < 4; ++i) {
        snprintf(names[i], sizeof(names[i]), "%s%d", filename_prefix, i + 1);
        unlink(names[i]);
    }

    read_write_test_arg_t args1 = READ_WRITE_TEST_ARG_INIT(names[0], 1);
    read_write_test_arg_t args2 = READ_WRITE_TEST_ARG_INIT(names[1], 2);

    printf("writing f1 and f2\n");

    xTaskCreatePinnedToCore(&read_write_task, "rw1", 2048, &args1, 3, NULL, 0);
    xTaskCreatePinnedToCore(&read_write_task, "rw2", 2048, &args2, 3, NULL, 1);

    [...]
}
[...]

techtutorialsx

ESP32: Get Task execution core
ESP32: Running code on a specific core
ESP32: Dual core execution speedup

Mutex + Semaphores

components/driver/rmt: portENTER_CRITICAL called from ISR context
esp-idf/components/freertos/include/freertos/portmacro.h

portENTER_CRITICAL
       vs
taskENTER_CRITICAL
       vs
vTaskEnterCritical

=================================

portMUX_TYPE adc_spinlock = portMUX_INITIALIZER_UNLOCKED;

portENTER_CRITICAL(&adc_spinlock);
[...]
portEXIT_CRITICAL(&adc_spinlock);

=====
 vs.
=====

void vTaskEnterCritical( portMUX_TYPE *mux )
void vTaskExitCritical( portMUX_TYPE *mux )
/*
Modifications to portENTER_CRITICAL:

The original portENTER_CRITICAL only disabled the ISRs. This is enough for single-CPU operation: by 
disabling the interrupts, there is no task switch so no other tasks can meddle in the data, and because
interrupts are disabled, ISRs can't corrupt data structures either.

For multiprocessing, things get a bit more hairy. First of all, disabling the interrupts doesn't stop
the tasks or ISRs on the other processors meddling with our CPU. For tasks, this is solved by adding
a spinlock to the portENTER_CRITICAL macro. A task running on the other CPU accessing the same data will
spinlock in the portENTER_CRITICAL code until the first CPU is done.

For ISRs, we now also need muxes: while portENTER_CRITICAL disabling interrupts will stop ISRs on the same
CPU from meddling with the data, it does not stop interrupts on the other cores from interfering with the
data. For this, we also use a spinlock in the routines called by the ISR, but these spinlocks
do not disable the interrupts (because they already are).

This all assumes that interrupts are either entirely disabled or enabled. Interrupr priority levels
will break this scheme.

Remark: For the ESP32, portENTER_CRITICAL and portENTER_CRITICAL_ISR both alias vTaskEnterCritical, meaning
that either function can be called both from ISR as well as task context. This is not standard FreeRTOS 
behaviour; please keep this in mind if you need any compatibility with other FreeRTOS implementations.
*/

[...]
void vTaskEnterCritical( portMUX_TYPE *mux );
void vTaskExitCritical( portMUX_TYPE *mux );
[...]

#define portENTER_CRITICAL(mux)        vTaskEnterCritical(mux)
#define portEXIT_CRITICAL(mux)         vTaskExitCritical(mux)
#define portENTER_CRITICAL_ISR(mux)    vTaskEnterCritical(mux)
#define portEXIT_CRITICAL_ISR(mux)     vTaskExitCritical(mux)
/**
 * task. h
 *
 * Macro to mark the start of a critical code region.  Preemptive context
 * switches cannot occur when in a critical region.
 *
 * NOTE: This may alter the stack (depending on the portable implementation)
 * so must be used with care!
 *
 * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL
 * \ingroup SchedulerControl
 */
#define taskENTER_CRITICAL(mux)         portENTER_CRITICAL(mux)
#define taskENTER_CRITICAL_ISR(mux)     portENTER_CRITICAL_ISR(mux)

/**
 * task. h
 *
 * Macro to mark the end of a critical code region.  Preemptive context
 * switches cannot occur when in a critical region.
 *
 * NOTE: This may alter the stack (depending on the portable implementation)
 * so must be used with care!
 *
 * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL
 * \ingroup SchedulerControl
 */
#define taskEXIT_CRITICAL(mux)          portEXIT_CRITICAL(mux)
#define taskEXIT_CRITICAL_ISR(mux)      portEXIT_CRITICAL_ISR(mux)

FAQ

Linker fails: libraries not found

$ xtensa-esp32-elf-gcc test.c
/opt/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find crt1-sim.o: No such file or directory
/opt/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find _vectors.o: No such file or directory
/opt/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lsim
/opt/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lhandlers-sim
/opt/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/5.2.0/../../../../xtensa-esp32-elf/bin/ld: cannot find -lhal
collect2: error: ld returned 1 exit status

Program Structure

General Notes About ESP-IDF Programming,
Build System, Makefile structure

  • PRO CPU = cpu0
  • APP CPU = cpu1
$ grep -r start_cpu0
[...]
components/bootloader/src/main/bootloader_start.c:void IRAM_ATTR call_start_cpu0()
components/bootloader/src/main/esp32.bootloader.ld:ENTRY(call_start_cpu0);
components/esp32/ld/esp32.common.ld:ENTRY(call_start_cpu0);
components/esp32/cpu_start.c:void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
components/esp32/cpu_start.c:void start_cpu0_default(void) IRAM_ATTR;
components/esp32/cpu_start.c:void IRAM_ATTR call_start_cpu0()
components/esp32/cpu_start.c:    start_cpu0();
components/esp32/cpu_start.c:void start_cpu0_default(void)
components/spi_flash/cache_utils.c:        // called from the 2nd stage bootloader or from user_start_cpu0, i.e. from
make/project.mk:	-u call_user_start_cpu0	\
[...]

$ grep -r component.mk
[...]
make/project.mk:# This Makefile is included directly from the user project Makefile in order to call the component.mk
make/project.mk:# A component is buildable if it has a component.mk makefile in it
make/project.mk:COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/component.mk),$(cp)))
make/project.mk:# stored in COMPONENT_LINKER_DEPS, built via component.mk files' COMPONENT_ADD_LINKER_DEPS variable
make/project.mk:+$(MAKE) -C $(BUILD_DIR_BASE)/$(2) -f $(IDF_PATH)/make/component_wrapper.mk COMPONENT_MAKEFILE=$(1)/component.mk COMPONENT_NAME=$(2)
make/project.mk:$(BUILD_DIR_BASE)/$(2)/component_project_vars.mk: $(1)/component.mk $(COMMON_MAKEFILES) $(SDKCONFIG_MAKEFILE) | $(BUILD_DIR_BASE)/$(2)
[...]

components/bootloader/src/main/esp32.bootloader.ld (Second stage bootloader)
==================================================
ENTRY(call_start_cpu0);

components/bootloader/src/main/bootloader_start.c (Second stage bootloader)
=================================================
void IRAM_ATTR call_start_cpu0()
void bootloader_main()
static void set_cache_and_start_app([...])
    entry_t entry = ((entry_t) entry_addr);
    (*entry)();

components/esp32/cpu_start.c (Application startup)
============================
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
void start_cpu0_default(void) IRAM_ATTR;

void IRAM_ATTR call_start_cpu0()
void start_cpu0(void) => default!
void start_cpu0_default(void)
    xTaskCreatePinnedToCore(&main_task, "main",
            ESP_TASK_MAIN_STACK, NULL,
            ESP_TASK_MAIN_PRIO, NULL, 0);
static void main_task(void* args)
app_main();

$ grep -r call_start_cpu1 .
[...]
./components/esp32/cpu_start.c:static void IRAM_ATTR call_start_cpu1();
./components/esp32/cpu_start.c:    ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1);
./components/esp32/cpu_start.c:    ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);
./components/esp32/cpu_start.c:void IRAM_ATTR call_start_cpu1()

$ grep -r ets_set_appcpu_boot_addr .
./components/esptool_py/esptool/flasher_stub/rom_32.ld:PROVIDE ( ets_set_appcpu_boot_addr = 0x4000689c );
./components/bootloader/src/main/bootloader_start.c:    ets_set_appcpu_boot_addr(0); 
./components/esp32/ld/esp32.rom.ld:PROVIDE ( ets_set_appcpu_boot_addr = 0x4000689c );
./components/esp32/cpu_start.c:    ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);
./components/esp32/cpu_start.c:    ets_set_appcpu_boot_addr(0);
./components/esp32/include/rom/ets_sys.h:void ets_set_appcpu_boot_addr(uint32_t start);

FreeRTOS SMP-aware

Interrupt allocation
esp-idf/components/freertos/readme_smp.txt

Interrupts:

  • Enabling and disabling interrupts will only affect the current core.
  • Use a mux, queue or semaphore to protect your structures instead.
$ grep -r xTaskCreatePinnedToCore
[...]
./components/freertos/include/freertos/task.h:    BaseType_t xTaskCreatePinnedToCore(	TaskFunction_t pxTaskCode,
./components/freertos/include/freertos/task.h:#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskCreatePinnedToCore( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), tskNO_AFFINITY )
[...]
components/freertos/tasks.c:	BaseType_t xTaskCreatePinnedToCore(	TaskFunction_t pxTaskCode,
components/freertos/tasks.c:			xReturn = xTaskCreatePinnedToCore( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle[i], i ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */
[...]

Interrupts, Interrupt Handlers, User Exception Handlers

Documentation / Guide

Interrupt allocation
High-Level Interrupts
External Interrupt Latency

Code

esp-idf/docs/api-reference/system/intr_alloc.rst
esp-idf/docs/api-guides/hlinterrupts.rst

esp-idf/components/driver/uart.c
uart_driver_install()
  p_uart_obj[uart_num]->xQueueUart  = xQueueCreate(queue_size, sizeof(uart_event_t));
  p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF);
  p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);

esp-idf/components/driver/uart.c
uart_rx_intr_handler_default()
  p_uart->tx_head = (uart_tx_data_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size);

  //Get the buffer from the FIFO
  rx_fifo_len = uart_reg->status.rxfifo_cnt;
  p_uart->rx_stash_len = rx_fifo_len;
  //We have to read out all data in RX FIFO to clear the interrupt signal
  while(buf_idx < rx_fifo_len) {
      p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte;
  }
  xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)

esp-idf/components/soc/esp32/include/soc/uart_reg.h
  #define UART_RXFIFO_RD_BYTE  0x000000FF (register itself)

esp-idf/components/soc/esp32/include/soc/uart_struct.h
  typedef struct uart_dev_t (register as struct)


esp-idf/components/freertos/xtensa_vectors.S     _Level2Vector
esp-idf/components/freertos/xtensa_vectors.S     dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK
esp-idf/components/freertos/xtensa_intr_asm.S    _xt_interrupt_table
esp-idf/components/freertos/xtensa_intr.c        extern _xt_interrupt_table
esp-idf/components/freertos/xtensa_intr.c        xt_set_interrupt_handler()
esp-idf/components/esp32/intr_alloc.c            esp_intr_alloc_intrstatus()
esp-idf/components/esp32/intr_alloc.c            esp_intr_alloc()
esp-idf/components/driver/uart.c                 uart_isr_register()
esp-idf/components/driver/uart.c                 uart_driver_install()

esp-idf/components/esp32/ld/esp32.peripherals.ld
  PROVIDE ( TIMERG0 = 0x3ff5F000 );
  PROVIDE ( TIMERG1 = 0x3ff60000 );

esp-idf/components/soc/esp32/include/soc/timer_group_struct.h
  extern timg_dev_t TIMERG0;
  extern timg_dev_t TIMERG1;

esp-idf/components/esp32/intr_alloc.c     esp_intr_alloc_intrstatus()
                                            xt_set_interrupt_handler()
                                            intr_matrix_set()
                                            ESP_INTR_ENABLE(intr);
esp-idf/components/driver/timer.c         timer_isr_register()
esp-idf/examples/peripherals/timer_group/main/timer_group_example_main.c

$ grep -r CCOMPARE0 .
esp-idf/components/esp32/include/xtensa/hal.h:                #define XTHAL_MAX_TIMERS            4   /* max number of timers (CCOMPARE0..CCOMPARE3) */
esp-idf/components/esp32/include/xtensa/config/core-isa.h:    #define XCHAL_TIMER0_INTERRUPT      6   /* CCOMPARE0 */

$ grep -r XCHAL_TIMER0_INTERRUPT .
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
esp-idf/components/freertos/include/freertos/xtensa_timer.h:    #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL

$ grep -r _xt_tick_divisor_init .
esp-idf/components/freertos/portasm.S:                        * Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called).
esp-idf/components/freertos/portasm.S:                        _frxt_timer_int:
esp-idf/components/freertos/portasm.S:                        _frxt_tick_timer_init:
esp-idf/components/freertos/port.c:                          _xt_tick_divisor_init();
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  extern void     _xt_tick_divisor_init(void);
esp-idf/components/freertos/xtensa_init.c:                    void _xt_tick_divisor_init(void)

$ grep -r _frxt_timer_int .
esp-idf/components/freertos/portasm.S:                        _frxt_timer_int:
esp-idf/components/freertos/include/freertos/xtensa_rtos.h:   #define XT_RTOS_TIMER_INT   _frxt_timer_int

$ grep -r XT_RTOS_TIMER_INT .
esp-idf/components/freertos/xtensa_vectors.S:                 call0   XT_RTOS_TIMER_INT
esp-idf/components/freertos/xtensa_vectors.S:                 call4   XT_RTOS_TIMER_INT
esp-idf/components/freertos/include/freertos/xtensa_rtos.h:   #define XT_RTOS_TIMER_INT   _frxt_timer_int
esp-idf/components/freertos/xtensa_init.c:                    #ifdef XT_RTOS_TIMER_INT

$ grep -r XT_TIMER_INTEN .
esp-idf/components/freertos/portasm.S:                        movi    a2, XT_TIMER_INTEN
esp-idf/components/freertos/portasm.S:                        movi    a6, XT_TIMER_INTEN
esp-idf/components/freertos/xtensa_vectors.S:                 movi    a3, XT_TIMER_INTEN      /* a3 = timer interrupt bit */
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #define XT_TIMER_INTEN          (1 << XT_TIMER_INTNUM)

$ grep -r XT_TIMER_INTNUM .
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #define XT_TIMER_INTNUM         XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #define XT_TIMER_INTPRI         XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #define XT_TIMER_INTEN          (1 << XT_TIMER_INTNUM)
esp-idf/components/freertos/include/freertos/xtensa_timer.h:  #if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED

$ grep -r xt_set_interrupt_handler .
esp-idf/components/freertos/xtensa_intr.c:                    xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
esp-idf/components/freertos/include/freertos/xtensa_api.h:    extern xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg);
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_CCOMPARE_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_EPWM_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_MPWM_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_SPI1_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_SPI2_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_SPI3_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_I2S0_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_PCNT_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_LEDC_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_WMAC_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_FRC_TIMER1_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_FRC_TIMER2_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_GPIO_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_UART0_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_WDT_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_RTC_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_SLC_INUM, (func), (void *)(arg))
esp-idf/components/esp32/include/esp_intr.h:                  xt_set_interrupt_handler(ETS_RMT_CTRL_INUM, (func), (void *)(arg))

$ grep -r xt_handler_table_entry
esp-idf/components/freertos/xtensa_intr.c:                    typedef struct xt_handler_table_entry {
esp-idf/components/freertos/xtensa_intr.c:                    extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];
esp-idf/components/esp32/intr_alloc.c:                        typedef struct xt_handler_table_entry
esp-idf/components/esp32/intr_alloc.c:                        extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];

$ grep -r _xt_interrupt_table
esp-idf/components/freertos/xtensa_intr.c:                    extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];
esp-idf/components/freertos/xtensa_vectors.S:                 movi    a4, _xt_interrupt_table
esp-idf/components/freertos/xtensa_intr_asm.S:               _xt_interrupt_table:
esp-idf/components/esp32/intr_alloc.c:                        extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];

]$ grep -r dispatch_c_isr .
esp-idf/components/freertos/xtensa_vectors.S:                 Macro dispatch_c_isr - dispatch interrupts to user ISRs.
esp-idf/components/freertos/xtensa_vectors.S:                 .macro  dispatch_c_isr    level  mask
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 3 XCHAL_INTLEVEL3_MASK
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 4 XCHAL_INTLEVEL4_MASK
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 5 XCHAL_INTLEVEL5_MASK
esp-idf/components/freertos/xtensa_vectors.S:                 dispatch_c_isr 6 XCHAL_INTLEVEL6_MASK

$ grep -r InterruptVector .
esp-idf/components/freertos/xtensa_vectors.S:                 .section    .Level2InterruptVector.text, "ax"
esp-idf/components/freertos/xtensa_vectors.S:                 .section    .Level3InterruptVector.text, "ax"
esp-idf/components/freertos/xtensa_vectors.S:                 .section    .Level4InterruptVector.text, "ax"
esp-idf/components/freertos/xtensa_vectors.S:                 .section    .Level5InterruptVector.text, "ax"
esp-idf/components/freertos/xtensa_vectors.S:                 .section    .Level6InterruptVector.text, "ax"
esp-idf/components/esp32/ld/esp32.common.ld:                  KEEP(*(.Level2InterruptVector.text));
esp-idf/components/esp32/ld/esp32.common.ld:                  KEEP(*(.Level3InterruptVector.text));
esp-idf/components/esp32/ld/esp32.common.ld:                  KEEP(*(.Level4InterruptVector.text));
esp-idf/components/esp32/ld/esp32.common.ld:                  KEEP(*(.Level5InterruptVector.text));

$ grep -rE "Vector =|Exception =|Interrupt =" .
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _DebugExceptionVector = 0x40000280 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _DoubleExceptionVector = 0x400003c0 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _KernelExceptionVector = 0x40000300 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _GeneralException = 0x40000e14 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _ResetVector = 0x40000400 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _UserExceptionVector = 0x40000340 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _NMIExceptionVector = 0x400002c0 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level2FromVector = 0x40000954 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level3FromVector = 0x40000a28 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level4FromVector = 0x40000af8 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level5FromVector = 0x40000c68 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level2Vector = 0x40000180 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level3Vector = 0x400001c0 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level4Vector = 0x40000200 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _Level5Vector = 0x40000240 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _LevelOneInterrupt = 0x40000835 );
esp-idf/components/esp32/ld/esp32.rom.ld:                     PROVIDE ( _SyscallException = 0x400007cf );

//CPU0 Interrupt number reserved, not touch this.
#define ETS_WMAC_INUM                           0
#define ETS_BT_HOST_INUM                        1
#define ETS_WBB_INUM                            4
#define ETS_TG0_T1_INUM                         10 /**< use edge interrupt*/
#define ETS_FRC1_INUM                           22
#define ETS_T1_WDT_INUM                         24
#define ETS_CACHEERR_INUM                       25
#define ETS_DPORT_INUM                          31

//CPU0 Interrupt number used in ROM, should be cancelled in SDK
#define ETS_SLC_INUM                            1
#define ETS_UART0_INUM                          5
#define ETS_UART1_INUM                          5
//Other interrupt number should be managed by the user

//Invalid interrupt for number interrupt matrix
#define ETS_INVALID_INUM                        6

/* Handler table is in xtensa_intr_asm.S */

typedef struct xt_handler_table_entry {
    void * handler;
    void * arg;
} xt_handler_table_entry;

extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS];

/*
  This function registers a handler for the specified interrupt. The "arg"
  parameter specifies the argument to be passed to the handler when it is
  invoked. The function returns the address of the previous handler.
  On error, it returns 0.
*/
xt_handler xt_set_interrupt_handler(int n, xt_handler f, void * arg)
{
    xt_handler_table_entry * entry;
    xt_handler               old;

    if( n < 0 || n >= XCHAL_NUM_INTERRUPTS )
        return 0;       /* invalid interrupt number */
    if( Xthal_intlevel[n] > XCHAL_EXCM_LEVEL )
        return 0;       /* priority level too high to safely handle in C */

    /* Convert exception number to _xt_exception_table name */
    n = n * portNUM_PROCESSORS + xPortGetCoreID();

    entry = _xt_interrupt_table + n;
    old   = entry->handler;

    if (f) {
        entry->handler = f;
        entry->arg     = arg;
    }
    else {
        entry->handler = &xt_unhandled_interrupt;
        entry->arg     = (void*)n;
    }

    return ((old == &xt_unhandled_interrupt) ? 0 : old);
}
/******************************************************************************
  Xtensa interrupt handling data and assembly routines.
  Also see xtensa_intr.c and xtensa_vectors.S.
******************************************************************************/

[...]

/*
-------------------------------------------------------------------------------
  Table of C-callable interrupt handlers for each interrupt. Note that not all
  slots can be filled, because interrupts at level > EXCM_LEVEL will not be
  dispatched to a C handler by default.

  Stored as:
  int 0 cpu 0
  int 0 cpu 1
  ...
  int 0 cpu n
  int 1 cpu 0
  int 1 cpu 1
  etc
-------------------------------------------------------------------------------
*/
_xt_interrupt_table:
    .set    i, 0
    .rept   XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS
    .word   xt_unhandled_interrupt      /* handler address               */
    .word   i                           /* handler arg (default: intnum) */
    .set    i, i+1
    .endr

/*
-------------------------------------------------------------------------------
  Table of C-callable exception handlers for each exception. Note that not all
  slots will be active, because some exceptions (e.g. coprocessor exceptions)
  are always handled by the OS and cannot be hooked by user handlers.

  Stored as:
  exc 0 cpu 0
  exc 0 cpu 1
  ...
  exc 0 cpu n
  exc 1 cpu 0
  exc 1 cpu 1
  etc
-------------------------------------------------------------------------------
*/
_xt_exception_table:
    .rept   XCHAL_EXCCAUSE_NUM * portNUM_PROCESSORS
    .word   xt_unhandled_exception    /* handler address */
    .endr


/*
-------------------------------------------------------------------------------
  unsigned int xt_ints_on ( unsigned int mask )

  Enables a set of interrupts. Does not simply set INTENABLE directly, but
  computes it as a function of the current virtual priority if XT_USE_SWPRI is
  enabled.
  Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
xt_ints_on:

[...]

/*******************************************************************************
        XTENSA VECTORS AND LOW LEVEL HANDLERS FOR AN RTOS

  Xtensa low level exception and interrupt vectors and handlers for an RTOS.

  Interrupt handlers and user exception handlers support interaction with
  the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT before and
  after user's specific interrupt handlers. These macros are defined in
  xtensa_<rtos>.h to call suitable functions in a specific RTOS.

  Users can install application-specific interrupt handlers for low and
  medium level interrupts, by calling xt_set_interrupt_handler(). These
  handlers can be written in C, and must obey C calling convention. The
  handler table is indexed by the interrupt number. Each handler may be
  provided with an argument. 

  Note that the system timer interrupt is handled specially, and is
  dispatched to the RTOS-specific handler. This timer cannot be hooked
  by application code.

  Optional hooks are also provided to install a handler per level at 
  run-time, made available by compiling this source file with 
  '-DXT_INTEXC_HOOKS' (useful for automated testing).

!!  This file is a template that usually needs to be modified to handle       !!
!!  application specific interrupts. Search USER_EDIT for helpful comments    !!
!!  on where to insert handlers and how to write them.                        !!

  Users can also install application-specific exception handlers in the
  same way, by calling xt_set_exception_handler(). One handler slot is
  provided for each exception type. Note that some exceptions are handled
  by the porting layer itself, and cannot be taken over by application
  code in this manner. These are the alloca, syscall, and coprocessor
  exceptions.

  The exception handlers can be written in C, and must follow C calling
  convention. Each handler is passed a pointer to an exception frame as
  its single argument. The exception frame is created on the stack, and
  holds the saved context of the thread that took the exception. If the
  handler returns, the context will be restored and the instruction that
  caused the exception will be retried. If the handler makes any changes
  to the saved state in the exception frame, the changes will be applied
  when restoring the context.

  Because Xtensa is a configurable architecture, this port supports all user
  generated configurations (except restrictions stated in the release notes).
  This is accomplished by conditional compilation using macros and functions
  defined in the Xtensa HAL (hardware adaptation layer) for your configuration.
  Only the relevant parts of this file will be included in your RTOS build.
  For example, this file provides interrupt vector templates for all types and
  all priority levels, but only the ones in your configuration are built.

  NOTES on the use of 'call0' for long jumps instead of 'j':
   1. This file should be assembled with the -mlongcalls option to xt-xcc.
   2. The -mlongcalls compiler option causes 'call0 dest' to be expanded to
      a sequence 'l32r a0, dest' 'callx0 a0' which works regardless of the
      distance from the call to the destination. The linker then relaxes
      it back to 'call0 dest' if it determines that dest is within range.
      This allows more flexibility in locating code without the performance
      overhead of the 'l32r' literal data load in cases where the destination
      is in range of 'call0'. There is an additional benefit in that 'call0'
      has a longer range than 'j' due to the target being word-aligned, so 
      the 'l32r' sequence is less likely needed.
   3. The use of 'call0' with -mlongcalls requires that register a0 not be 
      live at the time of the call, which is always the case for a function 
      call but needs to be ensured if 'call0' is used as a jump in lieu of 'j'.
   4. This use of 'call0' is independent of the C function call ABI.

*******************************************************************************/

[...]

/*
--------------------------------------------------------------------------------
  Macro dispatch_c_isr - dispatch interrupts to user ISRs.
  This will dispatch to user handlers (if any) that are registered in the
  XTOS dispatch table (_xtos_interrupt_table). These handlers would have
  been registered by calling _xtos_set_interrupt_handler(). There is one
  exception - the timer interrupt used by the OS will not be dispatched
  to a user handler - this must be handled by the caller of this macro.

  Level triggered and software interrupts are automatically deasserted by
  this code.

  ASSUMPTIONS:
    -- PS.INTLEVEL is set to "level" at entry
    -- PS.EXCM = 0, C calling enabled

  NOTE: For CALL0 ABI, a12-a15 have not yet been saved.

  NOTE: This macro will use registers a0 and a2-a6. The arguments are:
    level -- interrupt level
    mask  -- interrupt bitmask for this level
--------------------------------------------------------------------------------
*/

.macro  dispatch_c_isr    level  mask

/* Get mask of pending, enabled interrupts at this level into a2. */
.L_xt_user_int_&level&:
/*
        RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
                            (FreeRTOS Port)

This header is the primary glue between generic Xtensa RTOS support
sources and a specific RTOS port for Xtensa.  It contains definitions
and macros for use primarily by Xtensa assembly coded source files.

Macros in this header map callouts from generic Xtensa files to specific
RTOS functions. It may also be included in C source files.

Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa 
architecture, using the Xtensa hardware abstraction layer (HAL) to deal 
with configuration specifics.

Should be included by all Xtensa generic and RTOS port-specific sources.
*/

[..]

/*
Inform RTOS of the occurrence of a tick timer interrupt.
If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
May be coded in or called from C or assembly, per ABI conventions.
RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
*/
#define XT_RTOS_TIMER_INT   _frxt_timer_int
#define XT_TICK_PER_SEC     configTICK_RATE_HZ
/*
        XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY

This header contains definitions and macros for use primarily by Xtensa
RTOS assembly coded source files. It includes and uses the Xtensa hardware
abstraction layer (HAL) to deal with config specifics. It may also be
included in C source files.

User may edit to modify timer selection and to specify clock frequency and
tick duration to match timer interrupt to the real-time tick duration.

If the RTOS has no timer interrupt, then there is no tick timer and the
clock frequency is irrelevant, so all of these macros are left undefined
and the Xtensa core configuration need not have a timer.
*/
/*
**********************************************************************************************************
*                                           _frxt_timer_int
*                                      void _frxt_timer_int(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function for FreeRTOS.
* Called every timer interrupt.
* Manages the tick timer and calls xPortSysTickHandler() every tick.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
* Callable from C (obeys ABI conventions). Implemented in assmebly code for performance.
*
**********************************************************************************************************
*/
[...]
_frxt_timer_int:
[...]
    call0   xPortSysTickHandler
[...]

/*
**********************************************************************************************************
*                                           _frxt_tick_timer_init
*                                      void _frxt_tick_timer_init(void)
*
* Initialize timer and timer interrrupt handler (_xt_tick_divisor_init() has already been been called).
* Callable from C (obeys ABI conventions on entry).
*
**********************************************************************************************************
*/
[...]
_frxt_tick_timer_init:
[...]
    /*
    Enable the timer interrupt at the device level. Don't write directly
    to the INTENABLE register because it may be virtualized.
    */
    movi    a2, XT_TIMER_INTEN
    call0   xt_ints_on
[...]
[...]

Interrupt and Exception Handling
--------------------------------

FreeRTOS provides a complete set of efficient exception and first-level
interrupt handlers installed at the appropriate exception and interrupt
vector locations. The Xtensa architecture supports several different
classes of exceptions and interrupts. Being a configurable architecture,
many of these are optional, and the vector locations are determined by
your processor configuration. (Note that Diamond cores are pre-configured
with specific vector locations.) The handlers provided use conditional
compilation to adapt to your processor configuration and include only 
the code that is needed.

Xtensa vector locations may reside almost anywhere, including in ROM.
The amount of code space available at each of these locations is
often very small (e.g. due to following vectors). A small stub of
code installed at the vector jumps to the corresponding handler,
usually in RAM. The exception and interrupt handlers are defined in
xtensa_vectors.S. They are not specific to FreeRTOS, but call into
FreeRTOS where appropriate via macros defined in xtensa_rtos.h .

[...]

The following subsections describe the handling of each class of exception
and interrupt in more detail. Many have nothing to do with FreeRTOS but
are mentioned because there is code to handle them in xtensa_vectors.S.

User Exception and Interrupt Handler (Low/Medium Priority):

    All Xtensa 'general exceptions' come to the user, kernel, or double
    exception vector.  The exception type is identified by the EXCCAUSE
    special register (level 1 interrupts are one particular cause of a
    general exception). This port sets up PS to direct all such exceptions
    to the user vector. Exceptions taken at the other two vectors usually
    indicate a kernel or application bug.

    Level 1 interrupts are identified at the beginning of the handler
    and are dispatched to a dedicated handler. Then, syscall and alloca
    exceptions are identified and dispatched to special handlers described
    below. After this, coprocessor exceptions are identified and dispatched
    to the coprocessor handler.

    Any remaining exceptions are processed as follows:

    Having allocated the exception stack frame, the user exception handler
    saves the current task state and sets up a C environment and enables
    the high-priority class of interrupts (which do not interact with
    FreeRTOS), then reads EXCCAUSE and uses the cause (number) to index
    into a table of user-specified handlers. The correct handler is then
    called. If the handler returns, the context is restored and control is
    returned to the code that caused the exception. The user-defined handler
    may alter the saved context, or any other system state, that allows the
    faulting instruction to be retried.

    If the cause is a level 1 (low-priority) or medium-priority interrupt,
    the handler enables all interrupts above that priority level after
    saving the task context. It then sets up the environment for C code
    and then calls the handler (found in the handler table) for the
    interrupt number. If the user has not specified a handler, then the
    default handler will be called, which will terminate the program.

    If the interrupt is for the system timer, it calls a special interrupt
    handler for the system timer tick, which calls _frxt_timer_int then
    clears its bit from the mask. This interrupt cannot be hooked by the
    user-defined handler.

    Finally, the handler calls _frxt_int_exit to allow FreeRTOS to perform
    any scheduling necessary and return either to the interrupted task
    or another.

    If software prioritization is enabled, the handler will re-enable all
    interrupts at the same level that are numerically higher than the current
    one, before calling the user handler. This allows a higher priority
    interrupt to pre-empt the lower priority handler.

[...]

Medium Priority Interrupt Handlers:

    Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL,
    a configuration-specific maximum interrupt level affected by the global
    'exception mode' bit in the processor status word (PS.EXCM).
    Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class.
    The Xtensa hardware documentation considers medium priority interrupts
    to be a special case of high-priority interrupts, but from a software
    perspective they are very different.

    Dispatch of medium-priority interrupts is discussed in the section
    above.

High Priority Interrupt Handlers:

    High priority interrupts are those strictly above XCHAL_EXCM_LEVEL, 
    a configuration-specific maximum interrupt level affected by the 
    global 'exception mode' bit in the processor status word (PS.EXCM).
    High priority handlers may not directly interact with FreeRTOS at all,
    and are described here only for the sake of completeness. They must
    be coded in assembler (may not be coded in C) and are intended to be 
    used for handling extremely high frequency hardware events that need
    to be handled in only a few cycles. A high priority interrupt handler
    may trigger a software interrupt at a medium or low priority level to
    occasionally signal FreeRTOS. Please see Xtensa documentation.

    There is a separate vector and a few special registers for each high
    priority interrupt, providing for fast dispatch and efficient nesting
    on top of lower priority interrupts. Handlers are templates included
    only for the vectors that exist in your Xtensa processor configuration.
    These templates are written for only one interrupt per high priority 
    level to minimize latency servicing very fast time-critical interrupts.
    The vector code jumps to the corresponding first-level interrupt handler,
    which then executes application-provided assembler code before returning
    quickly to the interrupted task or lower priority handler.

Kernel Exception Handler:

    Kernel mode is not used in this port of FreeRTOS, and therefore kernel
    exceptions should not happen. A stub is provided for the vector that
    triggers the debugger (if connected) or calls _xt_panic to freeze the 
    processor should a kernel exception occur.

Alloca Exception Handler:

    Alloca exceptions are generated by the 'movsp' instruction, which
    is used only in the windowed ABI. Its purpose is to allocate some
    space on top of the stack. Because the window hardware may have
    spilled some registers to the 16 byte "base save" area below the
    stack pointer, it is necessary to protect those values. The alloca
    handler accomplishes this quickly without setting up an interrupt
    frame or entering FreeRTOS, by emulating a register underflow and
    re-executing 'movsp'.

Syscall Exception Handler:

    Syscall exceptions are generated by a 'syscall' instruction.
    The windowed ABI specifies that executing this instruction with
    a value of zero in register a2 must spill any unsaved registers
    in the windowed register file to their pre-determined locations
    on the caller's stack. The handler does exactly that, and skips
    over the 'syscall' instruction before returning to the caller.
    If a2 is non-zero, the handler returns a2 == -1 to the caller.

Co-Processor Exception Handler:

    A co-processor exception is generated when a task accesses a
    co-processor that it does not "own". Ownership represents which
    task's state is currently in the co-processor. Co-processors are
    context-switched "lazily" (on demand) only when a non-owning task
    uses a co-processor instruction, otherwise a task retains ownership
    even when it is preempted from the main processor. The co-processor
    exception handler performs the context-switch and manages ownership.

    Co-processors may not be used by any code outside the context of a
    task. A co-processor exception triggered by code that is not part
    of a running task is a fatal error and FreeRTOS for Xtensa will panic.
    This restriction is intended to reduce the overhead of saving and 
    restoring co-processor state (which can be quite large) and in 
    particular remove that overhead from interrupt handlers.

Debug Exception Handler:

    A debug exception is caused as a result of running code, such as by
    a 'break' instruction or hardware breakpoints and watchpoints, or
    as a result of an external debug interrupt, such as from an OCD based
    debugger or multiprocessor debug events ("breakin/breakout"). If the
    processor is running in OCD mode under control of an OCD-based debugger,
    the trigger event immediately halts the processor and gives control to
    the OCD debugger. Otherwise control is transferred to the debug vector.
    The debug vector handler calls the simulator if running on the ISS,
    which then takes control and interacts with any attached debugger.
    If running on hardware and not in OCD mode, debug exceptions are not
    expected, so the debug handler calls _xt_panic to freeze the processor.

Double Exception Handler:

    A double exception is a general exception that happens while the
    processor is in exception mode (PS.EXCM set), and thus indicates a
    bug in kernel code. The double exception vector handler triggers
    the debugger (if connected) or calls _xt_panic to freeze the 
    processor.

Window Overflow and Underflow Exception Handlers:

    Window overflow and underflow handlers are required for use of the
    windowed ABI. Each has its own dedicated vector and highly optimized
    code that is independent of OS. See Xtensa documentation for details.

Hooks for Dynamic Installation of Handlers:

    Optional hooks are provided in the user exception and low level
    interrupt handler and all medium and high priority interrupt handlers,
    to dynamically install a handler function (which may be coded in C,
    unless in a high-priority interrupt handler). These hooks are enabled
    and used by automatic regression tests, they are not part of a normal
    FreeRTOS build. However an application is free to take advantage of
    them. The interrupt/exception hooks are described in xtensa_rtos.h .

    It is recommended that the application not make use of these hooks, but
    rather use xt_set_interrupt_handler() and xt_set_exception_handler()
    to install application-specific handlers. This method is more convenient
    and allows arguments to be passed to the handlers. Software prioritization
    of interrupts works only with this method. See xtensa_api.h for details.

[...]

MyApp

$ git clone https://github.com/espressif/esp-idf-template.git myapp
$ cd myapp
$ make menuconfig
make[1]: Entering directory '/home/andreas/esp32/esp-idf/tools/kconfig'
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o mconf.o mconf.c
flex -L -P zconf -o zconf.lex.c zconf.l
zconf.l:255: warning, -s option given but default rule can be matched
bison -t -l -p zconf -o zconf.tab.c zconf.y
sed -E "s/\\x0D$//" zconf.gperf | gperf -t --output-file zconf.hash.c -a -C -E -g -k '1,3,$' -p -t
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o zconf.tab.o zconf.tab.c
lxdialog/check-lxdialog.sh -check cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE -lncurses -ltinfo
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/checklist.o lxdialog/checklist.c
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/util.o lxdialog/util.c
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/inputbox.o lxdialog/inputbox.c
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/textbox.o lxdialog/textbox.c
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/yesno.o lxdialog/yesno.c
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o lxdialog/menubox.o lxdialog/menubox.c
cc -o mconf mconf.o zconf.tab.o lxdialog/checklist.o lxdialog/util.o lxdialog/inputbox.o lxdialog/textbox.o lxdialog/yesno.o lxdialog/menubox.o -lncurses -ltinfo
cc  -D_GNU_SOURCE -DCURSES_LOC="<ncurses.h>" -DLOCALE   -c -o conf.o conf.c
cc -o conf conf.o  zconf.tab.o -lncurses -ltinfo
make[1]: Leaving directory '/home/andreas/esp32/esp-idf/tools/kconfig'
MENUCONFIG
configuration written to /home/andreas/esp32/apps/myapp/sdkconfig

*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.

GENCONFIG

$ make
CC src/bootloader_flash.o
CC src/efuse.o
CC src/secure_boot.o
CC src/secure_boot_signatures.o
CC src/flash_partitions.o
CC src/esp_image_format.o
CC src/flash_encrypt.o
CC src/bootloader_random.o
AR libbootloader_support.a
CC log.o
AR liblog.a
CC spi_flash_rom_patch.o
AR libspi_flash.a
CC micro-ecc/uECC.o
AR libmicro-ecc.a
CC esp32/rtc_pm.o
CC esp32/cpu_util.o
CC esp32/brownout.o
CC esp32/rtc_time.o
CC esp32/rtc_init.o
CC esp32/rtc_sleep.o
CC esp32/rtc_clk.o
AR libsoc.a
CC bootloader_start.o
CC flash_qio_mode.o
AR libmain.a
LD bootloader.elf
esptool.py v2.0.1
Building partitions from /home/andreas/esp32/esp-idf/components/partition_table/partitions_singleapp.csv...
CC app_trace_util.o
CC app_trace.o
AR libapp_trace.a
CC esp_ota_ops.o
AR libapp_update.a
CC src/bootloader_flash.o
CC src/efuse.o
CC src/secure_boot.o
CC src/secure_boot_signatures.o
CC src/flash_partitions.o
CC src/esp_image_format.o
CC src/flash_encrypt.o
CC src/bootloader_random.o
AR libbootloader_support.a
CC bt.o
CC bluedroid/bta/dm/bta_dm_api.o
CC bluedroid/bta/dm/bta_dm_sco.o
CC bluedroid/bta/dm/bta_dm_ci.o
CC bluedroid/bta/dm/bta_dm_act.o
CC bluedroid/bta/dm/bta_dm_pm.o
CC bluedroid/bta/dm/bta_dm_main.o
CC bluedroid/bta/dm/bta_dm_cfg.o
CC bluedroid/bta/gatt/bta_gatts_main.o
CC bluedroid/bta/gatt/bta_gattc_cache.o
CC bluedroid/bta/gatt/bta_gattc_main.o
CC bluedroid/bta/gatt/bta_gatts_api.o
CC bluedroid/bta/gatt/bta_gattc_utils.o
CC bluedroid/bta/gatt/bta_gattc_ci.o
CC bluedroid/bta/gatt/bta_gattc_act.o
CC bluedroid/bta/gatt/bta_gattc_api.o
CC bluedroid/bta/gatt/bta_gatts_act.o
CC bluedroid/bta/gatt/bta_gatts_utils.o
CC bluedroid/bta/hh/bta_hh_api.o
CC bluedroid/bta/hh/bta_hh_utils.o
CC bluedroid/bta/hh/bta_hh_le.o
CC bluedroid/bta/hh/bta_hh_act.o
CC bluedroid/bta/hh/bta_hh_main.o
CC bluedroid/bta/hh/bta_hh_cfg.o
CC bluedroid/bta/sdp/bta_sdp.o
CC bluedroid/bta/sdp/bta_sdp_act.o
CC bluedroid/bta/sdp/bta_sdp_cfg.o
CC bluedroid/bta/sdp/bta_sdp_api.o
CC bluedroid/bta/av/bta_av_api.o
CC bluedroid/bta/av/bta_av_ssm.o
CC bluedroid/bta/av/bta_av_cfg.o
CC bluedroid/bta/av/bta_av_ci.o
CC bluedroid/bta/av/bta_av_act.o
CC bluedroid/bta/av/bta_av_main.o
CC bluedroid/bta/av/bta_av_sbc.o
CC bluedroid/bta/av/bta_av_aact.o
CC bluedroid/bta/ar/bta_ar.o
CC bluedroid/bta/sys/bta_sys_main.o
CC bluedroid/bta/sys/utl.o
CC bluedroid/bta/sys/bta_sys_conn.o
CC bluedroid/btcore/bdaddr.o
CC bluedroid/btif/bta_gatts_co.o
CC bluedroid/btif/bta_dm_co.o
CC bluedroid/btif/bta_gattc_co.o
CC bluedroid/device/interop.o
CC bluedroid/device/controller.o
CC bluedroid/gki/gki_ulinux.o
CC bluedroid/gki/gki_buffer.o
CC bluedroid/hci/buffer_allocator.o
CC bluedroid/hci/hci_hal_h4.o
CC bluedroid/hci/hci_packet_parser.o
CC bluedroid/hci/packet_fragmenter.o
CC bluedroid/hci/hci_layer.o
CC bluedroid/hci/hci_packet_factory.o
CC bluedroid/main/bte_main.o
CC bluedroid/main/bte_init.o
CC bluedroid/osi/future.o
CC bluedroid/osi/hash_map.o
CC bluedroid/osi/fixed_queue.o
CC bluedroid/osi/allocator.o
CC bluedroid/osi/config.o
CC bluedroid/osi/list.o
CC bluedroid/osi/hash_functions.o
CC bluedroid/osi/alarm.o
CC bluedroid/osi/buffer.o
CC bluedroid/osi/osi_arch.o
CC bluedroid/external/sbc/decoder/srce/bitstream-decode.o
CC bluedroid/external/sbc/decoder/srce/synthesis-sbc.o
CC bluedroid/external/sbc/decoder/srce/decoder-oina.o
CC bluedroid/external/sbc/decoder/srce/bitalloc.o
CC bluedroid/external/sbc/decoder/srce/framing.o
CC bluedroid/external/sbc/decoder/srce/dequant.o
CC bluedroid/external/sbc/decoder/srce/alloc.o
CC bluedroid/external/sbc/decoder/srce/synthesis-dct8.o
CC bluedroid/external/sbc/decoder/srce/bitalloc-sbc.o
CC bluedroid/external/sbc/decoder/srce/decoder-private.o
CC bluedroid/external/sbc/decoder/srce/synthesis-8-generated.o
CC bluedroid/external/sbc/decoder/srce/framing-sbc.o
CC bluedroid/external/sbc/decoder/srce/oi_codec_version.o
CC bluedroid/external/sbc/decoder/srce/decoder-sbc.o
CC bluedroid/btc/core/btc_util.o
CC bluedroid/btc/core/btc_task.o
CC bluedroid/btc/core/btc_main.o
CC bluedroid/btc/core/btc_dev.o
CC bluedroid/btc/core/btc_storage.o
CC bluedroid/btc/core/btc_ble_storage.o
CC bluedroid/btc/core/btc_sm.o
CC bluedroid/btc/core/btc_profile_queue.o
CC bluedroid/btc/core/btc_alarm.o
CC bluedroid/btc/core/btc_manage.o
CC bluedroid/btc/core/btc_sec.o
CC bluedroid/btc/core/btc_config.o
CC bluedroid/btc/core/btc_dm.o
CC bluedroid/btc/profile/esp/blufi/blufi_prf.o
CC bluedroid/btc/profile/esp/blufi/blufi_protocol.o
CC bluedroid/btc/profile/std/gap/btc_gap_bt.o
CC bluedroid/btc/profile/std/gap/btc_gap_ble.o
CC bluedroid/btc/profile/std/gatt/btc_gatts.o
CC bluedroid/btc/profile/std/gatt/btc_gatt_util.o
CC bluedroid/btc/profile/std/gatt/btc_gattc.o
CC bluedroid/btc/profile/std/a2dp/bta_av_co.o
CC bluedroid/btc/profile/std/a2dp/btc_media_task.o
CC bluedroid/btc/profile/std/a2dp/btc_avk.o
CC bluedroid/btc/profile/std/avrc/btc_avrc.o
CC bluedroid/stack/btm/btm_ble_batchscan.o
CC bluedroid/stack/btm/btm_ble_cont_energy.o
CC bluedroid/stack/btm/btm_sec.o
CC bluedroid/stack/btm/btm_ble.o
CC bluedroid/stack/btm/btm_pm.o
CC bluedroid/stack/btm/btm_ble_adv_filter.o
CC bluedroid/stack/btm/btm_inq.o
CC bluedroid/stack/btm/btm_main.o
CC bluedroid/stack/btm/btm_devctl.o
CC bluedroid/stack/btm/btm_ble_privacy.o
CC bluedroid/stack/btm/btm_acl.o
CC bluedroid/stack/btm/btm_ble_bgconn.o
CC bluedroid/stack/btm/btm_dev.o
CC bluedroid/stack/btm/btm_ble_gap.o
CC bluedroid/stack/btm/btm_ble_multi_adv.o
CC bluedroid/stack/btm/btm_ble_addr.o
CC bluedroid/stack/btm/btm_sco.o
CC bluedroid/stack/btu/btu_hcif.o
CC bluedroid/stack/btu/btu_task.o
CC bluedroid/stack/btu/btu_init.o
CC bluedroid/stack/gap/gap_ble.o
CC bluedroid/stack/gap/gap_conn.o
CC bluedroid/stack/gap/gap_api.o
CC bluedroid/stack/gap/gap_utils.o
CC bluedroid/stack/gatt/gatt_db.o
CC bluedroid/stack/gatt/gatt_cl.o
CC bluedroid/stack/gatt/gatt_attr.o
CC bluedroid/stack/gatt/gatt_main.o
CC bluedroid/stack/gatt/gatt_sr.o
CC bluedroid/stack/gatt/att_protocol.o
CC bluedroid/stack/gatt/gatt_auth.o
CC bluedroid/stack/gatt/gatt_api.o
CC bluedroid/stack/gatt/gatt_utils.o
CC bluedroid/stack/hcic/hciblecmds.o
CC bluedroid/stack/hcic/hcicmds.o
CC bluedroid/stack/l2cap/l2c_ble.o
CC bluedroid/stack/l2cap/l2c_main.o
CC bluedroid/stack/l2cap/l2c_utils.o
CC bluedroid/stack/l2cap/l2c_ucd.o
CC bluedroid/stack/l2cap/l2c_api.o
CC bluedroid/stack/l2cap/l2cap_client.o
CC bluedroid/stack/l2cap/l2c_csm.o
CC bluedroid/stack/l2cap/l2c_link.o
CC bluedroid/stack/l2cap/l2c_fcr.o
CC bluedroid/stack/sdp/sdp_utils.o
CC bluedroid/stack/sdp/sdp_db.o
CC bluedroid/stack/sdp/sdp_discovery.o
CC bluedroid/stack/sdp/sdp_main.o
CC bluedroid/stack/sdp/sdp_server.o
CC bluedroid/stack/sdp/sdp_api.o
CC bluedroid/stack/smp/p_256_curvepara.o
CC bluedroid/stack/smp/smp_api.o
CC bluedroid/stack/smp/smp_utils.o
CC bluedroid/stack/smp/p_256_ecc_pp.o
CC bluedroid/stack/smp/smp_act.o
CC bluedroid/stack/smp/smp_cmac.o
CC bluedroid/stack/smp/smp_keys.o
CC bluedroid/stack/smp/smp_br_main.o
CC bluedroid/stack/smp/aes.o
CC bluedroid/stack/smp/smp_main.o
CC bluedroid/stack/smp/p_256_multprecision.o
CC bluedroid/stack/smp/smp_l2c.o
CC bluedroid/stack/avct/avct_lcb.o
CC bluedroid/stack/avct/avct_lcb_act.o
CC bluedroid/stack/avct/avct_l2c.o
CC bluedroid/stack/avct/avct_api.o
CC bluedroid/stack/avct/avct_ccb.o
CC bluedroid/stack/avrc/avrc_pars_ct.o
CC bluedroid/stack/avrc/avrc_opt.o
CC bluedroid/stack/avrc/avrc_bld_ct.o
CC bluedroid/stack/avrc/avrc_pars_tg.o
CC bluedroid/stack/avrc/avrc_bld_tg.o
CC bluedroid/stack/avrc/avrc_api.o
CC bluedroid/stack/avrc/avrc_utils.o
CC bluedroid/stack/avrc/avrc_sdp.o
CC bluedroid/stack/avdt/avdt_l2c.o
CC bluedroid/stack/avdt/avdt_api.o
CC bluedroid/stack/avdt/avdt_scb.o
CC bluedroid/stack/avdt/avdt_ccb_act.o
CC bluedroid/stack/avdt/avdt_ccb.o
CC bluedroid/stack/avdt/avdt_msg.o
CC bluedroid/stack/avdt/avdt_scb_act.o
CC bluedroid/stack/avdt/avdt_ad.o
CC bluedroid/stack/a2dp/a2d_sbc.o
CC bluedroid/stack/a2dp/a2d_api.o
CC bluedroid/utils/bt_utils.o
CC bluedroid/api/esp_avrc_api.o
CC bluedroid/api/esp_bt_main.o
CC bluedroid/api/esp_bt_device.o
CC bluedroid/api/esp_gap_bt_api.o
CC bluedroid/api/esp_a2dp_api.o
CC bluedroid/api/esp_gattc_api.o
CC bluedroid/api/esp_blufi_api.o
CC bluedroid/api/esp_gap_ble_api.o
CC bluedroid/api/esp_gatts_api.o
AR libbt.a
CC libcoap/src/address.o
CC libcoap/src/async.o
CC libcoap/src/block.o
CC libcoap/src/coap_time.o
CC libcoap/src/debug.o
CC libcoap/src/encode.o
CC libcoap/src/hashkey.o
CC libcoap/src/mem.o
CC libcoap/src/net.o
CC libcoap/src/option.o
CC libcoap/src/pdu.o
CC libcoap/src/resource.o
CC libcoap/src/str.o
CC libcoap/src/subscribe.o
CC libcoap/src/uri.o
CC port/coap_io_socket.o
AR libcoap.a
CXX cxx_guards.o
AR libcxx.a
CC spi_master.o
CC sigmadelta.o
CC uart.o
CC i2c.o
CC periph_ctrl.o
CC ledc.o
CC spi_common.o
CC gpio.o
CC pcnt.o
CC timer.o
CC rmt.o
CC mcpwm.o
CC sdmmc_transaction.o
CC spi_slave.o
CC sdmmc_host.o
CC i2s.o
CC rtc_module.o
AR libdriver.a
CC panic.o
CC core_dump.o
CC lib_printf.o
CC task_wdt.o
CC cpu_start.o
CC restore.o
CC crosscore_int.o
CC phy_init.o
CC deep_sleep.o
CC clk.o
CC freertos_hooks.o
CC gdbstub.o
CC cache_err_int.o
CC ipc.o
CC intr_alloc.o
CC heap_alloc_caps.o
CC int_wdt.o
CC event_loop.o
CC hw_random.o
CC dport_access.o
CC system_api.o
CC event_default_handlers.o
CC hwcrypto/sha.o
CC hwcrypto/aes.o
AR libesp32.a
CC emac_dev.o
CC emac_main.o
CC eth_phy/phy_common.o
CC eth_phy/phy_lan8720.o
CC eth_phy/phy_tlk110.o
AR libethernet.a
CC library/xmltok_ns.o
CC library/xmlparse.o
CC library/xmltok.o
CC library/xmlrole.o
CC library/xmltok_impl.o
CC port/minicheck.o
CC port/expat_element.o
CC port/chardata.o
AR libexpat.a
CC src/option/syscall.o
CC src/option/unicode.o
CC src/ff.o
CC src/vfs_fat_sdmmc.o
CC src/diskio_sdmmc.o
CC src/vfs_fat_spiflash.o
CC src/diskio_spiflash.o
CC src/vfs_fat.o
CC src/diskio.o
AR libfatfs.a
CC ringbuf.o
CC heap_regions_debug.o
CC xtensa_intr.o
CC queue.o
CC croutine.o
CC list.o
CC xtensa_init.o
CC port.o
CC heap_regions.o
CC event_groups.o
CC tasks.o
CC timers.o
CC FreeRTOS-openocd.o
CC xtensa_overlay_os_hook.o
AS xtensa_intr_asm.o
AS xtensa_context.o
AS xtensa_vectors.o
AS portasm.o
AR libfreertos.a
CC src//jsmn.o
AR libjsmn.a
CC library/cJSON.o
CC port/cJSON_Utils.o
AR libjson.a
CC private/randombytes_esp32.o
CC libsodium/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.o
CC libsodium/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.o
CC libsodium/src/libsodium/crypto_auth/crypto_auth.o
CC libsodium/src/libsodium/crypto_auth/hmacsha256/auth_hmacsha256.o
CC libsodium/src/libsodium/crypto_auth/hmacsha512/auth_hmacsha512.o
CC libsodium/src/libsodium/crypto_auth/hmacsha512256/auth_hmacsha512256.o
CC libsodium/src/libsodium/crypto_box/crypto_box_seal.o
CC libsodium/src/libsodium/crypto_box/crypto_box.o
CC libsodium/src/libsodium/crypto_box/crypto_box_easy.o
CC libsodium/src/libsodium/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.o
CC libsodium/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.o
CC libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.o
CC libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.o
CC libsodium/src/libsodium/crypto_core/hsalsa20/core_hsalsa20.o
CC libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.o
CC libsodium/src/libsodium/crypto_generichash/crypto_generichash.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/generichash_blake2.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.o
CC libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.o
CC libsodium/src/libsodium/crypto_hash/crypto_hash.o
CC libsodium/src/libsodium/crypto_hash/sha256/hash_sha256.o
CC libsodium/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.o
CC libsodium/src/libsodium/crypto_hash/sha512/hash_sha512.o
CC libsodium/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.o
CC libsodium/src/libsodium/crypto_kdf/blake2b/kdf_blake2b.o
CC libsodium/src/libsodium/crypto_kdf/crypto_kdf.o
CC libsodium/src/libsodium/crypto_kx/crypto_kx.o
CC libsodium/src/libsodium/crypto_onetimeauth/crypto_onetimeauth.o
CC libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.o
CC libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.o
CC libsodium/src/libsodium/crypto_pwhash/argon2/argon2.o
CC libsodium/src/libsodium/crypto_pwhash/crypto_pwhash.o
CC libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.o
CC libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.o
CC libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.o
CC libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.o
CC libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.o
CC libsodium/src/libsodium/crypto_scalarmult/crypto_scalarmult.o
CC libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.o
CC libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.o
CC libsodium/src/libsodium/crypto_secretbox/crypto_secretbox_easy.o
CC libsodium/src/libsodium/crypto_secretbox/crypto_secretbox.o
CC libsodium/src/libsodium/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.o
CC libsodium/src/libsodium/crypto_shorthash/crypto_shorthash.o
CC libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.o
CC libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphash24.o
CC libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.o
CC libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.o
CC libsodium/src/libsodium/crypto_sign/crypto_sign.o
CC libsodium/src/libsodium/crypto_sign/ed25519/sign_ed25519.o
CC libsodium/src/libsodium/crypto_sign/ed25519/ref10/obsolete.o
CC libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign.o
CC libsodium/src/libsodium/crypto_sign/ed25519/ref10/open.o
CC libsodium/src/libsodium/crypto_sign/ed25519/ref10/keypair.o
CC libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.o
CC libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.o
CC libsodium/src/libsodium/crypto_stream/crypto_stream.o
CC libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.o
CC libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.o
CC libsodium/src/libsodium/crypto_stream/xsalsa20/stream_xsalsa20.o
CC libsodium/src/libsodium/crypto_verify/sodium/verify.o
CC libsodium/src/libsodium/randombytes/randombytes.o
CC libsodium/src/libsodium/sodium/core.o
CC libsodium/src/libsodium/sodium/version.o
CC libsodium/src/libsodium/sodium/runtime.o
CC libsodium/src/libsodium/sodium/utils.o
AR liblibsodium.a
CC log.o
AR liblog.a
CC api/pppapi.o
CC api/netdb.o
CC api/api_lib.o
CC api/netifapi.o
CC api/tcpip.o
CC api/netbuf.o
CC api/err.o
CC api/api_msg.o
CC api/sockets.o
CC apps/dhcpserver.o
CC apps/sntp/sntp.o
CC apps/ping/ping.o
CC apps/ping/esp_ping.o
CC core/mem.o
CC core/inet_chksum.o
CC core/init.o
CC core/memp.o
CC core/sys.o
CC core/tcp_in.o
CC core/dns.o
CC core/ip.o
CC core/raw.o
CC core/tcp.o
CC core/pbuf.o
CC core/netif.o
CC core/stats.o
CC core/timers.o
CC core/def.o
CC core/udp.o
CC core/tcp_out.o
CC core/ipv4/ip_frag.o
CC core/ipv4/dhcp.o
CC core/ipv4/ip4_addr.o
CC core/ipv4/igmp.o
CC core/ipv4/ip4.o
CC core/ipv4/autoip.o
CC core/ipv4/icmp.o
CC core/ipv6/ip6_frag.o
CC core/ipv6/dhcp6.o
CC core/ipv6/inet6.o
CC core/ipv6/ip6_addr.o
CC core/ipv6/ip6.o
CC core/ipv6/nd6.o
CC core/ipv6/mld6.o
CC core/ipv6/ethip6.o
CC core/ipv6/icmp6.o
CC netif/slipif.o
CC netif/etharp.o
CC netif/ethernet.o
CC netif/lowpan6.o
CC netif/ethernetif.o
CC port/freertos/sys_arch.o
CC port/netif/wlanif.o
CC port/netif/ethernetif.o
CC port/debug/lwip_debug.o
AR liblwip.a
CC library/x509write_crt.o
CC library/pk_wrap.o
CC library/ecp_curves.o
CC library/sha512.o
CC library/pkcs12.o
CC library/ccm.o
CC library/md.o
CC library/sha1.o
CC library/x509_csr.o
CC library/ssl_cli.o
CC library/camellia.o
CC library/blowfish.o
CC library/x509.o
CC library/ssl_ticket.o
CC library/error.o
CC library/dhm.o
CC library/entropy_poll.o
CC library/cipher.o
CC library/version_features.o
CC library/ripemd160.o
CC library/rsa.o
CC library/net.o
CC library/entropy.o
CC library/md_wrap.o
CC library/pkwrite.o
CC library/ecp.o
CC library/asn1parse.o
CC library/padlock.o
CC library/ssl_ciphersuites.o
CC library/pem.o
CC library/version.o
CC library/ssl_cache.o
CC library/memory_buffer_alloc.o
CC library/md2.o
CC library/ecdsa.o
CC library/ssl_srv.o
CC library/x509_crt.o
CC library/ecdh.o
CC library/asn1write.o
CC library/md4.o
CC library/sha256.o
CC library/x509_create.o
CC library/ecjpake.o
CC library/oid.o
CC library/pkcs5.o
CC library/pkcs11.o
CC library/base64.o
CC library/xtea.o
CC library/ctr_drbg.o
CC library/cipher_wrap.o
CC library/arc4.o
CC library/bignum.o
CC library/pkparse.o
CC library/ssl_tls.o
CC library/debug.o
CC library/threading.o
CC library/x509_crl.o
CC library/gcm.o
CC library/havege.o
CC library/timing.o
CC library/certs.o
CC library/md5.o
CC library/ssl_cookie.o
CC library/aesni.o
CC library/hmac_drbg.o
CC library/des.o
CC library/x509write_csr.o
CC library/pk.o
CC library/platform.o
CC library/aes.o
CC port/mbedtls_debug.o
CC port/esp_sha1.o
CC port/net.o
CC port/esp_sha256.o
CC port/esp_bignum.o
CC port/esp_hardware.o
CC port/esp_sha512.o
AR libmbedtls.a
CC mdns.o
AR libmdns.a
CC micro-ecc/uECC.o
AR libmicro-ecc.a
CC time.o
CC reent_init.o
CC syscalls.o
CC syscall_table.o
CC locks.o
AR libnewlib.a
CC nghttp2/lib/nghttp2_http.o
CC nghttp2/lib/nghttp2_version.o
CC nghttp2/lib/nghttp2_mem.o
CC nghttp2/lib/nghttp2_hd_huffman.o
CC nghttp2/lib/nghttp2_session.o
CC nghttp2/lib/nghttp2_callbacks.o
CC nghttp2/lib/nghttp2_outbound_item.o
CC nghttp2/lib/nghttp2_stream.o
CC nghttp2/lib/nghttp2_hd.o
CC nghttp2/lib/nghttp2_priority_spec.o
CC nghttp2/lib/nghttp2_buf.o
CC nghttp2/lib/nghttp2_option.o
CC nghttp2/lib/nghttp2_npn.o
CC nghttp2/lib/nghttp2_rcbuf.o
CC nghttp2/lib/nghttp2_helper.o
CC nghttp2/lib/nghttp2_frame.o
CC nghttp2/lib/nghttp2_hd_huffman_data.o
CC nghttp2/lib/nghttp2_debug.o
CC nghttp2/lib/nghttp2_submit.o
CC nghttp2/lib/nghttp2_pq.o
CC nghttp2/lib/nghttp2_queue.o
CC nghttp2/lib/nghttp2_map.o
AR libnghttp.a
CXX src/nvs_types.o
CXX src/nvs_page.o
CXX src/nvs_item_hash_list.o
CXX src/nvs_pagemanager.o
CXX src/nvs_storage.o
CXX src/nvs_api.o
AR libnvs_flash.a
CC library/ssl_cert.o
CC library/ssl_methods.o
CC library/ssl_pkey.o
CC library/ssl_x509.o
CC library/ssl_lib.o
CC library/ssl_stack.o
CC platform/ssl_pm.o
CC platform/ssl_port.o
AR libopenssl.a
CC sdmmc_cmd.o
AR libsdmmc.a
CC esp32/rtc_pm.o
CC esp32/cpu_util.o
CC esp32/brownout.o
CC esp32/rtc_time.o
CC esp32/rtc_init.o
CC esp32/rtc_sleep.o
CC esp32/rtc_clk.o
AR libsoc.a
CC flash_mmap.o
CC partition.o
CC spi_flash_rom_patch.o
CC cache_utils.o
CC flash_ops.o
AR libspi_flash.a
CC tcpip_adapter_lwip.o
AR libtcpip_adapter.a
CC ulp.o
CC ulp_macro.o
AR libulp.a
CC vfs_uart.o
CC vfs.o
AR libvfs.a
CXX wear_levelling.o
CXX WL_Flash.o
CXX crc32.o
CXX SPI_Flash.o
CXX Partition.o
AR libwear_levelling.a
CC src/crypto/aes-internal-enc.o
CC src/crypto/sha256-internal.o
CC src/crypto/md5-internal.o
CC src/crypto/aes-internal.o
CC src/crypto/sha1.o
CC src/crypto/aes-internal-dec.o
CC src/crypto/aes-unwrap.o
CC src/crypto/crypto_internal-rsa.o
CC src/crypto/des-internal.o
CC src/crypto/dh_group5.o
CC src/crypto/ms_funcs.o
CC src/crypto/aes-wrap.o
CC src/crypto/sha1-internal.o
CC src/crypto/md4-internal.o
CC src/crypto/dh_groups.o
CC src/crypto/crypto_internal.o
CC src/crypto/sha256.o
CC src/crypto/rc4.o
CC src/crypto/md5.o
CC src/crypto/aes-cbc.o
CC src/crypto/sha1-pbkdf2.o
CC src/crypto/bignum.o
CC src/crypto/crypto_internal-modexp.o
CC src/crypto/crypto_internal-cipher.o
CC port/os_xtensa.o
AR libwpa_supplicant.a
CC eri.o
CC trax.o
AR libxtensa-debug-module.a
CC main.o
AR libmain.a
LD app-template.elf
esptool.py v2.0.1
To flash all build output, run 'make flash' or:
python /home/andreas/esp32/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 /home/andreas/esp32/apps/myapp/build/bootloader/bootloader.bin 0x10000 /home/andreas/esp32/apps/myapp/build/app-template.bin 0x8000 /home/andreas/esp32/apps/myapp/build/partitions_singleapp.bin

GNU ld

$ ./xtensa-esp32-elf-gcc a.c -Wl,-verbose
GNU ld (crosstool-NG crosstool-ng-1.22.0-61-gab8375a) 2.25.1
  Supported emulations:
   elf32xtensa
using internal linker script:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
/* Copyright (C) 2014 Free Software Foundation, Inc.
   Copying and distribution of this script, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.  */
ENTRY(_start)
SEARCH_DIR("=/home/ivan/e/crosstool-NG/builds/xtensa-esp32-elf/xtensa-esp32-elf/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = 0x400000); . = 0x400000 + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
    }
  .rela.plt       : { *(.rela.plt) }
  /* .plt* sections are embedded in .text */
  .text           :
  {
    *(.got.plt* .plt*)
    KEEP (*(.init.literal))
    KEEP (*(SORT_NONE(.init)))
    *(.literal .text .stub .literal.* .text.* .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
    KEEP (*(.fini.literal))
    KEEP (*(SORT_NONE(.fini)))
  } =0
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .got.loc        : { *(.got.loc) }
  .xt_except_table   : ONLY_IF_RO { KEEP (*(.xt_except_table .xt_except_table.* .gnu.linkonce.e.*)) }
  .eh_frame_hdr : { *(.eh_frame_hdr) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  /* Thread Local Storage sections  */
  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array     :
  {
     PROVIDE_HIDDEN (__init_array_start = .);
     KEEP (*(SORT(.init_array.*)))
     KEEP (*(.init_array))
     PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
  .xt_except_table   : ONLY_IF_RW { KEEP (*(.xt_except_table .xt_except_table.* .gnu.linkonce.e.*)) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  .xt_except_desc   :
  {
    *(.xt_except_desc .xt_except_desc.* .gnu.linkonce.h.*)
    *(.xt_except_desc_end)
  }
  .lit4           :
  {
    PROVIDE (_lit4_start = .);
    *(.lit4 .lit4.* .gnu.linkonce.lit4.*)
    PROVIDE (_lit4_end = .);
  }
  _edata = .; PROVIDE (edata = .);
  __bss_start = .;
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 32 / 8 : 1);
  }
  . = ALIGN(32 / 8);
  . = ALIGN(32 / 8);
  _end = .; PROVIDE (end = .);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end ) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3 */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  /* DWARF Extension.  */
  .debug_macro    0 : { *(.debug_macro) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  .xt.lit       0 : { KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) }
  .xt.insn      0 : { KEEP (*(.xt.insn .gnu.linkonce.x.*)) }
  .xt.prop      0 : { KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink)  *(.gnu.lto_*) }
}

Noduino

noduino.org
Jacks Lab: Noduino Quantum
Jacks Lab: ESP32 ADC

Leave a Reply

Your email address will not be published. Required fields are marked *