Espressif – Product Ordering Information
Difference between ESP32-WROVER and ESP32-WROVER-B
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
Download
ESP-IDF Windows Installer Download
ESP-IDF Programming Guide
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
Shop
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
D32 Pro
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
Naming Conventions
Coding Standard and Style Guide
Variables:
- Variables of type
uint32_t
are prefixedul
, where the'u'
denotes'unsigned'
and the'l
‘ denotes'long'
. - Variables of type
uint16_t
are prefixedus
, where the'u'
denotes'unsigned'
and the's'
denotes'short'
. - Variables of type
uint8_t
are prefixeduc
, where the'u'
denotes'unsigned'
and the'c'
denotes'char'
. - Variables of non stdint types are prefixed
x
. Examples includeBaseType_t
andTickType_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 typeUBaseType_t
(unsigned BaseType_t
) are prefixedux
. - Variables of type
size_t
are also prefixedx
. - Enumerated variables are prefixed
e
- Pointers have an additional prefixed
p
, for example a pointer to auint16_t
will have prefixpus
. - 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
forvoid
. - API function names start with the name of the file in which they are defined. For example
vTaskDelete()
is defined intasks.c
, and has avoid
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
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
Andreas Spiess
#149 ESP32 Deep Sleep, RTC Memory, “Secret” LoLin Pins
Tutorials
ESP-IDF Programming Guide
Get Started (ESP IDF, official, latest)
Debug
# 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_*) } }