forked from espressif/esp-idf
Merge branch 'doc/multi_target' into 'master'
docs: Multi target build support Closes IDF-523 See merge request espressif/esp-idf!6791
This commit is contained in:
@@ -6,7 +6,7 @@ stages:
|
||||
- target_test
|
||||
- post_check
|
||||
- deploy
|
||||
- post_check
|
||||
- post_deploy
|
||||
|
||||
variables:
|
||||
# System environment
|
||||
@@ -76,6 +76,9 @@ variables:
|
||||
rm -rf "$CUSTOM_TOOLCHAIN_PATH"
|
||||
|
||||
.setup_tools_unless_target_test: &setup_tools_unless_target_test |
|
||||
if [[ -n "$IDF_DONT_USE_MIRRORS" ]]; then
|
||||
export IDF_MIRROR_PREFIX_MAP=
|
||||
fi
|
||||
if [[ "$SETUP_TOOLS" == "1" || "$CI_JOB_STAGE" != "target_test" ]]; then
|
||||
tools/idf_tools.py --non-interactive install && eval "$(tools/idf_tools.py --non-interactive export)" || exit 1
|
||||
fi
|
||||
@@ -142,7 +145,7 @@ after_script:
|
||||
tags:
|
||||
- host_test
|
||||
dependencies: []
|
||||
extends: .before_script_lesser_nofilter
|
||||
extends: .before_script_lesser
|
||||
|
||||
.macos_build_template:
|
||||
stage: build
|
||||
@@ -163,3 +166,4 @@ include:
|
||||
- '/tools/ci/config/target-test.yml'
|
||||
- '/tools/ci/config/post_check.yml'
|
||||
- '/tools/ci/config/deploy.yml'
|
||||
- '/tools/ci/config/post_deploy.yml'
|
||||
|
@@ -2,8 +2,6 @@
|
||||
|
||||
* [中文版](./README_CN.md)
|
||||
|
||||
[](https://docs.espressif.com/projects/esp-idf/en/latest/?badge=latest)
|
||||
|
||||
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview) chip.
|
||||
|
||||
# Developing With ESP-IDF
|
||||
@@ -15,6 +13,8 @@ See setup guides for detailed instructions to set up the ESP-IDF:
|
||||
* [Getting Started Guide for the stable ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/)
|
||||
* [Getting Started Guide for the latest (master branch) ESP-IDF version](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/)
|
||||
|
||||
*Note: ESP-IDF Programmers Guide is in the process of transitioning to a new documentation host. Master branch ("latest") docs will not be updated from 2020-02-05 for approximately two weeks. This note will be removed once the master branch docs are updating again. Other branch & release docs continue to update as normal.*
|
||||
|
||||
### Non-GitHub forks
|
||||
|
||||
ESP-IDF uses relative locations as its submodules URLs ([.gitmodules](.gitmodules)). So they link to GitHub.
|
||||
|
@@ -439,11 +439,11 @@ typedef struct {
|
||||
struct esp_ble_mesh_model {
|
||||
/** Model ID */
|
||||
union {
|
||||
const uint16_t model_id;
|
||||
struct {
|
||||
uint16_t company_id;
|
||||
uint16_t model_id;
|
||||
} vnd;
|
||||
const uint16_t model_id; /*!< 16-bit model identifier */
|
||||
struct esp_ble_mesh_vnd_struct {
|
||||
uint16_t company_id; /*!< 16-bit company identifier */
|
||||
uint16_t model_id; /*!< 16-bit model identifier */
|
||||
} vnd; /*!< Structure encapsulating a model ID with a company ID */
|
||||
};
|
||||
|
||||
/** Internal information, mainly for persistent storage */
|
||||
@@ -656,7 +656,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
esp_ble_mesh_bd_addr_t addr; /*!< Device address */
|
||||
esp_ble_mesh_bd_addr_t addr; /*!< Device address */
|
||||
esp_ble_mesh_addr_type_t addr_type; /*!< Device address type */
|
||||
};
|
||||
uint8_t uuid[16]; /*!< Device UUID */
|
||||
|
@@ -31,7 +31,8 @@ extern "C" {
|
||||
|
||||
typedef uint8_t esp_a2d_mct_t;
|
||||
|
||||
/// A2DP media codec capabilities union
|
||||
/** A2DP media codec capabilities union
|
||||
*/
|
||||
typedef struct {
|
||||
esp_a2d_mct_t type; /*!< A2DP media codec type */
|
||||
#define ESP_A2D_CIE_LEN_SBC (4)
|
||||
@@ -39,10 +40,10 @@ typedef struct {
|
||||
#define ESP_A2D_CIE_LEN_M24 (6)
|
||||
#define ESP_A2D_CIE_LEN_ATRAC (7)
|
||||
union {
|
||||
uint8_t sbc[ESP_A2D_CIE_LEN_SBC];
|
||||
uint8_t m12[ESP_A2D_CIE_LEN_M12];
|
||||
uint8_t m24[ESP_A2D_CIE_LEN_M24];
|
||||
uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC];
|
||||
uint8_t sbc[ESP_A2D_CIE_LEN_SBC]; /*!< SBC codec capabilities */
|
||||
uint8_t m12[ESP_A2D_CIE_LEN_M12]; /*!< MPEG-1,2 audio codec capabilities */
|
||||
uint8_t m24[ESP_A2D_CIE_LEN_M24]; /*!< MPEG-2, 4 AAC audio codec capabilities */
|
||||
uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC]; /*!< ATRAC family codec capabilities */
|
||||
} cie; /*!< A2DP codec information element */
|
||||
} __attribute__((packed)) esp_a2d_mcc_t;
|
||||
|
||||
|
@@ -86,9 +86,9 @@ typedef struct {
|
||||
#define ESP_UUID_LEN_128 16
|
||||
uint16_t len; /*!< UUID length, 16bit, 32bit or 128bit */
|
||||
union {
|
||||
uint16_t uuid16;
|
||||
uint32_t uuid32;
|
||||
uint8_t uuid128[ESP_UUID_LEN_128];
|
||||
uint16_t uuid16; /*!< 16bit UUID */
|
||||
uint32_t uuid32; /*!< 32bit UUID */
|
||||
uint8_t uuid128[ESP_UUID_LEN_128]; /*!< 128bit UUID */
|
||||
} uuid; /*!< UUID */
|
||||
} __attribute__((packed)) esp_bt_uuid_t;
|
||||
|
||||
|
@@ -51,22 +51,22 @@ esp_err_t touch_pad_sw_start(void);
|
||||
* sleep_cycle decide the interval between each measurement.
|
||||
* t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency).
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
* @param meas_timers The times of charge and discharge in each measure process of touch channels.
|
||||
* The timer frequency is 8Mhz. Range: 0 ~ 0xffff.
|
||||
* Recommended typical value: Modify this value to make the measurement time around 1ms.
|
||||
* @param meas_time The time of charge and discharge in each measure process of touch channels.
|
||||
* The timer frequency is 8Mhz. Range: 0 ~ 0xffff.
|
||||
* Recommended typical value: Modify this value to make the measurement time around 1ms.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_times);
|
||||
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_time);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor times of charge and discharge and sleep time
|
||||
* @param sleep_cycle Pointer to accept sleep cycle number
|
||||
* @param meas_times Pointer to accept measurement times count.
|
||||
* @param meas_time Pointer to accept measurement time count.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_times);
|
||||
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_time);
|
||||
|
||||
/**
|
||||
* @brief Set connection type of touch channel in idle status.
|
||||
@@ -196,7 +196,7 @@ uint32_t touch_pad_read_intr_status_mask(void);
|
||||
|
||||
/**
|
||||
* @brief Enable touch sensor interrupt by bitmask.
|
||||
* @param type interrupt type
|
||||
* @param int_mask Pad mask to enable interrupts
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
@@ -204,7 +204,7 @@ esp_err_t touch_pad_intr_enable(touch_pad_intr_mask_t int_mask);
|
||||
|
||||
/**
|
||||
* @brief Disable touch sensor interrupt by bitmask.
|
||||
* @param type interrupt type
|
||||
* @param int_mask Pad mask to disable interrupts
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
@@ -215,12 +215,13 @@ esp_err_t touch_pad_intr_disable(touch_pad_intr_mask_t int_mask);
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @param fn Pointer to ISR handler
|
||||
* @param arg Parameter for ISR
|
||||
* @param int_mask Initial pad mask to enable interrupt for
|
||||
* @return
|
||||
* - ESP_OK Success ;
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
* - ESP_ERR_NO_MEM No memory
|
||||
*/
|
||||
esp_err_t touch_pad_isr_register(intr_handler_t fn, void* arg, touch_pad_intr_mask_t intr_mask);
|
||||
esp_err_t touch_pad_isr_register(intr_handler_t fn, void* arg, touch_pad_intr_mask_t int_mask);
|
||||
|
||||
/**
|
||||
* @brief get raw data of touch sensor.
|
||||
@@ -239,7 +240,7 @@ esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint32_t *raw_data);
|
||||
* @brief get baseline of touch sensor.
|
||||
* @note After initialization, the baseline value is the maximum during the first measurement period.
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
* @param basedata pointer to accept touch sensor baseline value
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch channel 0 havent this parameter.
|
||||
@@ -331,7 +332,7 @@ esp_err_t touch_pad_denoise_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Get denoise measure value (TOUCH_PAD_NUM0).
|
||||
* @param denoise value of denoise
|
||||
* @param data Pointer to receive denoise value
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
*/
|
||||
@@ -405,7 +406,7 @@ esp_err_t touch_pad_proximity_get_config(touch_pad_proximity_t *proximity);
|
||||
* @brief Get measure count of proximity channel.
|
||||
* The proximity sensor measurement is the accumulation of touch channel measurements.
|
||||
* @param touch_num touch pad index
|
||||
* @param proximity parameter of proximity
|
||||
* @param cnt Pointer to receive proximity channel measurement count
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG parameter is NULL
|
||||
@@ -462,4 +463,4 @@ esp_err_t touch_pad_sleep_channel_read_proximity_cnt(uint32_t *proximity_cnt);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -331,8 +331,6 @@ esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num);
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t timer_num) __attribute__((deprecated));
|
||||
|
||||
@@ -341,8 +339,6 @@ void timer_group_intr_clr_in_isr(timer_group_t group_num, timer_idx_t timer_num)
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
@@ -351,8 +347,6 @@ void timer_group_clr_intr_status_in_isr(timer_group_t group_num, timer_idx_t tim
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param timer_num Timer index.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_enable_alarm_in_isr(timer_group_t group_num, timer_idx_t timer_num);
|
||||
|
||||
@@ -372,8 +366,6 @@ uint64_t timer_group_get_counter_value_in_isr(timer_group_t group_num, timer_idx
|
||||
* @param timer_num Timer index.
|
||||
* @param alarm_val Alarm threshold.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_val);
|
||||
|
||||
@@ -383,8 +375,6 @@ void timer_group_set_alarm_value_in_isr(timer_group_t group_num, timer_idx_t tim
|
||||
* @param timer_num Timer index.
|
||||
* @param counter_en Enable/disable.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_set_counter_enable_in_isr(timer_group_t group_num, timer_idx_t timer_num, timer_start_t counter_en);
|
||||
|
||||
@@ -411,8 +401,6 @@ uint32_t timer_group_get_intr_status_in_isr(timer_group_t group_num);
|
||||
* @param group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
|
||||
* @param intr_mask Masked interrupt.
|
||||
*
|
||||
* @return
|
||||
* - None
|
||||
*/
|
||||
void timer_group_clr_intr_sta_in_isr(timer_group_t group_num, timer_intr_t intr_mask) __attribute__((deprecated));
|
||||
|
||||
|
@@ -56,7 +56,6 @@ extern "C" {
|
||||
#define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \
|
||||
ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \
|
||||
ESP_INTR_FLAG_NMI) ///< Mask for all level flags
|
||||
/**@}*/
|
||||
|
||||
|
||||
/** @addtogroup Intr_Alloc_Pseudo_Src
|
||||
@@ -78,16 +77,23 @@ extern "C" {
|
||||
|
||||
/**@}*/
|
||||
|
||||
// This is used to provide SystemView with positive IRQ IDs, otherwise sheduler events are not shown properly
|
||||
/** Provides SystemView with positive IRQ IDs, otherwise scheduler events are not shown properly
|
||||
*/
|
||||
#define ETS_INTERNAL_INTR_SOURCE_OFF (-ETS_INTERNAL_PROFILING_INTR_SOURCE)
|
||||
|
||||
/** Enable interrupt by interrupt number */
|
||||
#define ESP_INTR_ENABLE(inum) xt_ints_on((1<<inum))
|
||||
|
||||
/** Disable interrupt by interrupt number */
|
||||
#define ESP_INTR_DISABLE(inum) xt_ints_off((1<<inum))
|
||||
|
||||
/** Function prototype for interrupt handler function */
|
||||
typedef void (*intr_handler_t)(void *arg);
|
||||
|
||||
|
||||
/** Interrupt handler associated data structure */
|
||||
typedef struct intr_handle_data_t intr_handle_data_t;
|
||||
|
||||
/** Handle to an interrupt handler */
|
||||
typedef intr_handle_data_t* intr_handle_t ;
|
||||
|
||||
/**
|
||||
|
@@ -56,7 +56,6 @@ extern "C" {
|
||||
#define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \
|
||||
ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \
|
||||
ESP_INTR_FLAG_NMI) ///< Mask for all level flags
|
||||
/**@}*/
|
||||
|
||||
|
||||
/** @addtogroup Intr_Alloc_Pseudo_Src
|
||||
@@ -78,16 +77,23 @@ extern "C" {
|
||||
|
||||
/**@}*/
|
||||
|
||||
// This is used to provide SystemView with positive IRQ IDs, otherwise sheduler events are not shown properly
|
||||
/** Provides SystemView with positive IRQ IDs, otherwise scheduler events are not shown properly
|
||||
*/
|
||||
#define ETS_INTERNAL_INTR_SOURCE_OFF (-ETS_INTERNAL_PROFILING_INTR_SOURCE)
|
||||
|
||||
/** Enable interrupt by interrupt number */
|
||||
#define ESP_INTR_ENABLE(inum) xt_ints_on((1<<inum))
|
||||
|
||||
/** Disable interrupt by interrupt number */
|
||||
#define ESP_INTR_DISABLE(inum) xt_ints_off((1<<inum))
|
||||
|
||||
/** Function prototype for interrupt handler function */
|
||||
typedef void (*intr_handler_t)(void *arg);
|
||||
|
||||
|
||||
/** Interrupt handler associated data structure */
|
||||
typedef struct intr_handle_data_t intr_handle_data_t;
|
||||
|
||||
/** Handle to an interrupt handler */
|
||||
typedef intr_handle_data_t* intr_handle_t ;
|
||||
|
||||
/**
|
||||
|
@@ -302,6 +302,7 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
|
||||
/**
|
||||
* @brief Special variant of esp_event_post_to for posting events from interrupt handlers
|
||||
*
|
||||
* @param[in] event_loop the event loop to post to
|
||||
* @param[in] event_base the event base that identifies the event
|
||||
* @param[in] event_id the event id that identifies the event
|
||||
* @param[in] event_data the data, specific to the event occurence, that gets passed to the handler
|
||||
|
@@ -308,7 +308,8 @@ endmenu # Wi-Fi
|
||||
menu "PHY"
|
||||
|
||||
config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
|
||||
# ToDo: remove once NVS and PHY partial calibration are supported
|
||||
# ToDo: remove target dependency once NVS and PHY partial calibration are supported
|
||||
# also re-enable the <RF_calibration> entry in docs/../api-guides/index.rst
|
||||
depends on IDF_TARGET_ESP32
|
||||
bool "Store phy calibration data in NVS"
|
||||
default y
|
||||
|
@@ -114,7 +114,7 @@ typedef union {
|
||||
uart_port_t port; /*!< Modbus communication port (UART) number */
|
||||
uint32_t baudrate; /*!< Modbus baudrate */
|
||||
uart_parity_t parity; /*!< Modbus UART parity settings */
|
||||
uint16_t dummy_port;
|
||||
uint16_t dummy_port; /*!< Dummy field, unused */
|
||||
};
|
||||
// Tcp communication structure
|
||||
struct {
|
||||
|
@@ -83,11 +83,11 @@ typedef struct{
|
||||
union {
|
||||
struct {
|
||||
uint32_t clk_speed; /*!< I2C clock frequency for master mode, (no higher than 1MHz for now) */
|
||||
} master;
|
||||
} master; /*!< I2C master config */
|
||||
struct {
|
||||
uint8_t addr_10bit_en; /*!< I2C 10bit address mode enable for slave mode */
|
||||
uint16_t slave_addr; /*!< I2C address for slave mode */
|
||||
} slave;
|
||||
} slave; /*!< I2C slave config */
|
||||
};
|
||||
} i2c_config_t;
|
||||
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "soc/touch_sensor_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/** Touch pad channel */
|
||||
typedef enum {
|
||||
TOUCH_PAD_NUM0 = 0, /*!< Touch pad channel 0 is GPIO4(ESP32) */
|
||||
TOUCH_PAD_NUM1, /*!< Touch pad channel 1 is GPIO0(ESP32) / GPIO1(ESP32-S2) */
|
||||
@@ -38,6 +39,7 @@ typedef enum {
|
||||
TOUCH_PAD_MAX,
|
||||
} touch_pad_t;
|
||||
|
||||
/** Touch sensor high reference voltage */
|
||||
typedef enum {
|
||||
TOUCH_HVOLT_KEEP = -1, /*!<Touch sensor high reference voltage, no change */
|
||||
TOUCH_HVOLT_2V4 = 0, /*!<Touch sensor high reference voltage, 2.4V */
|
||||
@@ -47,6 +49,7 @@ typedef enum {
|
||||
TOUCH_HVOLT_MAX,
|
||||
} touch_high_volt_t;
|
||||
|
||||
/** Touch sensor low reference voltage */
|
||||
typedef enum {
|
||||
TOUCH_LVOLT_KEEP = -1, /*!<Touch sensor low reference voltage, no change */
|
||||
TOUCH_LVOLT_0V5 = 0, /*!<Touch sensor low reference voltage, 0.5V */
|
||||
@@ -56,6 +59,7 @@ typedef enum {
|
||||
TOUCH_LVOLT_MAX,
|
||||
} touch_low_volt_t;
|
||||
|
||||
/** Touch sensor high reference voltage attenuation */
|
||||
typedef enum {
|
||||
TOUCH_HVOLT_ATTEN_KEEP = -1, /*!<Touch sensor high reference voltage attenuation, no change */
|
||||
TOUCH_HVOLT_ATTEN_1V5 = 0, /*!<Touch sensor high reference voltage attenuation, 1.5V attenuation */
|
||||
@@ -65,6 +69,7 @@ typedef enum {
|
||||
TOUCH_HVOLT_ATTEN_MAX,
|
||||
} touch_volt_atten_t;
|
||||
|
||||
/** Touch sensor charge/discharge speed */
|
||||
typedef enum {
|
||||
TOUCH_PAD_SLOPE_0 = 0, /*!<Touch sensor charge / discharge speed, always zero */
|
||||
TOUCH_PAD_SLOPE_1 = 1, /*!<Touch sensor charge / discharge speed, slowest */
|
||||
@@ -77,12 +82,14 @@ typedef enum {
|
||||
TOUCH_PAD_SLOPE_MAX,
|
||||
} touch_cnt_slope_t;
|
||||
|
||||
/** Touch sensor initial charge level */
|
||||
typedef enum {
|
||||
TOUCH_PAD_TIE_OPT_LOW = 0, /*!<Initial level of charging voltage, low level */
|
||||
TOUCH_PAD_TIE_OPT_HIGH = 1, /*!<Initial level of charging voltage, high level */
|
||||
TOUCH_PAD_TIE_OPT_MAX,
|
||||
} touch_tie_opt_t;
|
||||
|
||||
/** Touch sensor FSM mode */
|
||||
typedef enum {
|
||||
TOUCH_FSM_MODE_TIMER = 0, /*!<To start touch FSM by timer */
|
||||
TOUCH_FSM_MODE_SW, /*!<To start touch FSM by software trigger */
|
||||
@@ -175,6 +182,7 @@ typedef enum {
|
||||
TOUCH_PAD_DENOISE_CAP_MAX
|
||||
} touch_pad_denoise_cap_t;
|
||||
|
||||
/** Touch sensor denoise configuration */
|
||||
typedef struct touch_pad_denoise {
|
||||
touch_pad_denoise_grade_t grade; /*!<Select denoise range of denoise channel.
|
||||
Determined by measuring the noise amplitude of the denoise channel. */
|
||||
@@ -195,6 +203,7 @@ typedef enum {
|
||||
TOUCH_PAD_SHIELD_DRV_MAX
|
||||
} touch_pad_shield_driver_t;
|
||||
|
||||
/** Touch sensor waterproof configuration */
|
||||
typedef struct touch_pad_waterproof {
|
||||
touch_pad_t guard_ring_pad; /*!<Waterproof. Select touch channel use for guard pad */
|
||||
touch_pad_shield_driver_t shield_driver;/*!<Waterproof. Select max equivalent capacitance for sheild pad
|
||||
@@ -202,6 +211,7 @@ typedef struct touch_pad_waterproof {
|
||||
reading to the Touch0 reading to estimate the equivalent capacitance.*/
|
||||
} touch_pad_waterproof_t;
|
||||
|
||||
/** Touch sensor proximity detection configuration */
|
||||
typedef struct touch_pad_proximity {
|
||||
touch_pad_t select_pad[SOC_TOUCH_PROXIMITY_CHANNEL_NUM]; /*!<Set touch channel number for proximity pad.
|
||||
If clear the proximity channel, point this pad to `TOUCH_PAD_NUM0` */
|
||||
@@ -209,9 +219,10 @@ typedef struct touch_pad_proximity {
|
||||
#define TOUCH_PROXIMITY_MEAS_NUM_MAX (0xFF)
|
||||
} touch_pad_proximity_t;
|
||||
|
||||
/** Touch channel idle state configuration */
|
||||
typedef enum {
|
||||
TOUCH_PAD_CONN_HIGHZ = 0, /*!<Idel status of touch channel is high resistance state */
|
||||
TOUCH_PAD_CONN_GND = 1, /*!<Idel status of touch channel is ground connection */
|
||||
TOUCH_PAD_CONN_HIGHZ = 0, /*!<Idle status of touch channel is high resistance state */
|
||||
TOUCH_PAD_CONN_GND = 1, /*!<Idle status of touch channel is ground connection */
|
||||
TOUCH_PAD_CONN_MAX
|
||||
} touch_pad_conn_type_t;
|
||||
|
||||
@@ -223,6 +234,7 @@ typedef enum {
|
||||
TOUCH_PAD_FILTER_MAX
|
||||
} touch_filter_mode_t;
|
||||
|
||||
/** Touch sensor filter configuration */
|
||||
typedef struct touch_filter_config {
|
||||
touch_filter_mode_t mode; /*!<Set filter mode. The input to the filter is raw data and the output is the baseline value.
|
||||
Larger filter coefficients increase the stability of the baseline. */
|
||||
@@ -253,6 +265,7 @@ typedef struct touch_filter_config {
|
||||
#define TOUCH_JITTER_STEP_MAX (15)
|
||||
} touch_filter_config_t;
|
||||
|
||||
/** Touch sensor channel sleep configuration */
|
||||
typedef struct {
|
||||
touch_pad_t touch_num; /*!<Set touch channel number for sleep pad.
|
||||
Only one touch sensor channel is supported in deep sleep mode. */
|
||||
@@ -261,4 +274,4 @@ typedef struct {
|
||||
bool en_proximity; /*!<enable proximity function for sleep pad */
|
||||
} touch_pad_sleep_channel_t;
|
||||
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||
|
@@ -136,7 +136,7 @@ typedef struct {
|
||||
uint8_t rx_flow_ctrl_thresh; /*!< UART HW RTS threshold*/
|
||||
union {
|
||||
uart_sclk_t source_clk; /*!< UART source clock selection */
|
||||
bool use_ref_tick __attribute__((deprecated));
|
||||
bool use_ref_tick __attribute__((deprecated)); /*!< Deprecated method to select ref tick clock source, set source_clk field instead */
|
||||
};
|
||||
} uart_config_t;
|
||||
|
||||
|
@@ -101,137 +101,137 @@ typedef struct
|
||||
{
|
||||
int flags; /*!< ESP_VFS_FLAG_CONTEXT_PTR or ESP_VFS_FLAG_DEFAULT */
|
||||
union {
|
||||
ssize_t (*write_p)(void* p, int fd, const void * data, size_t size);
|
||||
ssize_t (*write)(int fd, const void * data, size_t size);
|
||||
ssize_t (*write_p)(void* p, int fd, const void * data, size_t size); /*!< Write with context pointer */
|
||||
ssize_t (*write)(int fd, const void * data, size_t size); /*!< Write without context pointer */
|
||||
};
|
||||
union {
|
||||
off_t (*lseek_p)(void* p, int fd, off_t size, int mode);
|
||||
off_t (*lseek)(int fd, off_t size, int mode);
|
||||
off_t (*lseek_p)(void* p, int fd, off_t size, int mode); /*!< Seek with context pointer */
|
||||
off_t (*lseek)(int fd, off_t size, int mode); /*!< Seek without context pointer */
|
||||
};
|
||||
union {
|
||||
ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size);
|
||||
ssize_t (*read)(int fd, void * dst, size_t size);
|
||||
ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size); /*!< Read with context pointer */
|
||||
ssize_t (*read)(int fd, void * dst, size_t size); /*!< Read without context pointer */
|
||||
};
|
||||
union {
|
||||
ssize_t (*pread_p)(void *ctx, int fd, void * dst, size_t size, off_t offset);
|
||||
ssize_t (*pread)(int fd, void * dst, size_t size, off_t offset);
|
||||
ssize_t (*pread_p)(void *ctx, int fd, void * dst, size_t size, off_t offset); /*!< pread with context pointer */
|
||||
ssize_t (*pread)(int fd, void * dst, size_t size, off_t offset); /*!< pread without context pointer */
|
||||
};
|
||||
union {
|
||||
ssize_t (*pwrite_p)(void *ctx, int fd, const void *src, size_t size, off_t offset);
|
||||
ssize_t (*pwrite)(int fd, const void *src, size_t size, off_t offset);
|
||||
ssize_t (*pwrite_p)(void *ctx, int fd, const void *src, size_t size, off_t offset); /*!< pwrite with context pointer */
|
||||
ssize_t (*pwrite)(int fd, const void *src, size_t size, off_t offset); /*!< pwrite without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*open_p)(void* ctx, const char * path, int flags, int mode);
|
||||
int (*open)(const char * path, int flags, int mode);
|
||||
int (*open_p)(void* ctx, const char * path, int flags, int mode); /*!< open with context pointer */
|
||||
int (*open)(const char * path, int flags, int mode); /*!< open without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*close_p)(void* ctx, int fd);
|
||||
int (*close)(int fd);
|
||||
int (*close_p)(void* ctx, int fd); /*!< close with context pointer */
|
||||
int (*close)(int fd); /*!< close without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*fstat_p)(void* ctx, int fd, struct stat * st);
|
||||
int (*fstat)(int fd, struct stat * st);
|
||||
int (*fstat_p)(void* ctx, int fd, struct stat * st); /*!< fstat with context pointer */
|
||||
int (*fstat)(int fd, struct stat * st); /*!< fstat without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*stat_p)(void* ctx, const char * path, struct stat * st);
|
||||
int (*stat)(const char * path, struct stat * st);
|
||||
int (*stat_p)(void* ctx, const char * path, struct stat * st); /*!< stat with context pointer */
|
||||
int (*stat)(const char * path, struct stat * st); /*!< stat without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*link_p)(void* ctx, const char* n1, const char* n2);
|
||||
int (*link)(const char* n1, const char* n2);
|
||||
int (*link_p)(void* ctx, const char* n1, const char* n2); /*!< link with context pointer */
|
||||
int (*link)(const char* n1, const char* n2); /*!< link without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*unlink_p)(void* ctx, const char *path);
|
||||
int (*unlink)(const char *path);
|
||||
int (*unlink_p)(void* ctx, const char *path); /*!< unlink with context pointer */
|
||||
int (*unlink)(const char *path); /*!< unlink without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*rename_p)(void* ctx, const char *src, const char *dst);
|
||||
int (*rename)(const char *src, const char *dst);
|
||||
int (*rename_p)(void* ctx, const char *src, const char *dst); /*!< rename with context pointer */
|
||||
int (*rename)(const char *src, const char *dst); /*!< rename without context pointer */
|
||||
};
|
||||
union {
|
||||
DIR* (*opendir_p)(void* ctx, const char* name);
|
||||
DIR* (*opendir)(const char* name);
|
||||
DIR* (*opendir_p)(void* ctx, const char* name); /*!< opendir with context pointer */
|
||||
DIR* (*opendir)(const char* name); /*!< opendir without context pointer */
|
||||
};
|
||||
union {
|
||||
struct dirent* (*readdir_p)(void* ctx, DIR* pdir);
|
||||
struct dirent* (*readdir)(DIR* pdir);
|
||||
struct dirent* (*readdir_p)(void* ctx, DIR* pdir); /*!< readdir with context pointer */
|
||||
struct dirent* (*readdir)(DIR* pdir); /*!< readdir without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*readdir_r_p)(void* ctx, DIR* pdir, struct dirent* entry, struct dirent** out_dirent);
|
||||
int (*readdir_r)(DIR* pdir, struct dirent* entry, struct dirent** out_dirent);
|
||||
int (*readdir_r_p)(void* ctx, DIR* pdir, struct dirent* entry, struct dirent** out_dirent); /*!< readdir_r with context pointer */
|
||||
int (*readdir_r)(DIR* pdir, struct dirent* entry, struct dirent** out_dirent); /*!< readdir_r without context pointer */
|
||||
};
|
||||
union {
|
||||
long (*telldir_p)(void* ctx, DIR* pdir);
|
||||
long (*telldir)(DIR* pdir);
|
||||
long (*telldir_p)(void* ctx, DIR* pdir); /*!< telldir with context pointer */
|
||||
long (*telldir)(DIR* pdir); /*!< telldir without context pointer */
|
||||
};
|
||||
union {
|
||||
void (*seekdir_p)(void* ctx, DIR* pdir, long offset);
|
||||
void (*seekdir)(DIR* pdir, long offset);
|
||||
void (*seekdir_p)(void* ctx, DIR* pdir, long offset); /*!< seekdir with context pointer */
|
||||
void (*seekdir)(DIR* pdir, long offset); /*!< seekdir without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*closedir_p)(void* ctx, DIR* pdir);
|
||||
int (*closedir)(DIR* pdir);
|
||||
int (*closedir_p)(void* ctx, DIR* pdir); /*!< closedir with context pointer */
|
||||
int (*closedir)(DIR* pdir); /*!< closedir without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*mkdir_p)(void* ctx, const char* name, mode_t mode);
|
||||
int (*mkdir)(const char* name, mode_t mode);
|
||||
int (*mkdir_p)(void* ctx, const char* name, mode_t mode); /*!< mkdir with context pointer */
|
||||
int (*mkdir)(const char* name, mode_t mode); /*!< mkdir without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*rmdir_p)(void* ctx, const char* name);
|
||||
int (*rmdir)(const char* name);
|
||||
int (*rmdir_p)(void* ctx, const char* name); /*!< rmdir with context pointer */
|
||||
int (*rmdir)(const char* name); /*!< rmdir without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*fcntl_p)(void* ctx, int fd, int cmd, int arg);
|
||||
int (*fcntl)(int fd, int cmd, int arg);
|
||||
int (*fcntl_p)(void* ctx, int fd, int cmd, int arg); /*!< fcntl with context pointer */
|
||||
int (*fcntl)(int fd, int cmd, int arg); /*!< fcntl without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*ioctl_p)(void* ctx, int fd, int cmd, va_list args);
|
||||
int (*ioctl)(int fd, int cmd, va_list args);
|
||||
int (*ioctl_p)(void* ctx, int fd, int cmd, va_list args); /*!< ioctl with context pointer */
|
||||
int (*ioctl)(int fd, int cmd, va_list args); /*!< ioctl without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*fsync_p)(void* ctx, int fd);
|
||||
int (*fsync)(int fd);
|
||||
int (*fsync_p)(void* ctx, int fd); /*!< fsync with context pointer */
|
||||
int (*fsync)(int fd); /*!< fsync without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*access_p)(void* ctx, const char *path, int amode);
|
||||
int (*access)(const char *path, int amode);
|
||||
int (*access_p)(void* ctx, const char *path, int amode); /*!< access with context pointer */
|
||||
int (*access)(const char *path, int amode); /*!< access without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*truncate_p)(void* ctx, const char *path, off_t length);
|
||||
int (*truncate)(const char *path, off_t length);
|
||||
int (*truncate_p)(void* ctx, const char *path, off_t length); /*!< truncate with context pointer */
|
||||
int (*truncate)(const char *path, off_t length); /*!< truncate without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*utime_p)(void* ctx, const char *path, const struct utimbuf *times);
|
||||
int (*utime)(const char *path, const struct utimbuf *times);
|
||||
int (*utime_p)(void* ctx, const char *path, const struct utimbuf *times); /*!< utime with context pointer */
|
||||
int (*utime)(const char *path, const struct utimbuf *times); /*!< utime without context pointer */
|
||||
};
|
||||
#ifdef CONFIG_VFS_SUPPORT_TERMIOS
|
||||
union {
|
||||
int (*tcsetattr_p)(void *ctx, int fd, int optional_actions, const struct termios *p);
|
||||
int (*tcsetattr)(int fd, int optional_actions, const struct termios *p);
|
||||
int (*tcsetattr_p)(void *ctx, int fd, int optional_actions, const struct termios *p); /*!< tcsetattr with context pointer */
|
||||
int (*tcsetattr)(int fd, int optional_actions, const struct termios *p); /*!< tcsetattr without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*tcgetattr_p)(void *ctx, int fd, struct termios *p);
|
||||
int (*tcgetattr)(int fd, struct termios *p);
|
||||
int (*tcgetattr_p)(void *ctx, int fd, struct termios *p); /*!< tcgetattr with context pointer */
|
||||
int (*tcgetattr)(int fd, struct termios *p); /*!< tcgetattr without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*tcdrain_p)(void *ctx, int fd);
|
||||
int (*tcdrain)(int fd);
|
||||
int (*tcdrain_p)(void *ctx, int fd); /*!< tcdrain with context pointer */
|
||||
int (*tcdrain)(int fd); /*!< tcdrain without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*tcflush_p)(void *ctx, int fd, int select);
|
||||
int (*tcflush)(int fd, int select);
|
||||
int (*tcflush_p)(void *ctx, int fd, int select); /*!< tcflush with context pointer */
|
||||
int (*tcflush)(int fd, int select); /*!< tcflush without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*tcflow_p)(void *ctx, int fd, int action);
|
||||
int (*tcflow)(int fd, int action);
|
||||
int (*tcflow_p)(void *ctx, int fd, int action); /*!< tcflow with context pointer */
|
||||
int (*tcflow)(int fd, int action); /*!< tcflow without context pointer */
|
||||
};
|
||||
union {
|
||||
pid_t (*tcgetsid_p)(void *ctx, int fd);
|
||||
pid_t (*tcgetsid)(int fd);
|
||||
pid_t (*tcgetsid_p)(void *ctx, int fd); /*!< tcgetsid with context pointer */
|
||||
pid_t (*tcgetsid)(int fd); /*!< tcgetsid without context pointer */
|
||||
};
|
||||
union {
|
||||
int (*tcsendbreak_p)(void *ctx, int fd, int duration);
|
||||
int (*tcsendbreak)(int fd, int duration);
|
||||
int (*tcsendbreak_p)(void *ctx, int fd, int duration); /*!< tcsendbreak with context pointer */
|
||||
int (*tcsendbreak)(int fd, int duration); /*!< tcsendbreak without context pointer */
|
||||
};
|
||||
#endif // CONFIG_VFS_SUPPORT_TERMIOS
|
||||
|
||||
|
359
docs/Doxyfile
359
docs/Doxyfile
@@ -24,270 +24,271 @@ INPUT = \
|
||||
##
|
||||
## Wi-Fi - API Reference
|
||||
##
|
||||
../../components/esp_wifi/include/esp_wifi.h \
|
||||
../../components/esp_wifi/include/esp_wifi_types.h \
|
||||
../../components/esp_wifi/include/esp_smartconfig.h \
|
||||
../../components/esp_wifi/include/esp_now.h \
|
||||
../../components/esp_wifi/include/esp_wifi_default.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi_types.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_smartconfig.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_now.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_wifi_default.h \
|
||||
## Mesh - API Reference
|
||||
../../components/esp_wifi/include/esp_mesh.h \
|
||||
$(IDF_PATH)/components/esp_wifi/include/esp_mesh.h \
|
||||
## Event loop - API Reference
|
||||
../../components/esp_event/include/esp_event.h \
|
||||
../../components/esp_event/include/esp_event_base.h \
|
||||
../../components/esp_event/include/esp_event_legacy.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event_base.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event_legacy.h \
|
||||
## Bluetooth - API Reference
|
||||
## Controller && VHCI
|
||||
../../components/bt/include/esp_bt.h \
|
||||
$(IDF_PATH)/components/bt/include/esp_bt.h \
|
||||
## Bluetooth COMMON
|
||||
## Issue with __attribute__
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_bt_defs.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_bt_main.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_bt_device.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_main.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_bt_device.h \
|
||||
## Bluetooth LE
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h \
|
||||
## Issue with __attribute__
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_gatts_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_gattc_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_blufi_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_blufi_api.h \
|
||||
## Bluetooth Classic
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h \
|
||||
## Issue with __attribute__
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_avrc_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_spp_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_hf_defs.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h \
|
||||
../../components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_spp_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h \
|
||||
$(IDF_PATH)/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h \
|
||||
## NimBLE related Bluetooth APIs
|
||||
../../components/bt/host/nimble/esp-hci/include/esp_nimble_hci.h \
|
||||
$(IDF_PATH)/components/bt/host/nimble/esp-hci/include/esp_nimble_hci.h \
|
||||
## ESP BLE Mesh APIs
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_low_power_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_proxy_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_config_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_generic_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_health_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_lighting_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_sensor_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_time_scene_model_api.h \
|
||||
../../components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_local_data_operation_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_low_power_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_networking_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_provisioning_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_proxy_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_config_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_generic_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_health_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_lighting_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_sensor_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/models/include/esp_ble_mesh_time_scene_model_api.h \
|
||||
$(IDF_PATH)/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h \
|
||||
##
|
||||
## Ethernet - API Reference
|
||||
##
|
||||
../../components/esp_eth/include/esp_eth.h \
|
||||
../../components/esp_eth/include/esp_eth_com.h \
|
||||
../../components/esp_eth/include/esp_eth_mac.h \
|
||||
../../components/esp_eth/include/esp_eth_phy.h \
|
||||
../../components/esp_eth/include/esp_eth_netif_glue.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_com.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_mac.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_phy.h \
|
||||
$(IDF_PATH)/components/esp_eth/include/esp_eth_netif_glue.h \
|
||||
##
|
||||
## Peripherals - API Reference
|
||||
##
|
||||
../../components/driver/include/driver/adc.h \
|
||||
../../components/driver/include/driver/can.h \
|
||||
../../components/soc/include/hal/can_types.h \
|
||||
../../components/driver/include/driver/dac.h \
|
||||
../../components/driver/include/driver/gpio.h \
|
||||
../../components/driver/include/driver/rtc_io.h \
|
||||
../../components/driver/include/driver/i2c.h \
|
||||
../../components/driver/include/driver/i2s.h \
|
||||
../../components/driver/include/driver/ledc.h \
|
||||
../../components/driver/include/driver/mcpwm.h \
|
||||
../../components/soc/include/hal/mcpwm_types.h \
|
||||
../../components/driver/include/driver/pcnt.h \
|
||||
../../components/driver/include/driver/rmt.h \
|
||||
../../components/driver/include/driver/sigmadelta.h \
|
||||
../../components/driver/include/driver/spi_common.h \
|
||||
../../components/driver/include/driver/spi_master.h \
|
||||
../../components/driver/include/driver/spi_slave.h \
|
||||
../../components/driver/esp32s2/include/temp_sensor.h \
|
||||
../../components/driver/include/driver/timer.h \
|
||||
../../components/driver/include/driver/touch_pad.h \
|
||||
../../components/driver/include/driver/uart.h \
|
||||
../../components/esp_adc_cal/include/esp_adc_cal.h \
|
||||
../../components/soc/include/hal/rmt_types.h \
|
||||
../../components/soc/include/hal/spi_types.h \
|
||||
../../components/soc/include/hal/pcnt_types.h \
|
||||
../../components/soc/include/hal/i2s_types.h \
|
||||
../../components/soc/include/hal/rtc_io_types.h \
|
||||
../../components/soc/include/hal/sigmadelta_types.h \
|
||||
../../components/soc/include/hal/timer_types.h \
|
||||
../../components/soc/include/hal/ledc_types.h \
|
||||
../../components/soc/include/hal/i2c_types.h \
|
||||
../../components/soc/include/hal/dac_types.h \
|
||||
../../components/soc/include/hal/adc_types.h \
|
||||
../../components/soc/include/hal/gpio_types.h \
|
||||
../../components/soc/include/hal/uart_types.h \
|
||||
../../components/soc/include/hal/touch_sensor_types.h \
|
||||
../../components/soc/esp32/include/soc/adc_channel.h \
|
||||
../../components/soc/esp32/include/soc/dac_channel.h \
|
||||
../../components/soc/esp32/include/soc/touch_sensor_channel.h \
|
||||
../../components/soc/esp32/include/soc/uart_channel.h \
|
||||
../../components/soc/esp32/include/soc/rtc_io_channel.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/adc.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/can.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/can_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/dac.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/gpio.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/rtc_io.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/i2c.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/i2s.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/ledc.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/mcpwm.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/mcpwm_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/pcnt.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/rmt.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sigmadelta.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_master.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/spi_slave.h \
|
||||
$(IDF_PATH)/components/driver/$(IDF_TARGET)/include/touch_sensor.h \
|
||||
$(IDF_PATH)/components/driver/esp32s2/include/temp_sensor.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/timer.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/touch_sensor_common.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/uart.h \
|
||||
$(IDF_PATH)/components/esp_adc_cal/include/esp_adc_cal.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/rmt_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/spi_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/pcnt_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/i2s_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/rtc_io_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/sigmadelta_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/timer_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/ledc_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/i2c_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/dac_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/adc_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/gpio_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/uart_types.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/touch_sensor_types.h \
|
||||
$(IDF_PATH)/components/soc/esp32/include/soc/adc_channel.h \
|
||||
$(IDF_PATH)/components/soc/esp32/include/soc/dac_channel.h \
|
||||
$(IDF_PATH)/components/soc/esp32/include/soc/touch_sensor_channel.h \
|
||||
$(IDF_PATH)/components/soc/esp32/include/soc/uart_channel.h \
|
||||
$(IDF_PATH)/components/soc/esp32/include/soc/rtc_io_channel.h \
|
||||
## esp_netif - API Reference
|
||||
../../components/esp_netif/include/esp_netif.h \
|
||||
../../components/esp_netif/include/esp_netif_net_stack.h \
|
||||
$(IDF_PATH)/components/esp_netif/include/esp_netif.h \
|
||||
$(IDF_PATH)/components/esp_netif/include/esp_netif_net_stack.h \
|
||||
##
|
||||
## Protocols - API Reference
|
||||
##
|
||||
## ESP-TLS
|
||||
../../components/esp-tls/esp_tls.h \
|
||||
$(IDF_PATH)/components/esp-tls/esp_tls.h \
|
||||
## MQTT
|
||||
../../components/mqtt/esp-mqtt/include/mqtt_client.h \
|
||||
$(IDF_PATH)/components/mqtt/esp-mqtt/include/mqtt_client.h \
|
||||
## ICMP-ECHO
|
||||
../../components/lwip/include/apps/ping/ping_sock.h \
|
||||
$(IDF_PATH)/components/lwip/include/apps/ping/ping_sock.h \
|
||||
## SNTP
|
||||
../../components/lwip/include/apps/sntp/sntp.h \
|
||||
$(IDF_PATH)/components/lwip/include/apps/sntp/sntp.h \
|
||||
## mDNS
|
||||
../../components/mdns/include/mdns.h \
|
||||
../../components/esp_http_client/include/esp_http_client.h \
|
||||
../../components/esp_websocket_client/include/esp_websocket_client.h \
|
||||
$(IDF_PATH)/components/mdns/include/mdns.h \
|
||||
$(IDF_PATH)/components/esp_http_client/include/esp_http_client.h \
|
||||
$(IDF_PATH)/components/esp_websocket_client/include/esp_websocket_client.h \
|
||||
## HTTP / HTTPS Server
|
||||
../../components/esp_http_server/include/esp_http_server.h \
|
||||
../../components/esp_https_server/include/esp_https_server.h \
|
||||
$(IDF_PATH)/components/esp_http_server/include/esp_http_server.h \
|
||||
$(IDF_PATH)/components/esp_https_server/include/esp_https_server.h \
|
||||
## ESP Local Ctrl
|
||||
../../components/esp_local_ctrl/include/esp_local_ctrl.h \
|
||||
$(IDF_PATH)/components/esp_local_ctrl/include/esp_local_ctrl.h \
|
||||
## ESP Serial Slave Link
|
||||
../../components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
|
||||
../../components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
|
||||
$(IDF_PATH)/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
|
||||
$(IDF_PATH)/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
|
||||
##
|
||||
## Provisioning - API Reference
|
||||
##
|
||||
## Protocol Communication
|
||||
../../components/protocomm/include/common/protocomm.h \
|
||||
../../components/protocomm/include/security/protocomm_security.h \
|
||||
../../components/protocomm/include/security/protocomm_security0.h \
|
||||
../../components/protocomm/include/security/protocomm_security1.h \
|
||||
../../components/protocomm/include/transports/protocomm_ble.h \
|
||||
../../components/protocomm/include/transports/protocomm_console.h \
|
||||
../../components/protocomm/include/transports/protocomm_httpd.h \
|
||||
$(IDF_PATH)/components/protocomm/include/common/protocomm.h \
|
||||
$(IDF_PATH)/components/protocomm/include/security/protocomm_security.h \
|
||||
$(IDF_PATH)/components/protocomm/include/security/protocomm_security0.h \
|
||||
$(IDF_PATH)/components/protocomm/include/security/protocomm_security1.h \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_ble.h \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_console.h \
|
||||
$(IDF_PATH)/components/protocomm/include/transports/protocomm_httpd.h \
|
||||
## WiFi Provisioning
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/manager.h \
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h \
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h \
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/scheme_console.h \
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/wifi_config.h \
|
||||
../../components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/manager.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/scheme_console.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/wifi_config.h \
|
||||
$(IDF_PATH)/components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h \
|
||||
##
|
||||
## Storage - API Reference
|
||||
##
|
||||
## SPI Flash and Partition APIs
|
||||
../../components/spi_flash/include/esp_flash_spi_init.h \
|
||||
../../components/spi_flash/include/esp_flash.h \
|
||||
../../components/spi_flash/include/esp_partition.h \
|
||||
../../components/bootloader_support/include/esp_flash_encrypt.h \
|
||||
../../components/soc/include/hal/spi_flash_types.h \
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_flash_spi_init.h \
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_flash.h \
|
||||
$(IDF_PATH)/components/spi_flash/include/esp_partition.h \
|
||||
$(IDF_PATH)/components/bootloader_support/include/esp_flash_encrypt.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/spi_flash_types.h \
|
||||
## SPIFFS
|
||||
../../components/spiffs/include/esp_spiffs.h \
|
||||
$(IDF_PATH)/components/spiffs/include/esp_spiffs.h \
|
||||
## SD/MMC Card Host
|
||||
../../components/sdmmc/include/sdmmc_cmd.h \
|
||||
../../components/driver/include/driver/sdmmc_host.h \
|
||||
../../components/driver/include/driver/sdmmc_types.h \
|
||||
../../components/driver/include/driver/sdspi_host.h \
|
||||
$(IDF_PATH)/components/sdmmc/include/sdmmc_cmd.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdmmc_host.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdmmc_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdspi_host.h \
|
||||
## SDIO slave
|
||||
../../components/driver/include/driver/sdio_slave.h \
|
||||
../../components/soc/include/hal/sdio_slave_types.h \
|
||||
$(IDF_PATH)/components/driver/include/driver/sdio_slave.h \
|
||||
$(IDF_PATH)/components/soc/include/hal/sdio_slave_types.h \
|
||||
## Non-Volatile Storage
|
||||
../../components/nvs_flash/include/nvs.h \
|
||||
../../components/nvs_flash/include/nvs_flash.h \
|
||||
$(IDF_PATH)/components/nvs_flash/include/nvs.h \
|
||||
$(IDF_PATH)/components/nvs_flash/include/nvs_flash.h \
|
||||
## Virtual Filesystem
|
||||
../../components/vfs/include/esp_vfs.h \
|
||||
../../components/vfs/include/esp_vfs_dev.h \
|
||||
../../components/vfs/include/esp_vfs_semihost.h \
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs.h \
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs_dev.h \
|
||||
$(IDF_PATH)/components/vfs/include/esp_vfs_semihost.h \
|
||||
## FAT Filesystem
|
||||
## NOTE: for two lines below header_file.inc is not used
|
||||
../../components/fatfs/vfs/esp_vfs_fat.h \
|
||||
../../components/fatfs/diskio/diskio_impl.h \
|
||||
../../components/fatfs/diskio/diskio_sdmmc.h \
|
||||
../../components/fatfs/diskio/diskio_wl.h \
|
||||
../../components/fatfs/diskio/diskio_rawflash.h \
|
||||
$(IDF_PATH)/components/fatfs/vfs/esp_vfs_fat.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_impl.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_sdmmc.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_wl.h \
|
||||
$(IDF_PATH)/components/fatfs/diskio/diskio_rawflash.h \
|
||||
## Wear Levelling
|
||||
../../components/wear_levelling/include/wear_levelling.h \
|
||||
$(IDF_PATH)/components/wear_levelling/include/wear_levelling.h \
|
||||
##
|
||||
## System - API Reference
|
||||
##
|
||||
## Memory Allocation #
|
||||
../../components/heap/include/esp_heap_caps.h \
|
||||
../../components/heap/include/esp_heap_trace.h \
|
||||
../../components/heap/include/esp_heap_caps_init.h \
|
||||
../../components/heap/include/multi_heap.h \
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_caps.h \
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_trace.h \
|
||||
$(IDF_PATH)/components/heap/include/esp_heap_caps_init.h \
|
||||
$(IDF_PATH)/components/heap/include/multi_heap.h \
|
||||
## Himem
|
||||
../../components/esp32/include/esp32/himem.h \
|
||||
$(IDF_PATH)/components/esp32/include/esp32/himem.h \
|
||||
## Interrupt Allocation
|
||||
../../components/esp32/include/esp_intr_alloc.h \
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/esp_intr_alloc.h \
|
||||
## Watchdogs
|
||||
## NOTE: for two lines below header_file.inc is not used
|
||||
../../components/esp_common/include/esp_int_wdt.h \
|
||||
../../components/esp_common/include/esp_task_wdt.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_int_wdt.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_task_wdt.h \
|
||||
## Hooks
|
||||
../../components/esp_common/include/esp_freertos_hooks.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_freertos_hooks.h \
|
||||
## Inter-Processor Call
|
||||
../../components/esp_common/include/esp_ipc.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_ipc.h \
|
||||
## Call Function with External stack
|
||||
../../components/esp_common/include/esp_expression_with_stack.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_expression_with_stack.h \
|
||||
## Over The Air Updates (OTA)
|
||||
../../components/app_update/include/esp_ota_ops.h \
|
||||
$(IDF_PATH)/components/app_update/include/esp_ota_ops.h \
|
||||
## ESP HTTPS OTA
|
||||
../../components/esp_https_ota/include/esp_https_ota.h \
|
||||
$(IDF_PATH)/components/esp_https_ota/include/esp_https_ota.h \
|
||||
## Sleep
|
||||
../../components/esp32/include/esp_sleep.h \
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/esp_sleep.h \
|
||||
## Logging
|
||||
../../components/log/include/esp_log.h \
|
||||
$(IDF_PATH)/components/log/include/esp_log.h \
|
||||
## Base MAC address
|
||||
## NOTE: for line below header_file.inc is not used
|
||||
../../components/esp_common/include/esp_system.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_system.h \
|
||||
## IDF version
|
||||
../../components/esp_common/include/esp_idf_version.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_idf_version.h \
|
||||
##
|
||||
## ULP Coprocessor - API Guides
|
||||
##
|
||||
## NOTE: for line below header_file.inc is not used
|
||||
../../components/ulp/include/esp32/ulp.h \
|
||||
../../components/ulp/include/ulp_common.h \
|
||||
$(IDF_PATH)/components/ulp/include/$(IDF_TARGET)/ulp.h \
|
||||
$(IDF_PATH)/components/ulp/include/ulp_common.h \
|
||||
##
|
||||
## Application Level Tracing - API Reference
|
||||
##
|
||||
../../components/app_trace/include/esp_app_trace.h \
|
||||
../../components/app_trace/include/esp_sysview_trace.h \
|
||||
$(IDF_PATH)/components/app_trace/include/esp_app_trace.h \
|
||||
$(IDF_PATH)/components/app_trace/include/esp_sysview_trace.h \
|
||||
### Power management
|
||||
../../components/esp_common/include/esp_pm.h \
|
||||
../../components/esp32/include/esp32/pm.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_pm.h \
|
||||
$(IDF_PATH)/components/$(IDF_TARGET)/include/$(IDF_TARGET)/pm.h \
|
||||
### esp_timer, High Resolution Timer
|
||||
../../components/esp_timer/include/esp_timer.h \
|
||||
$(IDF_PATH)/components/esp_timer/include/esp_timer.h \
|
||||
### esp_event, Event Loop Library
|
||||
../../components/esp_event/include/esp_event.h \
|
||||
../../components/esp_event/include/esp_event_base.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event.h \
|
||||
$(IDF_PATH)/components/esp_event/include/esp_event_base.h \
|
||||
### eFuse Manager
|
||||
../../components/efuse/include/esp_efuse.h \
|
||||
$(IDF_PATH)/components/efuse/include/esp_efuse.h \
|
||||
### App Image Format
|
||||
../../components/bootloader_support/include/esp_app_format.h \
|
||||
$(IDF_PATH)/components/bootloader_support/include/esp_app_format.h \
|
||||
### ESP Pthread parameters
|
||||
../../components/pthread/include/esp_pthread.h \
|
||||
$(IDF_PATH)/components/pthread/include/esp_pthread.h \
|
||||
###
|
||||
### FreeRTOS
|
||||
###
|
||||
../../components/freertos/include/freertos/task.h \
|
||||
../../components/freertos/include/freertos/queue.h \
|
||||
../../components/freertos/include/freertos/semphr.h \
|
||||
../../components/freertos/include/freertos/timers.h \
|
||||
../../components/freertos/include/freertos/event_groups.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/task.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/queue.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/semphr.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/timers.h \
|
||||
$(IDF_PATH)/components/freertos/include/freertos/event_groups.h \
|
||||
### Ringbuffer
|
||||
../../components/esp_ringbuf/include/freertos/ringbuf.h \
|
||||
$(IDF_PATH)/components/esp_ringbuf/include/freertos/ringbuf.h \
|
||||
### Helper functions for error codes
|
||||
../../components/esp_common/include/esp_err.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_err.h \
|
||||
### System APIs
|
||||
../../components/esp_common/include/esp_system.h \
|
||||
$(IDF_PATH)/components/esp_common/include/esp_system.h \
|
||||
### Modbus controller component header file
|
||||
../../components/freemodbus/common/include/esp_modbus_common.h \
|
||||
../../components/freemodbus/common/include/esp_modbus_slave.h \
|
||||
../../components/freemodbus/common/include/esp_modbus_master.h \
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_common.h \
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_slave.h \
|
||||
$(IDF_PATH)/components/freemodbus/common/include/esp_modbus_master.h \
|
||||
### Performance Monitor component header file
|
||||
../../components/perfmon/include/xtensa_perfmon_access.h \
|
||||
../../components/perfmon/include/xtensa_perfmon_apis.h \
|
||||
../../components/perfmon/include/xtensa_perfmon_masks.h
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_access.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_apis.h \
|
||||
$(IDF_PATH)/components/perfmon/include/xtensa_perfmon_masks.h
|
||||
|
||||
|
||||
## Get warnings for functions that have no documentation for their parameters or return value
|
||||
@@ -300,7 +301,9 @@ ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
PREDEFINED = \
|
||||
$(ENV_DOXYGEN_DEFINES) \
|
||||
__attribute__(x)= \
|
||||
_Static_assert()= \
|
||||
IDF_DEPRECATED(X)= \
|
||||
IRAM_ATTR= \
|
||||
configSUPPORT_DYNAMIC_ALLOCATION=1 \
|
||||
|
@@ -16,16 +16,12 @@ The above URLs are all for the master branch latest version. Click the drop-down
|
||||
|
||||
# Building Documentation
|
||||
|
||||
* Install `make` and `doxygen` for your platform (`make` may already be installed as an ESP-IDF prerequisite).
|
||||
* Change to either the docs/en or docs/zh_CN subdirectory and run `make html`
|
||||
* `make` will probably prompt you to run a python pip install step to get some other Python-related prerequisites. Run the command as shown, then re-run `make html` to build the docs.
|
||||
* Documentation build requres Python 3 and will not work with Python 2
|
||||
* Install dependencies for ESP-IDF as per the Getting Started guide
|
||||
* Install documentation Python depdendencies, ie `pip install -r $IDF_PATH/docs/requirements.txt`
|
||||
* Run `./build_docs.py build` to build docs for all supported Language & Target combinations, or `./build_docs.py -t esp32 -l en build` to build docs for a single supported language & target combination only.
|
||||
|
||||
## For MSYS2 MINGW32 on Windows
|
||||
See [Documenting Code](https://docs.espressif.com/projects/esp-idf/en/latest/contribute/documenting-code.rst) for more information.
|
||||
|
||||
If using Windows and the MSYS2 MINGW32 terminal, run this command before running "make html" the first time:
|
||||
Available languages are `en` and `zh_CN`, targets are any target supported by ESP-IDF - for example `esp32` or `esp32s2`.
|
||||
|
||||
```
|
||||
pacman -S doxygen mingw-w64-i686-python2-pillow
|
||||
```
|
||||
|
||||
Note: Currently it is not possible to build docs on Windows without using a Unix-on-Windows layer such as MSYS2 MINGW32.
|
||||
|
368
docs/build_docs.py
Executable file
368
docs/build_docs.py
Executable file
@@ -0,0 +1,368 @@
|
||||
#!/usr/bin/env python3
|
||||
# coding=utf-8
|
||||
#
|
||||
# Top-level docs builder
|
||||
#
|
||||
# This is just a front-end to sphinx-build that can call it multiple times for different language/target combinations
|
||||
#
|
||||
# Will build out to _build/LANG/TARGET by default
|
||||
#
|
||||
# Specific custom docs functionality should be added in conf_common.py or in a Sphinx extension, not here.
|
||||
#
|
||||
from __future__ import print_function
|
||||
import argparse
|
||||
import locale
|
||||
import math
|
||||
import multiprocessing
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
LANGUAGES = ["en", "zh_CN"]
|
||||
TARGETS = ["esp32", "esp32s2"]
|
||||
|
||||
SPHINX_WARN_LOG = "sphinx-warning-log.txt"
|
||||
SPHINX_SANITIZED_LOG = "sphinx-warning-log-sanitized.txt"
|
||||
SPHINX_KNOWN_WARNINGS = os.path.join(os.environ["IDF_PATH"], "docs", "sphinx-known-warnings.txt")
|
||||
|
||||
DXG_WARN_LOG = "doxygen-warning-log.txt"
|
||||
DXG_SANITIZED_LOG = "doxygen-warning-log-sanitized.txt"
|
||||
DXG_KNOWN_WARNINGS = os.path.join(os.environ["IDF_PATH"], "docs", "doxygen-known-warnings.txt")
|
||||
|
||||
LogMessage = namedtuple("LogMessage", "original_text sanitized_text")
|
||||
|
||||
languages = LANGUAGES
|
||||
targets = TARGETS
|
||||
|
||||
|
||||
def main():
|
||||
# check Python dependencies for docs
|
||||
try:
|
||||
subprocess.check_call([sys.executable,
|
||||
os.path.join(os.environ["IDF_PATH"],
|
||||
"tools",
|
||||
"check_python_dependencies.py"),
|
||||
"-r",
|
||||
"{}/docs/requirements.txt".format(os.environ["IDF_PATH"])
|
||||
])
|
||||
except subprocess.CalledProcessError:
|
||||
raise SystemExit(2) # stdout will already have these errors
|
||||
|
||||
# This is not the only way to make sure that all files opened by Python are treated as UTF-8, but the other way is passing encoding='utf-8' to all open()
|
||||
# functions and this way makes Python 2 compatibility really tough if there is any code that assumes text files contain strings (kconfiglib assumes this).
|
||||
# The reason for that is that you need to import io.open() to support the encoding argument on Python 2, and this function always uses Py2's unicode
|
||||
# type not the str type.
|
||||
if 'UTF-8' not in locale.getlocale():
|
||||
raise RuntimeError("build_docs.py requires the default locale's encoding to be UTF-8. " +
|
||||
"Setting environment variable LC_ALL=C.UTF-8 when running build_docs.py may be enough to fix this.")
|
||||
|
||||
parser = argparse.ArgumentParser(description='build_docs.py: Build IDF docs', prog='build_docs.py')
|
||||
|
||||
parser.add_argument("--language", "-l", choices=LANGUAGES, required=False)
|
||||
parser.add_argument("--target", "-t", choices=TARGETS, required=False)
|
||||
parser.add_argument("--build-dir", "-b", type=str, default="_build")
|
||||
parser.add_argument("--sphinx-parallel-builds", "-p", choices=["auto"] + [str(x) for x in range(8)],
|
||||
help="Parallel Sphinx builds - number of independent Sphinx builds to run", default="auto")
|
||||
parser.add_argument("--sphinx-parallel-jobs", "-j", choices=["auto"] + [str(x) for x in range(8)],
|
||||
help="Sphinx parallel jobs argument - number of threads for each Sphinx build to use", default="1")
|
||||
|
||||
action_parsers = parser.add_subparsers(dest='action')
|
||||
|
||||
build_parser = action_parsers.add_parser('build', help='Build documentation')
|
||||
build_parser.add_argument("--check-warnings-only", "-w", action='store_true')
|
||||
|
||||
action_parsers.add_parser('linkcheck', help='Check links (a current IDF revision should be uploaded to GitHub)')
|
||||
|
||||
action_parsers.add_parser('gh-linkcheck', help='Checking for hardcoded GitHub links')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
global languages
|
||||
if args.language is None:
|
||||
print("Building all languages")
|
||||
languages = LANGUAGES
|
||||
else:
|
||||
languages = [args.language]
|
||||
|
||||
global targets
|
||||
if args.target is None:
|
||||
print("Building all targets")
|
||||
targets = TARGETS
|
||||
else:
|
||||
targets = [args.target]
|
||||
|
||||
if args.action == "build" or args.action is None:
|
||||
sys.exit(action_build(args))
|
||||
|
||||
if args.action == "linkcheck":
|
||||
sys.exit(action_linkcheck(args))
|
||||
|
||||
if args.action == "gh-linkcheck":
|
||||
sys.exit(action_gh_linkcheck(args))
|
||||
|
||||
|
||||
def parallel_call(args, callback):
|
||||
num_sphinx_builds = len(languages) * len(targets)
|
||||
num_cpus = multiprocessing.cpu_count()
|
||||
|
||||
if args.sphinx_parallel_builds == "auto":
|
||||
# at most one sphinx build per CPU, up to the number of CPUs
|
||||
args.sphinx_parallel_builds = min(num_sphinx_builds, num_cpus)
|
||||
else:
|
||||
args.sphinx_parallel_builds = int(args.sphinx_parallel_builds)
|
||||
|
||||
# Force -j1 because sphinx works incorrectly
|
||||
args.sphinx_parallel_jobs = 1
|
||||
if args.sphinx_parallel_jobs == "auto":
|
||||
# N CPUs per build job, rounded up - (maybe smarter to round down to avoid contention, idk)
|
||||
args.sphinx_parallel_jobs = int(math.ceil(num_cpus / args.sphinx_parallel_builds))
|
||||
else:
|
||||
args.sphinx_parallel_jobs = int(args.sphinx_parallel_jobs)
|
||||
|
||||
print("Will use %d parallel builds and %d jobs per build" % (args.sphinx_parallel_builds, args.sphinx_parallel_jobs))
|
||||
pool = multiprocessing.Pool(args.sphinx_parallel_builds)
|
||||
|
||||
if args.sphinx_parallel_jobs > 1:
|
||||
print("WARNING: Sphinx parallel jobs currently produce incorrect docs output with Sphinx 1.8.5")
|
||||
|
||||
# make a list of all combinations of build_docs() args as tuples
|
||||
#
|
||||
# there's probably a fancy way to do this with itertools but this way is actually readable
|
||||
entries = []
|
||||
for target in targets:
|
||||
for language in languages:
|
||||
build_dir = os.path.realpath(os.path.join(args.build_dir, language, target))
|
||||
entries.append((language, target, build_dir, args.sphinx_parallel_jobs))
|
||||
|
||||
print(entries)
|
||||
errcodes = pool.map(callback, entries)
|
||||
print(errcodes)
|
||||
|
||||
is_error = False
|
||||
for ret in errcodes:
|
||||
if ret != 0:
|
||||
print("\nThe following language/target combinations failed to build:")
|
||||
is_error = True
|
||||
break
|
||||
if is_error:
|
||||
for ret, entry in zip(errcodes, entries):
|
||||
if ret != 0:
|
||||
print("language: %s, target: %s, errcode: %d" % (entry[0], entry[1], ret))
|
||||
# Don't re-throw real error code from each parallel process
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def sphinx_call(language, target, build_dir, sphinx_parallel_jobs, buildername):
|
||||
# Note: because this runs in a multiprocessing Process, everything which happens here should be isolated to a single process
|
||||
# (ie it doesn't matter if Sphinx is using global variables, as they're it's own copy of the global variables)
|
||||
|
||||
# wrap stdout & stderr in a way that lets us see which build_docs instance they come from
|
||||
#
|
||||
# this doesn't apply to subprocesses, they write to OS stdout & stderr so no prefix appears
|
||||
prefix = "%s/%s: " % (language, target)
|
||||
|
||||
print("Building in build_dir: %s" % (build_dir))
|
||||
try:
|
||||
os.makedirs(build_dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
environ = {}
|
||||
environ.update(os.environ)
|
||||
environ['BUILDDIR'] = build_dir
|
||||
|
||||
args = [sys.executable, "-u", "-m", "sphinx.cmd.build",
|
||||
"-j", str(sphinx_parallel_jobs),
|
||||
"-b", buildername,
|
||||
"-d", os.path.join(build_dir, "doctrees"),
|
||||
"-w", SPHINX_WARN_LOG,
|
||||
"-t", target,
|
||||
"-D", "idf_target={}".format(target),
|
||||
os.path.join(os.path.abspath(os.path.dirname(__file__)), language), # srcdir for this language
|
||||
os.path.join(build_dir, buildername) # build directory
|
||||
]
|
||||
|
||||
saved_cwd = os.getcwd()
|
||||
os.chdir(build_dir) # also run sphinx in the build directory
|
||||
print("Running '%s'" % (" ".join(args)))
|
||||
|
||||
ret = 1
|
||||
try:
|
||||
# Note: we can't call sphinx.cmd.build.main() here as multiprocessing doesn't est >1 layer deep
|
||||
# and sphinx.cmd.build() also does a lot of work in the calling thread, especially for j ==1,
|
||||
# so using a Pyhthon thread for this part is a poor option (GIL)
|
||||
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
for c in iter(lambda: p.stdout.readline(), b''):
|
||||
sys.stdout.write(prefix)
|
||||
sys.stdout.write(c.decode('utf-8'))
|
||||
ret = p.wait()
|
||||
assert (ret is not None)
|
||||
sys.stdout.flush()
|
||||
except KeyboardInterrupt: # this seems to be the only way to get Ctrl-C to kill everything?
|
||||
p.kill()
|
||||
os.chdir(saved_cwd)
|
||||
return 130 # FIXME It doesn't return this errorcode, why? Just prints stacktrace
|
||||
os.chdir(saved_cwd)
|
||||
return ret
|
||||
|
||||
|
||||
def action_build(args):
|
||||
if not args.check_warnings_only:
|
||||
ret = parallel_call(args, call_build_docs)
|
||||
if ret != 0:
|
||||
return ret
|
||||
|
||||
# check Doxygen warnings:
|
||||
ret = 0
|
||||
for target in targets:
|
||||
for language in languages:
|
||||
build_dir = os.path.realpath(os.path.join(args.build_dir, language, target))
|
||||
ret += check_docs(language, target,
|
||||
log_file=os.path.join(build_dir, DXG_WARN_LOG),
|
||||
known_warnings_file=DXG_KNOWN_WARNINGS,
|
||||
out_sanitized_log_file=os.path.join(build_dir, DXG_SANITIZED_LOG))
|
||||
|
||||
# check Sphinx warnings:
|
||||
for target in targets:
|
||||
for language in languages:
|
||||
build_dir = os.path.realpath(os.path.join(args.build_dir, language, target))
|
||||
ret += check_docs(language, target,
|
||||
log_file=os.path.join(build_dir, SPHINX_WARN_LOG),
|
||||
known_warnings_file=SPHINX_KNOWN_WARNINGS,
|
||||
out_sanitized_log_file=os.path.join(build_dir, SPHINX_SANITIZED_LOG))
|
||||
if ret != 0:
|
||||
return ret
|
||||
|
||||
|
||||
def call_build_docs(entry):
|
||||
return sphinx_call(*entry, buildername="html")
|
||||
|
||||
|
||||
SANITIZE_FILENAME_REGEX = re.compile("[^:]*/([^/:]*)(:.*)")
|
||||
SANITIZE_LINENUM_REGEX = re.compile("([^:]*)(:[0-9]+:)(.*)")
|
||||
|
||||
|
||||
def sanitize_line(line):
|
||||
"""
|
||||
Clear a log message from insignificant parts
|
||||
|
||||
filter:
|
||||
- only filename, no path at the beginning
|
||||
- no line numbers after the filename
|
||||
"""
|
||||
|
||||
line = re.sub(SANITIZE_FILENAME_REGEX, r'\1\2', line)
|
||||
line = re.sub(SANITIZE_LINENUM_REGEX, r'\1:line:\3', line)
|
||||
return line
|
||||
|
||||
|
||||
def check_docs(language, target, log_file, known_warnings_file, out_sanitized_log_file):
|
||||
"""
|
||||
Check for Documentation warnings in `log_file`: should only contain (fuzzy) matches to `known_warnings_file`
|
||||
|
||||
It prints all unknown messages with `target`/`language` prefix
|
||||
It leaves `out_sanitized_log_file` file for observe and debug
|
||||
"""
|
||||
|
||||
# Sanitize all messages
|
||||
all_messages = list()
|
||||
with open(log_file) as f, open(out_sanitized_log_file, 'w') as o:
|
||||
for line in f:
|
||||
sanitized_line = sanitize_line(line)
|
||||
all_messages.append(LogMessage(line, sanitized_line))
|
||||
o.write(sanitized_line)
|
||||
|
||||
known_messages = list()
|
||||
with open(known_warnings_file) as k:
|
||||
for known_line in k:
|
||||
known_messages.append(known_line)
|
||||
|
||||
if "doxygen" in known_warnings_file:
|
||||
# Clean a known Doxygen limitation: it's expected to always document anonymous
|
||||
# structs/unions but we don't do this in our docs, so filter these all out with a regex
|
||||
# (this won't match any named field, only anonymous members -
|
||||
# ie the last part of the field is is just <something>::@NUM not <something>::name)
|
||||
RE_ANONYMOUS_FIELD = re.compile(r".+:line: warning: parameters of member [^:\s]+(::[^:\s]+)*(::@\d+)+ are not \(all\) documented")
|
||||
all_messages = [msg for msg in all_messages if not re.match(RE_ANONYMOUS_FIELD, msg.sanitized_text)]
|
||||
|
||||
# Collect all new messages that are not match with the known messages.
|
||||
# The order is an important.
|
||||
new_messages = list()
|
||||
known_idx = 0
|
||||
for msg in all_messages:
|
||||
try:
|
||||
known_idx = known_messages.index(msg.sanitized_text, known_idx)
|
||||
except ValueError:
|
||||
new_messages.append(msg)
|
||||
|
||||
if new_messages:
|
||||
print("\n%s/%s: Build failed due to new/different warnings (%s):\n" % (language, target, log_file))
|
||||
for msg in new_messages:
|
||||
print("%s/%s: %s" % (language, target, msg.original_text), end='')
|
||||
print("\n%s/%s: (Check files %s and %s for full details.)" % (language, target, known_warnings_file, log_file))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def action_linkcheck(args):
|
||||
return parallel_call(args, call_linkcheck)
|
||||
|
||||
|
||||
def call_linkcheck(entry):
|
||||
return sphinx_call(*entry, buildername="linkcheck")
|
||||
|
||||
|
||||
# https://github.com/espressif/esp-idf/tree/
|
||||
# https://github.com/espressif/esp-idf/blob/
|
||||
# https://github.com/espressif/esp-idf/raw/
|
||||
GH_LINK_RE = r"https://github.com/espressif/esp-idf/(?:tree|blob|raw)/[^\s]+"
|
||||
|
||||
# we allow this one link, because we always want users to see the latest support policy
|
||||
GH_LINK_ALLOWED = ["https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md"]
|
||||
|
||||
|
||||
def action_gh_linkcheck(args):
|
||||
print("Checking for hardcoded GitHub links\n")
|
||||
|
||||
github_links = []
|
||||
|
||||
docs_dir = os.path.relpath(os.path.dirname(__file__))
|
||||
for root, _, files in os.walk(docs_dir):
|
||||
if "_build" in root:
|
||||
continue
|
||||
files = [os.path.join(root, f) for f in files if f.endswith(".rst")]
|
||||
for path in files:
|
||||
with open(path, "r") as f:
|
||||
for link in re.findall(GH_LINK_RE, f.read()):
|
||||
if link not in GH_LINK_ALLOWED:
|
||||
github_links.append((path, link))
|
||||
|
||||
if github_links:
|
||||
for path, link in github_links:
|
||||
print("%s: %s" % (path, link))
|
||||
print("WARNING: Some .rst files contain hardcoded Github links.")
|
||||
print("Please check above output and replace links with one of the following:")
|
||||
print("- :idf:`dir` - points to directory inside ESP-IDF")
|
||||
print("- :idf_file:`file` - points to file inside ESP-IDF")
|
||||
print("- :idf_raw:`file` - points to raw view of the file inside ESP-IDF")
|
||||
print("- :component:`dir` - points to directory inside ESP-IDF components dir")
|
||||
print("- :component_file:`file` - points to file inside ESP-IDF components dir")
|
||||
print("- :component_raw:`file` - points to raw view of the file inside ESP-IDF components dir")
|
||||
print("- :example:`dir` - points to directory inside ESP-IDF examples dir")
|
||||
print("- :example_file:`file` - points to file inside ESP-IDF examples dir")
|
||||
print("- :example_raw:`file` - points to raw view of the file inside ESP-IDF examples dir")
|
||||
print("These link types will point to the correct GitHub version automatically")
|
||||
return 1
|
||||
else:
|
||||
print("No hardcoded links found")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Check for Documentation warnings:
|
||||
# doxygen-warning-log.txt should be an empty file
|
||||
# sphinx-warning-log.txt should only contain (fuzzy) matches to ../sphinx-known-warnings.txt
|
||||
RESULT=0
|
||||
STARS='***************************************************'
|
||||
|
||||
if [ -s doxygen-warning-log.txt ]; then
|
||||
echo "$STARS"
|
||||
echo "Build failed due to doxygen warnings:"
|
||||
cat doxygen-warning-log.txt
|
||||
echo "$STARS"
|
||||
RESULT=1
|
||||
fi
|
||||
|
||||
# Remove escape characters, file paths, line numbers from
|
||||
# the Sphinx warning log
|
||||
# (escape char removal from https://www.commandlinefu.com/commands/view/6141/remove-color-codes-special-characters-with-sed
|
||||
sed -r 's:\x1B\[[0-9;]*[mK]::g' sphinx-warning-log.txt | \
|
||||
sed -E "s/.*\/(.*):[0-9]+:/\1:line:/" > sphinx-warning-log-sanitized.txt
|
||||
|
||||
# diff sanitized warnings, ignoring lines which only appear in ../sphinx-known-warnings.txt
|
||||
|
||||
# format is to display only lines new or changed in second argument
|
||||
DIFF_FORMAT="--unchanged-line-format= --old-line-format= --new-line-format=%L"
|
||||
|
||||
SPHINX_WARNINGS=$(diff $DIFF_FORMAT ../sphinx-known-warnings.txt sphinx-warning-log-sanitized.txt)
|
||||
if ! [ -z "$SPHINX_WARNINGS" ]; then
|
||||
echo "$STARS"
|
||||
echo "Build failed due to new/different Sphinx warnings:"
|
||||
echo "$SPHINX_WARNINGS"
|
||||
echo "$STARS"
|
||||
RESULT=1
|
||||
echo "(Check files ../sphinx-known-warnings.txt and sphinx-warning-log.txt for full details.)"
|
||||
fi
|
||||
|
||||
exit $RESULT
|
||||
|
@@ -18,141 +18,15 @@ from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
# Note: If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute
|
||||
|
||||
from local_util import run_cmd_get_output, copy_if_modified
|
||||
from idf_extensions.util import download_file_if_missing
|
||||
|
||||
# build_docs on the CI server sometimes fails under Python3. This is a workaround:
|
||||
sys.setrecursionlimit(3500)
|
||||
|
||||
try:
|
||||
builddir = os.environ['BUILDDIR']
|
||||
except KeyError:
|
||||
builddir = '_build'
|
||||
|
||||
# Fill in a default IDF_PATH if it's missing (ie when Read The Docs is building the docs)
|
||||
try:
|
||||
idf_path = os.environ['IDF_PATH']
|
||||
except KeyError:
|
||||
idf_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
|
||||
def call_with_python(cmd):
|
||||
# using sys.executable ensures that the scripts are called with the same Python interpreter
|
||||
if os.system('{} {}'.format(sys.executable, cmd)) != 0:
|
||||
raise RuntimeError('{} failed'.format(cmd))
|
||||
|
||||
|
||||
# Call Doxygen to get XML files from the header files
|
||||
print("Calling Doxygen to generate latest XML files")
|
||||
if os.system("doxygen ../Doxyfile") != 0:
|
||||
raise RuntimeError('Doxygen call failed')
|
||||
|
||||
# Doxygen has generated XML files in 'xml' directory.
|
||||
# Copy them to 'xml_in', only touching the files which have changed.
|
||||
copy_if_modified('xml/', 'xml_in/')
|
||||
|
||||
# Generate 'api_name.inc' files using the XML files by Doxygen
|
||||
call_with_python('../gen-dxd.py')
|
||||
|
||||
|
||||
def find_component_files(parent_dir, target_filename):
|
||||
parent_dir = os.path.abspath(parent_dir)
|
||||
result = []
|
||||
|
||||
component_files = dict()
|
||||
|
||||
for (dirpath, dirnames, filenames) in os.walk(parent_dir):
|
||||
try:
|
||||
# note: trimming "examples" dir as MQTT submodule
|
||||
# has its own examples directory in the submodule, not part of IDF
|
||||
dirnames.remove("examples")
|
||||
except ValueError:
|
||||
pass
|
||||
if target_filename in filenames:
|
||||
component_files[os.path.basename(dirpath)] = os.path.join(dirpath, target_filename)
|
||||
|
||||
components = sorted(component_files.keys())
|
||||
|
||||
for component in components:
|
||||
result.append(component_files[component])
|
||||
|
||||
print("List of %s: %s" % (target_filename, ", ".join(components)))
|
||||
return result
|
||||
|
||||
|
||||
# Generate 'kconfig.inc' file from components' Kconfig files
|
||||
print("Generating kconfig.inc from kconfig contents")
|
||||
kconfig_inc_path = '{}/inc/kconfig.inc'.format(builddir)
|
||||
temp_sdkconfig_path = '{}/sdkconfig.tmp'.format(builddir)
|
||||
|
||||
kconfigs = find_component_files("../../components", "Kconfig")
|
||||
kconfig_projbuilds = find_component_files("../../components", "Kconfig.projbuild")
|
||||
sdkconfig_renames = find_component_files("../../components", "sdkconfig.rename")
|
||||
|
||||
kconfigs_source_path = '{}/inc/kconfigs_source.in'.format(builddir)
|
||||
kconfig_projbuilds_source_path = '{}/inc/kconfig_projbuilds_source.in'.format(builddir)
|
||||
|
||||
prepare_kconfig_files_args = [sys.executable,
|
||||
"../../tools/kconfig_new/prepare_kconfig_files.py",
|
||||
"--env", "COMPONENT_KCONFIGS={}".format(" ".join(kconfigs)),
|
||||
"--env", "COMPONENT_KCONFIGS_PROJBUILD={}".format(" ".join(kconfig_projbuilds)),
|
||||
"--env", "COMPONENT_KCONFIGS_SOURCE_FILE={}".format(kconfigs_source_path),
|
||||
"--env", "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE={}".format(kconfig_projbuilds_source_path),
|
||||
]
|
||||
subprocess.check_call(prepare_kconfig_files_args)
|
||||
|
||||
confgen_args = [sys.executable,
|
||||
"../../tools/kconfig_new/confgen.py",
|
||||
"--kconfig", "../../Kconfig",
|
||||
"--sdkconfig-rename", "../../sdkconfig.rename",
|
||||
"--config", temp_sdkconfig_path,
|
||||
"--env", "COMPONENT_KCONFIGS={}".format(" ".join(kconfigs)),
|
||||
"--env", "COMPONENT_KCONFIGS_PROJBUILD={}".format(" ".join(kconfig_projbuilds)),
|
||||
"--env", "COMPONENT_SDKCONFIG_RENAMES={}".format(" ".join(sdkconfig_renames)),
|
||||
"--env", "COMPONENT_KCONFIGS_SOURCE_FILE={}".format(kconfigs_source_path),
|
||||
"--env", "COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE={}".format(kconfig_projbuilds_source_path),
|
||||
"--env", "IDF_PATH={}".format(idf_path),
|
||||
"--env", "IDF_TARGET={}".format(os.environ.get('IDF_TARGET', 'esp32')),
|
||||
"--output", "docs", kconfig_inc_path + '.in'
|
||||
]
|
||||
subprocess.check_call(confgen_args)
|
||||
copy_if_modified(kconfig_inc_path + '.in', kconfig_inc_path)
|
||||
|
||||
# Generate 'esp_err_defs.inc' file with ESP_ERR_ error code definitions
|
||||
esp_err_inc_path = '{}/inc/esp_err_defs.inc'.format(builddir)
|
||||
call_with_python('../../tools/gen_esp_err_to_name.py --rst_output ' + esp_err_inc_path + '.in')
|
||||
copy_if_modified(esp_err_inc_path + '.in', esp_err_inc_path)
|
||||
|
||||
|
||||
# Generate version-related includes
|
||||
#
|
||||
# (Note: this is in a function as it needs to access configuration to get the language)
|
||||
def generate_version_specific_includes(app):
|
||||
print("Generating version-specific includes...")
|
||||
version_tmpdir = '{}/version_inc'.format(builddir)
|
||||
call_with_python('../gen-version-specific-includes.py {} {}'.format(app.config.language, version_tmpdir))
|
||||
copy_if_modified(version_tmpdir, '{}/inc'.format(builddir))
|
||||
|
||||
|
||||
# Generate toolchain download links
|
||||
print("Generating toolchain download links")
|
||||
base_url = 'https://dl.espressif.com/dl/'
|
||||
toolchain_tmpdir = '{}/toolchain_inc'.format(builddir)
|
||||
call_with_python('../gen-toolchain-links.py ../../tools/toolchain_versions.mk {} {}'.format(base_url, toolchain_tmpdir))
|
||||
copy_if_modified(toolchain_tmpdir, '{}/inc'.format(builddir))
|
||||
|
||||
print("Generating IDF Tools list")
|
||||
os.environ["IDF_MAINTAINER"] = "1"
|
||||
tools_rst = os.path.join(builddir, 'idf-tools-inc.rst')
|
||||
tools_rst_tmp = os.path.join(builddir, 'inc', 'idf-tools-inc.rst')
|
||||
call_with_python("{}/tools/idf_tools.py gen-doc --output {}".format(idf_path, tools_rst_tmp))
|
||||
copy_if_modified(tools_rst_tmp, tools_rst)
|
||||
config_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# http://stackoverflow.com/questions/12772927/specifying-an-online-image-in-sphinx-restructuredtext-format
|
||||
#
|
||||
@@ -160,23 +34,41 @@ suppress_warnings = ['image.nonlocal_uri']
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
idf_target = ''
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['breathe',
|
||||
'link-roles',
|
||||
|
||||
'sphinx.ext.todo',
|
||||
|
||||
'sphinxcontrib.blockdiag',
|
||||
'sphinxcontrib.seqdiag',
|
||||
'sphinxcontrib.actdiag',
|
||||
'sphinxcontrib.nwdiag',
|
||||
'sphinxcontrib.rackdiag',
|
||||
'sphinxcontrib.packetdiag',
|
||||
'html_redirects',
|
||||
'sphinx.ext.todo',
|
||||
|
||||
'extensions.html_redirects',
|
||||
'extensions.toctree_filter',
|
||||
|
||||
'idf_extensions.include_build_file',
|
||||
'idf_extensions.link_roles',
|
||||
'idf_extensions.build_system',
|
||||
'idf_extensions.esp_err_definitions',
|
||||
'idf_extensions.gen_toolchain_links',
|
||||
'idf_extensions.gen_version_specific_includes',
|
||||
'idf_extensions.kconfig_reference',
|
||||
'idf_extensions.run_doxygen',
|
||||
'idf_extensions.gen_idf_tools_links',
|
||||
'idf_extensions.format_idf_target',
|
||||
|
||||
# from https://github.com/pfalcon/sphinx_selective_exclude
|
||||
'sphinx_selective_exclude.eager_only',
|
||||
# TODO: determine if we need search_auto_exclude
|
||||
# 'sphinx_selective_exclude.search_auto_exclude',
|
||||
]
|
||||
|
||||
# sphinx.ext.todo extension parameters
|
||||
@@ -187,13 +79,6 @@ todo_include_todos = False
|
||||
# Enabling this fixes cropping of blockdiag edge labels
|
||||
seqdiag_antialias = True
|
||||
|
||||
# Breathe extension variables
|
||||
|
||||
# Doxygen regenerates files in 'xml/' directory every time,
|
||||
# but we copy files to 'xml_in/' only when they change, to speed up
|
||||
# incremental builds.
|
||||
breathe_projects = {"esp32-idf": "xml_in/"}
|
||||
breathe_default_project = "esp32-idf"
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -222,7 +107,7 @@ master_doc = 'index'
|
||||
# This is supposed to be "the short X.Y version", but it's the only version
|
||||
# visible when you open index.html.
|
||||
# Display full version to make things less confusing.
|
||||
version = run_cmd_get_output('git describe')
|
||||
version = subprocess.check_output(['git', 'describe']).strip().decode('utf-8')
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
# If needed, nearest tag is returned by 'git describe --abbrev=0'.
|
||||
release = version
|
||||
@@ -236,7 +121,45 @@ print('Version: {0} Release: {1}'.format(version, release))
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build','README.md']
|
||||
exclude_patterns = ['**/inc/**', '_static', '**/_build']
|
||||
|
||||
|
||||
# Add target-specific excludes based on tags (for the IDF_TARGET). Haven't found any better way to do this yet
|
||||
def update_exclude_patterns(tags):
|
||||
if "esp32" not in tags:
|
||||
# Exclude ESP32-only document pages so they aren't found in the initial search for .rst files
|
||||
# note: in toctrees, these also need to be marked with a :esp32: filter
|
||||
for e in ['api-guides/blufi.rst',
|
||||
'api-guides/build-system-legacy.rst',
|
||||
'api-guides/esp-ble-mesh/**',
|
||||
'api-guides/RF_calibration.rst', # temporary until support re-added in esp_wifi
|
||||
'api-guides/ulp-legacy.rst',
|
||||
'api-guides/unit-tests-legacy.rst',
|
||||
'api-guides/ulp_instruction_set.rst',
|
||||
'api-guides/jtag-debugging/configure-wrover.rst',
|
||||
'api-reference/system/himem.rst',
|
||||
'api-reference/bluetooth/**',
|
||||
'api-reference/peripherals/sdio_slave.rst',
|
||||
'api-reference/peripherals/esp_slave_protocol.rst',
|
||||
'api-reference/peripherals/mcpwm.rst',
|
||||
'api-reference/peripherals/sd_pullup_requirements.rst',
|
||||
'api-reference/peripherals/sdmmc_host.rst',
|
||||
'api-reference/protocols/esp_serial_slave_link.rst',
|
||||
'api-reference/system/ipc.rst',
|
||||
'get-started-legacy/**',
|
||||
'gnu-make-legacy.rst',
|
||||
'hw-reference/esp32/**',
|
||||
]:
|
||||
exclude_patterns.append(e)
|
||||
|
||||
if "esp32s2" not in tags:
|
||||
# Exclude ESP32-only document pages so they aren't found in the initial search for .rst files
|
||||
# note: in toctrees, these also need to be marked with a :esp32: filter
|
||||
for e in ['hw-reference/esp32s2/**',
|
||||
'api-guides/ulps2_instruction_set.rst',
|
||||
'api-reference/peripherals/temp_sensor.rst']:
|
||||
exclude_patterns.append(e)
|
||||
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
@@ -442,4 +365,36 @@ texinfo_documents = [
|
||||
# https://github.com/rtfd/sphinx_rtd_theme/pull/432
|
||||
def setup(app):
|
||||
app.add_stylesheet('theme_overrides.css')
|
||||
generate_version_specific_includes(app)
|
||||
app.add_config_value('idf_target', '', 'env')
|
||||
# Breathe extension variables (depend on build_dir)
|
||||
# note: we generate into xml_in and then copy_if_modified to xml dir
|
||||
app.config.breathe_projects = {"esp32-idf": os.path.join(app.config.build_dir, "xml_in/")}
|
||||
app.config.breathe_default_project = "esp32-idf"
|
||||
|
||||
setup_diag_font(app)
|
||||
|
||||
|
||||
def setup_diag_font(app):
|
||||
# blockdiag and other tools require a font which supports their character set
|
||||
# the font file is stored on the download server to save repo size
|
||||
|
||||
font_name = {
|
||||
'en': 'DejaVuSans.ttf',
|
||||
'zh_CN': 'NotoSansSC-Regular.otf',
|
||||
}[app.config.language]
|
||||
|
||||
font_dir = os.path.join(config_dir, '_static')
|
||||
assert os.path.exists(font_dir)
|
||||
|
||||
print("Downloading font file %s for %s" % (font_name, app.config.language))
|
||||
download_file_if_missing('https://dl.espressif.com/dl/esp-idf/docs/_static/{}'.format(font_name), font_dir)
|
||||
|
||||
font_path = os.path.abspath(os.path.join(font_dir, font_name))
|
||||
assert os.path.exists(font_path)
|
||||
|
||||
app.config.blockdiag_fontpath = font_path
|
||||
app.config.seqdiag_fontpath = font_path
|
||||
app.config.actdiag_fontpath = font_path
|
||||
app.config.nwdiag_fontpath = font_path
|
||||
app.config.rackdiag_fontpath = font_path
|
||||
app.config.packetdiag_fontpath = font_path
|
||||
|
@@ -1,217 +0,0 @@
|
||||
# "Common" Makefile for Sphinx documentation
|
||||
#
|
||||
# (included from en/Makefile & zh_CN/Makefile
|
||||
#
|
||||
# NOTE: This makefile runs with cwd=either en or zh_CN subfolder, so this
|
||||
# (docs/) directory is '..' relative to it.
|
||||
|
||||
# ************ IMPORTANT *****************
|
||||
#
|
||||
# ReadTheDocs DOES NOT USE THIS MAKEFILE,
|
||||
# so any behaviour additions must be
|
||||
# done via Sphinx Config not here
|
||||
#
|
||||
# ****************************************
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
# note: this is changed from sphinx-build so it depends on default python interpreter, not on /bin/sphinx-build
|
||||
# (which will be the most recently installed version of sphinx and may not match)
|
||||
SPHINXBUILD = python -m sphinx
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) -w sphinx-warning-log.txt .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext dependencies version-specific-includes check_python_packages
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>\' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled) "
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
# Notify users when some of the required python packages are not installed.
|
||||
# Note: This is intended to help developers who generate the documentation on their local machine. Read The Docs uses
|
||||
# the requirements.txt file directly and calls sphinx also directly without the use of the makefile!
|
||||
check_python_packages:
|
||||
$(IDF_PATH)/tools/check_python_dependencies.py -r $(IDF_PATH)/docs/requirements.txt
|
||||
|
||||
html: | check_python_packages
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml: | check_python_packages
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml: | check_python_packages
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle: | check_python_packages
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json: | check_python_packages
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp: | check_python_packages
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp: | check_python_packages
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ReadtheDocsTemplate.qhc"
|
||||
|
||||
devhelp: | check_python_packages
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ReadtheDocsTemplate"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub: | check_python_packages
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex: | check_python_packages
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf: | check_python_packages
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja: | check_python_packages
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text: | check_python_packages
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man: | check_python_packages
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo: | check_python_packages
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info: | check_python_packages
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext: | check_python_packages
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes: | check_python_packages
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck: | check_python_packages
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
gh-linkcheck: | check_python_packages
|
||||
@echo "Checking for hardcoded GitHub links" # note: exception for links to support policy doc as we *want* this to be a link to master's policy
|
||||
@if (find ../ -name '*.rst' | xargs grep \
|
||||
'https://github.com/espressif/esp-idf/tree\|https://github.com/espressif/esp-idf/blob\|https://github.com/espressif/esp-idf/raw' \
|
||||
| grep -v 'SUPPORT_POLICY\.md' \
|
||||
); \
|
||||
then \
|
||||
echo "WARNINIG: Some .rst files contain hardcoded Github links."; \
|
||||
echo "Please check above output and replace links with one of the following:"; \
|
||||
echo "- :idf:\`dir\` - points to directory inside ESP-IDF"; \
|
||||
echo "- :idf_file:\`file\` - points to file inside ESP-IDF"; \
|
||||
echo "- :idf_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \
|
||||
echo "- :component:\`dir\` - points to directory inside ESP-IDF components dir"; \
|
||||
echo "- :component_file:\`file\` - points to file inside ESP-IDF components dir"; \
|
||||
echo "- :component_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \
|
||||
echo " components dir"; \
|
||||
echo "- :example:\`dir\` - points to directory inside ESP-IDF examples dir"; \
|
||||
echo "- :example_file:\`file\` - points to file inside ESP-IDF examples dir"; \
|
||||
echo "- :example_raw:\`file\` - points to raw view of the file inside ESP-IDF"; \
|
||||
echo " examples dir"; \
|
||||
echo "These link types will point to the correct GitHub version automatically"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "No hardcoded links found"
|
||||
|
||||
doctest: | check_python_packages
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
xml: | check_python_packages
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml: | check_python_packages
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
1
docs/doxygen-known-warnings.txt
Normal file
1
docs/doxygen-known-warnings.txt
Normal file
@@ -0,0 +1 @@
|
||||
semphr.h:line: warning: argument 'pxStaticSemaphore' of command @param is not found in the argument list of xSemaphoreCreateCounting(uxMaxCount, uxInitialCount)
|
@@ -1,2 +0,0 @@
|
||||
LANGUAGE=en
|
||||
include ../docs_common.mk
|
@@ -2,9 +2,18 @@ About
|
||||
=====
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
This is documentation of `ESP-IDF <https://github.com/espressif/esp-idf>`_, the framework to develop applications for `ESP32 <https://espressif.com/en/products/hardware/esp32/overview>`_ chip by `Espressif <https://espressif.com>`_.
|
||||
.. only:: esp32
|
||||
|
||||
The ESP32 is 2.4 GHz Wi-Fi and Bluetooth combo, which integrates one or two 32-bit microprocessors, with up to 600 DMIPS processing power.
|
||||
This is documentation of `ESP-IDF <https://github.com/espressif/esp-idf>`_, the framework to develop applications for `{IDF_TARGET_NAME} <https://espressif.com/en/products/hardware/esp32/overview>`_ chip by `Espressif <https://espressif.com>`_.
|
||||
|
||||
The {IDF_TARGET_NAME} is 2.4 GHz Wi-Fi and Bluetooth combo, which integrates one or two 32-bit microprocessors, with up to 600 DMIPS processing power.
|
||||
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
This is documentation of `ESP-IDF <https://github.com/espressif/esp-idf>`_, the framework to develop applications for {IDF_TARGET_NAME}.
|
||||
|
||||
The {IDF_TARGET_NAME} is a 2.4 GHz Wi-Fi module, which integrates a 32-bit microprocessors, with up to 600 DMIPS processing power.
|
||||
|
||||
.. figure:: ../_static/about-doc.png
|
||||
:align: center
|
||||
@@ -13,5 +22,5 @@ The ESP32 is 2.4 GHz Wi-Fi and Bluetooth combo, which integrates one or two 32-b
|
||||
|
||||
Espressif IoT Integrated Development Framework
|
||||
|
||||
The ESP-IDF, Espressif IoT Development Framework, provides toolchain, API, components and workflows to develop applications for ESP32 using Windows, Linux and Mac OS operating systems.
|
||||
The ESP-IDF, Espressif IoT Development Framework, provides toolchain, API, components and workflows to develop applications for {IDF_TARGET_NAME} using Windows, Linux and Mac OS operating systems.
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
RF calibration
|
||||
==============
|
||||
|
||||
ESP32 supports three RF calibration methods during RF initialization:
|
||||
{IDF_TARGET_NAME} supports three RF calibration methods during RF initialization:
|
||||
|
||||
1. Partial calibration
|
||||
|
||||
@@ -11,8 +11,8 @@ ESP32 supports three RF calibration methods during RF initialization:
|
||||
|
||||
Partial calibration
|
||||
-------------------
|
||||
During RF initialization, the partial calibration method is used by default for RF calibration.
|
||||
It is done based on the full calibration data which is stored in the NVS.
|
||||
During RF initialization, the partial calibration method is used by default for RF calibration.
|
||||
It is done based on the full calibration data which is stored in the NVS.
|
||||
To use this method, please go to ``menuconfig`` and enable :ref:`CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE`.
|
||||
|
||||
Full calibration
|
||||
@@ -20,8 +20,8 @@ Full calibration
|
||||
Full calibration is triggered in the follwing conditions:
|
||||
|
||||
1. NVS does not exist.
|
||||
|
||||
2. The NVS partition to store calibration data is erased.
|
||||
|
||||
2. The NVS partition to store calibration data is erased.
|
||||
|
||||
3. Hardware MAC address is changed.
|
||||
|
||||
@@ -29,31 +29,32 @@ Full calibration is triggered in the follwing conditions:
|
||||
|
||||
5. The RF calibration data loaded from the NVS partition is broken.
|
||||
|
||||
It takes about 100ms more than partial calibration.
|
||||
If boot duration is not critical, it is suggested to use the full calibration method.
|
||||
To switch to the full calibration method, go to ``menuconfig`` and disable :ref:`CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE`.
|
||||
It takes about 100ms more than partial calibration.
|
||||
If boot duration is not critical, it is suggested to use the full calibration method.
|
||||
To switch to the full calibration method, go to ``menuconfig`` and disable :ref:`CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE`.
|
||||
If you use the default method of RF calibration, there are two ways to add the function of triggering full calibration as a last-resort remedy.
|
||||
|
||||
1. Erase the NVS partition if you don't mind all of the data stored in the NVS partition is erased. That is indeed the easiest way.
|
||||
|
||||
2. Call API :cpp:func:`esp_phy_erase_cal_data_in_nvs` before initializing WiFi and BT/BLE based on some conditions (e.g. an option provided in some diagnostic mode).
|
||||
2. Call API :cpp:func:`esp_phy_erase_cal_data_in_nvs` before initializing WiFi and BT/BLE based on some conditions (e.g. an option provided in some diagnostic mode).
|
||||
In this case, only phy namespace of the NVS partition is erased.
|
||||
|
||||
No calibration
|
||||
---------------
|
||||
No calibration method is only used when ESP32 wakes up from deep sleep.
|
||||
No calibration method is only used when {IDF_TARGET_NAME} wakes up from deep sleep.
|
||||
|
||||
PHY initialization data
|
||||
-----------------------
|
||||
The PHY initialization data is used for RF calibration.
|
||||
There are two ways to get the PHY initialization data.
|
||||
The PHY initialization data is used for RF calibration.
|
||||
There are two ways to get the PHY initialization data.
|
||||
|
||||
One is the default initialization data which is located in the header file :idf_file:`components/esp_wifi/esp32/include/phy_init_data.h`.
|
||||
It is embedded into the application binary after compiling and then stored into read-only memory (DROM).
|
||||
To use the default initialization data, please go to ``menuconfig`` and disable :ref:`CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION`.
|
||||
One is the default initialization data which is located in the header file :idf_file:`components/esp_wifi/{IDF_TARGET_PATH_NAME}/include/phy_init_data.h`.
|
||||
|
||||
Another is the initialization data which is stored in a partition.
|
||||
When using a custom partition table, make sure that PHY data partition is included (type: `data`, subtype: `phy`).
|
||||
With default partition table, this is done automatically.
|
||||
If initialization data is stored in a partition, it has to be flashed there, otherwise runtime error will occur.
|
||||
It is embedded into the application binary after compiling and then stored into read-only memory (DROM).
|
||||
To use the default initialization data, please go to ``menuconfig`` and disable :ref:`CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION`.
|
||||
|
||||
Another is the initialization data which is stored in a partition.
|
||||
When using a custom partition table, make sure that PHY data partition is included (type: `data`, subtype: `phy`).
|
||||
With default partition table, this is done automatically.
|
||||
If initialization data is stored in a partition, it has to be flashed there, otherwise runtime error will occur.
|
||||
To switch to the initialization data stored in a partition, go to ``menuconfig`` and enable :ref:`CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION`.
|
||||
|
@@ -5,7 +5,7 @@ Application Level Tracing library
|
||||
Overview
|
||||
--------
|
||||
|
||||
IDF provides useful feature for program behavior analysis: application level tracing. It is implemented in the corresponding library and can be enabled in menuconfig. This feature allows to transfer arbitrary data between host and ESP32 via JTAG interface with small overhead on program execution.
|
||||
IDF provides useful feature for program behavior analysis: application level tracing. It is implemented in the corresponding library and can be enabled in menuconfig. This feature allows to transfer arbitrary data between host and {IDF_TARGET_NAME} via JTAG interface with small overhead on program execution.
|
||||
|
||||
Developers can use this library to send application specific state of execution to the host and receive commands or other type of info in the opposite direction at runtime. The main use cases of this library are:
|
||||
|
||||
@@ -31,7 +31,7 @@ The library supports two modes of operation:
|
||||
|
||||
**Post-mortem mode**. This is the default mode. The mode does not need interaction with the host side. In this mode tracing module does not check whether host has read all the data from *HW UP BUFFER* buffer and overwrites old data with the new ones. This mode is useful when only the latest trace data are interesting to the user, e.g. for analyzing program's behavior just before the crash. Host can read the data later on upon user request, e.g. via special OpenOCD command in case of working via JTAG interface.
|
||||
|
||||
**Streaming mode.** Tracing module enters this mode when host connects to ESP32. In this mode before writing new data to *HW UP BUFFER* tracing module checks that there is enough space in it and if necessary waits for the host to read data and free enough memory. Maximum waiting time is controlled via timeout values passed by users to corresponding API routines. So when application tries to write data to trace buffer using finite value of the maximum waiting time it is possible situation that this data will be dropped. Especially this is true for tracing from time critical code (ISRs, OS scheduler code etc.) when infinite timeouts can lead to system malfunction. In order to avoid loss of such critical data developers can enable additional data buffering via menuconfig option :ref:`CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX`. This macro specifies the size of data which can be buffered in above conditions. The option can also help to overcome situation when data transfer to the host is temporarily slowed down, e.g due to USB bus congestions etc. But it will not help when average bitrate of trace data stream exceeds HW interface capabilities.
|
||||
**Streaming mode.** Tracing module enters this mode when host connects to {IDF_TARGET_NAME}. In this mode before writing new data to *HW UP BUFFER* tracing module checks that there is enough space in it and if necessary waits for the host to read data and free enough memory. Maximum waiting time is controlled via timeout values passed by users to corresponding API routines. So when application tries to write data to trace buffer using finite value of the maximum waiting time it is possible situation that this data will be dropped. Especially this is true for tracing from time critical code (ISRs, OS scheduler code etc.) when infinite timeouts can lead to system malfunction. In order to avoid loss of such critical data developers can enable additional data buffering via menuconfig option :ref:`CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX`. This macro specifies the size of data which can be buffered in above conditions. The option can also help to overcome situation when data transfer to the host is temporarily slowed down, e.g due to USB bus congestions etc. But it will not help when average bitrate of trace data stream exceeds HW interface capabilities.
|
||||
|
||||
|
||||
Configuration Options and Dependencies
|
||||
@@ -55,7 +55,7 @@ There are two additional menuconfig options not mentioned above:
|
||||
How to use this library
|
||||
-----------------------
|
||||
|
||||
This library provides API for transferring arbitrary data between host and ESP32. When enabled in menuconfig target application tracing module is initialized automatically at the system startup, so all what the user needs to do is to call corresponding API to send, receive or flush the data.
|
||||
This library provides API for transferring arbitrary data between host and {IDF_TARGET_NAME}. When enabled in menuconfig target application tracing module is initialized automatically at the system startup, so all what the user needs to do is to call corresponding API to send, receive or flush the data.
|
||||
|
||||
.. _app_trace-application-specific-tracing:
|
||||
|
||||
@@ -192,7 +192,7 @@ Start command syntax:
|
||||
``outfile``
|
||||
Path to file to save data from both CPUs. This argument should have the following format: ``file://path/to/file``.
|
||||
``poll_period``
|
||||
Data polling period (in ms) for available trace data. If greater than 0 then command runs in non-blocking mode. By default 1 ms.
|
||||
Data polling period (in ms) for available trace data. If greater than 0 then command runs in non-blocking mode. By default 1 ms.
|
||||
``trace_size``
|
||||
Maximum size of data to collect (in bytes). Tracing is stopped after specified amount of data is received. By default -1 (trace size stop trigger is disabled).
|
||||
``stop_tmo``
|
||||
@@ -216,7 +216,7 @@ Command usage examples:
|
||||
|
||||
esp32 apptrace start file://trace.log 1 2048 5 0 0
|
||||
|
||||
The tracing data will be retrieved and saved in non-blocking mode. This process will stop automatically after 2048 bytes are collected, or if no data are available for more than 5 seconds.
|
||||
The tracing data will be retrieved and saved in non-blocking mode. This process will stop automatically after 2048 bytes are collected, or if no data are available for more than 5 seconds.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -326,7 +326,7 @@ How To Use It
|
||||
|
||||
Support for this feature is enabled by *Component config > Application Level Tracing > FreeRTOS SystemView Tracing* (:ref:`CONFIG_SYSVIEW_ENABLE`) menuconfig option. There are several other options enabled under the same menu:
|
||||
|
||||
1. *ESP32 timer to use as SystemView timestamp source* (:ref:`CONFIG_SYSVIEW_TS_SOURCE`) selects the source of timestamps for SystemView events. In single core mode timestamps are generated using ESP32 internal cycle counter running at maximum 240 Mhz (~4 ns granularity). In dual-core mode external timer working at 40 Mhz is used, so timestamp granularity is 25 ns.
|
||||
1. {IDF_TARGET_NAME} timer to use as SystemView timestamp source: (:ref:`CONFIG_SYSVIEW_TS_SOURCE`) selects the source of timestamps for SystemView events. In single core mode timestamps are generated using {IDF_TARGET_NAME} internal cycle counter running at maximum 240 Mhz (~4 ns granularity). In dual-core mode external timer working at 40 Mhz is used, so timestamp granularity is 25 ns.
|
||||
2. Individually enabled or disabled collection of SystemView events (``CONFIG_SYSVIEW_EVT_XXX``):
|
||||
|
||||
- Trace Buffer Overflow Event
|
||||
@@ -340,7 +340,7 @@ Support for this feature is enabled by *Component config > Application Level Tra
|
||||
- Task Create Event
|
||||
- Task Terminate Event
|
||||
- System Idle Event
|
||||
- Timer Enter Event
|
||||
- Timer Enter Event
|
||||
- Timer Exit Event
|
||||
|
||||
IDF has all the code required to produce SystemView compatible traces, so user can just configure necessary project options (see above), build, download the image to target and use OpenOCD to collect data as described in the previous sections.
|
||||
@@ -371,7 +371,7 @@ Start command syntax:
|
||||
``outfile2``
|
||||
Path to file to save data from APP CPU. This argument should have the following format: ``file://path/to/file``.
|
||||
``poll_period``
|
||||
Data polling period (in ms) for available trace data. If greater then 0 then command runs in non-blocking mode. By default 1 ms.
|
||||
Data polling period (in ms) for available trace data. If greater then 0 then command runs in non-blocking mode. By default 1 ms.
|
||||
``trace_size``
|
||||
Maximum size of data to collect (in bytes). Tracing is stopped after specified amount of data is received. By default -1 (trace size stop trigger is disabled).
|
||||
``stop_tmo``
|
||||
@@ -405,7 +405,7 @@ Command usage examples:
|
||||
Data Visualization
|
||||
""""""""""""""""""
|
||||
|
||||
After trace data are collected user can use special tool to visualize the results and inspect behavior of the program. Unfortunately SystemView does not support tracing from multiple cores. So when tracing from ESP32 working in dual-core mode two files are generated: one for PRO CPU and another one for APP CPU. User can load every file into separate instance of the tool.
|
||||
After trace data are collected user can use special tool to visualize the results and inspect behavior of the program. Unfortunately SystemView does not support tracing from multiple cores. So when tracing from {IDF_TARGET_NAME} working in dual-core mode two files are generated: one for PRO CPU and another one for APP CPU. User can load every file into separate instance of the tool.
|
||||
|
||||
It is uneasy and awkward to analyze data for every core in separate instance of the tool. Fortunately there is Eclipse plugin called *Impulse* which can load several trace files and makes it possible to inspect events from both cores in one view. Also this plugin has no limitation of 1,000,000 events as compared to free version of SystemView.
|
||||
|
||||
@@ -501,7 +501,7 @@ The dumping of coverage data is done via OpenOCD (see :doc:`JTAG Debugging <../a
|
||||
|
||||
When the target dumps code coverage data, the ``.gcda`` files are stored in the project's build directory. For example, if ``gcov_example_main.c`` of the ``main`` component was compiled with the ``--coverage`` option, then dumping the code coverage data would generate a ``gcov_example_main.gcda`` in ``build/esp-idf/main/CMakeFiles/__idf_main.dir/gcov_example_main.c.gcda`` (or ``build/main/gcov_example_main.gcda`` if using the legacy Make build system). Note that the ``.gcno`` files produced during compilation are also placed in the same directory.
|
||||
|
||||
The dumping of code coverage data can be done multiple times throughout an application's life time. Each dump will simply update the ``.gcda`` file with the newest code coverage information. Code coverage data is accumulative, thus the newest data will contain the total execution count of each code path over the application's entire lifetime.
|
||||
The dumping of code coverage data can be done multiple times throughout an application's life time. Each dump will simply update the ``.gcda`` file with the newest code coverage information. Code coverage data is accumulative, thus the newest data will contain the total execution count of each code path over the application's entire lifetime.
|
||||
|
||||
ESP-IDF supports two methods of dumping code coverage data form the target to the host:
|
||||
|
||||
@@ -511,15 +511,12 @@ ESP-IDF supports two methods of dumping code coverage data form the target to th
|
||||
Instant Run-Time Dump
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An Instant Run-Time Dump is triggered by calling the ``esp32 gcov`` OpenOCD command (via a telnet session). Once called, OpenOCD will immediately preempt the ESP32's current state and execute a builtin IDF Gcov debug stub function. The debug stub function will handle the dumping of data to the Host. Upon completion, the ESP32 will resume it's current state.
|
||||
|
||||
.. note::
|
||||
Due to the use of the debug stub function, the OpenOCD Debug Stub option must be enabled in project configuration. The option can be found under ``Component config -> ESP32-specific -> OpenOCD debug stubs``.
|
||||
An Instant Run-Time Dump is triggered by calling the ``esp32 gcov`` OpenOCD command (via a telnet session). Once called, OpenOCD will immediately preempt the {IDF_TARGET_NAME}'s current state and execute a builtin IDF Gcov debug stub function. The debug stub function will handle the dumping of data to the Host. Upon completion, the {IDF_TARGET_NAME} will resume it's current state.
|
||||
|
||||
Hard-coded Dump
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
A Hard-coded Dump is triggered by the application itself by calling :cpp:func:`esp_gcov_dump` from somewhere within the application. When called, the application will halt and wait for OpenOCD to connect and retrieve the code coverage data. Once :cpp:func:`esp_gcov_dump` is called, the Host must execute the ``esp32 gcov dump`` OpenOCD command (via a telnet session). The ``esp32 gcov dump`` command will cause OpenOCD to connect to the ESP32, retrieve the code coverage data, then disconnect from the ESP32 thus allowing the application to resume. Hard-coded Dumps can also be triggered multiple times throughout an application's lifetime.
|
||||
A Hard-coded Dump is triggered by the application itself by calling :cpp:func:`esp_gcov_dump` from somewhere within the application. When called, the application will halt and wait for OpenOCD to connect and retrieve the code coverage data. Once :cpp:func:`esp_gcov_dump` is called, the Host must execute the ``esp32 gcov dump`` OpenOCD command (via a telnet session). The ``esp32 gcov dump`` command will cause OpenOCD to connect to the {IDF_TARGET_NAME}, retrieve the code coverage data, then disconnect from the {IDF_TARGET_NAME} thus allowing the application to resume. Hard-coded Dumps can also be triggered multiple times throughout an application's lifetime.
|
||||
|
||||
Hard-coded dumps are useful if code coverage data is required at certain points of an application's lifetime by placing :cpp:func:`esp_gcov_dump` where necessary (e.g., after application initialization, during each iteration of an application's main loop).
|
||||
|
||||
|
@@ -4,7 +4,7 @@ BluFi
|
||||
|
||||
Overview
|
||||
--------
|
||||
The BluFi for ESP32 is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to the ESP32. Using this information ESP32 can then e.g. connect to an AP or establish a SoftAP.
|
||||
The BluFi for {IDF_TARGET_NAME} is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to the {IDF_TARGET_NAME}. Using this information {IDF_TARGET_NAME} can then e.g. connect to an AP or establish a SoftAP.
|
||||
|
||||
Fragmenting, data encryption, checksum verification in the BluFi layer are the key elements of this process.
|
||||
|
||||
@@ -16,29 +16,29 @@ The BluFi networking flow includes the configuration of the SoftAP and Station.
|
||||
|
||||
The following uses Station as an example to illustrate the core parts of the procedure, including broadcast, connection, service discovery, negotiation of the shared key, data transmission, connection status backhaul.
|
||||
|
||||
1. Set the ESP32 into GATT Server mode and then it will send broadcasts with specific *advertising data*. You can customize this broadcast as needed, which is not a part of the BluFi Profile.
|
||||
1. Set the {IDF_TARGET_NAME} into GATT Server mode and then it will send broadcasts with specific *advertising data*. You can customize this broadcast as needed, which is not a part of the BluFi Profile.
|
||||
|
||||
2. Use the App installed on the mobile phone to search for this particular broadcast. The mobile phone will connect to ESP32 as the GATT Client once the broadcast is confirmed. The App used during this part is up to you.
|
||||
2. Use the App installed on the mobile phone to search for this particular broadcast. The mobile phone will connect to {IDF_TARGET_NAME} as the GATT Client once the broadcast is confirmed. The App used during this part is up to you.
|
||||
|
||||
3. After the GATT connection is successfully established, the mobile phone will send a data frame for key negotiation to ESP32 (see the section :ref:`frame_formats` for details).
|
||||
3. After the GATT connection is successfully established, the mobile phone will send a data frame for key negotiation to {IDF_TARGET_NAME} (see the section :ref:`frame_formats` for details).
|
||||
|
||||
4. After ESP32 receives the data frame of key negotiation, it will parse the content according to the user-defined negotiation method.
|
||||
4. After {IDF_TARGET_NAME} receives the data frame of key negotiation, it will parse the content according to the user-defined negotiation method.
|
||||
|
||||
5. The mobile phone works with ESP32 for key negotiation using the encryption algorithms such as DH, RSA or ECC.
|
||||
5. The mobile phone works with {IDF_TARGET_NAME} for key negotiation using the encryption algorithms such as DH, RSA or ECC.
|
||||
|
||||
6. After the negotiation process is completed, the mobile phone will send a control frame for security-mode setup to ESP32.
|
||||
6. After the negotiation process is completed, the mobile phone will send a control frame for security-mode setup to {IDF_TARGET_NAME}.
|
||||
|
||||
7. When receiving this control frame, ESP32 will be able to encrypt and decrypt the communication data using the shared key and the security configuration.
|
||||
7. When receiving this control frame, {IDF_TARGET_NAME} will be able to encrypt and decrypt the communication data using the shared key and the security configuration.
|
||||
|
||||
8. The mobile phone sends the data frame defined in the section of :ref:`frame_formats`,with the Wi-Fi configuration information to ESP32, including SSID, password, etc.
|
||||
8. The mobile phone sends the data frame defined in the section of :ref:`frame_formats`,with the Wi-Fi configuration information to {IDF_TARGET_NAME}, including SSID, password, etc.
|
||||
|
||||
9. The mobile phone sends a control frame of Wi-Fi connection request to ESP32. When receiving this control frame, ESP32 will regard the communication of essential information as done and get ready to connect to the Wi-Fi.
|
||||
9. The mobile phone sends a control frame of Wi-Fi connection request to {IDF_TARGET_NAME}. When receiving this control frame, {IDF_TARGET_NAME} will regard the communication of essential information as done and get ready to connect to the Wi-Fi.
|
||||
|
||||
10. After connecting to the Wi-Fi, ESP32 will send a control frame of Wi-Fi connection status report to the mobile phone,to report the connection status. At this point the networking procedure is completed.
|
||||
10. After connecting to the Wi-Fi, {IDF_TARGET_NAME} will send a control frame of Wi-Fi connection status report to the mobile phone,to report the connection status. At this point the networking procedure is completed.
|
||||
|
||||
.. note::
|
||||
|
||||
1. After ESP32 receives the control frame of security-mode configuration, it will execute the operations in accordance with the defined security mode.
|
||||
1. After {IDF_TARGET_NAME} receives the control frame of security-mode configuration, it will execute the operations in accordance with the defined security mode.
|
||||
|
||||
2. The data lengths before and after symmetric encryption/decryption must stay the same. It also supports in-place encryption and decryption.
|
||||
|
||||
@@ -55,18 +55,18 @@ The flow chart of BluFi
|
||||
node_height = 60;
|
||||
edge_length = 380;
|
||||
span_height = 10;
|
||||
default_fontsize = 12;
|
||||
default_fontsize = 12;
|
||||
|
||||
Phone <- ESP32 [label="Advertising"];
|
||||
Phone -> ESP32 [label="Create GATT connection"];
|
||||
Phone <- ESP32 [label="Negotiate key procedure"];
|
||||
Phone -> ESP32 [label="Negotiate key procedure"];
|
||||
Phone -> ESP32 [label="CTRL: Set ESP32 to Phone Security mode"];
|
||||
Phone -> ESP32 [label="DATA: SSID"];
|
||||
Phone -> ESP32 [label="DATA: Password"];
|
||||
Phone -> ESP32 [label="DATA: Other information, such as CA certification"];
|
||||
Phone -> ESP32 [label="CTRL: Connect to AP"];
|
||||
Phone <- ESP32 [label="DATA: Connection State Report"];
|
||||
Phone <- {IDF_TARGET_NAME} [label="Advertising"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="Create GATT connection"];
|
||||
Phone <- {IDF_TARGET_NAME} [label="Negotiate key procedure"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="Negotiate key procedure"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="CTRL: Set {IDF_TARGET_NAME} to Phone Security mode"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="DATA: SSID"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="DATA: Password"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="DATA: Other information, such as CA certification"];
|
||||
Phone -> {IDF_TARGET_NAME} [label="CTRL: Connect to AP"];
|
||||
Phone <- {IDF_TARGET_NAME} [label="DATA: Connection State Report"];
|
||||
}
|
||||
|
||||
.. _frame_formats:
|
||||
@@ -74,7 +74,7 @@ The flow chart of BluFi
|
||||
The Frame Formats Defined in BluFi
|
||||
-----------------------------------
|
||||
|
||||
The frame formats for the communication between the mobile phone App and ESP32 are defined as follows:
|
||||
The frame formats for the communication between the mobile phone App and {IDF_TARGET_NAME} are defined as follows:
|
||||
|
||||
The frame format with no fragment (8 bit):
|
||||
|
||||
@@ -144,8 +144,8 @@ The format of Ack Frame(8 bit):
|
||||
* The control frame is not encrypted for the time being and supports to be verified;
|
||||
|
||||
* The data frame supports to be encrypted and verified.
|
||||
|
||||
**1.1 Control Frame (0x0 b’00)**
|
||||
|
||||
**1.1 Control Frame (0x0 b’00)**
|
||||
|
||||
+-------------------------+--------------------------------------------------------------+---------------------------------------------------------------+---------------------------------------------------------------+
|
||||
| Control Frame (Binary) | Implication | Explanation | Note |
|
||||
@@ -391,8 +391,8 @@ The format of Ack Frame(8 bit):
|
||||
|
||||
This field takes 2 bytes that is used to check "sequence + data length + clear text data".
|
||||
|
||||
The Security Implementation of ESP32
|
||||
-------------------------------------
|
||||
The Security Implementation of {IDF_TARGET_NAME}
|
||||
------------------------------------------------
|
||||
|
||||
1. Securing data
|
||||
|
||||
@@ -410,15 +410,15 @@ The Security Implementation of ESP32
|
||||
|
||||
It is added to the Sequence field and used during the checksum verification.
|
||||
|
||||
For the coding of ESP32, you can determine and develop the security processing, such as key negotiation. The mobile application sends the negotiation data to ESP32 and then the data will be sent to the application layer for processing. If the application layer does not process it, you can use the DH encryption algorithm provided by BluFi to negotiate the key.
|
||||
|
||||
For the coding of {IDF_TARGET_NAME}, you can determine and develop the security processing, such as key negotiation. The mobile application sends the negotiation data to {IDF_TARGET_NAME} and then the data will be sent to the application layer for processing. If the application layer does not process it, you can use the DH encryption algorithm provided by BluFi to negotiate the key.
|
||||
|
||||
The application layer needs to register several security-related functions to BluFi:
|
||||
|
||||
.. code-block:: c
|
||||
.. code-block:: c
|
||||
|
||||
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free)
|
||||
|
||||
This function is for ESP32 to receive normal data during negotiation, and after processing is completed, the data will be transmitted using Output_data and Output_len.
|
||||
This function is for {IDF_TARGET_NAME} to receive normal data during negotiation, and after processing is completed, the data will be transmitted using Output_data and Output_len.
|
||||
|
||||
BluFi will send output_data from Negotiate_data_handler after Negotiate_data_handler is called.
|
||||
|
||||
@@ -426,7 +426,7 @@ Here are two "*", because the length of the data to be emitted is unknown that r
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len)
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len)
|
||||
|
||||
The data to be encrypted and decrypted must use the same length. The IV8 is a 8 bit sequence value of frames, which can be used as a 8 bit of IV.
|
||||
|
||||
@@ -450,6 +450,6 @@ UUID
|
||||
|
||||
BluFi Service UUID: 0xFFFF,16 bit
|
||||
|
||||
BluFi (the mobile -> ESP32): 0xFF01, writable
|
||||
BluFi (the mobile -> {IDF_TARGET_NAME}): 0xFF01, writable
|
||||
|
||||
Blufi (ESP32 -> the mobile phone): 0xFF02, readable and callable
|
||||
Blufi ({IDF_TARGET_NAME} -> the mobile phone): 0xFF02, readable and callable
|
||||
|
@@ -22,7 +22,7 @@ Overview
|
||||
An ESP-IDF project can be seen as an amalgamation of a number of components.
|
||||
For example, for a webserver that shows the current humidity, there could be:
|
||||
|
||||
- The ESP32 base libraries (libc, rom bindings etc)
|
||||
- The {IDF_TARGET_NAME} base libraries (libc, rom bindings etc)
|
||||
- The Wi-Fi drivers
|
||||
- A TCP/IP stack
|
||||
- The FreeRTOS operating system
|
||||
@@ -107,7 +107,7 @@ Minimal Example Makefile
|
||||
::
|
||||
|
||||
PROJECT_NAME := myProject
|
||||
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
|
||||
@@ -150,10 +150,10 @@ Running the ``make list-components`` target dumps many of these variables and ca
|
||||
Multiple components with the same name
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When esp-idf is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means the
|
||||
When esp-idf is collecting all the components to compile, it will do this in the order specified by ``COMPONENT_DIRS``; by default, this means the
|
||||
idf components first, the project components second and optionally the components in ``EXTRA_COMPONENT_DIRS`` last. If two or more of these directories
|
||||
contain component subdirectories with the same name, the component in the last place searched is used. This allows, for example, overriding esp-idf components
|
||||
with a modified version by simply copying the component from the esp-idf component directory to the project component tree and then modifying it there.
|
||||
contain component subdirectories with the same name, the component in the last place searched is used. This allows, for example, overriding esp-idf components
|
||||
with a modified version by simply copying the component from the esp-idf component directory to the project component tree and then modifying it there.
|
||||
If used in this way, the esp-idf directory itself can remain untouched.
|
||||
|
||||
Minimal Component Makefile
|
||||
@@ -191,7 +191,7 @@ The following variables are set at the project level, but exported for use in th
|
||||
- ``HOSTCC``, ``HOSTLD``, ``HOSTAR``: Full names of each tool from the host native toolchain.
|
||||
- ``IDF_VER``: ESP-IDF version, retrieved from either ``$(IDF_PATH)/version.txt`` file (if present) else using git command ``git describe``. Recommended format here is single liner that specifies major IDF release version, e.g. ``v2.0`` for a tagged release or ``v2.0-275-g0efaa4f`` for an arbitrary commit. Application can make use of this by calling :cpp:func:`esp_get_idf_version`.
|
||||
- ``IDF_VERSION_MAJOR``, ``IDF_VERSION_MINOR``, ``IDF_VERSION_PATCH``: Components of ESP-IDF version, to be used in conditional expressions. Note that this information is less precise than that provided by ``IDF_VER`` variable. ``v4.0-dev-*``, ``v4.0-beta1``, ``v4.0-rc1`` and ``v4.0`` will all have the same values of ``ESP_IDF_VERSION_*`` variables, but different ``IDF_VER`` values.
|
||||
- ``PROJECT_VER``: Project version.
|
||||
- ``PROJECT_VER``: Project version.
|
||||
|
||||
* If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used.
|
||||
* Else, if ``PROJECT_VER`` variable is set in project Makefile file, its value will be used.
|
||||
@@ -285,7 +285,7 @@ The following variables can be set inside ``component.mk`` to control the build
|
||||
settings. Component-specific additions can be made via ``CXXFLAGS
|
||||
+=``. It is also possible (although not recommended) to override
|
||||
this variable completely for a component.
|
||||
- ``COMPONENT_ADD_LDFRAGMENTS``: Paths to linker fragment files for the linker
|
||||
- ``COMPONENT_ADD_LDFRAGMENTS``: Paths to linker fragment files for the linker
|
||||
script generation functionality. See :doc:`Linker Script Generation <linker-script-generation>`.
|
||||
|
||||
To apply compilation flags to a single source file, you can add a variable override as a target, ie::
|
||||
@@ -326,7 +326,7 @@ Top Level: Project Makefile
|
||||
- ``project.mk`` fills in default project-level make variables and includes make variables from the project configuration. If the generated makefile containing project configuration is out of date, then it is regenerated (via targets in ``project_config.mk``) and then the make process restarts from the top.
|
||||
- ``project.mk`` builds a list of components to build, based on the default component directories or a custom list of components set in `optional project variables`.
|
||||
- Each component can set some `optional project-wide component variables`_. These are included via generated makefiles named ``component_project_vars.mk`` - there is one per component. These generated makefiles are included into ``project.mk``. If any are missing or out of date, they are regenerated (via a recursive make call to the component makefile) and then the make process restarts from the top.
|
||||
- `Makefile.projbuild` files from components are included into the make process, to add extra targets or configuration.
|
||||
- `Makefile.projbuild` files from components are included into the make process, to add extra targets or configuration.
|
||||
- By default, the project makefile also generates top-level build & clean targets for each component and sets up `app` and `clean` targets to invoke all of these sub-targets.
|
||||
- In order to compile each component, a recursive make is performed for the component makefile.
|
||||
|
||||
@@ -484,11 +484,11 @@ has the compile_only_if and compile_only_if_not macros:
|
||||
$(call compile_only_if,$(CONFIG_FOO_ENABLE_BAR),bar.o)
|
||||
|
||||
|
||||
As can be seen in the example, the ``compile_only_if`` macro takes a condition and a
|
||||
As can be seen in the example, the ``compile_only_if`` macro takes a condition and a
|
||||
list of object files as parameters. If the condition is true (in this case: if the
|
||||
BAR feature is enabled in menuconfig) the object files (in this case: bar.o) will
|
||||
always be compiled. The opposite goes as well: if the condition is not true, bar.o
|
||||
will never be compiled. ``compile_only_if_not`` does the opposite: compile if the
|
||||
always be compiled. The opposite goes as well: if the condition is not true, bar.o
|
||||
will never be compiled. ``compile_only_if_not`` does the opposite: compile if the
|
||||
condition is false, not compile if the condition is true.
|
||||
|
||||
This can also be used to select or stub out an implementation, as such:
|
||||
@@ -523,12 +523,12 @@ This can also be used to select or stub out an implementation, as such:
|
||||
$(call compile_only_if,$(or $(CONFIG_ENABLE_LCD_CONSOLE),$(CONFIG_ENABLE_LCD_PLOT)), font.o)
|
||||
|
||||
Note the use of the Make 'or' function to include the font file. Other substitution functions,
|
||||
like 'and' and 'if' will also work here. Variables that do not come from menuconfig can also
|
||||
be used: ESP-IDF uses the default Make policy of judging a variable which is empty or contains
|
||||
like 'and' and 'if' will also work here. Variables that do not come from menuconfig can also
|
||||
be used: ESP-IDF uses the default Make policy of judging a variable which is empty or contains
|
||||
only whitespace to be false while a variable with any non-whitespace in it is true.
|
||||
|
||||
(Note: Older versions of this document advised conditionally adding object file names to
|
||||
``COMPONENT_OBJS``. While this still is possible, this will only work when all object
|
||||
``COMPONENT_OBJS``. While this still is possible, this will only work when all object
|
||||
files for a component are named explicitely, and will not clean up deselected object files
|
||||
in a ``make clean`` pass.)
|
||||
|
||||
@@ -596,8 +596,8 @@ For an example of using this technique, see :example:`protocols/https_request` -
|
||||
Code and Data Placements
|
||||
------------------------
|
||||
|
||||
ESP-IDF has a feature called linker script generation that enables components to define where its code and data will be placed in memory through
|
||||
linker fragment files. These files are processed by the build system, and is used to augment the linker script used for linking
|
||||
ESP-IDF has a feature called linker script generation that enables components to define where its code and data will be placed in memory through
|
||||
linker fragment files. These files are processed by the build system, and is used to augment the linker script used for linking
|
||||
app binary. See :doc:`Linker Script Generation <linker-script-generation>` for a quick start guide as well as a detailed discussion
|
||||
of the mechanism.
|
||||
|
||||
|
@@ -5,7 +5,9 @@ Build System
|
||||
|
||||
This document explains the implementation of the ESP-IDF build system and the concept of "components". Read this document if you want to know how to organise and build a new ESP-IDF project or component.
|
||||
|
||||
.. note:: This document describes the CMake-based build system, which is the default since ESP-IDF V4.0. ESP-IDF also supports a :doc:`legacy build system based on GNU Make <build-system-legacy>`, which was the default before ESP-IDF V4.0.
|
||||
.. only:: esp32
|
||||
|
||||
.. note:: This document describes the CMake-based build system, which is the default since ESP-IDF V4.0. ESP-IDF also supports a :doc:`legacy build system based on GNU Make <build-system-legacy>`, which was the default before ESP-IDF V4.0.
|
||||
|
||||
|
||||
Overview
|
||||
@@ -14,7 +16,7 @@ Overview
|
||||
An ESP-IDF project can be seen as an amalgamation of a number of components.
|
||||
For example, for a webserver that shows the current humidity, there could be:
|
||||
|
||||
- The ESP32 base libraries (libc, ROM bindings, etc)
|
||||
- The ESP-IDF base libraries (libc, ROM bindings, etc)
|
||||
- The WiFi drivers
|
||||
- A TCP/IP stack
|
||||
- The FreeRTOS operating system
|
||||
@@ -61,7 +63,7 @@ The ``idf.py`` command line tool provides a front-end for easily managing your p
|
||||
|
||||
- CMake_, which configures the project to be built
|
||||
- A command line build tool (either Ninja_ build or `GNU Make`)
|
||||
- `esptool.py`_ for flashing ESP32.
|
||||
- `esptool.py`_ for flashing the target.
|
||||
|
||||
The :ref:`getting started guide <get-started-configure>` contains a brief introduction to how to set up ``idf.py`` to configure, build, and flash projects.
|
||||
|
||||
@@ -80,10 +82,10 @@ Type ``idf.py --help`` for a list of commands. Here are a summary of the most us
|
||||
Building is incremental so if no source files or configuration has changed since the last build, nothing will be done.
|
||||
- ``idf.py clean`` will "clean" the project by deleting build output files from the build directory, forcing a "full rebuild" the next time the project is built. Cleaning doesn't delete CMake configuration output and some other files.
|
||||
- ``idf.py fullclean`` will delete the entire "build" directory contents. This includes all CMake configuration output. The next time the project is built, CMake will configure it from scratch. Note that this option recursively deletes *all* files in the build directory, so use with care. Project configuration is not deleted.
|
||||
- ``idf.py flash`` will automatically build the project if necessary, and then flash it to an ESP32. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively.
|
||||
- ``idf.py monitor`` will display serial output from the ESP32. The ``-p`` option can be used to set the serial port name. Type ``Ctrl-]`` to exit the monitor. See :doc:`tools/idf-monitor` for more details about using the monitor.
|
||||
- ``idf.py flash`` will automatically build the project if necessary, and then flash it to the target. The ``-p`` and ``-b`` options can be used to set serial port name and flasher baud rate, respectively.
|
||||
- ``idf.py monitor`` will display serial output from the target. The ``-p`` option can be used to set the serial port name. Type ``Ctrl-]`` to exit the monitor. See :doc:`tools/idf-monitor` for more details about using the monitor.
|
||||
|
||||
Multiple ``idf.py`` commands can be combined into one. For example, ``idf.py -p COM4 clean flash monitor`` will clean the source tree, then build the project and flash it to the ESP32 before running the serial monitor.
|
||||
Multiple ``idf.py`` commands can be combined into one. For example, ``idf.py -p COM4 clean flash monitor`` will clean the source tree, then build the project and flash it to the target before running the serial monitor.
|
||||
|
||||
For commands that are not known to ``idf.py`` an attempt to execute them as a build system target will be made.
|
||||
|
||||
@@ -95,8 +97,8 @@ Advanced Commands
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
- ``idf.py app``, ``idf.py bootloader``, ``idf.py partition_table`` can be used to build only the app, bootloader, or partition table from the project as applicable.
|
||||
- There are matching commands ``idf.py app-flash``, etc. to flash only that single part of the project to the ESP32.
|
||||
- ``idf.py -p PORT erase_flash`` will use esptool.py to erase the ESP32's entire flash chip.
|
||||
- There are matching commands ``idf.py app-flash``, etc. to flash only that single part of the project to the target.
|
||||
- ``idf.py -p PORT erase_flash`` will use esptool.py to erase the target's entire flash chip.
|
||||
- ``idf.py size`` prints some size information about the app. ``size-components`` and ``size-files`` are similar commands which print more detailed per-component or per-source-file information, respectively. If you define variable ``-DOUTPUT_JSON=1`` when running CMake (or ``idf.py``), the output will be formatted as JSON not as human readable text.
|
||||
- ``idf.py reconfigure`` re-runs CMake_ even if it doesn't seem to need re-running. This isn't necessary during normal usage, but can be useful after adding/removing files from the source tree, or when modifying CMake cache variables. For example, ``idf.py -DNAME='VALUE' reconfigure`` can be used to set variable ``NAME`` in CMake cache to value ``VALUE``.
|
||||
|
||||
@@ -883,7 +885,9 @@ the ESP-IDF build system entirely by using a CMake feature called ExternalProjec
|
||||
- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is.
|
||||
- Finally, the generated library is added to `ADDITIONAL_MAKE_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.)
|
||||
|
||||
.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
|
||||
.. only:: esp32
|
||||
|
||||
.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
|
||||
|
||||
.. _ADDITIONAL_MAKE_CLEAN_FILES_note:
|
||||
|
||||
@@ -1108,7 +1112,10 @@ It is possible to do so by using the :ref:`build system APIs provided<cmake_buil
|
||||
The example in :example:`build_system/cmake/idf_as_lib` demonstrates the creation of an application equivalent to :example:`hello world application <get-started/hello_world>`
|
||||
using a custom CMake project.
|
||||
|
||||
.. note:: The IDF build system can only set compiler flags for source files that it builds. When an external CMakeLists.txt file is used and PSRAM is enabled, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
|
||||
.. only:: esp32
|
||||
|
||||
.. note:: The IDF build system can only set compiler flags for source files that it builds. When an external CMakeLists.txt file is used and PSRAM is enabled, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
|
||||
|
||||
.. _cmake_buildsystem_api:
|
||||
|
||||
ESP-IDF CMake Build System API
|
||||
|
@@ -14,9 +14,9 @@ These facilities can be used together or independently. For example, it is possi
|
||||
Line editing
|
||||
------------
|
||||
|
||||
Line editing feature lets users compose commands by typing them, erasing symbols using 'backspace' key, navigating within the command using left/right keys, navigating to previously typed commands using up/down keys, and performing autocompletion using 'tab' key.
|
||||
Line editing feature lets users compose commands by typing them, erasing symbols using 'backspace' key, navigating within the command using left/right keys, navigating to previously typed commands using up/down keys, and performing autocompletion using 'tab' key.
|
||||
|
||||
.. note:: This feature relies on ANSI escape sequence support in the terminal application. As such, serial monitors which display raw UART data can not be used together with the line editing library. If you see ``[6n`` or similar escape sequence when running get_started/console example instead of a command prompt (``[esp32]>``), it means that the serial monitor does not support escape sequences. Programs which are known to work are GNU screen, minicom, and idf_monitor.py (which can be invoked using ``idf.py monitor`` from project directory).
|
||||
.. note:: This feature relies on ANSI escape sequence support in the terminal application. As such, serial monitors which display raw UART data can not be used together with the line editing library. If you see ``[6n`` or similar escape sequence when running get_started/console example instead of a command prompt (``[{IDF_TARGET_PATH_NAME}]>``), it means that the serial monitor does not support escape sequences. Programs which are known to work are GNU screen, minicom, and idf_monitor.py (which can be invoked using ``idf.py monitor`` from project directory).
|
||||
|
||||
Here is an overview of functions provided by `linenoise`_ library.
|
||||
|
||||
|
@@ -1,9 +1,15 @@
|
||||
ESP32 Core Dump
|
||||
===============
|
||||
Core Dump
|
||||
=========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
.. note::
|
||||
|
||||
The python utility does not currently support ESP32-S2
|
||||
|
||||
ESP-IDF provides support to generate core dumps on unrecoverable software errors. This useful technique allows post-mortem analysis of software state at the moment of failure.
|
||||
Upon the crash system enters panic state, prints some information and halts or reboots depending configuration. User can choose to generate core dump in order to analyse
|
||||
the reason of failure on PC later on. Core dump contains snapshots of all tasks in the system at the moment of failure. Snapshots include tasks control blocks (TCB) and stacks.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
Deep Sleep Wake Stubs
|
||||
=====================
|
||||
|
||||
ESP32 supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally.
|
||||
{IDF_TARGET_NAME} supports running a "deep sleep wake stub" when coming out of deep sleep. This function runs immediately as soon as the chip wakes up - before any normal initialisation, bootloader, or ESP-IDF code has run. After the wake stub runs, the SoC can go back to sleep or continue to start ESP-IDF normally.
|
||||
|
||||
Deep sleep wake stub code is loaded into "RTC Fast Memory" and any data which it uses must also be loaded into RTC memory. RTC memory regions hold their contents during deep sleep.
|
||||
|
||||
@@ -33,7 +33,7 @@ It is not necessary to implement ``esp_wake_deep_sleep()`` in your app in order
|
||||
|
||||
If you want to swap between different deep sleep stubs at runtime, it is also possible to do this by calling the ``esp_set_deep_sleep_wake_stub()`` function. This is not necessary if you only use the default ``esp_wake_deep_sleep()`` function.
|
||||
|
||||
All of these functions are declared in the ``esp_deepsleep.h`` header under components/esp32.
|
||||
All of these functions are declared in the ``esp_sleep.h`` header under components/{IDF_TARGET_PATH_NAME}.
|
||||
|
||||
Loading Code Into RTC Memory
|
||||
----------------------------
|
||||
@@ -69,9 +69,11 @@ The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify
|
||||
ets_printf(fmt_str, wake_count++);
|
||||
}
|
||||
|
||||
The RTC memory area where this data will be placed can be configured via menuconfig option named ``CONFIG_ESP32_RTCDATA_IN_FAST_MEM``. This option allows to keep slow memory area for ULP programs and once it is enabled the data marked with ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` are placed in the RTC fast memory segment otherwise it goes to RTC slow memory (default option). This option depends on the ``CONFIG_FREERTOS_UNICORE`` because RTC fast memory can be accessed only by PRO_CPU.
|
||||
.. only:: esp32
|
||||
|
||||
The similar attributes ``RTC_FAST_ATTR`` and ``RTC_SLOW_ATTR`` can be used to specify data that will be force placed into RTC_FAST and RTC_SLOW memory respectively. Any access to data marked with ``RTC_FAST_ATTR`` is allowed by PRO_CPU only and it is responsibility of user to make sure about it.
|
||||
The RTC memory area where this data will be placed can be configured via menuconfig option named ``CONFIG_ESP32_RTCDATA_IN_FAST_MEM``. This option allows to keep slow memory area for ULP programs and once it is enabled the data marked with ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` are placed in the RTC fast memory segment otherwise it goes to RTC slow memory (default option). This option depends on the ``CONFIG_FREERTOS_UNICORE`` because RTC fast memory can be accessed only by PRO_CPU.
|
||||
|
||||
The attributes ``RTC_FAST_ATTR`` and ``RTC_SLOW_ATTR`` can be used to specify data that will be force placed into RTC_FAST and RTC_SLOW memory respectively. Any access to data marked with ``RTC_FAST_ATTR`` is allowed by PRO_CPU only and it is responsibility of user to make sure about it.
|
||||
|
||||
Unfortunately, any string constants used in this way must be declared as arrays and marked with RTC_RODATA_ATTR, as shown in the example above.
|
||||
|
||||
|
@@ -527,7 +527,7 @@ Generally, a Provisioner is used to provision unprovisioned devices and form a m
|
||||
3.2 Why is the Wi-Fi throughput so low when Wi-Fi and ESP-BLE-MESH coexist?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The `ESP32-DevKitC <../../hw-reference/get-started-devkitc>`_ board without PSRAM can run properly but the throughput of it is low since it has no PSRAM. When Bluetooth and Wi-Fi coexist, the throughput of ESP32-DevKitC with PSRAM can be stabilized to more than 1Mbps.
|
||||
The `ESP32-DevKitC <../../hw-reference/esp32/get-started-devkitc>`_ board without PSRAM can run properly but the throughput of it is low since it has no PSRAM. When Bluetooth and Wi-Fi coexist, the throughput of ESP32-DevKitC with PSRAM can be stabilized to more than 1Mbps.
|
||||
|
||||
And some configurations in menuconfig shall be enabled to support PSRAM.
|
||||
|
||||
@@ -647,8 +647,8 @@ You can find meaning of errors or warnings when they appear at the bottom of ESP
|
||||
|
||||
The examples use :cpp:func:`ESP_LOG_BUFFER_HEX` to print the message context while the ESP-BLE-MESH protocol stack uses :cpp:func:`bt_hex`.
|
||||
|
||||
7.2 Which API can be used to restart ESP32?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
7.2 Which API can be used to restart {IDF_TARGET_NAME}?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The API :cpp:func:`esp_restart`.
|
||||
|
||||
|
@@ -14,11 +14,11 @@ Built on top of Zephyr Bluetooth Mesh stack, the ESP-BLE-MESH implementation sup
|
||||
|
||||
Please see the :doc:`ble-mesh-architecture` for information about the implementation of ESP-BLE-MESH architecture and :doc:`ESP-BLE-MESH API Reference <../../api-reference/bluetooth/esp-ble-mesh>` for information about respective API.
|
||||
|
||||
ESP-BLE-MESH is implemented and certified based on the latest Mesh Profile v1.0.1, users can refer `here <https://launchstudio.bluetooth.com/ListingDetails/94304>`_ for the certification details of ESP-BLE-MESH.
|
||||
ESP-BLE-MESH is implemented and certified based on the latest Mesh Profile v1.0.1, users can refer `here <https://launchstudio.bluetooth.com/ListingDetails/94304>`_ for the certification details of ESP-BLE-MESH.
|
||||
|
||||
.. note::
|
||||
|
||||
If you are looking for Wi-Fi based implementation of mesh for ESP32, please check another product by Espressif called ESP-MESH. For more information and documentation see :doc:`ESP-MESH <../../api-reference/network/esp_mesh>`.
|
||||
If you are looking for Wi-Fi based implementation of mesh for {IDF_TARGET_NAME}, please check another product by Espressif called ESP-MESH. For more information and documentation see :doc:`ESP-MESH <../../api-reference/network/esp_mesh>`.
|
||||
|
||||
|
||||
.. _getting-started-with-ble-mesh:
|
||||
@@ -26,7 +26,7 @@ ESP-BLE-MESH is implemented and certified based on the latest Mesh Profile v1.0.
|
||||
Getting Started with ESP-BLE-MESH
|
||||
=================================
|
||||
|
||||
This section is intended to help you get started with ESP-BLE-MESH for the hardware based on the ESP32 chip by Espressif.
|
||||
This section is intended to help you get started with ESP-BLE-MESH for the hardware based on the {IDF_TARGET_NAME} chip by Espressif.
|
||||
|
||||
We are going to demonstrate process of setting and operation of a small ESP-BLE-MESH network of three nodes. This process will cover device provisioning and node configuration, and then sending on/off commands to Generic OnOff Server Models on specific nodes.
|
||||
|
||||
@@ -38,14 +38,14 @@ What You Need
|
||||
|
||||
Hardware:
|
||||
|
||||
* Three ESP32 boards, see :ref:`options <get-started-ble-mesh-check-hardware>`.
|
||||
* Three {IDF_TARGET_NAME} boards, see :ref:`options <get-started-ble-mesh-check-hardware>`.
|
||||
* USB cables to connect the boards.
|
||||
* Computer configured with ESP-IDF.
|
||||
* Mobile phone or tablet running Android or iOS.
|
||||
|
||||
Software:
|
||||
|
||||
* Example application :example:`bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server` code to load to the ESP32 boards.
|
||||
* Example application :example:`bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server` code to load to the ${IDF_TARGET_NAME} boards.
|
||||
* Mobile App: **nRF Mesh** for Android or iOS. Optionally you can use some other Apps:
|
||||
|
||||
- `EspBleMesh <https://github.com/EspressifApp/EspBLEMeshForAndroid/releases/tag/v1.0.0>`_ Android App
|
||||
@@ -219,7 +219,7 @@ ESP-BLE-MESH Examples
|
||||
|
||||
* ESP-BLE-MESH Fast Provisioning - :example:`Client <bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/tutorial/BLE_Mesh_Fast_Prov_Client_Example_Walkthrough.md>` and :example:`Server <bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/tutorial/BLE_Mesh_Fast_Prov_Server_Example_Walkthrough.md>` - this example is used for showing how fast provisioning can be used in order to create a mesh network. It takes no more than 60 seconds to provision 100 devices, see :example:`example client code <bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client>` and :example:`example server code <bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server>`.
|
||||
|
||||
* :example:`ESP-BLE-MESH and Wi-Fi Coexistence <bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/tutorial/BLE_Mesh_WiFi_Coexist_Example_Walkthrough.md>` - an example that demonstrates the Wi-Fi and Bluetooth (BLE/BR/EDR) coexistence feature of ESP32. Simply put, users can use the Wi-Fi while operating Bluetooth, see :example:`example code <bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist>`.
|
||||
* :example:`ESP-BLE-MESH and Wi-Fi Coexistence <bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist/tutorial/BLE_Mesh_WiFi_Coexist_Example_Walkthrough.md>` - an example that demonstrates the Wi-Fi and Bluetooth (BLE/BR/EDR) coexistence feature of {IDF_TARGET_NAME}. Simply put, users can use the Wi-Fi while operating Bluetooth, see :example:`example code <bluetooth/esp_ble_mesh/ble_mesh_wifi_coexist>`.
|
||||
|
||||
* ESP-BLE-MESH Node Console - an example that implements BLE Mesh node basic features. Within this example a node can be scanned and provisioned by Provisioner and reply to get/set message from Provisioner, see :example:`example node code <bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_node>` and :example:`example Provisioner code <bluetooth/esp_ble_mesh/ble_mesh_console/ble_mesh_provisioner>`.
|
||||
|
||||
|
@@ -9,30 +9,33 @@ Support for external RAM
|
||||
Introduction
|
||||
============
|
||||
|
||||
ESP32 has a few hundred kilobytes of internal RAM, residing on the same die as the rest of the chip components. It can be insufficient for some purposes, so ESP32 has the ability to also use up to 4 MB of external SPI RAM memory. The external memory is incorporated in the memory map and, with certain restrictions, is usable in the same way as internal data RAM.
|
||||
{IDF_TARGET_NAME} has a few hundred kilobytes of internal RAM, residing on the same die as the rest of the chip components. It can be insufficient for some purposes, so {IDF_TARGET_NAME} has the ability to also use up to 4 MB of external SPI RAM memory. The external memory is incorporated in the memory map and, with certain restrictions, is usable in the same way as internal data RAM.
|
||||
|
||||
|
||||
Hardware
|
||||
========
|
||||
|
||||
ESP32 supports SPI PSRAM connected in parallel with the SPI flash chip. While ESP32 is capable of supporting several types of RAM chips, the ESP32 SDK only supports the ESP-PSRAM32 chip at the moment.
|
||||
{IDF_TARGET_NAME} supports SPI PSRAM connected in parallel with the SPI flash chip. While {IDF_TARGET_NAME} is capable of supporting several types of RAM chips, ESP-IDF only supports the ESP-PSRAM32 chip at the moment.
|
||||
|
||||
The ESP-PSRAM32 chip is a 1.8 V device which can only be used in parallel with a 1.8 V flash component. Make sure to either set the MTDI pin to a high signal level on bootup, or program ESP32 eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip.
|
||||
The ESP-PSRAM32 chip is a 1.8 V device which can only be used in parallel with a 1.8 V flash component. Make sure to either set the MTDI pin to a high signal level on bootup, or program {IDF_TARGET_NAME} eFuses to always use the VDD_SIO level of 1.8 V. Not doing this can damage the PSRAM and/or flash chip.
|
||||
|
||||
To connect the ESP-PSRAM32 chip to ESP32D0W*, connect the following signals:
|
||||
.. only:: esp32
|
||||
|
||||
* PSRAM /CE (pin 1) > ESP32 GPIO 16
|
||||
* PSRAM SO (pin 2) > flash DO
|
||||
* PSRAM SIO[2] (pin 3) > flash WP
|
||||
* PSRAM SI (pin 5) > flash DI
|
||||
* PSRAM SCLK (pin 6) > ESP32 GPIO 17
|
||||
* PSRAM SIO[3] (pin 7) > flash HOLD
|
||||
* PSRAM Vcc (pin 8) > ESP32 VCC_SDIO
|
||||
To connect the ESP-PSRAM32 chip to ESP32D0W*, connect the following signals:
|
||||
|
||||
Connections for ESP32D2W* chips are TBD.
|
||||
* PSRAM /CE (pin 1) > ESP32 GPIO 16
|
||||
* PSRAM SO (pin 2) > flash DO
|
||||
* PSRAM SIO[2] (pin 3) > flash WP
|
||||
* PSRAM SI (pin 5) > flash DI
|
||||
* PSRAM SCLK (pin 6) > ESP32 GPIO 17
|
||||
* PSRAM SIO[3] (pin 7) > flash HOLD
|
||||
* PSRAM Vcc (pin 8) > ESP32 VCC_SDIO
|
||||
|
||||
.. NOTE::
|
||||
Espressif produces the line of ESP32-WROVER modules which contain ESP32, 1.8 V flash, and ESP-PSRAM32. These modules are ready to be mounted on an end product PCB.
|
||||
Connections for ESP32D2W* chips are TBD.
|
||||
|
||||
.. note::
|
||||
|
||||
Espressif produces the line of ESP32-WROVER modules which contain ESP32, 1.8 V flash, and ESP-PSRAM32. These modules are ready to be mounted on an end product PCB.
|
||||
|
||||
.. _external_ram_config:
|
||||
|
||||
@@ -50,10 +53,10 @@ ESP-IDF fully supports the use of external memory in applications. Once the exte
|
||||
.. _external_ram_config_memory_map:
|
||||
|
||||
|
||||
Integrate RAM into the ESP32 memory map
|
||||
---------------------------------------
|
||||
Integrate RAM into the {IDF_TARGET_NAME} memory map
|
||||
---------------------------------------------------
|
||||
|
||||
Select this option by choosing "Integrate RAM into ESP32 memory map" from :ref:`CONFIG_SPIRAM_USE`.
|
||||
Select this option by choosing "Integrate RAM into memory map" from :ref:`CONFIG_SPIRAM_USE`.
|
||||
|
||||
This is the most basic option for external SPI RAM integration. Most likely, you will need another, more advanced option.
|
||||
|
||||
@@ -119,36 +122,12 @@ External RAM use has the following restrictions:
|
||||
* When flash cache is disabled (for example, if the flash is being written to), the external RAM also becomes inaccessible; any reads from or writes to it will lead to an illegal cache access exception. This is also the reason why ESP-IDF does not by default allocate any task stacks in external RAM (see below).
|
||||
* External RAM cannot be used as a place to store DMA transaction descriptors or as a buffer for a DMA transfer to read from or write into. Any buffers that will be used in combination with DMA must be allocated using ``heap_caps_malloc(size, MALLOC_CAP_DMA)`` and can be freed using a standard ``free()`` call.
|
||||
* External RAM uses the same cache region as the external flash. This means that frequently accessed variables in external RAM can be read and modified almost as quickly as in internal ram. However, when accessing large chunks of data (>32 KB), the cache can be insufficient, and speeds will fall back to the access speed of the external RAM. Moreover, accessing large chunks of data can "push out" cached flash, possibly making the execution of code slower afterwards.
|
||||
* External RAM cannot be used as task stack memory. Due to this, :cpp:func:`xTaskCreate` and similar functions will always allocate internal memory for stack and task TCBs, and functions such as :cpp:func:`xTaskCreateStatic` will check if the buffers passed are internal. However, for tasks not calling on code in ROM in any way, directly or indirectly, the menuconfig option :ref:`CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` will eliminate the check in xTaskCreateStatic, allowing a task's stack to be in external RAM. Using this is not advised, however.
|
||||
* External RAM cannot be used as task stack memory. Due to this, :cpp:func:`xTaskCreate` and similar functions will always allocate internal memory for stack and task TCBs, and functions such as :cpp:func:`xTaskCreateStatic` will check if the buffers passed are internal.
|
||||
* By default, failure to initialize external RAM will cause the ESP-IDF startup to abort. This can be disabled by enabling the config item :ref:`CONFIG_SPIRAM_IGNORE_NOTFOUND`. If :ref:`CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY` is enabled, the option to ignore failure is not available as the linker will have assigned symbols to external memory addresses at link time.
|
||||
* When used at 80 MHz clock speed, external RAM must also occupy either the HSPI or VSPI bus. Select which SPI host will be used by :ref:`CONFIG_SPIRAM_OCCUPY_SPI_HOST`.
|
||||
|
||||
|
||||
Chip revisions
|
||||
==============
|
||||
|
||||
There are some issues with certain revisions of ESP32 that have repercussions for use with external RAM. The issues are documented in the ESP32 ECO_ document. In particular, ESP-IDF handles the bugs mentioned in the following ways:
|
||||
|
||||
|
||||
ESP32 rev v0
|
||||
------------
|
||||
ESP-IDF has no workaround for the bugs in this revision of silicon, and it cannot be used to map external PSRAM into ESP32's main memory map.
|
||||
|
||||
|
||||
ESP32 rev v1
|
||||
------------
|
||||
The bugs in this revision of silicon cause issues if certain sequences of machine instructions operate on external memory. (ESP32 ECO 3.2). As a workaround, the GCC compiler received the flag ``-mfix-esp32-psram-cache-issue`` to filter these sequences and only output the code that can safely be executed. Enable this flag by checking :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND`.
|
||||
|
||||
Aside from linking to a recompiled version of Newlib with the additional flag, ESP-IDF also does the following:
|
||||
|
||||
- Avoids using some ROM functions
|
||||
- Allocates static memory for the WiFi stack
|
||||
|
||||
|
||||
.. _ECO: https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf
|
||||
|
||||
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
.. include:: inc/external-ram-esp32-notes.rst
|
||||
|
||||
.. _ESP32 ECO: https://www.espressif.com/sites/default/files/documentation/eco_and_workarounds_for_bugs_in_esp32_en.pdf
|
||||
|
@@ -38,32 +38,34 @@ For some of the system level checks (interrupt watchdog, cache access error), th
|
||||
|
||||
In all cases, error cause will be printed in parens. See `Guru Meditation Errors`_ for a list of possible error causes.
|
||||
|
||||
Subsequent behavior of the panic handler can be set using :ref:`CONFIG_ESP32_PANIC` configuration choice. The available options are:
|
||||
Subsequent behavior of the panic handler can be set using :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_PANIC` configuration choice. The available options are:
|
||||
|
||||
- Print registers and reboot — default option.
|
||||
|
||||
- Print registers and reboot (``CONFIG_ESP32_PANIC_PRINT_REBOOT``) — default option.
|
||||
|
||||
This will print register values at the point of the exception, print the backtrace, and restart the chip.
|
||||
|
||||
- Print registers and halt (``CONFIG_ESP32_PANIC_PRINT_HALT``)
|
||||
- Print registers and halt
|
||||
|
||||
Similar to the above option, but halt instead of rebooting. External reset is required to restart the program.
|
||||
|
||||
- Silent reboot (``CONFIG_ESP32_PANIC_SILENT_REBOOT``)
|
||||
- Silent reboot
|
||||
|
||||
Don't print registers or backtrace, restart the chip immediately.
|
||||
|
||||
- Invoke GDB Stub (``CONFIG_ESP32_PANIC_GDBSTUB``)
|
||||
- Invoke GDB Stub
|
||||
|
||||
Start GDB server which can communicate with GDB over console UART port. See `GDB Stub`_ for more details.
|
||||
|
||||
Behavior of panic handler is affected by two other configuration options.
|
||||
|
||||
- If :ref:`CONFIG_ESP32_DEBUG_OCDAWARE` is enabled (which is the default), panic handler will detect whether a JTAG debugger is connected. If it is, execution will be halted and control will be passed to the debugger. In this case registers and backtrace are not dumped to the console, and GDBStub / Core Dump functions are not used.
|
||||
- If :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_DEBUG_OCDAWARE` is enabled (which is the default), panic handler will detect whether a JTAG debugger is connected. If it is, execution will be halted and control will be passed to the debugger. In this case registers and backtrace are not dumped to the console, and GDBStub / Core Dump functions are not used.
|
||||
|
||||
- If :doc:`Core Dump <core_dump>` feature is enabled (``CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH`` or ``CONFIG_ESP32_ENABLE_COREDUMP_TO_UART`` options), then system state (task stacks and registers) will be dumped either to Flash or UART, for later analysis.
|
||||
- If :doc:`Core Dump <core_dump>` feature is enabled, then system state (task stacks and registers) will be dumped either to Flash or UART, for later analysis.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
- If :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM` is disabled (disabled by default), the panic handler code is placed in flash memory not IRAM. This means that if ESP-IDF crashes while flash cache is disabled, the panic handler will automatically re-enable flash cache before running GDB Stub or Core Dump. This adds some minor risk, if the flash cache status is also corrupted during the crash.
|
||||
|
||||
- If :ref:`CONFIG_ESP_PANIC_HANDLER_IRAM` is disabled (disabled by default), the panic handler code is placed in flash memory not IRAM. This means that if ESP-IDF crashes while flash cache is disabled, the panic handler will automatically re-enable flash cache before running GDB Stub or Core Dump. This adds some minor risk, if the flash cache status is also corrupted during the crash.
|
||||
|
||||
If this option is enabled, the panic handler code is placed in IRAM. This allows the panic handler to run without needing to re-enable cache first. This may be necessary to debug some complex issues with crashes while flash cache is disabled (for example, when writing to SPI flash).
|
||||
|
||||
The following diagram illustrates panic handler behavior:
|
||||
@@ -72,7 +74,7 @@ The following diagram illustrates panic handler behavior:
|
||||
:scale: 100%
|
||||
:caption: Panic Handler Flowchart (click to enlarge)
|
||||
:align: center
|
||||
|
||||
|
||||
blockdiag panic-handler {
|
||||
orientation = portrait;
|
||||
edge_layout = flowchart;
|
||||
@@ -114,15 +116,15 @@ The following diagram illustrates panic handler behavior:
|
||||
Register Dump and Backtrace
|
||||
---------------------------
|
||||
|
||||
Unless ``CONFIG_ESP32_PANIC_SILENT_REBOOT`` option is enabled, panic handler prints some of the CPU registers, and the backtrace, to the console::
|
||||
Unless ``CONFIG_{IDF_TARGET_CFG_PREFIX}_PANIC_SILENT_REBOOT`` option is enabled, panic handler prints some of the CPU registers, and the backtrace, to the console::
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc
|
||||
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000
|
||||
A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8
|
||||
A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d
|
||||
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc
|
||||
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000
|
||||
A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8
|
||||
A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d
|
||||
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff
|
||||
|
||||
Backtrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb5050
|
||||
|
||||
@@ -137,28 +139,28 @@ Backtrace line contains PC:SP pairs, where PC is the Program Counter and SP is S
|
||||
If :doc:`IDF Monitor <tools/idf-monitor>` is used, Program Counter values will be converted to code locations (function name, file name, and line number), and the output will be annotated with additional lines::
|
||||
|
||||
Core 0 register dump:
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030
|
||||
0x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:36
|
||||
|
||||
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc
|
||||
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000
|
||||
A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8
|
||||
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc
|
||||
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000
|
||||
A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8
|
||||
0x40082d1c: _calloc_r at /Users/user/esp/esp-idf/components/newlib/syscalls.c:51
|
||||
|
||||
A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d
|
||||
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff
|
||||
A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d
|
||||
EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff
|
||||
|
||||
Backtrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb5050
|
||||
0x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:36
|
||||
|
||||
0x400d0802: main_task at /Users/user/esp/esp-idf/components/esp32/cpu_start.c:470
|
||||
0x400d0802: main_task at /Users/user/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/cpu_start.c:470
|
||||
|
||||
To find the location where a fatal error has happened, look at the lines which follow the "Backtrace" line. Fatal error location is the top line, and subsequent lines show the call stack.
|
||||
|
||||
GDB Stub
|
||||
--------
|
||||
|
||||
If ``CONFIG_ESP32_PANIC_GDBSTUB`` option is enabled, panic handler will not reset the chip when fatal error happens. Instead, it will start GDB remote protocol server, commonly referred to as GDB Stub. When this happens, GDB instance running on the host computer can be instructed to connect to the ESP32 UART port.
|
||||
If ``CONFIG_{IDF_TARGET_CFG_PREFIX}_PANIC_GDBSTUB`` option is enabled, panic handler will not reset the chip when fatal error happens. Instead, it will start GDB remote protocol server, commonly referred to as GDB Stub. When this happens, GDB instance running on the host computer can be instructed to connect to the {IDF_TARGET_NAME} UART port.
|
||||
|
||||
If :doc:`IDF Monitor <tools/idf-monitor>` is used, GDB is started automatically when GDB Stub prompt is detected on the UART. The output would look like this::
|
||||
|
||||
@@ -169,7 +171,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, GDB is started automatically
|
||||
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_apple-darwin16.3.0 --target=xtensa-esp32-elf".
|
||||
This GDB was configured as "--host=x86_64-build_apple-darwin16.3.0 --target=xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf".
|
||||
Type "show configuration" for configuration details.
|
||||
For bug reporting instructions, please see:
|
||||
<http://www.gnu.org/software/gdb/bugs/>.
|
||||
@@ -182,7 +184,7 @@ If :doc:`IDF Monitor <tools/idf-monitor>` is used, GDB is started automatically
|
||||
0x400e1b41 in app_main ()
|
||||
at /Users/user/esp/example/main/main.cpp:36
|
||||
36 *((int*) 0) = 0;
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
GDB prompt can be used to inspect CPU registers, local and static variables, and arbitrary locations in memory. It is not possible to set breakpoints, change PC, or continue execution. To reset the program, exit GDB and perform external reset: Ctrl-T Ctrl-R in IDF Monitor, or using external reset button on the development board.
|
||||
|
||||
@@ -207,10 +209,10 @@ Most common reasons for this error include:
|
||||
- FreeRTOS task function has returned. In FreeRTOS, if task function needs to terminate, it should call :cpp:func:`vTaskDelete` function and delete itself, instead of returning.
|
||||
|
||||
- Failure to load next instruction from SPI flash. This usually happens if:
|
||||
|
||||
|
||||
- Application has reconfigured SPI flash pins as some other function (GPIO, UART, etc.). Consult Hardware Design Guidelines and the Datasheet for the chip or module for details about SPI flash pins.
|
||||
|
||||
- Some external device was accidentally connected to SPI flash pins, and has interfered with communication between ESP32 and SPI flash.
|
||||
|
||||
- Some external device was accidentally connected to SPI flash pins, and has interfered with communication between {IDF_TARGET_NAME} and SPI flash.
|
||||
|
||||
|
||||
InstrFetchProhibited
|
||||
@@ -265,7 +267,8 @@ Other Fatal Errors
|
||||
Brownout
|
||||
^^^^^^^^
|
||||
|
||||
ESP32 has a built-in brownout detector, which is enabled by default. Brownout detector can trigger system reset if supply voltage goes below safe level. Brownout detector can be configured using :ref:`CONFIG_ESP32_BROWNOUT_DET` and :ref:`CONFIG_ESP32_BROWNOUT_DET_LVL_SEL` options.
|
||||
{IDF_TARGET_NAME} has a built-in brownout detector, which is enabled by default. Brownout detector can trigger system reset if supply voltage goes below safe level. Brownout detector can be configured using :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_BROWNOUT_DET` and :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_BROWNOUT_DET_LVL_SEL` options.
|
||||
|
||||
When brownout detector triggers, the following message is printed::
|
||||
|
||||
Brownout detector was triggered
|
||||
|
@@ -4,76 +4,80 @@ ESP-IDF FreeRTOS SMP Changes
|
||||
Overview
|
||||
--------
|
||||
|
||||
The vanilla FreeRTOS is designed to run on a single core. However the ESP32 is
|
||||
dual core containing a Protocol CPU (known as **CPU 0** or **PRO_CPU**) and an
|
||||
Application CPU (known as **CPU 1** or **APP_CPU**). The two cores are
|
||||
identical in practice and share the same memory. This allows the two cores to
|
||||
run tasks interchangeably between them.
|
||||
.. only:: esp32
|
||||
|
||||
The ESP-IDF FreeRTOS is a modified version of vanilla FreeRTOS which supports
|
||||
symmetric multiprocessing (SMP). ESP-IDF FreeRTOS is based on the Xtensa port
|
||||
of FreeRTOS v8.2.0. This guide outlines the major differences between vanilla
|
||||
FreeRTOS and ESP-IDF FreeRTOS. The API reference for vanilla FreeRTOS can be
|
||||
The vanilla FreeRTOS is designed to run on a single core. However the ESP32 is
|
||||
dual core containing a Protocol CPU (known as **CPU 0** or **PRO_CPU**) and an
|
||||
Application CPU (known as **CPU 1** or **APP_CPU**). The two cores are
|
||||
identical in practice and share the same memory. This allows the two cores to
|
||||
run tasks interchangeably between them.
|
||||
|
||||
The ESP-IDF FreeRTOS is a modified version of vanilla FreeRTOS which supports
|
||||
symmetric multiprocessing (SMP). ESP-IDF FreeRTOS is based on the Xtensa port
|
||||
of FreeRTOS v8.2.0. This guide outlines the major differences between vanilla
|
||||
FreeRTOS and ESP-IDF FreeRTOS. The API reference for vanilla FreeRTOS can be
|
||||
found via http://www.freertos.org/a00106.html
|
||||
|
||||
For information regarding features that are exclusive to ESP-IDF FreeRTOS,
|
||||
see :doc:`ESP-IDF FreeRTOS Additions<../api-reference/system/freertos_additions>`.
|
||||
|
||||
:ref:`backported-features`: Although ESP-IDF FreeRTOS is based on the Xtensa
|
||||
:ref:`backported-features`: Although ESP-IDF FreeRTOS is based on the Xtensa
|
||||
port of FreeRTOS v8.2.0, a number of FreeRTOS v9.0.0 features have been backported
|
||||
to ESP-IDF.
|
||||
|
||||
:ref:`tasks-and-task-creation`: Use :cpp:func:`xTaskCreatePinnedToCore` or
|
||||
:cpp:func:`xTaskCreateStaticPinnedToCore` to create tasks in ESP-IDF FreeRTOS. The
|
||||
last parameter of the two functions is ``xCoreID``. This parameter specifies
|
||||
which core the task is pinned to. Acceptable values are ``0`` for **PRO_CPU**,
|
||||
``1`` for **APP_CPU**, or ``tskNO_AFFINITY`` which allows the task to run on
|
||||
both.
|
||||
.. only:: esp32
|
||||
|
||||
:ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler will skip tasks when
|
||||
implementing Round-Robin scheduling between multiple tasks in the Ready state
|
||||
that are of the same priority. To avoid this behavior, ensure that those tasks either
|
||||
enter a blocked state, or are distributed across a wider range of priorities.
|
||||
:ref:`tasks-and-task-creation`: Use :cpp:func:`xTaskCreatePinnedToCore` or
|
||||
:cpp:func:`xTaskCreateStaticPinnedToCore` to create tasks in ESP-IDF FreeRTOS. The
|
||||
last parameter of the two functions is ``xCoreID``. This parameter specifies
|
||||
which core the task is pinned to. Acceptable values are ``0`` for **PRO_CPU**,
|
||||
``1`` for **APP_CPU**, or ``tskNO_AFFINITY`` which allows the task to run on
|
||||
both.
|
||||
|
||||
:ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only
|
||||
affect the scheduler on the the calling core. In other words, calling
|
||||
:cpp:func:`vTaskSuspendAll` on **PRO_CPU** will not prevent **APP_CPU** from scheduling, and
|
||||
vice versa. Use critical sections or semaphores instead for simultaneous
|
||||
access protection.
|
||||
:ref:`round-robin-scheduling`: The ESP-IDF FreeRTOS scheduler will skip tasks when
|
||||
implementing Round-Robin scheduling between multiple tasks in the Ready state
|
||||
that are of the same priority. To avoid this behavior, ensure that those tasks either
|
||||
enter a blocked state, or are distributed across a wider range of priorities.
|
||||
|
||||
:ref:`tick-interrupt-synchronicity`: Tick interrupts of **PRO_CPU** and **APP_CPU**
|
||||
are not synchronized. Do not expect to use :cpp:func:`vTaskDelay` or
|
||||
:cpp:func:`vTaskDelayUntil` as an accurate method of synchronizing task execution
|
||||
between the two cores. Use a counting semaphore instead as their context
|
||||
switches are not tied to tick interrupts due to preemption.
|
||||
:ref:`scheduler-suspension`: Suspending the scheduler in ESP-IDF FreeRTOS will only
|
||||
affect the scheduler on the the calling core. In other words, calling
|
||||
:cpp:func:`vTaskSuspendAll` on **PRO_CPU** will not prevent **APP_CPU** from scheduling, and
|
||||
vice versa. Use critical sections or semaphores instead for simultaneous
|
||||
access protection.
|
||||
|
||||
:ref:`critical-sections`: In ESP-IDF FreeRTOS, critical sections are implemented using
|
||||
mutexes. Entering critical sections involve taking a mutex, then disabling the
|
||||
scheduler and interrupts of the calling core. However the other core is left
|
||||
unaffected. If the other core attemps to take same mutex, it will spin until
|
||||
the calling core has released the mutex by exiting the critical section.
|
||||
:ref:`tick-interrupt-synchronicity`: Tick interrupts of **PRO_CPU** and **APP_CPU**
|
||||
are not synchronized. Do not expect to use :cpp:func:`vTaskDelay` or
|
||||
:cpp:func:`vTaskDelayUntil` as an accurate method of synchronizing task execution
|
||||
between the two cores. Use a counting semaphore instead as their context
|
||||
switches are not tied to tick interrupts due to preemption.
|
||||
|
||||
:ref:`floating-points`: The ESP32 supports hardware acceleration of single
|
||||
precision floating point arithmetic (``float``). However the use of hardware
|
||||
acceleration leads to some behavioral restrictions in ESP-IDF FreeRTOS.
|
||||
Therefore, tasks that utilize ``float`` will automatically be pinned to a core if
|
||||
not done so already. Furthermore, ``float`` cannot be used in interrupt service
|
||||
routines.
|
||||
:ref:`critical-sections`: In ESP-IDF FreeRTOS, critical sections are implemented using
|
||||
mutexes. Entering critical sections involve taking a mutex, then disabling the
|
||||
scheduler and interrupts of the calling core. However the other core is left
|
||||
unaffected. If the other core attemps to take same mutex, it will spin until
|
||||
the calling core has released the mutex by exiting the critical section.
|
||||
|
||||
:ref:`task-deletion`: Task deletion behavior has been backported from FreeRTOS
|
||||
v9.0.0 and modified to be SMP compatible. Task memory will be freed immediately
|
||||
when :cpp:func:`vTaskDelete` is called to delete a task that is not currently running
|
||||
and not pinned to the other core. Otherwise, freeing of task memory will still
|
||||
:ref:`floating-points`: The {IDF_TARGET_NAME} supports hardware acceleration of single
|
||||
precision floating point arithmetic (``float``). However the use of hardware
|
||||
acceleration leads to some behavioral restrictions in ESP-IDF FreeRTOS.
|
||||
Therefore, tasks that utilize ``float`` will automatically be pinned to a core if
|
||||
not done so already. Furthermore, ``float`` cannot be used in interrupt service
|
||||
routines.
|
||||
|
||||
`Task Deletion`_: Task deletion behavior has been backported from FreeRTOS
|
||||
v9.0.0 and modified to be SMP compatible. Task memory will be freed immediately
|
||||
when :cpp:func:`vTaskDelete` is called to delete a task that is not currently running
|
||||
and not pinned to the other core. Otherwise, freeing of task memory will still
|
||||
be delegated to the Idle Task.
|
||||
|
||||
:ref:`deletion-callbacks`: ESP-IDF FreeRTOS has backported the Thread Local
|
||||
:ref:`deletion-callbacks`: ESP-IDF FreeRTOS has backported the Thread Local
|
||||
Storage Pointers (TLSP) feature. However the extra feature of Deletion Callbacks has been
|
||||
added. Deletion callbacks are called automatically during task deletion and are
|
||||
used to free memory pointed to by TLSP. Call
|
||||
used to free memory pointed to by TLSP. Call
|
||||
:cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback()` to set TLSP and Deletion
|
||||
Callbacks.
|
||||
|
||||
:ref:`esp-idf-freertos-configuration`: Several aspects of ESP-IDF FreeRTOS can be
|
||||
:ref:`esp-idf-freertos-configuration`: Several aspects of ESP-IDF FreeRTOS can be
|
||||
set in the project configuration (``idf.py menuconfig``) such as running ESP-IDF in
|
||||
Unicore (single core) Mode, or configuring the number of Thread Local Storage Pointers
|
||||
each task will have.
|
||||
@@ -89,9 +93,9 @@ The following features have been backported from FreeRTOS v9.0.0 to ESP-IDF.
|
||||
Static Alocation
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
This feature has been backported from FreeRTOS v9.0.0 to ESP-IDF. The
|
||||
This feature has been backported from FreeRTOS v9.0.0 to ESP-IDF. The
|
||||
:ref:`CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION` option must be enabled in `menuconfig`
|
||||
in order for static allocation functions to be available. Once enabled, the
|
||||
in order for static allocation functions to be available. Once enabled, the
|
||||
following functions can be called...
|
||||
|
||||
- :cpp:func:`xTaskCreateStatic` (see :ref:`backporting-notes` below)
|
||||
@@ -119,32 +123,34 @@ Other Features
|
||||
Backporting Notes
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
**1)** :cpp:func:`xTaskCreateStatic` has been made SMP compatible in a similar
|
||||
fashion to :cpp:func:`xTaskCreate` (see :ref:`tasks-and-task-creation`). Therefore
|
||||
**1)** :cpp:func:`xTaskCreateStatic` has been made SMP compatible in a similar
|
||||
fashion to :cpp:func:`xTaskCreate` (see :ref:`tasks-and-task-creation`). Therefore
|
||||
:cpp:func:`xTaskCreateStaticPinnedToCore` can also be called.
|
||||
|
||||
**2)** Although vanilla FreeRTOS allows the Timer feature's daemon task to
|
||||
be statically allocated, the daemon task is always dynamically allocated in
|
||||
ESP-IDF. Therefore ``vApplicationGetTimerTaskMemory`` **does not** need to be
|
||||
**2)** Although vanilla FreeRTOS allows the Timer feature's daemon task to
|
||||
be statically allocated, the daemon task is always dynamically allocated in
|
||||
ESP-IDF. Therefore ``vApplicationGetTimerTaskMemory`` **does not** need to be
|
||||
defined when using statically allocated timers in ESP-IDF FreeRTOS.
|
||||
|
||||
**3)** The Thread Local Storage Pointer feature has been modified in ESP-IDF
|
||||
FreeRTOS to include Deletion Callbacks (see :ref:`deletion-callbacks`). Therefore
|
||||
the function :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback` can also be
|
||||
the function :cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback` can also be
|
||||
called.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _tasks-and-task-creation:
|
||||
|
||||
Tasks and Task Creation
|
||||
-----------------------
|
||||
|
||||
Tasks in ESP-IDF FreeRTOS are designed to run on a particular core, therefore
|
||||
two new task creation functions have been added to ESP-IDF FreeRTOS by
|
||||
appending ``PinnedToCore`` to the names of the task creation functions in
|
||||
Tasks in ESP-IDF FreeRTOS are designed to run on a particular core, therefore
|
||||
two new task creation functions have been added to ESP-IDF FreeRTOS by
|
||||
appending ``PinnedToCore`` to the names of the task creation functions in
|
||||
vanilla FreeRTOS. The vanilla FreeRTOS functions of :cpp:func:`xTaskCreate`
|
||||
and :cpp:func:`xTaskCreateStatic` have led to the addition of
|
||||
:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore` in
|
||||
and :cpp:func:`xTaskCreateStatic` have led to the addition of
|
||||
:cpp:func:`xTaskCreatePinnedToCore` and :cpp:func:`xTaskCreateStaticPinnedToCore` in
|
||||
ESP-IDF FreeRTOS (see :ref:`backported-features`).
|
||||
|
||||
For more details see :component_file:`freertos/task.c`
|
||||
@@ -349,15 +355,22 @@ context switches and servicing of ISRs during a critical section. Therefore,
|
||||
critical sections are used as a valid protection method against simultaneous
|
||||
access in vanilla FreeRTOS.
|
||||
|
||||
On the other hand, the ESP32 has no hardware method for cores to disable each
|
||||
other’s interrupts. Calling ``portDISABLE_INTERRUPTS()`` will have no effect on
|
||||
the interrupts of the other core. Therefore, disabling interrupts is **NOT**
|
||||
a valid protection method against simultaneous access to shared data as it
|
||||
leaves the other core free to access the data even if the current core has
|
||||
disabled its own interrupts.
|
||||
.. only:: esp32
|
||||
|
||||
On the other hand, the ESP32 has no hardware method for cores to disable each
|
||||
other’s interrupts. Calling ``portDISABLE_INTERRUPTS()`` will have no effect on
|
||||
the interrupts of the other core. Therefore, disabling interrupts is **NOT**
|
||||
a valid protection method against simultaneous access to shared data as it
|
||||
leaves the other core free to access the data even if the current core has
|
||||
disabled its own interrupts.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
ESP-IDF contains some modifications to work with dual core concurrency,
|
||||
and the dual core API is used even on a single core only chip.
|
||||
|
||||
For this reason, ESP-IDF FreeRTOS implements critical sections using special mutexes,
|
||||
referred by portMUX_Type objects on top of specific ESP32 spinlock component
|
||||
referred by portMUX_Type objects on top of specific spinlock component
|
||||
and calls to enter or exit a critical must provide a spinlock object that
|
||||
is associated with a shared resource requiring access protection.
|
||||
When entering a critical section in ESP-IDF FreeRTOS, the calling core will disable
|
||||
@@ -394,46 +407,42 @@ spinlock is provided upon entering and exiting, the type of call should not
|
||||
matter.
|
||||
|
||||
|
||||
.. _floating-points:
|
||||
.. only:: esp32
|
||||
|
||||
Floating Point Aritmetic
|
||||
------------------------
|
||||
.. _floating-points:
|
||||
|
||||
The ESP32 supports hardware acceleration of single precision floating point
|
||||
arithmetic (``float``) via Floating Point Units (FPU, also known as coprocessors)
|
||||
attached to each core. The use of the FPUs imposes some behavioral restrictions
|
||||
on ESP-IDF FreeRTOS.
|
||||
Floating Point Arithmetic
|
||||
-------------------------
|
||||
|
||||
ESP-IDF FreeRTOS implements Lazy Context Switching for FPUs. In other words,
|
||||
the state of a core's FPU registers are not immediately saved when a context
|
||||
switch occurs. Therefore, tasks that utilize ``float`` must be pinned to a
|
||||
particular core upon creation. If not, ESP-IDF FreeRTOS will automatically pin
|
||||
the task in question to whichever core the task was running on upon the task's
|
||||
first use of ``float``. Likewise due to Lazy Context Switching, only interrupt
|
||||
service routines of lowest priority (that is it the Level 1) can use ``float``,
|
||||
higher priority interrupts do not support FPU usage.
|
||||
|
||||
ESP32 does not support hardware acceleration for double precision floating point
|
||||
arithmetic (``double``). Instead ``double`` is implemented via software hence the
|
||||
behavioral restrictions with regards to ``float`` do not apply to ``double``. Note
|
||||
that due to the lack of hardware acceleration, ``double`` operations may consume
|
||||
significantly larger amount of CPU time in comparison to ``float``.
|
||||
ESP-IDF FreeRTOS implements Lazy Context Switching for FPUs. In other words,
|
||||
the state of a core's FPU registers are not immediately saved when a context
|
||||
switch occurs. Therefore, tasks that utilize ``float`` must be pinned to a
|
||||
particular core upon creation. If not, ESP-IDF FreeRTOS will automatically pin
|
||||
the task in question to whichever core the task was running on upon the task's
|
||||
first use of ``float``. Likewise due to Lazy Context Switching, only interrupt
|
||||
service routines of lowest priority (that is it the Level 1) can use ``float``,
|
||||
higher priority interrupts do not support FPU usage.
|
||||
|
||||
ESP32 does not support hardware acceleration for double precision floating point
|
||||
arithmetic (``double``). Instead ``double`` is implemented via software hence the
|
||||
behavioral restrictions with regards to ``float`` do not apply to ``double``. Note
|
||||
that due to the lack of hardware acceleration, ``double`` operations may consume
|
||||
significantly larger amount of CPU time in comparison to ``float``.
|
||||
|
||||
.. _task-deletion:
|
||||
|
||||
Task Deletion
|
||||
-------------
|
||||
|
||||
FreeRTOS task deletion prior to v9.0.0 delegated the freeing of task memory
|
||||
FreeRTOS task deletion prior to v9.0.0 delegated the freeing of task memory
|
||||
entirely to the Idle Task. Currently, the freeing of task memory will occur
|
||||
immediately (within :cpp:func:`vTaskDelete`) if the task being deleted is not currently
|
||||
running or is not pinned to the other core (with respect to the core
|
||||
immediately (within :cpp:func:`vTaskDelete`) if the task being deleted is not currently
|
||||
running or is not pinned to the other core (with respect to the core
|
||||
:cpp:func:`vTaskDelete` is called on). TLSP deletion callbacks will also run immediately
|
||||
if the same conditions are met.
|
||||
|
||||
However, calling :cpp:func:`vTaskDelete` to delete a task that is either currently
|
||||
running or pinned to the other core will still result in the freeing of memory
|
||||
However, calling :cpp:func:`vTaskDelete` to delete a task that is either currently
|
||||
running or pinned to the other core will still result in the freeing of memory
|
||||
being delegated to the Idle Task.
|
||||
|
||||
|
||||
@@ -442,32 +451,32 @@ being delegated to the Idle Task.
|
||||
Thread Local Storage Pointers & Deletion Callbacks
|
||||
--------------------------------------------------
|
||||
|
||||
Thread Local Storage Pointers (TLSP) are pointers stored directly in the TCB.
|
||||
TLSP allow each task to have its own unique set of pointers to data structures.
|
||||
However task deletion behavior in vanilla FreeRTOS does not automatically
|
||||
Thread Local Storage Pointers (TLSP) are pointers stored directly in the TCB.
|
||||
TLSP allow each task to have its own unique set of pointers to data structures.
|
||||
However task deletion behavior in vanilla FreeRTOS does not automatically
|
||||
free the memory pointed to by TLSP. Therefore if the memory pointed to by
|
||||
TLSP is not explicitly freed by the user before task deletion, memory leak will
|
||||
TLSP is not explicitly freed by the user before task deletion, memory leak will
|
||||
occur.
|
||||
|
||||
ESP-IDF FreeRTOS provides the added feature of Deletion Callbacks. Deletion
|
||||
ESP-IDF FreeRTOS provides the added feature of Deletion Callbacks. Deletion
|
||||
Callbacks are called automatically during task deletion to free memory pointed
|
||||
to by TLSP. Each TLSP can have its own Deletion Callback. Note that due to the
|
||||
to :ref:`task-deletion` behavior, there can be instances where Deletion
|
||||
to `Task Deletion`_ behavior, there can be instances where Deletion
|
||||
Callbacks are called in the context of the Idle Tasks. Therefore Deletion
|
||||
Callbacks **should never attempt to block** and critical sections should be kept
|
||||
as short as possible to minimize priority inversion.
|
||||
|
||||
Deletion callbacks are of type
|
||||
``void (*TlsDeleteCallbackFunction_t)( int, void * )`` where the first parameter
|
||||
is the index number of the associated TLSP, and the second parameter is the
|
||||
is the index number of the associated TLSP, and the second parameter is the
|
||||
TLSP itself.
|
||||
|
||||
Deletion callbacks are set alongside TLSP by calling
|
||||
:cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback`. Calling the vanilla
|
||||
Deletion callbacks are set alongside TLSP by calling
|
||||
:cpp:func:`vTaskSetThreadLocalStoragePointerAndDelCallback`. Calling the vanilla
|
||||
FreeRTOS function :cpp:func:`vTaskSetThreadLocalStoragePointer` will simply set the
|
||||
TLSP's associated Deletion Callback to `NULL` meaning that no callback will be
|
||||
called for that TLSP during task deletion. If a deletion callback is `NULL`,
|
||||
users should manually free the memory pointed to by the associated TLSP before
|
||||
users should manually free the memory pointed to by the associated TLSP before
|
||||
task deletion in order to avoid memory leak.
|
||||
|
||||
:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` in menuconfig can be used
|
||||
@@ -487,27 +496,27 @@ highlights some of the ESP-IDF FreeRTOS configuration options. For a full list o
|
||||
ESP-IDF FreeRTOS configurations, see :doc:`FreeRTOS <../api-reference/kconfig>`
|
||||
|
||||
:ref:`CONFIG_FREERTOS_UNICORE` will run ESP-IDF FreeRTOS only
|
||||
on **PRO_CPU**. Note that this is **not equivalent to running vanilla
|
||||
FreeRTOS**. Behaviors of multiple components in ESP-IDF will be modified such
|
||||
as :component_file:`esp32/cpu_start.c`. For more details regarding the
|
||||
effects of running ESP-IDF FreeRTOS on a single core, search for
|
||||
on **PRO_CPU**. Note that this is **not equivalent to running vanilla
|
||||
FreeRTOS**. Behaviors of multiple components in ESP-IDF will be modified such
|
||||
as :component_file:`{IDF_TARGET_PATH_NAME}/cpu_start.c`. For more details regarding the
|
||||
effects of running ESP-IDF FreeRTOS on a single core, search for
|
||||
occurences of ``CONFIG_FREERTOS_UNICORE`` in the ESP-IDF components.
|
||||
|
||||
:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` will define the
|
||||
number of Thread Local Storage Pointers each task will have in ESP-IDF
|
||||
|
||||
:ref:`CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS` will define the
|
||||
number of Thread Local Storage Pointers each task will have in ESP-IDF
|
||||
FreeRTOS.
|
||||
|
||||
:ref:`CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION` will enable the backported
|
||||
functionality of :cpp:func:`xTaskCreateStaticPinnedToCore` in ESP-IDF FreeRTOS
|
||||
|
||||
|
||||
:ref:`CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION` will trigger a halt in
|
||||
particular functions in ESP-IDF FreeRTOS which have not been fully tested
|
||||
in an SMP context.
|
||||
|
||||
:ref:`CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER` will enclose all task functions
|
||||
within a wrapper function. In the case that a task function mistakenly returns
|
||||
(i.e. does not call :cpp:func:`vTaskDelete`), the call flow will return to the
|
||||
wrapper function. The wrapper function will then log an error and abort the
|
||||
:ref:`CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER` will enclose all task functions
|
||||
within a wrapper function. In the case that a task function mistakenly returns
|
||||
(i.e. does not call :cpp:func:`vTaskDelete`), the call flow will return to the
|
||||
wrapper function. The wrapper function will then log an error and abort the
|
||||
application, as illustrated below::
|
||||
|
||||
E (25) FreeRTOS: FreeRTOS task should not return. Aborting now!
|
||||
|
@@ -18,7 +18,7 @@ This process is explained in detail in the following sections.
|
||||
First stage bootloader
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After SoC reset, PRO CPU will start running immediately, executing reset vector code, while APP CPU will be held in reset. During startup process, PRO CPU does all the initialization. APP CPU reset is de-asserted in the ``call_start_cpu0`` function of application startup code. Reset vector code is located at address 0x40000400 in the mask ROM of the ESP32 chip and can not be modified.
|
||||
After SoC reset, PRO CPU will start running immediately, executing reset vector code, while APP CPU will be held in reset. During startup process, PRO CPU does all the initialization. APP CPU reset is de-asserted in the ``call_start_cpu0`` function of application startup code. Reset vector code is located at address 0x40000400 in the mask ROM of the {IDF_TARGET_NAME} chip and can not be modified.
|
||||
|
||||
Startup code called from the reset vector determines the boot mode by checking ``GPIO_STRAP_REG`` register for bootstrap pin states. Depending on the reset reason, the following takes place:
|
||||
|
||||
@@ -28,18 +28,18 @@ Startup code called from the reset vector determines the boot mode by checking `
|
||||
|
||||
3. For software CPU reset and watchdog CPU reset: configure SPI flash based on EFUSE values, and attempt to load the code from flash. This step is described in more detail in the next paragraphs. If loading code from flash fails, unpack BASIC interpreter into the RAM and start it. Note that RTC watchdog is still enabled when this happens, so unless any input is received by the interpreter, watchdog will reset the SOC in a few hundred milliseconds, repeating the whole process. If the interpreter receives any input from the UART, it disables the watchdog.
|
||||
|
||||
Application binary image is loaded from flash starting at address 0x1000. First 4kB sector of flash is used to store secure boot IV and signature of the application image. Please check secure boot documentation for details about this.
|
||||
Application binary image is loaded from flash starting at address 0x1000. First 4kB sector of flash is used to store secure boot IV and signature of the application image. Please check secure boot documentation for details about this.
|
||||
|
||||
.. TODO: describe application binary image format, describe optional flash configuration commands.
|
||||
|
||||
Second stage bootloader
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In ESP-IDF, the binary image which resides at offset 0x1000 in flash is the second stage bootloader. Second stage bootloader source code is available in components/bootloader directory of ESP-IDF. Note that this arrangement is not the only one possible with the ESP32 chip. It is possible to write a fully featured application which would work when flashed to offset 0x1000, but this is out of scope of this document. Second stage bootloader is used in ESP-IDF to add flexibility to flash layout (using partition tables), and allow for various flows associated with flash encryption, secure boot, and over-the-air updates (OTA) to take place.
|
||||
In ESP-IDF, the binary image which resides at offset 0x1000 in flash is the second stage bootloader. Second stage bootloader source code is available in components/bootloader directory of ESP-IDF. Note that this arrangement is not the only one possible with the {IDF_TARGET_NAME} chip. It is possible to write a fully featured application which would work when flashed to offset 0x1000, but this is out of scope of this document. Second stage bootloader is used in ESP-IDF to add flexibility to flash layout (using partition tables), and allow for various flows associated with flash encryption, secure boot, and over-the-air updates (OTA) to take place.
|
||||
|
||||
When the first stage bootloader is finished checking and loading the second stage bootloader, it jumps to the second stage bootloader entry point found in the binary image header.
|
||||
|
||||
Second stage bootloader reads the partition table found at offset 0x8000. See :doc:`partition tables <partition-tables>` documentation for more information. The bootloader finds factory and OTA partitions, and decides which one to boot based on data found in *OTA info* partition.
|
||||
Second stage bootloader reads the partition table found at offset 0x8000. See :doc:`partition tables <partition-tables>` documentation for more information. The bootloader finds factory and OTA partitions, and decides which one to boot based on data found in *OTA info* partition.
|
||||
|
||||
For the selected partition, second stage bootloader copies data and code sections which are mapped into IRAM and DRAM to their load addresses. For sections which have load addresses in DROM and IROM regions, flash MMU is configured to provide the correct mapping. Note that the second stage bootloader configures flash MMU for both PRO and APP CPUs, but it only enables flash MMU for PRO CPU. Reason for this is that second stage bootloader code is loaded into the memory region used by APP CPU cache. The duty of enabling cache for APP CPU is passed on to the application. Once code is loaded and flash MMU is set up, second stage bootloader jumps to the application entry point found in the binary image header.
|
||||
|
||||
@@ -48,9 +48,9 @@ Currently it is not possible to add application-defined hooks to the bootloader
|
||||
Application startup
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
ESP-IDF application entry point is ``call_start_cpu0`` function found in ``components/esp32/cpu_start.c``. Two main things this function does are to enable heap allocator and to make APP CPU jump to its entry point, ``call_start_cpu1``. The code on PRO CPU sets the entry point for APP CPU, de-asserts APP CPU reset, and waits for a global flag to be set by the code running on APP CPU, indicating that it has started. Once this is done, PRO CPU jumps to ``start_cpu0`` function, and APP CPU jumps to ``start_cpu1`` function.
|
||||
ESP-IDF application entry point is ``call_start_cpu0`` function found in ``components/{IDF_TARGET_PATH_NAME}/cpu_start.c``. Two main things this function does are to enable heap allocator and to make APP CPU jump to its entry point, ``call_start_cpu1``. The code on PRO CPU sets the entry point for APP CPU, de-asserts APP CPU reset, and waits for a global flag to be set by the code running on APP CPU, indicating that it has started. Once this is done, PRO CPU jumps to ``start_cpu0`` function, and APP CPU jumps to ``start_cpu1`` function.
|
||||
|
||||
Both ``start_cpu0`` and ``start_cpu1`` are weak functions, meaning that they can be overridden in the application, if some application-specific change to initialization sequence is needed. Default implementation of ``start_cpu0`` enables or initializes components depending on choices made in ``menuconfig``. Please see source code of this function in ``components/esp32/cpu_start.c`` for an up to date list of steps performed. Note that any C++ global constructors present in the application will be called at this stage. Once all essential components are initialized, *main task* is created and FreeRTOS scheduler is started.
|
||||
Both ``start_cpu0`` and ``start_cpu1`` are weak functions, meaning that they can be overridden in the application, if some application-specific change to initialization sequence is needed. Default implementation of ``start_cpu0`` enables or initializes components depending on choices made in ``menuconfig``. Please see source code of this function in ``components/{IDF_TARGET_PATH_NAME}/cpu_start.c`` for an up to date list of steps performed. Note that any C++ global constructors present in the application will be called at this stage. Once all essential components are initialized, *main task* is created and FreeRTOS scheduler is started.
|
||||
|
||||
While PRO CPU does initialization in ``start_cpu0`` function, APP CPU spins in ``start_cpu1`` function, waiting for the scheduler to be started on the PRO CPU. Once the scheduler is started on the PRO CPU, code on the APP CPU starts the scheduler as well.
|
||||
|
||||
@@ -61,7 +61,7 @@ Main task is the task which runs ``app_main`` function. Main task stack size and
|
||||
Application memory layout
|
||||
-------------------------
|
||||
|
||||
ESP32 chip has flexible memory mapping features. This section describes how ESP-IDF uses these features by default.
|
||||
{IDF_TARGET_NAME} chip has flexible memory mapping features. This section describes how ESP-IDF uses these features by default.
|
||||
|
||||
Application code in ESP-IDF can be placed into one of the following memory regions.
|
||||
|
||||
@@ -75,17 +75,17 @@ A few components of ESP-IDF and parts of WiFi stack are placed into this region
|
||||
If some application code needs to be placed into IRAM, it can be done using ``IRAM_ATTR`` define::
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void IRAM_ATTR gpio_isr_handler(void* arg)
|
||||
{
|
||||
// ...
|
||||
// ...
|
||||
}
|
||||
|
||||
Here are the cases when parts of application may or should be placed into IRAM.
|
||||
|
||||
- Interrupt handlers must be placed into IRAM if ``ESP_INTR_FLAG_IRAM`` is used when registering the interrupt handler. In this case, ISR may only call functions placed into IRAM or functions present in ROM. *Note 1:* all FreeRTOS APIs are currently placed into IRAM, so are safe to call from interrupt handlers. If the ISR is placed into IRAM, all constant data used by the ISR and functions called from ISR (including, but not limited to, ``const char`` arrays), must be placed into DRAM using ``DRAM_ATTR``.
|
||||
|
||||
- Some timing critical code may be placed into IRAM to reduce the penalty associated with loading the code from flash. ESP32 reads code and data from flash via a 32 kB cache. In some cases, placing a function into IRAM may reduce delays caused by a cache miss.
|
||||
- Some timing critical code may be placed into IRAM to reduce the penalty associated with loading the code from flash. {IDF_TARGET_NAME} reads code and data from flash via a 32 kB cache. In some cases, placing a function into IRAM may reduce delays caused by a cache miss.
|
||||
|
||||
IROM (code executed from Flash)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -140,7 +140,7 @@ DMA Capable Requirement
|
||||
Most DMA controllers (e.g. SPI, sdmmc, etc.) have requirements that sending/receiving buffers should be placed in DRAM
|
||||
and word-aligned. We suggest to place DMA buffers in static variables rather than in the stack. Use macro ``DMA_ATTR``
|
||||
to declare global/local static variables like::
|
||||
|
||||
|
||||
DMA_ATTR uint8_t buffer[]="I want to send something";
|
||||
|
||||
void app_main()
|
||||
|
@@ -4,7 +4,7 @@ High-Level Interrupts
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
The Xtensa architecture has support for 32 interrupts, divided over 8 levels, plus an assortment of exceptions. On the ESP32, the interrupt mux allows most interrupt sources to be routed to these interrupts using the :doc:`interrupt allocator <../api-reference/system/intr_alloc>`. Normally, interrupts will be written in C, but ESP-IDF allows high-level interrupts to be written in assembly as well, allowing for very low interrupt latencies.
|
||||
The Xtensa architecture has support for 32 interrupts, divided over 8 levels, plus an assortment of exceptions. On the {IDF_TARGET_NAME}, the interrupt mux allows most interrupt sources to be routed to these interrupts using the :doc:`interrupt allocator <../api-reference/system/intr_alloc>`. Normally, interrupts will be written in C, but ESP-IDF allows high-level interrupts to be written in assembly as well, allowing for very low interrupt latencies.
|
||||
|
||||
Interrupt Levels
|
||||
----------------
|
||||
@@ -28,11 +28,11 @@ Using these symbols is done by creating an assembly file (suffix .S) and definin
|
||||
.align 4
|
||||
xt_highint5:
|
||||
... your code here
|
||||
rsr a0, EXCSAVE_5
|
||||
rsr a0, EXCSAVE_5
|
||||
rfi 5
|
||||
|
||||
For a real-life example, see the :component_file:`{IDF_TARGET_PATH_NAME}/dport_panic_highint_hdl.S` file; the panic handler interrupt is implemented there.
|
||||
|
||||
For a real-life example, see the :component_file:`esp32/dport_panic_highint_hdl.S` file; the panic handler interrupt is implemented there.
|
||||
|
||||
Notes
|
||||
-----
|
||||
@@ -49,7 +49,7 @@ Notes
|
||||
ld_include_my_isr_file:
|
||||
|
||||
|
||||
(The symbol is called ``ld_include_my_isr_file`` here but can have any arbitrary name not defined anywhere else.)
|
||||
(The symbol is called ``ld_include_my_isr_file`` here but can have any arbitrary name not defined anywhere else.)
|
||||
Then, in the component.mk, add this file as an unresolved symbol to the ld command line arguments::
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -u ld_include_my_isr_file
|
||||
|
23
docs/en/api-guides/inc/external-ram-esp32-notes.rst
Normal file
23
docs/en/api-guides/inc/external-ram-esp32-notes.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
* Regarding stacks in PSRAM: For tasks not calling on code in ROM in any way, directly or indirectly, the menuconfig option :ref:`CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` will eliminate the check in xTaskCreateStatic, allowing a task's stack to be in external RAM. Using this is not advised, however.
|
||||
* When used at 80 MHz clock speed, external RAM must also occupy either the HSPI or VSPI bus. Select which SPI host will be used by :ref:`CONFIG_SPIRAM_OCCUPY_SPI_HOST`.
|
||||
|
||||
|
||||
Chip revisions
|
||||
==============
|
||||
|
||||
There are some issues with certain revisions of ESP32 that have repercussions for use with external RAM. The issues are documented in the `ESP32 ECO`_ document. In particular, ESP-IDF handles the bugs mentioned in the following ways:
|
||||
|
||||
|
||||
ESP32 rev v0
|
||||
------------
|
||||
ESP-IDF has no workaround for the bugs in this revision of silicon, and it cannot be used to map external PSRAM into ESP32's main memory map.
|
||||
|
||||
|
||||
ESP32 rev v1
|
||||
------------
|
||||
The bugs in this revision of silicon cause issues if certain sequences of machine instructions operate on external memory. (`ESP32 ECO`_ 3.2). As a workaround, the GCC compiler received the flag ``-mfix-esp32-psram-cache-issue`` to filter these sequences and only output the code that can safely be executed. Enable this flag by checking :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND`.
|
||||
|
||||
Aside from linking to a recompiled version of Newlib with the additional flag, ESP-IDF also does the following:
|
||||
|
||||
- Avoids using some ROM functions
|
||||
- Allocates static memory for the WiFi stack
|
@@ -6,16 +6,16 @@ API Guides
|
||||
:maxdepth: 1
|
||||
|
||||
Application Level Tracing <app_trace>
|
||||
BluFi <blufi>
|
||||
:esp32: BluFi <blufi>
|
||||
Bootloader <bootloader>
|
||||
Build System <build-system>
|
||||
Build System (Legacy GNU Make) <build-system-legacy>
|
||||
:esp32: Build System (Legacy GNU Make) <build-system-legacy>
|
||||
Console Component <console>
|
||||
Deep Sleep Wake Stubs <deep-sleep-stub>
|
||||
Error Handling <error-handling>
|
||||
ESP-BLE-MESH <esp-ble-mesh/ble-mesh-index>
|
||||
:esp32: ESP-BLE-MESH <esp-ble-mesh/ble-mesh-index>
|
||||
ESP-MESH (Wi-Fi) <mesh>
|
||||
ESP32 Core Dump <core_dump>
|
||||
Core Dump <core_dump>
|
||||
Event Handling <event-handling>
|
||||
External SPI-connected RAM <external-ram>
|
||||
Fatal Errors <fatal-errors>
|
||||
@@ -27,13 +27,13 @@ API Guides
|
||||
Linker Script Generation <linker-script-generation>
|
||||
lwIP TCP/IP Stack <lwip>
|
||||
Partition Tables <partition-tables>
|
||||
RF Calibration <RF_calibration>
|
||||
:esp32: RF Calibration <RF_calibration>
|
||||
ROM debug console <romconsole>
|
||||
Secure Boot <../security/secure-boot>
|
||||
Thread Local Storage <thread-local-storage>
|
||||
Tools <tools/index>
|
||||
ULP Coprocessor <ulp>
|
||||
ULP Coprocessor (Legacy GNU Make) <ulp-legacy>
|
||||
Unit Testing (Legacy GNU Make) <unit-tests-legacy>
|
||||
:esp32: ULP Coprocessor (Legacy GNU Make) <ulp-legacy>
|
||||
Unit Testing <unit-tests>
|
||||
:esp32: Unit Testing (Legacy GNU Make) <unit-tests-legacy>
|
||||
WiFi Driver <wifi>
|
||||
|
@@ -11,7 +11,7 @@ The following instructions are alternative to downloading binary OpenOCD from `E
|
||||
Download Sources of OpenOCD
|
||||
===========================
|
||||
|
||||
The sources for the ESP32-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
The sources for the {IDF_TARGET_NAME}-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/openocd-esp32.git
|
||||
@@ -61,9 +61,9 @@ Optionally you can add ``sudo make install`` step at the end. Skip it, if you ha
|
||||
|
||||
.. note::
|
||||
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* If there is a submodule problem from OpenOCD, please ``cd`` to the ``openocd-esp32`` directory and input ``git submodule update --init``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the information of your device is not shown in the log, use ``./configure`` to enable it as described in ``../openocd-esp32/doc/INSTALL.txt``.
|
||||
* For details concerning compiling OpenOCD, please refer to ``openocd-esp32/README``.
|
||||
|
||||
@@ -73,4 +73,4 @@ Once ``make`` process is successfully completed, the executable of OpenOCD will
|
||||
Next Steps
|
||||
==========
|
||||
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-esp32-target`.
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-target`.
|
||||
|
@@ -10,7 +10,7 @@ The following instructions are alternative to downloading binary OpenOCD from `E
|
||||
Download Sources of OpenOCD
|
||||
===========================
|
||||
|
||||
The sources for the ESP32-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
The sources for the {IDF_TARGET_NAME}-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/openocd-esp32.git
|
||||
@@ -39,9 +39,9 @@ Optionally you can add ``sudo make install`` step at the end. Skip it, if you ha
|
||||
|
||||
.. note::
|
||||
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* If there is a submodule problem from OpenOCD, please ``cd`` to the ``openocd-esp32`` directory and input ``git submodule update --init``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the information of your device is not shown in the log, use ``./configure`` to enable it as described in ``../openocd-esp32/doc/INSTALL.txt``.
|
||||
* For details concerning compiling OpenOCD, please refer to ``openocd-esp32/README.OSX``.
|
||||
|
||||
@@ -50,6 +50,5 @@ Once ``make`` process is successfully completed, the executable of OpenOCD will
|
||||
Next Steps
|
||||
==========
|
||||
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-esp32-target`.
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-target`.
|
||||
|
||||
|
@@ -29,7 +29,7 @@ Install packages that are required to compile OpenOCD::
|
||||
Download Sources of OpenOCD
|
||||
===========================
|
||||
|
||||
The sources for the ESP32-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
The sources for the {IDF_TARGET_NAME}-enabled variant of OpenOCD are available from Espressif GitHub under https://github.com/espressif/openocd-esp32. To download the sources, use the following commands::
|
||||
|
||||
cd ~/esp
|
||||
git clone --recursive https://github.com/espressif/openocd-esp32.git
|
||||
@@ -62,18 +62,18 @@ Proceed with configuring and building OpenOCD::
|
||||
make
|
||||
cp ../libusb/MinGW32/dll/libusb-1.0.dll ./src
|
||||
cp /opt/i686-w64-mingw32/bin/libwinpthread-1.dll ./src
|
||||
|
||||
|
||||
|
||||
Optionally you can add ``make install`` step at the end. Skip it, if you have an existing OpenOCD (from e.g. another development platform), as it may get overwritten. Also you could use ``export DESTDIR="/custom/install/dir"; make install``.
|
||||
|
||||
.. note::
|
||||
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* Should an error occur, resolve it and try again until the command ``make`` works.
|
||||
* If there is a submodule problem from OpenOCD, please ``cd`` to the ``openocd-esp32`` directory and input ``git submodule update --init``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the ``./configure`` is successfully run, information of enabled JTAG will be printed under ``OpenOCD configuration summary``.
|
||||
* If the information of your device is not shown in the log, use ``./configure`` to enable it as described in ``../openocd-esp32/doc/INSTALL.txt``.
|
||||
* For details concerning compiling OpenOCD, please refer to ``openocd-esp32/README.Windows``.
|
||||
* Don't forget to copy `libusb-1.0.dll` and `libwinpthread-1.dll` into `OOCD_INSTALLDIR/bin` from ``~/esp/openocd-esp32/src``.
|
||||
* Don't forget to copy `libusb-1.0.dll` and `libwinpthread-1.dll` into `OOCD_INSTALLDIR/bin` from ``~/esp/openocd-esp32/src``.
|
||||
|
||||
Once ``make`` process is successfully completed, the executable of OpenOCD will be saved in ``~/esp/openocd-esp32/src`` directory.
|
||||
|
||||
@@ -110,4 +110,4 @@ A complete described previously process is provided below for the faster executi
|
||||
Next Steps
|
||||
==========
|
||||
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-esp32-target`.
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-configuring-target`.
|
||||
|
@@ -2,44 +2,64 @@ Configure Other JTAG Interface
|
||||
==============================
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Refer to section :ref:`jtag-debugging-selecting-jtag-adapter` for guidance what JTAG interface to select, so it is able to operate with OpenOCD and ESP32. Then follow three configuration steps below to get it working.
|
||||
Refer to section :ref:`jtag-debugging-selecting-jtag-adapter` for guidance what JTAG interface to select, so it is able to operate with OpenOCD and {IDF_TARGET_NAME}. Then follow three configuration steps below to get it working.
|
||||
|
||||
|
||||
Configure Hardware
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1. Identify all pins / signals on JTAG interface and ESP32 board, that should be connected to establish communication.
|
||||
1. Identify all pins / signals on JTAG interface and {IDF_TARGET_NAME} board, that should be connected to establish communication.
|
||||
|
||||
+---+---------------+-------------+
|
||||
| | ESP32 Pin | JTAG Signal |
|
||||
+===+===============+=============+
|
||||
| 1 | CHIP_PU | TRST_N |
|
||||
+---+---------------+-------------+
|
||||
| 2 | MTDO / GPIO15 | TDO |
|
||||
+---+---------------+-------------+
|
||||
| 3 | MTDI / GPIO12 | TDI |
|
||||
+---+---------------+-------------+
|
||||
| 4 | MTCK / GPIO13 | TCK |
|
||||
+---+---------------+-------------+
|
||||
| 5 | MTMS / GPIO14 | TMS |
|
||||
+---+---------------+-------------+
|
||||
| 6 | GND | GND |
|
||||
+---+---------------+-------------+
|
||||
.. only:: esp32
|
||||
|
||||
2. Verify if ESP32 pins used for JTAG communication are not connected to some other h/w that may disturb JTAG operation.
|
||||
+---+-----------------------+-------------+
|
||||
| | ESP32 Pin | JTAG Signal |
|
||||
+===+=======================+=============+
|
||||
| 1 | CHIP_PU | TRST_N |
|
||||
+---+-----------------------+-------------+
|
||||
| 2 | MTDO / GPIO15 | TDO |
|
||||
+---+-----------------------+-------------+
|
||||
| 3 | MTDI / GPIO12 | TDI |
|
||||
+---+-----------------------+-------------+
|
||||
| 4 | MTCK / GPIO13 | TCK |
|
||||
+---+-----------------------+-------------+
|
||||
| 5 | MTMS / GPIO14 | TMS |
|
||||
+---+-----------------------+-------------+
|
||||
| 6 | GND | GND |
|
||||
+---+-----------------------+-------------+
|
||||
|
||||
3. Connect identified pin / signals of ESP32 and JTAG interface.
|
||||
.. only:: esp32s2
|
||||
|
||||
+---+-----------------------+-------------+
|
||||
| | ESP32-S2 Pin | JTAG Signal |
|
||||
+===+=======================+=============+
|
||||
| 1 | CHIP_PU | TRST_N |
|
||||
+---+-----------------------+-------------+
|
||||
| 2 | MTDO / GPIO40 | TDO |
|
||||
+---+-----------------------+-------------+
|
||||
| 3 | MTDI / GPIO41 | TDI |
|
||||
+---+-----------------------+-------------+
|
||||
| 4 | MTCK / GPIO39 | TCK |
|
||||
+---+-----------------------+-------------+
|
||||
| 5 | MTMS / GPIO42 | TMS |
|
||||
+---+-----------------------+-------------+
|
||||
| 6 | GND | GND |
|
||||
+---+-----------------------+-------------+
|
||||
|
||||
2. Verify if {IDF_TARGET_NAME} pins used for JTAG communication are not connected to some other h/w that may disturb JTAG operation.
|
||||
|
||||
3. Connect identified pin / signals of {IDF_TARGET_NAME} and JTAG interface.
|
||||
|
||||
|
||||
Configure Drivers
|
||||
^^^^^^^^^^^^^^^^^
|
||||
You may need to install driver s/w to make JTAG work with computer. Refer to documentation of JTAG adapter, that should provide related details.
|
||||
You may need to install driver s/w to make JTAG work with computer. Refer to documentation of JTAG adapter, that should provide related details.
|
||||
|
||||
|
||||
Connect
|
||||
^^^^^^^
|
||||
|
||||
Connect JTAG interface to the computer. Power on ESP32 and JTAG interface boards. Check if JTAG interface is visible by computer.
|
||||
Connect JTAG interface to the computer. Power on {IDF_TARGET_NAME} and JTAG interface boards. Check if JTAG interface is visible by computer.
|
||||
|
||||
|
||||
To carry on with debugging environment setup, proceed to section :ref:`jtag-debugging-run-openocd`.
|
||||
|
@@ -8,7 +8,7 @@ All versions of ESP-WROVER-KIT boards have built-in JTAG functionality. Putting
|
||||
Configure Hardware
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1. Enable on-board JTAG functionality by setting JP8 according to :doc:`../../hw-reference/get-started-wrover-kit`, Section :ref:`get-started-esp-wrover-kit-v4.1-setup-options`.
|
||||
1. Enable on-board JTAG functionality by setting JP8 according to :doc:`../../hw-reference/esp32/get-started-wrover-kit`, Section :ref:`get-started-esp-wrover-kit-v4.1-setup-options`.
|
||||
|
||||
2. Verify if ESP32 pins used for JTAG communication are not connected to some other h/w that may disturb JTAG operation:
|
||||
|
||||
@@ -104,7 +104,7 @@ On macOS, using FT2232 for JTAG and serial port at the same time needs some addi
|
||||
|
||||
1. Manually unload the FTDI serial port driver before starting OpenOCD, start OpenOCD, then load the serial port driver.
|
||||
|
||||
2. Modify FTDI driver configuration so that it doesn't load itself for channel B of FT2232 chip, which is the channel used for JTAG on WROVER KIT.
|
||||
2. Modify FTDI driver configuration so that it doesn't load itself for channel B of FT2232 chip, which is the channel used for JTAG on WROVER KIT.
|
||||
|
||||
Manually unloading the driver
|
||||
.............................
|
||||
|
@@ -38,7 +38,7 @@ Examples in this section
|
||||
Navigating through the code, call stack and threads
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When the target is halted, debugger shows the list of threads in "Debug" window. The line of code where program halted is highlighted in another window below, as shown on the following picture. The LED stops blinking.
|
||||
When the target is halted, debugger shows the list of threads in "Debug" window. The line of code where program halted is highlighted in another window below, as shown on the following picture. The LED stops blinking.
|
||||
|
||||
.. figure:: ../../../_static/debugging-target-halted.jpg
|
||||
:align: center
|
||||
@@ -47,7 +47,7 @@ When the target is halted, debugger shows the list of threads in "Debug" window.
|
||||
|
||||
Target halted during debugging
|
||||
|
||||
Specific thread where the program halted is expanded showing the call stack. It represents function calls that lead up to the highlighted line of code, where the target halted. The first line of call stack under Thread #1 contains the last called function ``app_main()``, that in turn was called from function ``main_task()`` shown in a line below. Each line of the stack also contains the file name and line number where the function was called. By clicking / highlighting the stack entries, in window below, you will see contents of this file.
|
||||
Specific thread where the program halted is expanded showing the call stack. It represents function calls that lead up to the highlighted line of code, where the target halted. The first line of call stack under Thread #1 contains the last called function ``app_main()``, that in turn was called from function ``main_task()`` shown in a line below. Each line of the stack also contains the file name and line number where the function was called. By clicking / highlighting the stack entries, in window below, you will see contents of this file.
|
||||
|
||||
By expanding threads you can navigate throughout the application. Expand Thread #5 that contains much longer call stack. You will see there, besides function calls, numbers like ``0x4000000c``. They represent addresses of binary code not provided in source form.
|
||||
|
||||
@@ -70,7 +70,7 @@ Setting and clearing breakpoints
|
||||
|
||||
When debugging, we would like to be able to stop the application at critical lines of code and then examine the state of specific variables, memory and registers / peripherals. To do so we are using breakpoints. They provide a convenient way to quickly get to and halt the application at specific line.
|
||||
|
||||
Let's establish two breakpoints when the state of LED changes. Basing on code listing above, this happens at lines 33 and 36. To do so, hold the "Control" on the keyboard and double clink on number ``33`` in file ``blink.c`` file. A dialog will open where you can confirm your selection by pressing "OK" button. If you do not like to see the dialog just double click the line number. Set another breakpoint in line 36.
|
||||
Let's establish two breakpoints when the state of LED changes. Basing on code listing above, this happens at lines 33 and 36. To do so, hold the "Control" on the keyboard and double clink on number ``33`` in file ``blink.c`` file. A dialog will open where you can confirm your selection by pressing "OK" button. If you do not like to see the dialog just double click the line number. Set another breakpoint in line 36.
|
||||
|
||||
.. figure:: ../../../_static/debugging-setting-breakpoint.jpg
|
||||
:align: center
|
||||
@@ -141,7 +141,7 @@ If you press "Step Into (F5)" instead, then debugger will step inside subroutine
|
||||
|
||||
Stepping through the code with "Step Into (F5)"
|
||||
|
||||
In this particular case debugger stepped inside ``gpio_set_level(BLINK_GPIO, 0)`` and effectively moved to ``gpio.c`` driver code.
|
||||
In this particular case debugger stepped inside ``gpio_set_level(BLINK_GPIO, 0)`` and effectively moved to ``gpio.c`` driver code.
|
||||
|
||||
See :ref:`jtag-debugging-tip-why-next-works-as-step` for potential limitation of using ``next`` command.
|
||||
|
||||
@@ -150,10 +150,11 @@ See :ref:`jtag-debugging-tip-why-next-works-as-step` for potential limitation of
|
||||
|
||||
Checking and setting memory
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To display or set contents of memory use "Memory" tab at the bottom of "Debug" perspective.
|
||||
|
||||
With the "Memory" tab, we will read from and write to the memory location ``0x3FF44004`` labeled as ``GPIO_OUT_REG`` used to set and clear individual GPIO's. For more information please refer to `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>`__, chapter IO_MUX and GPIO Matrix.
|
||||
With the "Memory" tab, we will read from and write to the memory location ``0x3FF44004`` labeled as ``GPIO_OUT_REG`` used to set and clear individual GPIO's.
|
||||
|
||||
For more information please refer to `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`__, chapter IO_MUX and GPIO Matrix.
|
||||
|
||||
Being in the same ``blink.c`` project as before, set two breakpoints right after ``gpio_set_level`` instruction. Click "Memory" tab and then "Add Memory Monitor" button. Enter ``0x3FF44004`` in provided dialog.
|
||||
|
||||
@@ -175,7 +176,7 @@ You should see one bit being flipped over at memory location ``0x3FF44004`` (and
|
||||
|
||||
Observing memory location 0x3FF44004 changing one bit to "OFF"
|
||||
|
||||
To set memory use the same "Monitor" tab and the same memory location. Type in alternate bit pattern as previously observed. Immediately after pressing enter you will see LED changing the state.
|
||||
To set memory use the same "Monitor" tab and the same memory location. Type in alternate bit pattern as previously observed. Immediately after pressing enter you will see LED changing the state.
|
||||
|
||||
|
||||
.. _jtag-debugging-examples-eclipse-06:
|
||||
@@ -209,7 +210,7 @@ To modify ``i`` enter a new number in "Value" column. After pressing "Resume (F8
|
||||
Setting conditional breakpoints
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Here comes more interesting part. You may set a breakpoint to halt the program execution, if certain condition is satisfied. Right click on the breakpoint to open a context menu and select "Breakpoint Properties". Change the selection under "Type:" to "Hardware" and enter a "Condition:" like ``i == 2``.
|
||||
Here comes more interesting part. You may set a breakpoint to halt the program execution, if certain condition is satisfied. Right click on the breakpoint to open a context menu and select "Breakpoint Properties". Change the selection under "Type:" to "Hardware" and enter a "Condition:" like ``i == 2``.
|
||||
|
||||
.. figure:: ../../../_static/debugging-setting-conditional-breakpoint.jpg
|
||||
:align: center
|
||||
@@ -230,7 +231,7 @@ Verify if your target is ready and loaded with :example:`get-started/blink` exam
|
||||
|
||||
Temporary breakpoint 1, app_main () at /home/user-name/esp/blink/main/./blink.c:43
|
||||
43 xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
|
||||
|
||||
@@ -251,19 +252,19 @@ Examples in this section
|
||||
Navigating through the code, call stack and threads
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When you see the ``(gdb)`` prompt, the application is halted. LED should not be blinking.
|
||||
When you see the ``(gdb)`` prompt, the application is halted. LED should not be blinking.
|
||||
|
||||
To find out where exactly the code is halted, enter ``l`` or ``list``, and debugger will show couple of lines of code around the halt point (line 43 of code in file ``blink.c``) ::
|
||||
|
||||
(gdb) l
|
||||
38 }
|
||||
39 }
|
||||
40
|
||||
40
|
||||
41 void app_main()
|
||||
42 {
|
||||
43 xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
|
||||
44 }
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
|
||||
Check how code listing works by entering, e.g. ``l 30, 40`` to see particular range of lines of code.
|
||||
@@ -272,15 +273,15 @@ You can use ``bt`` or ``backtrace`` to see what function calls lead up to this c
|
||||
|
||||
(gdb) bt
|
||||
#0 app_main () at /home/user-name/esp/blink/main/./blink.c:43
|
||||
#1 0x400d057e in main_task (args=0x0) at /home/user-name/esp/esp-idf/components/esp32/./cpu_start.c:339
|
||||
(gdb)
|
||||
#1 0x400d057e in main_task (args=0x0) at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./cpu_start.c:339
|
||||
(gdb)
|
||||
|
||||
Line #0 of output provides the last function call before the application halted, i.e. ``app_main ()`` we have listed previously. The ``app_main ()`` was in turn called by function ``main_task`` from line 339 of code located in file ``cpu_start.c``.
|
||||
Line #0 of output provides the last function call before the application halted, i.e. ``app_main ()`` we have listed previously. The ``app_main ()`` was in turn called by function ``main_task`` from line 339 of code located in file ``cpu_start.c``.
|
||||
|
||||
To get to the context of ``main_task`` in file ``cpu_start.c``, enter ``frame N``, where N = 1, because the ``main_task`` is listed under #1)::
|
||||
|
||||
(gdb) frame 1
|
||||
#1 0x400d057e in main_task (args=0x0) at /home/user-name/esp/esp-idf/components/esp32/./cpu_start.c:339
|
||||
#1 0x400d057e in main_task (args=0x0) at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./cpu_start.c:339
|
||||
339 app_main();
|
||||
(gdb)
|
||||
|
||||
@@ -295,8 +296,8 @@ Enter ``l`` and this will reveal the piece of code that called ``app_main()`` (i
|
||||
339 app_main();
|
||||
340 vTaskDelete(NULL);
|
||||
341 }
|
||||
342
|
||||
(gdb)
|
||||
342
|
||||
(gdb)
|
||||
|
||||
By listing some lines before, you will see the function name ``main_task`` we have been looking for::
|
||||
|
||||
@@ -317,27 +318,27 @@ By listing some lines before, you will see the function name ``main_task`` we ha
|
||||
339 app_main();
|
||||
340 vTaskDelete(NULL);
|
||||
341 }
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
To see the other code, enter ``i threads``. This will show the list of threads running on target::
|
||||
|
||||
(gdb) i threads
|
||||
Id Target Id Frame
|
||||
Id Target Id Frame
|
||||
8 Thread 1073411336 (dport) 0x400d0848 in dport_access_init_core (arg=<optimized out>)
|
||||
at /home/user-name/esp/esp-idf/components/esp32/./dport_access.c:170
|
||||
7 Thread 1073408744 (ipc0) xQueueGenericReceive (xQueue=0x3ffae694, pvBuffer=0x0, xTicksToWait=1644638200,
|
||||
at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./dport_access.c:170
|
||||
7 Thread 1073408744 (ipc0) xQueueGenericReceive (xQueue=0x3ffae694, pvBuffer=0x0, xTicksToWait=1644638200,
|
||||
xJustPeeking=0) at /home/user-name/esp/esp-idf/components/freertos/./queue.c:1452
|
||||
6 Thread 1073431096 (Tmr Svc) prvTimerTask (pvParameters=0x0)
|
||||
at /home/user-name/esp/esp-idf/components/freertos/./timers.c:445
|
||||
5 Thread 1073410208 (ipc1 : Running) 0x4000bfea in ?? ()
|
||||
4 Thread 1073432224 (dport) dport_access_init_core (arg=0x0)
|
||||
at /home/user-name/esp/esp-idf/components/esp32/./dport_access.c:150
|
||||
at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./dport_access.c:150
|
||||
3 Thread 1073413156 (IDLE) prvIdleTask (pvParameters=0x0)
|
||||
at /home/user-name/esp/esp-idf/components/freertos/./tasks.c:3282
|
||||
2 Thread 1073413512 (IDLE) prvIdleTask (pvParameters=0x0)
|
||||
at /home/user-name/esp/esp-idf/components/freertos/./tasks.c:3282
|
||||
* 1 Thread 1073411772 (main : Running) app_main () at /home/user-name/esp/blink/main/./blink.c:43
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
The thread list shows the last function calls per each thread together with the name of C source file if available.
|
||||
|
||||
@@ -360,7 +361,7 @@ Then check the backtrace::
|
||||
#6 0x4000000c in ?? ()
|
||||
#7 0x4000000c in ?? ()
|
||||
#8 0x4000000c in ?? ()
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
As you see, the backtrace may contain several entries. This will let you check what exact sequence of function calls lead to the code where the target halted. Question marks ``??`` instead of a function name indicate that application is available only in binary format, without any source file in C language. The value like ``0x4000bfea`` is the memory address of the function call.
|
||||
|
||||
@@ -385,18 +386,18 @@ If you new enter ``c``, the processor will run and halt at a breakpoint. Enterin
|
||||
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB6F6 (active) APP_CPU: PC=0x400D10D8
|
||||
Target halted. PRO_CPU: PC=0x400DB6F6 (active) APP_CPU: PC=0x400D10D8
|
||||
|
||||
Breakpoint 2, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:33
|
||||
33 gpio_set_level(BLINK_GPIO, 0);
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB6F8 (active) APP_CPU: PC=0x400D10D8
|
||||
Target halted. PRO_CPU: PC=0x400DB704 (active) APP_CPU: PC=0x400D10D8
|
||||
Target halted. PRO_CPU: PC=0x400DB6F8 (active) APP_CPU: PC=0x400D10D8
|
||||
Target halted. PRO_CPU: PC=0x400DB704 (active) APP_CPU: PC=0x400D10D8
|
||||
|
||||
Breakpoint 3, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:36
|
||||
36 gpio_set_level(BLINK_GPIO, 1);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
You will be also able to see that LED is changing the state only if you resume program execution by entering ``c``.
|
||||
|
||||
@@ -408,16 +409,16 @@ To examine how many breakpoints are set and where, use command ``info break``::
|
||||
breakpoint already hit 1 time
|
||||
3 breakpoint keep y 0x400db704 in blink_task at /home/user-name/esp/blink/main/./blink.c:36
|
||||
breakpoint already hit 1 time
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
Please note that breakpoint numbers (listed under ``Num``) start with ``2``. This is because first breakpoint has been already established at function ``app_main()`` by running command ``thb app_main`` on debugger launch. As it was a temporary breakpoint, it has been automatically deleted and now is not listed anymore.
|
||||
|
||||
To remove breakpoints enter ``delete N`` command (in short ``d N``), where ``N`` is the breakpoint number::
|
||||
To remove breakpoints enter ``delete N`` command (in short ``d N``), where ``N`` is the breakpoint number::
|
||||
|
||||
(gdb) delete 1
|
||||
No breakpoint number 1.
|
||||
(gdb) delete 2
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
Read more about breakpoints under :ref:`jtag-debugging-tip-breakpoints` and :ref:`jtag-debugging-tip-where-breakpoints`
|
||||
|
||||
@@ -438,9 +439,9 @@ To check it delete all breakpoints and enter ``c`` to resume application. Then e
|
||||
|
||||
Program received signal SIGINT, Interrupt.
|
||||
[Switching to Thread 1073413512]
|
||||
0x400d0c00 in esp_vApplicationIdleHook () at /home/user-name/esp/esp-idf/components/esp32/./freertos_hooks.c:52
|
||||
0x400d0c00 in esp_vApplicationIdleHook () at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./freertos_hooks.c:52
|
||||
52 asm("waiti 0");
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
In particular case above, the application has been halted in line 52 of code in file ``freertos_hooks.c``. Now you can resume it again by enter ``c`` or do some debugging as discussed below.
|
||||
|
||||
@@ -462,46 +463,46 @@ To demonstrate this functionality, using command ``break`` and ``delete`` discus
|
||||
Num Type Disp Enb Address What
|
||||
3 breakpoint keep y 0x400db704 in blink_task at /home/user-name/esp/blink/main/./blink.c:36
|
||||
breakpoint already hit 1 time
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
Resume program by entering ``c`` and let it halt::
|
||||
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB754 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB754 (active) APP_CPU: PC=0x400D1128
|
||||
|
||||
Breakpoint 3, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:36
|
||||
36 gpio_set_level(BLINK_GPIO, 1);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
Then enter ``n`` couple of times to see how debugger is stepping one program line at a time::
|
||||
|
||||
(gdb) n
|
||||
Target halted. PRO_CPU: PC=0x400DB756 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB758 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75B (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB756 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB758 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75B (active) APP_CPU: PC=0x400D1128
|
||||
37 vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
(gdb) n
|
||||
Target halted. PRO_CPU: PC=0x400DB75E (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400846FC (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB761 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB746 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75E (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400846FC (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB761 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB746 (active) APP_CPU: PC=0x400D1128
|
||||
33 gpio_set_level(BLINK_GPIO, 0);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
If you enter ``s`` instead, then debugger will step inside subroutine calls::
|
||||
|
||||
(gdb) s
|
||||
Target halted. PRO_CPU: PC=0x400DB748 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB748 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128
|
||||
gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/driver/./gpio.c:183
|
||||
183 GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
In this particular case debugger stepped inside ``gpio_set_level(BLINK_GPIO, 0)`` and effectively moved to ``gpio.c`` driver code.
|
||||
In this particular case debugger stepped inside ``gpio_set_level(BLINK_GPIO, 0)`` and effectively moved to ``gpio.c`` driver code.
|
||||
|
||||
See :ref:`jtag-debugging-tip-why-next-works-as-step` for potential limitation of using ``next`` command.
|
||||
|
||||
@@ -513,14 +514,16 @@ Checking and setting memory
|
||||
|
||||
Displaying the contents of memory is done with command ``x``. With additional parameters you may vary the format and count of memory locations displayed. Run ``help x`` to see more details. Companion command to ``x`` is ``set`` that let you write values to the memory.
|
||||
|
||||
We will demonstrate how ``x`` and ``set`` work by reading from and writing to the memory location ``0x3FF44004`` labeled as ``GPIO_OUT_REG`` used to set and clear individual GPIO's. For more information please refer to `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>`__, chapter IO_MUX and GPIO Matrix.
|
||||
We will demonstrate how ``x`` and ``set`` work by reading from and writing to the memory location ``0x3FF44004`` labeled as ``GPIO_OUT_REG`` used to set and clear individual GPIO's.
|
||||
|
||||
For more information please refer to `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`__, chapter IO_MUX and GPIO Matrix.
|
||||
|
||||
Being in the same ``blink.c`` project as before, set two breakpoints right after ``gpio_set_level`` instruction. Enter two times ``c`` to get to the break point followed by ``x /1wx 0x3FF44004`` to display contents of ``GPIO_OUT_REG`` memory location::
|
||||
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB75E (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB74E (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75E (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB74E (active) APP_CPU: PC=0x400D1128
|
||||
|
||||
Breakpoint 2, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:34
|
||||
34 vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
@@ -528,14 +531,14 @@ Being in the same ``blink.c`` project as before, set two breakpoints right after
|
||||
0x3ff44004: 0x00000000
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB751 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75B (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB751 (active) APP_CPU: PC=0x400D1128
|
||||
Target halted. PRO_CPU: PC=0x400DB75B (active) APP_CPU: PC=0x400D1128
|
||||
|
||||
Breakpoint 3, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:37
|
||||
37 vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
(gdb) x /1wx 0x3FF44004
|
||||
0x3ff44004: 0x00000010
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
If your are blinking LED connected to GPIO4, then you should see fourth bit being flipped each time the LED changes the state::
|
||||
|
||||
@@ -571,7 +574,7 @@ This will insert so called "watchpoint" in each place of code where variable ``i
|
||||
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB751 (active) APP_CPU: PC=0x400D0811
|
||||
Target halted. PRO_CPU: PC=0x400DB751 (active) APP_CPU: PC=0x400D0811
|
||||
[New Thread 1073432196]
|
||||
|
||||
Program received signal SIGTRAP, Trace/breakpoint trap.
|
||||
@@ -584,14 +587,14 @@ Resume application couple more times so ``i`` gets incremented. Now you can ente
|
||||
|
||||
(gdb) p i
|
||||
$1 = 3
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
To modify the value of ``i`` use ``set`` command as below (you can then print it out to check if it has been indeed changed)::
|
||||
|
||||
(gdb) set var i = 0
|
||||
(gdb) p i
|
||||
$3 = 0
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
You may have up to two watchpoints, see :ref:`jtag-debugging-tip-breakpoints`.
|
||||
|
||||
@@ -607,21 +610,21 @@ Here comes more interesting part. You may set a breakpoint to halt the program e
|
||||
Breakpoint 3 at 0x400db753: file /home/user-name/esp/blink/main/./blink.c, line 34.
|
||||
(gdb)
|
||||
|
||||
Above command sets conditional breakpoint to halt program execution in line ``34`` of ``blink.c`` if ``i == 2``.
|
||||
Above command sets conditional breakpoint to halt program execution in line ``34`` of ``blink.c`` if ``i == 2``.
|
||||
|
||||
If current value of ``i`` is less than ``2`` and program is resumed, it will blink LED in a loop until condition ``i == 2`` gets true and then finally halt::
|
||||
|
||||
(gdb) set var i = 0
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Target halted. PRO_CPU: PC=0x400DB755 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB753 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB755 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB753 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB755 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB753 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB755 (active) APP_CPU: PC=0x400D112C
|
||||
Target halted. PRO_CPU: PC=0x400DB753 (active) APP_CPU: PC=0x400D112C
|
||||
|
||||
Breakpoint 3, blink_task (pvParameter=0x0) at /home/user-name/esp/blink/main/./blink.c:34
|
||||
34 gpio_set_level(BLINK_GPIO, 0);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
|
||||
Obtaining help on commands
|
||||
@@ -635,7 +638,7 @@ Commands presented so for should provide are very basis and intended to let you
|
||||
Unlike "step", if the current source line calls a subroutine,
|
||||
this command does not enter the subroutine, but instead steps over
|
||||
the call, in effect treating it as a single source line.
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
By typing just ``help``, you will get top level list of command classes, to aid you drilling down to more details. Optionally refer to available GDB cheat sheets, for instance http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf. Good to have as a reference (even if not all commands are applicable in an embedded environment).
|
||||
|
||||
@@ -643,7 +646,7 @@ By typing just ``help``, you will get top level list of command classes, to aid
|
||||
Ending debugger session
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To quit debugger enter ``q``::
|
||||
To quit debugger enter ``q``::
|
||||
|
||||
(gdb) q
|
||||
A debugging session is active.
|
||||
@@ -653,4 +656,4 @@ To quit debugger enter ``q``::
|
||||
Quit anyway? (y or n) y
|
||||
Detaching from program: /home/user-name/esp/blink/build/blink.elf, Remote target
|
||||
Ending remote debugging.
|
||||
user-name@computer-name:~/esp/blink$
|
||||
user-name@computer-name:~/esp/blink$
|
||||
|
@@ -2,18 +2,18 @@ JTAG Debugging
|
||||
==============
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
This document provides a guide to installing OpenOCD for ESP32 and debugging using
|
||||
This document provides a guide to installing OpenOCD for {IDF_TARGET_NAME} and debugging using
|
||||
GDB. The document is structured as follows:
|
||||
|
||||
:ref:`jtag-debugging-introduction`
|
||||
Introduction to the purpose of this guide.
|
||||
:ref:`jtag-debugging-how-it-works`
|
||||
Description how ESP32, JTAG interface, OpenOCD and GDB are interconnected and working together to enable debugging of ESP32.
|
||||
Description how {IDF_TARGET_NAME}, JTAG interface, OpenOCD and GDB are interconnected and working together to enable debugging of {IDF_TARGET_NAME}.
|
||||
:ref:`jtag-debugging-selecting-jtag-adapter`
|
||||
What are the criteria and options to select JTAG adapter hardware.
|
||||
:ref:`jtag-debugging-setup-openocd`
|
||||
Procedure to install OpenOCD and verify that it is installed.
|
||||
:ref:`jtag-debugging-configuring-esp32-target`
|
||||
:ref:`jtag-debugging-configuring-target`
|
||||
Configuration of OpenOCD software and set up JTAG adapter hardware that will make together a debugging target.
|
||||
:ref:`jtag-debugging-launching-debugger`
|
||||
Steps to start up a debug session with GDB from :ref:`jtag-debugging-using-debugger-eclipse` and from :ref:`jtag-debugging-using-debugger-command-line`.
|
||||
@@ -22,7 +22,7 @@ GDB. The document is structured as follows:
|
||||
:ref:`jtag-debugging-building-openocd`
|
||||
Procedure to build OpenOCD from sources for :doc:`Windows <building-openocd-windows>`, :doc:`Linux <building-openocd-linux>` and :doc:`MacOS <building-openocd-macos>` operating systems.
|
||||
:ref:`jtag-debugging-tips-and-quirks`
|
||||
This section provides collection of tips and quirks related JTAG debugging of ESP32 with OpenOCD and GDB.
|
||||
This section provides collection of tips and quirks related JTAG debugging of {IDF_TARGET_NAME} with OpenOCD and GDB.
|
||||
|
||||
|
||||
.. _jtag-debugging-introduction:
|
||||
@@ -30,13 +30,15 @@ GDB. The document is structured as follows:
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The ESP32 has two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS OS that comes with ESP-IDF is capable of multi-core preemptive multithreading, allowing for an intuitive way of writing software.
|
||||
.. only:: esp32
|
||||
|
||||
The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused by two threads, running even simultaneously on two different CPU cores, can take a long time when all you have are printf statements. A better and in many cases quicker way to debug such problems is by using a debugger, connected to the processors over a debug port.
|
||||
The ESP32 has two powerful Xtensa cores, allowing for a great deal of variety of program architectures. The FreeRTOS OS that comes with ESP-IDF is capable of multi-core preemptive multithreading, allowing for an intuitive way of writing software.
|
||||
|
||||
Espressif has ported OpenOCD to support the ESP32 processor and the multicore FreeRTOS, which will be the foundation of most ESP32 apps, and has written some tools to help with features OpenOCD does not support natively.
|
||||
The downside of the ease of programming is that debugging without the right tools is harder: figuring out a bug that is caused by two threads, running even simultaneously on two different CPU cores, can take a long time when all you have are printf statements. A better and in many cases quicker way to debug such problems is by using a debugger, connected to the processors over a debug port.
|
||||
|
||||
This document provides a guide to installing OpenOCD for ESP32 and debugging using GDB under Linux, Windows and MacOS. Except for OS specific installation procedures, the s/w user interface and use procedures are the same across all supported operating systems.
|
||||
Espressif has ported OpenOCD to support the {IDF_TARGET_NAME} processor and the multicore FreeRTOS, which will be the foundation of most {IDF_TARGET_NAME} apps, and has written some tools to help with features OpenOCD does not support natively.
|
||||
|
||||
This document provides a guide to installing OpenOCD for {IDF_TARGET_NAME} and debugging using GDB under Linux, Windows and MacOS. Except for OS specific installation procedures, the s/w user interface and use procedures are the same across all supported operating systems.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -47,20 +49,22 @@ This document provides a guide to installing OpenOCD for ESP32 and debugging usi
|
||||
How it Works?
|
||||
-------------
|
||||
|
||||
The key software and hardware to perform debugging of ESP32 with OpenOCD over JTAG (Joint Test Action Group) interface is presented below and includes **xtensa-esp32-elf-gdb debugger**, **OpenOCD on chip debugger** and **JTAG adapter** connected to **ESP32** target.
|
||||
The key software and hardware to perform debugging of {IDF_TARGET_NAME} with OpenOCD over JTAG (Joint Test Action Group) interface is presented below and includes xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-gdb debugger, OpenOCD on chip debugger and JTAG adapter connected to {IDF_TARGET_NAME} target.
|
||||
|
||||
.. figure:: ../../../_static/jtag-debugging-overview.jpg
|
||||
:align: center
|
||||
:alt: JTAG debugging - overview diagram
|
||||
:alt: JTAG debugging - overview diagram
|
||||
:figclass: align-center
|
||||
|
||||
JTAG debugging - overview diagram
|
||||
JTAG debugging - overview diagram
|
||||
|
||||
Under "Application Loading and Monitoring" there is another software and hardware to compile, build and flash application to ESP32, as well as to provide means to monitor diagnostic messages from ESP32.
|
||||
Under "Application Loading and Monitoring" there is another software and hardware to compile, build and flash application to {IDF_TARGET_NAME}, as well as to provide means to monitor diagnostic messages from {IDF_TARGET_NAME}.
|
||||
|
||||
Debugging using JTAG and application loading / monitoring is integrated under the `Eclipse <https://www.eclipse.org/>`_ environment, to provide quick and easy transition from writing, compiling and loading the code to debugging, back to writing the code, and so on. All the software is available for Windows, Linux and MacOS platforms.
|
||||
|
||||
If the :doc:`ESP-WROVER-KIT <../../hw-reference/modules-and-boards>` is used, then connection from PC to ESP32 is done effectively with a single USB cable thanks to FT2232H chip installed on WROVER, which provides two USB channels, one for JTAG and the second for UART connection.
|
||||
.. only:: esp32
|
||||
|
||||
If the :doc:`ESP-WROVER-KIT <../../hw-reference/modules-and-boards>` is used, then connection from PC to ESP32 is done effectively with a single USB cable thanks to FT2232H chip installed on WROVER, which provides two USB channels, one for JTAG and the second for UART connection.
|
||||
|
||||
Depending on user preferences, both `debugger` and `idf.py build` can be operated directly from terminal/command line, instead from Eclipse.
|
||||
|
||||
@@ -70,13 +74,13 @@ Depending on user preferences, both `debugger` and `idf.py build` can be operate
|
||||
Selecting JTAG Adapter
|
||||
----------------------
|
||||
|
||||
The quickest and most convenient way to start with JTAG debugging is by using :doc:`ESP-WROVER-KIT <../../hw-reference/modules-and-boards>`. Each version of this development board has JTAG interface already build in. No need for an external JTAG adapter and extra wiring / cable to connect JTAG to ESP32. WROVER KIT is using FT2232H JTAG interface operating at 20 MHz clock speed, which is difficult to achieve with an external adapter.
|
||||
The quickest and most convenient way to start with JTAG debugging is by using :doc:`ESP-WROVER-KIT <../../hw-reference/modules-and-boards>`. Each version of this development board has JTAG interface already build in. No need for an external JTAG adapter and extra wiring / cable to connect JTAG to {IDF_TARGET_NAME}. WROVER KIT is using FT2232H JTAG interface operating at 20 MHz clock speed, which is difficult to achieve with an external adapter.
|
||||
|
||||
If you decide to use separate JTAG adapter, look for one that is compatible with both the voltage levels on the ESP32 as well as with the OpenOCD software. The JTAG port on the ESP32 is an industry-standard JTAG port which lacks (and does not need) the TRST pin. The JTAG I/O pins all are powered from the VDD_3P3_RTC pin (which normally would be powered by a 3.3 V rail) so the JTAG adapter needs to be able to work with JTAG pins in that voltage range.
|
||||
If you decide to use separate JTAG adapter, look for one that is compatible with both the voltage levels on the {IDF_TARGET_NAME} as well as with the OpenOCD software. The JTAG port on the {IDF_TARGET_NAME} is an industry-standard JTAG port which lacks (and does not need) the TRST pin. The JTAG I/O pins all are powered from the VDD_3P3_RTC pin (which normally would be powered by a 3.3 V rail) so the JTAG adapter needs to be able to work with JTAG pins in that voltage range.
|
||||
|
||||
On the software side, OpenOCD supports a fair amount of JTAG adapters. See http://openocd.org/doc/html/Debug-Adapter-Hardware.html for an (unfortunately slightly incomplete) list of the adapters OpenOCD works with. This page lists SWD-compatible adapters as well; take note that the ESP32 does not support SWD. JTAG adapters that are hardcoded to a specific product line, e.g. ST-LINK debugging adapters for STM32 families, will not work.
|
||||
On the software side, OpenOCD supports a fair amount of JTAG adapters. See http://openocd.org/doc/html/Debug-Adapter-Hardware.html for an (unfortunately slightly incomplete) list of the adapters OpenOCD works with. This page lists SWD-compatible adapters as well; take note that the {IDF_TARGET_NAME} does not support SWD. JTAG adapters that are hardcoded to a specific product line, e.g. ST-LINK debugging adapters for STM32 families, will not work.
|
||||
|
||||
The minimal signalling to get a working JTAG connection are TDI, TDO, TCK, TMS and GND. Some JTAG debuggers also need a connection from the ESP32 power line to a line called e.g. Vtar to set the working voltage. SRST can optionally be connected to the CH_PD of the ESP32, although for now, support in OpenOCD for that line is pretty minimal.
|
||||
The minimal signalling to get a working JTAG connection are TDI, TDO, TCK, TMS and GND. Some JTAG debuggers also need a connection from the {IDF_TARGET_NAME} power line to a line called e.g. Vtar to set the working voltage. SRST can optionally be connected to the CH_PD of the {IDF_TARGET_NAME}, although for now, support in OpenOCD for that line is pretty minimal.
|
||||
|
||||
|
||||
.. _jtag-debugging-setup-openocd:
|
||||
@@ -94,7 +98,7 @@ If you have already set up ESP-IDF with CMake build system according to the :doc
|
||||
|
||||
The output should be as follows (although the version may be more recent than listed here)::
|
||||
|
||||
Open On-Chip Debugger v0.10.0-esp32-20190708 (2019-07-08-11:04)
|
||||
Open On-Chip Debugger v0.10.0-{IDF_TARGET_TOOLCHAIN_NAME}-20190708 (2019-07-08-11:04)
|
||||
Licensed under GNU GPL v2
|
||||
For bug reports, read
|
||||
http://openocd.org/doc/doxygen/bugs.html
|
||||
@@ -107,12 +111,12 @@ If any of these steps do not work, please go back to the :ref:`setting up the to
|
||||
|
||||
It is also possible to build OpenOCD from source. Please refer to :ref:`jtag-debugging-building-openocd` section for details.
|
||||
|
||||
.. _jtag-debugging-configuring-esp32-target:
|
||||
.. _jtag-debugging-configuring-target:
|
||||
|
||||
Configuring ESP32 Target
|
||||
------------------------
|
||||
Configuring {IDF_TARGET_NAME} Target
|
||||
-------------------------------------
|
||||
|
||||
Once OpenOCD is installed, move to configuring ESP32 target (i.e ESP32 board with JTAG interface). You will do it in the following three steps:
|
||||
Once OpenOCD is installed, move to configuring {IDF_TARGET_NAME} target (i.e {IDF_TARGET_NAME} board with JTAG interface). You will do it in the following three steps:
|
||||
|
||||
* Configure and connect JTAG interface
|
||||
* Run OpenOCD
|
||||
@@ -122,12 +126,12 @@ Once OpenOCD is installed, move to configuring ESP32 target (i.e ESP32 board wit
|
||||
Configure and connect JTAG interface
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This step depends on JTAG and ESP32 board you are using - see the two cases described below.
|
||||
This step depends on JTAG and {IDF_TARGET_NAME} board you are using - see the two cases described below.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
configure-wrover
|
||||
:esp32: configure-wrover
|
||||
configure-other-jtag
|
||||
|
||||
|
||||
@@ -146,7 +150,7 @@ Open a terminal and set it up for using the ESP-IDF as described in the :ref:`se
|
||||
|
||||
.. note::
|
||||
|
||||
The files provided after ``-f`` above are specific for ESP-WROVER-KIT with :ref:`esp-modules-and-boards-esp32-wroom-32` module. You may need to provide different files depending on used hardware. For guidance see :ref:`jtag-debugging-tip-openocd-configure-target`.
|
||||
The files provided after ``-f`` above are specific for ESP-WROVER-KIT with esp32-wroom-32 module. You may need to provide different files depending on used hardware. For guidance see :ref:`jtag-debugging-tip-openocd-configure-target`.
|
||||
|
||||
.. highlight:: none
|
||||
|
||||
@@ -168,8 +172,8 @@ You should now see similar output (this log is for ESP-WROVER-KIT)::
|
||||
Info : esp32: Core was reset (pwrstat=0x5F, after clear 0x0F).
|
||||
|
||||
* If there is an error indicating permission problems, please see the "Permissions delegation" bit in the OpenOCD README file in ``~/esp/openocd-esp32`` directory.
|
||||
* In case there is an error finding configuration files, e.g. ``Can't find board/esp32-wrover-kit-3.3v.cfg``, check the path after ``-s``. This path is used by OpenOCD to look for the files specified after ``-f``. Also check if the file is indeed under provided path.
|
||||
* If you see JTAG errors (...all ones/...all zeroes) please check your connections, whether no other signals are connected to JTAG besides ESP32's pins, and see if everything is powered on.
|
||||
* In case there is an error finding configuration files, e.g. ``Can't find board/esp32-wrover-kit-3.3v.cfg``, check the path after ``-s``. This path is used by OpenOCD to look for the files specified after ``-f``. Also check if the file is indeed under provided path.
|
||||
* If you see JTAG errors (...all ones/...all zeroes) please check your connections, whether no other signals are connected to JTAG besides {IDF_TARGET_NAME}'s pins, and see if everything is powered on.
|
||||
|
||||
|
||||
.. _jtag-upload-app-debug:
|
||||
@@ -177,7 +181,7 @@ You should now see similar output (this log is for ESP-WROVER-KIT)::
|
||||
Upload application for debugging
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Build and upload your application to ESP32 as usual, see :ref:`get-started-build`.
|
||||
Build and upload your application to {IDF_TARGET_NAME} as usual, see :ref:`get-started-build`.
|
||||
|
||||
Another option is to write application image to flash using OpenOCD via JTAG with commands like this::
|
||||
|
||||
@@ -201,9 +205,9 @@ You are now ready to start application debugging. Follow steps described in sect
|
||||
Launching Debugger
|
||||
------------------
|
||||
|
||||
The toolchain for ESP32 features GNU Debugger, in short GDB. It is available with other toolchain programs under filename ``xtensa-esp32-elf-gdb``. GDB can be called and operated directly from command line in a terminal. Another option is to call it from within IDE (like Eclipse, Visual Studio Code, etc.) and operate indirectly with help of GUI instead of typing commands in a terminal.
|
||||
The toolchain for {IDF_TARGET_NAME} features GNU Debugger, in short GDB. It is available with other toolchain programs under filename: xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-gdb. GDB can be called and operated directly from command line in a terminal. Another option is to call it from within IDE (like Eclipse, Visual Studio Code, etc.) and operate indirectly with help of GUI instead of typing commands in a terminal.
|
||||
|
||||
Both options of using debugger are discussed under links below.
|
||||
Both options of using debugger are discussed under links below.
|
||||
|
||||
* :ref:`jtag-debugging-using-debugger-eclipse`
|
||||
* :ref:`jtag-debugging-using-debugger-command-line`
|
||||
@@ -226,9 +230,9 @@ This section is intended for users not familiar with GDB. It presents example de
|
||||
6. :ref:`jtag-debugging-examples-eclipse-06`
|
||||
7. :ref:`jtag-debugging-examples-eclipse-07`
|
||||
|
||||
Similar debugging actions are provided using GDB from :ref:`jtag-debugging-examples-command-line`.
|
||||
Similar debugging actions are provided using GDB from :ref:`jtag-debugging-examples-command-line`.
|
||||
|
||||
Before proceeding to examples, set up your ESP32 target and load it with :example:`get-started/blink`.
|
||||
Before proceeding to examples, set up your {IDF_TARGET_NAME} target and load it with :example:`get-started/blink`.
|
||||
|
||||
|
||||
.. _jtag-debugging-building-openocd:
|
||||
@@ -275,20 +279,10 @@ Tips and Quirks
|
||||
|
||||
This section provides collection of links to all tips and quirks referred to from various parts of this guide.
|
||||
|
||||
* :ref:`jtag-debugging-tip-breakpoints`
|
||||
* :ref:`jtag-debugging-tip-where-breakpoints`
|
||||
* :ref:`jtag-debugging-tip-flash-mappings`
|
||||
* :ref:`jtag-debugging-tip-why-next-works-as-step`
|
||||
* :ref:`jtag-debugging-tip-code-options`
|
||||
* :ref:`jtag-debugging-tip-freertos-support`
|
||||
* :ref:`jtag-debugging-tip-code-flash-voltage`
|
||||
* :ref:`jtag-debugging-tip-optimize-jtag-speed`
|
||||
* :ref:`jtag-debugging-tip-debugger-startup-commands`
|
||||
* :ref:`jtag-debugging-tip-openocd-configure-target`
|
||||
* :ref:`jtag-debugging-tip-reset-by-debugger`
|
||||
* :ref:`jtag-debugging-tip-jtag-pins-reconfigured`
|
||||
* :ref:`jtag-debugging-tip-at-firmware-issue`
|
||||
* :ref:`jtag-debugging-tip-reporting-issues`
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
tips-and-quirks
|
||||
|
||||
|
||||
Related Documents
|
||||
|
@@ -10,7 +10,7 @@ This section provides collection of all tips and quirks referred to from various
|
||||
Breakpoints and watchpoints available
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
ESP32 debugger supports 2 hardware implemented breakpoints and 64 software ones. Hardware breakpoints are implemented by ESP32 chip's logic and can be set anywhere in the code: either in flash or IRAM program's regions. Additionally there are 2 types of software breakpoints implemented by OpenOCD: flash (up to 32) and IRAM (up to 32) breakpoints. Currently GDB can not set software breakpoints in flash. So until this limitation is removed those breakpoints have to be emulated by OpenOCD as hardware ones (see :ref:`below <jtag-debugging-tip-where-breakpoints>` for details). ESP32 also supports two watchpoints, so two variables can be watched for change or read by the GDB command ``watch myVariable``. Note that menuconfig option :ref:`CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK` uses the 2nd watchpoint and will not provide expected results, if you also try to use it within OpenOCD / GDB. See menuconfig's help for detailed description.
|
||||
{IDF_TARGET_NAME} debugger supports 2 hardware implemented breakpoints and 64 software ones. Hardware breakpoints are implemented by {IDF_TARGET_NAME} chip's logic and can be set anywhere in the code: either in flash or IRAM program's regions. Additionally there are 2 types of software breakpoints implemented by OpenOCD: flash (up to 32) and IRAM (up to 32) breakpoints. Currently GDB can not set software breakpoints in flash. So until this limitation is removed those breakpoints have to be emulated by OpenOCD as hardware ones (see :ref:`below <jtag-debugging-tip-where-breakpoints>` for details). {IDF_TARGET_NAME} also supports two watchpoints, so two variables can be watched for change or read by the GDB command ``watch myVariable``. Note that menuconfig option :ref:`CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK` uses the 2nd watchpoint and will not provide expected results, if you also try to use it within OpenOCD / GDB. See menuconfig's help for detailed description.
|
||||
|
||||
|
||||
.. _jtag-debugging-tip-where-breakpoints:
|
||||
@@ -26,9 +26,9 @@ Emulating part of hardware breakpoints using software flash ones means that the
|
||||
Flash Mappings vs SW Flash Breakpoints
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In order to set/clear software breakpoints in flash, OpenOCD needs to know their flash addresses. To accomplish conversion from the ESP32 address space to the flash one, OpenOCD uses mappings of program's code regions resided in flash. Those mappings are kept in the image header which is prepended to program binary data (code and data segments) and is specific to every application image written to the flash. So to support software flash breakpoints OpenOCD should know where application image under debugging is resided in the flash. By default OpenOCD reads partition table at 0x8000 and uses mappings from the first found application image, but there can be the cases when it will not work, e.g. partition table is not at standard flash location or even there can be multiple images: one factory and two OTA and you may want to debbug any of them. To cover all possible debugging scenarios OpenOCD supports special command which can be used to set arbitrary location of application image to debug. The command has the following format:
|
||||
In order to set/clear software breakpoints in flash, OpenOCD needs to know their flash addresses. To accomplish conversion from the {IDF_TARGET_NAME} address space to the flash one, OpenOCD uses mappings of program's code regions resided in flash. Those mappings are kept in the image header which is prepended to program binary data (code and data segments) and is specific to every application image written to the flash. So to support software flash breakpoints OpenOCD should know where application image under debugging is resided in the flash. By default OpenOCD reads partition table at 0x8000 and uses mappings from the first found application image, but there can be the cases when it will not work, e.g. partition table is not at standard flash location or even there can be multiple images: one factory and two OTA and you may want to debbug any of them. To cover all possible debugging scenarios OpenOCD supports special command which can be used to set arbitrary location of application image to debug. The command has the following format:
|
||||
|
||||
``esp32 appimage_offset <offset>``
|
||||
``esp32 appimage_offset <offset>``
|
||||
|
||||
Offset should be in hex format. To reset to the default behaviour you can specify ``-1`` as offset.
|
||||
|
||||
@@ -55,7 +55,8 @@ Support options for OpenOCD at compile time
|
||||
|
||||
ESP-IDF has some support options for OpenOCD debugging which can be set at compile time:
|
||||
|
||||
* :ref:`CONFIG_ESP32_DEBUG_OCDAWARE` is enabled by default. If a panic or unhandled exception is thrown and a JTAG debugger is connected (ie OpenOCD is running), ESP-IDF will break into the debugger.
|
||||
* :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_DEBUG_OCDAWARE` is enabled by default. If a panic or unhandled exception is thrown and a JTAG debugger is connected (ie OpenOCD is running), ESP-IDF will break into the debugger.
|
||||
|
||||
* :ref:`CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK` (disabled by default) sets watchpoint index 1 (the second of two) at the end of any task stack. This is the most accurate way to debug task stack overflows. Click the link for more details.
|
||||
|
||||
Please see the :ref:`project configuration menu <get-started-configure>` menu for more details on setting compile-time options.
|
||||
@@ -70,14 +71,16 @@ OpenOCD has explicit support for the ESP-IDF FreeRTOS. GDB can see FreeRTOS task
|
||||
|
||||
.. _jtag-debugging-tip-code-flash-voltage:
|
||||
|
||||
Why to set SPI flash voltage in OpenOCD configuration?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. only:: esp33
|
||||
|
||||
The MTDI pin of ESP32, being among four pins used for JTAG communication, is also one of ESP32's bootstrapping pins. On power up ESP32 is sampling binary level on MTDI to set it's internal voltage regulator used to supply power to external SPI flash chip. If binary level on MDTI pin on power up is low, the voltage regulator is set to deliver 3.3 V, if it is high, then the voltage is set to 1.8 V. The MTDI pin should have a pull-up or may rely on internal weak pull down resistor (see `ESP32 Series Datasheet <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_ for details), depending on the type of SPI chip used. Once JTAG is connected, it overrides the pull-up or pull-down resistor that is supposed to do the bootstrapping.
|
||||
Why to set SPI flash voltage in OpenOCD configuration?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To handle this issue OpenOCD's board configuration file (e.g. ``boards\esp-wroom-32.cfg`` for ESP32-WROOM-32 module) provides ``ESP32_FLASH_VOLTAGE`` parameter to set the idle state of the ``TDO`` line to a specified binary level, therefore reducing the chance of a bad bootup of application due to incorrect flash voltage.
|
||||
The MTDI pin of ESP32, being among four pins used for JTAG communication, is also one of ESP32's bootstrapping pins. On power up ESP32 is sampling binary level on MTDI to set it's internal voltage regulator used to supply power to external SPI flash chip. If binary level on MDTI pin on power up is low, the voltage regulator is set to deliver 3.3 V, if it is high, then the voltage is set to 1.8 V. The MTDI pin should have a pull-up or may rely on internal weak pull down resistor (see `ESP32 Series Datasheet <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_ for details), depending on the type of SPI chip used. Once JTAG is connected, it overrides the pull-up or pull-down resistor that is supposed to do the bootstrapping.
|
||||
|
||||
Check specification of ESP32 module connected to JTAG, what is the power supply voltage of SPI flash chip. Then set ``ESP32_FLASH_VOLTAGE`` accordingly. Most WROOM modules use 3.3 V flash, while WROVER modules use 1.8 V flash.
|
||||
To handle this issue OpenOCD's board configuration file (e.g. ``boards\esp-wroom-32.cfg`` for ESP32-WROOM-32 module) provides ``ESP32_FLASH_VOLTAGE`` parameter to set the idle state of the ``TDO`` line to a specified binary level, therefore reducing the chance of a bad bootup of application due to incorrect flash voltage.
|
||||
|
||||
Check specification of ESP32 module connected to JTAG, what is the power supply voltage of SPI flash chip. Then set ``ESP32_FLASH_VOLTAGE`` accordingly. Most WROOM modules use 3.3 V flash, while WROVER modules use 1.8 V flash.
|
||||
|
||||
|
||||
.. _jtag-debugging-tip-optimize-jtag-speed:
|
||||
@@ -98,9 +101,9 @@ In order to achieve higher data rates and minimize number of dropped packets it
|
||||
What is the meaning of debugger's startup commands?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
On startup, debugger is issuing sequence of commands to reset the chip and halt it at specific line of code. This sequence (shown below) is user defined to pick up at most convenient / appropriate line and start debugging.
|
||||
On startup, debugger is issuing sequence of commands to reset the chip and halt it at specific line of code. This sequence (shown below) is user defined to pick up at most convenient / appropriate line and start debugging.
|
||||
|
||||
* ``set remote hardware-watchpoint-limit 2`` — Restrict GDB to using two hardware watchpoints supported by ESP32. For more information see https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html.
|
||||
* ``set remote hardware-watchpoint-limit 2`` — Restrict GDB to using two hardware watchpoints supported by the chip, 2 for {IDF_TARGET_NAME}. For more information see https://sourceware.org/gdb/onlinedocs/gdb/Remote-Configuration.html.
|
||||
* ``mon reset halt`` — reset the chip and keep the CPUs halted
|
||||
* ``flushregs`` — monitor (``mon``) command can not inform GDB that the target state has changed. GDB will assume that whatever stack the target had before ``mon reset halt`` will still be valid. In fact, after reset the target state will change, and executing ``flushregs`` is a way to force GDB to get new state from the target.
|
||||
* ``thb app_main`` — insert a temporary hardware breakpoint at ``app_main``, put here another function name if required
|
||||
@@ -114,7 +117,7 @@ Configuration of OpenOCD for specific target
|
||||
|
||||
OpenOCD needs to be told what JTAG adapter to use and processor the JTAG adapter is connected to. To do so, use existing **board** configuration files located in OpenOCD's ``share/openocd/scripts/board`` folder.
|
||||
|
||||
For example, if you connect to ESP-WROVER-KIT with ESP-WROOM-32 module installed (see section :ref:`esp-modules-and-boards-esp-wrover-kit-v1`), use the following configuration files:
|
||||
For example, if you connect to ESP-WROVER-KIT with ESP-WROOM-32 module installed, use the following configuration files:
|
||||
|
||||
* ``board/esp32-wrover-kit-3.3v.cfg``
|
||||
|
||||
@@ -132,15 +135,16 @@ Adapter's clock speed
|
||||
|
||||
See :ref:`jtag-debugging-tip-optimize-jtag-speed` for guidance how to set this value.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
Single core debugging
|
||||
"""""""""""""""""""""
|
||||
Single core debugging
|
||||
"""""""""""""""""""""
|
||||
|
||||
::
|
||||
::
|
||||
|
||||
set ESP32_ONLYCPU 1
|
||||
set ESP32_ONLYCPU 1
|
||||
|
||||
Comment out this line for dual core debugging.
|
||||
Comment out this line for dual core debugging.
|
||||
|
||||
|
||||
Disable RTOS support
|
||||
@@ -163,40 +167,42 @@ Power supply voltage of ESP32's SPI flash chip
|
||||
Comment out this line to set 3.3 V, ref: :ref:`jtag-debugging-tip-code-flash-voltage`
|
||||
|
||||
|
||||
Configuration file for ESP32 targets
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
.. only:: esp32
|
||||
|
||||
::
|
||||
Configuration file for ESP32 targets
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
|
||||
source [find target/esp32.cfg]
|
||||
::
|
||||
|
||||
.. note::
|
||||
source [find target/esp32.cfg]
|
||||
|
||||
Do not change ``source [find target/esp32.cfg]`` line unless you are familiar with OpenOCD internals.
|
||||
.. note::
|
||||
|
||||
Currently ``target/esp32.cfg`` remains the only configuration file for ESP32 targets (esp108 and esp32). The matrix of supported configurations is as follows:
|
||||
Do not change ``source [find target/esp32.cfg]`` line unless you are familiar with OpenOCD internals.
|
||||
|
||||
+---------------+---------------+---------------+
|
||||
| Dual/single | RTOS | Target used |
|
||||
+===============+===============+===============+
|
||||
| dual | FreeRTOS | esp32 |
|
||||
+---------------+---------------+---------------+
|
||||
| single | FreeRTOS | esp108 (*) |
|
||||
+---------------+---------------+---------------+
|
||||
| dual | none | esp108 |
|
||||
+---------------+---------------+---------------+
|
||||
| single | none | esp108 |
|
||||
+---------------+---------------+---------------+
|
||||
Currently ``target/esp32.cfg`` remains the only configuration file for ESP32 targets (esp108 and esp32). The matrix of supported configurations is as follows:
|
||||
|
||||
(*) — we plan to fix this and add support for single core debugging with esp32 target in a subsequent commits.
|
||||
+---------------+---------------+---------------+
|
||||
| Dual/single | RTOS | Target used |
|
||||
+===============+===============+===============+
|
||||
| dual | FreeRTOS | esp32 |
|
||||
+---------------+---------------+---------------+
|
||||
| single | FreeRTOS | esp108 (*) |
|
||||
+---------------+---------------+---------------+
|
||||
| dual | none | esp108 |
|
||||
+---------------+---------------+---------------+
|
||||
| single | none | esp108 |
|
||||
+---------------+---------------+---------------+
|
||||
|
||||
Look inside ``board/esp-wroom-32.cfg`` for additional information provided in comments besides each configuration parameter.
|
||||
(*) — we plan to fix this and add support for single core debugging with esp32 target in a subsequent commits.
|
||||
|
||||
Look inside ``board/esp-wroom-32.cfg`` for additional information provided in comments besides each configuration parameter.
|
||||
|
||||
|
||||
.. _jtag-debugging-tip-reset-by-debugger:
|
||||
|
||||
How debugger resets ESP32?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
How debugger resets {IDF_TARGET_NAME}?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The board can be reset by entering ``mon reset`` or ``mon reset halt`` into GDB.
|
||||
|
||||
@@ -206,21 +212,37 @@ The board can be reset by entering ``mon reset`` or ``mon reset halt`` into GDB.
|
||||
Do not use JTAG pins for something else
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Operation of JTAG may be disturbed, if some other h/w is connected to JTAG pins besides ESP32 module and JTAG adapter. ESP32 JTAG us using the following pins:
|
||||
Operation of JTAG may be disturbed, if some other h/w is connected to JTAG pins besides {IDF_TARGET_NAME} module and JTAG adapter. {IDF_TARGET_NAME} JTAG us using the following pins:
|
||||
|
||||
+---+----------------+-------------+
|
||||
| | ESP32 JTAG Pin | JTAG Signal |
|
||||
+===+================+=============+
|
||||
| 1 | MTDO / GPIO15 | TDO |
|
||||
+---+----------------+-------------+
|
||||
| 2 | MTDI / GPIO12 | TDI |
|
||||
+---+----------------+-------------+
|
||||
| 3 | MTCK / GPIO13 | TCK |
|
||||
+---+----------------+-------------+
|
||||
| 4 | MTMS / GPIO14 | TMS |
|
||||
+---+----------------+-------------+
|
||||
.. only:: esp32
|
||||
|
||||
JTAG communication will likely fail, if configuration of JTAG pins is changed by user application. If OpenOCD initializes correctly (detects the two Tensilica cores), but loses sync and spews out a lot of DTR/DIR errors when the program is ran, it is likely that the application reconfigures the JTAG pins to something else, or the user forgot to connect Vtar to a JTAG adapter that needed it.
|
||||
+---+-----------------------+-------------+
|
||||
| | ESP32 Pin | JTAG Signal |
|
||||
+===+=======================+=============+
|
||||
| 1 | MTDO / GPIO15 | TDO |
|
||||
+---+-----------------------+-------------+
|
||||
| 2 | MTDI / GPIO12 | TDI |
|
||||
+---+-----------------------+-------------+
|
||||
| 3 | MTCK / GPIO13 | TCK |
|
||||
+---+-----------------------+-------------+
|
||||
| 4 | MTMS / GPIO14 | TMS |
|
||||
+---+-----------------------+-------------+
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
+---+-----------------------+-------------+
|
||||
| | ESP32-S2 Pin | JTAG Signal |
|
||||
+===+=======================+=============+
|
||||
| 1 | MTDO / GPIO40 | TDO |
|
||||
+---+-----------------------+-------------+
|
||||
| 2 | MTDI / GPIO41 | TDI |
|
||||
+---+-----------------------+-------------+
|
||||
| 3 | MTCK / GPIO39 | TCK |
|
||||
+---+-----------------------+-------------+
|
||||
| 4 | MTMS / GPIO42 | TMS |
|
||||
+---+-----------------------+-------------+
|
||||
|
||||
JTAG communication will likely fail, if configuration of JTAG pins is changed by user application. If OpenOCD initializes correctly (detects the two Tensilica cores), but loses sync and spews out a lot of DTR/DIR errors when the program is ran, it is likely that the application reconfigures the JTAG pins to something else, or the user forgot to connect Vtar to a JTAG adapter that needed it.
|
||||
|
||||
.. highlight:: none
|
||||
|
||||
@@ -236,12 +258,14 @@ Below is an excerpt from series of errors reported by GDB after the application
|
||||
|
||||
.. _jtag-debugging-tip-at-firmware-issue:
|
||||
|
||||
JTAG and ESP32-WROOM-32 AT firmware Compatibility Issue
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. only:: esp32
|
||||
|
||||
The ESP32-WROOM series of modules come pre-flashed with AT firmware. This firmware configures the pins GPIO12 to GPIO15 as SPI slave interface, which makes using JTAG impossible.
|
||||
JTAG and ESP32-WROOM-32 AT firmware Compatibility Issue
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To make JTAG available, build new firmware that is not using pins GPIO12 to GPIO15 dedicated to JTAG communication. After that, flash the firmware onto your module. See also :ref:`jtag-debugging-tip-jtag-pins-reconfigured`.
|
||||
The ESP32-WROOM series of modules come pre-flashed with AT firmware. This firmware configures the pins GPIO12 to GPIO15 as SPI slave interface, which makes using JTAG impossible.
|
||||
|
||||
To make JTAG available, build new firmware that is not using pins GPIO12 to GPIO15 dedicated to JTAG communication. After that, flash the firmware onto your module. See also :ref:`jtag-debugging-tip-jtag-pins-reconfigured`.
|
||||
|
||||
|
||||
.. _jtag-debugging-tip-reporting-issues:
|
||||
@@ -249,7 +273,7 @@ To make JTAG available, build new firmware that is not using pins GPIO12 to GPIO
|
||||
Reporting issues with OpenOCD / GDB
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In case you encounter a problem with OpenOCD or GDB programs itself and do not find a solution searching available resources on the web, open an issue in the OpenOCD issue tracker under https://github.com/espressif/openocd-esp32/issues.
|
||||
In case you encounter a problem with OpenOCD or GDB programs itself and do not find a solution searching available resources on the web, open an issue in the OpenOCD issue tracker under https://github.com/espressif/openocd-esp32/issues.
|
||||
|
||||
1. In issue report provide details of your configuration:
|
||||
|
||||
|
@@ -36,9 +36,9 @@ Once installation is complete, configure debugging session following steps below
|
||||
|
||||
Configuration of GDB Hardware Debugging - Main tab
|
||||
|
||||
6. Click "Debugger" tab. In field "GDB Command" enter ``xtensa-esp32-elf-gdb`` to invoke debugger.
|
||||
6. Click "Debugger" tab. In field "GDB Command" enter ``xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-gdb`` to invoke debugger.
|
||||
|
||||
7. Change default configuration of "Remote host" by entering ``3333`` under the "Port number".
|
||||
7. Change default configuration of "Remote host" by entering ``3333`` under the "Port number".
|
||||
|
||||
Configuration entered in points 6 and 7 is shown on the following picture.
|
||||
|
||||
@@ -65,7 +65,7 @@ Once installation is complete, configure debugging session following steps below
|
||||
|
||||
For description of ``program_esp`` command see :ref:`jtag-upload-app-debug`.
|
||||
|
||||
9. Under "Load Image and Symbols" uncheck "Load image" option.
|
||||
9. Under "Load Image and Symbols" uncheck "Load image" option.
|
||||
|
||||
10. Further down on the same tab, establish an initial breakpoint to halt CPUs after they are reset by debugger. The plugin will set this breakpoint at the beginning of the function entered under "Set break point at:". Checkout this option and enter ``app_main`` in provided field.
|
||||
|
||||
@@ -82,9 +82,9 @@ Once installation is complete, configure debugging session following steps below
|
||||
|
||||
If the "Startup" sequence looks convoluted and respective "Initialization Commands" are not clear to you, check :ref:`jtag-debugging-tip-debugger-startup-commands` for additional explanation.
|
||||
|
||||
12. If you previously completed :ref:`jtag-debugging-configuring-esp32-target` steps described above, so the target is running and ready to talk to debugger, go right to debugging by pressing "Debug" button. Otherwise press "Apply" to save changes, go back to :ref:`jtag-debugging-configuring-esp32-target` and return here to start debugging.
|
||||
12. If you previously completed :ref:`jtag-debugging-configuring-target` steps described above, so the target is running and ready to talk to debugger, go right to debugging by pressing "Debug" button. Otherwise press "Apply" to save changes, go back to :ref:`jtag-debugging-configuring-target` and return here to start debugging.
|
||||
|
||||
Once all 1 - 12 configuration steps are satisfied, the new Eclipse perspective called "Debug" will open as shown on example picture below.
|
||||
Once all 1 - 12 configuration steps are satisfied, the new Eclipse perspective called "Debug" will open as shown on example picture below.
|
||||
|
||||
.. figure:: ../../../_static/debug-perspective.jpg
|
||||
:align: center
|
||||
@@ -101,7 +101,7 @@ If you are not quite sure how to use GDB, check :ref:`jtag-debugging-examples-ec
|
||||
Command Line
|
||||
^^^^^^^^^^^^
|
||||
|
||||
1. Begin with completing steps described under :ref:`jtag-debugging-configuring-esp32-target`. This is prerequisite to start a debugging session.
|
||||
1. Begin with completing steps described under :ref:`jtag-debugging-configuring-target`. This is prerequisite to start a debugging session.
|
||||
|
||||
.. highlight:: bash
|
||||
|
||||
@@ -124,7 +124,7 @@ Command Line
|
||||
thb app_main
|
||||
c
|
||||
|
||||
Save this file in current directory.
|
||||
Save this file in current directory.
|
||||
|
||||
For more details what's inside ``gdbinit`` file, see :ref:`jtag-debugging-tip-debugger-startup-commands`
|
||||
|
||||
@@ -134,7 +134,7 @@ Command Line
|
||||
|
||||
::
|
||||
|
||||
xtensa-esp32-elf-gdb -x gdbinit build/blink.elf
|
||||
xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-gdb -x gdbinit build/blink.elf
|
||||
|
||||
.. highlight:: none
|
||||
|
||||
@@ -142,14 +142,14 @@ Command Line
|
||||
|
||||
::
|
||||
|
||||
user-name@computer-name:~/esp/blink$ xtensa-esp32-elf-gdb -x gdbinit build/blink.elf
|
||||
user-name@computer-name:~/esp/blink$ xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-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".
|
||||
This GDB was configured as "--host=x86_64-build_pc-linux-gnu --target=xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf".
|
||||
Type "show configuration" for configuration details.
|
||||
For bug reporting instructions, please see:
|
||||
<http://www.gnu.org/software/gdb/bugs/>.
|
||||
@@ -158,20 +158,20 @@ Command Line
|
||||
For help, type "help".
|
||||
Type "apropos word" to search for commands related to "word"...
|
||||
Reading symbols from build/blink.elf...done.
|
||||
0x400d10d8 in esp_vApplicationIdleHook () at /home/user-name/esp/esp-idf/components/esp32/./freertos_hooks.c:52
|
||||
0x400d10d8 in esp_vApplicationIdleHook () at /home/user-name/esp/esp-idf/components/{IDF_TARGET_PATH_NAME}/./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.slave 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
|
||||
JTAG tap: {IDF_TARGET_PATH_NAME}.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
|
||||
JTAG tap: {IDF_TARGET_PATH_NAME}.slave tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1)
|
||||
{IDF_TARGET_PATH_NAME}: Debug controller was reset (pwrstat=0x5F, after clear 0x0F).
|
||||
{IDF_TARGET_PATH_NAME}: Core was reset (pwrstat=0x5F, after clear 0x0F).
|
||||
Target halted. PRO_CPU: PC=0x5000004B (active) APP_CPU: PC=0x00000000
|
||||
{IDF_TARGET_PATH_NAME}: target state: halted
|
||||
{IDF_TARGET_PATH_NAME}: Core was reset (pwrstat=0x1F, after clear 0x0F).
|
||||
Target halted. PRO_CPU: PC=0x40000400 (active) APP_CPU: PC=0x40000400
|
||||
{IDF_TARGET_PATH_NAME}: target state: halted
|
||||
Hardware assisted breakpoint 1 at 0x400db717: file /home/user-name/esp/blink/main/./blink.c, line 43.
|
||||
0x0: 0x00000000
|
||||
Target halted. PRO_CPU: PC=0x400DB717 (active) APP_CPU: PC=0x400D10D8
|
||||
Target halted. PRO_CPU: PC=0x400DB717 (active) APP_CPU: PC=0x400D10D8
|
||||
[New Thread 1073428656]
|
||||
[New Thread 1073413708]
|
||||
[New Thread 1073431316]
|
||||
@@ -180,10 +180,10 @@ Command Line
|
||||
[New Thread 1073432196]
|
||||
[New Thread 1073411552]
|
||||
[Switching to Thread 1073411996]
|
||||
|
||||
|
||||
Temporary breakpoint 1, app_main () at /home/user-name/esp/blink/main/./blink.c:43
|
||||
43 xTaskCreate(&blink_task, "blink_task", 512, NULL, 5, NULL);
|
||||
(gdb)
|
||||
(gdb)
|
||||
|
||||
Note the third line from bottom that shows debugger halting at breakpoint established in ``gdbinit`` file at function ``app_main()``. Since the processor is halted, the LED should not be blinking. If this is what you see as well, you are ready to start debugging.
|
||||
|
||||
|
@@ -21,15 +21,15 @@ This section presents a guide for quickly placing code/data to RAM and RTC memor
|
||||
For this guide, suppose we have the following::
|
||||
|
||||
- components/
|
||||
- my_component/
|
||||
- my_component/
|
||||
- CMakeLists.txt
|
||||
- component.mk
|
||||
- Kconfig
|
||||
- Kconfig
|
||||
- src/
|
||||
- my_src1.c
|
||||
- my_src2.c
|
||||
- my_src3.c
|
||||
- my_linker_fragment_file.lf
|
||||
- my_src1.c
|
||||
- my_src2.c
|
||||
- my_src3.c
|
||||
- my_linker_fragment_file.lf
|
||||
|
||||
|
||||
- a component named ``my_component`` that is archived as library ``libmy_component.a`` during build
|
||||
@@ -65,7 +65,7 @@ created linker fragment file.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# file paths relative to CMakeLists.txt
|
||||
# file paths relative to CMakeLists.txt
|
||||
idf_component_register(...
|
||||
LDFRAGMENTS "path/to/linker_fragment_file.lf" "path/to/another_linker_fragment_file.lf"
|
||||
...
|
||||
@@ -86,7 +86,7 @@ It is possible to specify placements at the following levels of granularity:
|
||||
Placing object files
|
||||
""""""""""""""""""""
|
||||
|
||||
Suppose the entirety of ``my_src1.o`` is performance-critical, so it is desirable to place it in RAM.
|
||||
Suppose the entirety of ``my_src1.o`` is performance-critical, so it is desirable to place it in RAM.
|
||||
On the other hand, the entirety of ``my_src2.o`` contains symbols needed coming out of deep sleep, so it needs to be put under RTC memory.
|
||||
In the the linker fragment file, we can write:
|
||||
|
||||
@@ -99,7 +99,7 @@ In the the linker fragment file, we can write:
|
||||
my_src2 (rtc) # places all my_src2 code/ data and read-only data under RTC fast memory/RTC slow memory
|
||||
|
||||
What happens to ``my_src3.o``? Since it is not specified, default placements are used for ``my_src3.o``. More on default placements
|
||||
:ref:`here<ldgen-default-placements>`.
|
||||
:ref:`here<ldgen-default-placements>`.
|
||||
|
||||
Placing symbols
|
||||
""""""""""""""""
|
||||
@@ -215,7 +215,7 @@ As the name suggests, it is where code and data are usually placed, i.e. code/co
|
||||
placed in RAM, etc. More on the default scheme :ref:`here<ldgen-default-scheme>`.
|
||||
|
||||
.. note::
|
||||
For an example of an ESP-IDF component using the linker script generation mechanism, see :component_file:`freertos/CMakeLists.txt`.
|
||||
For an example of an ESP-IDF component using the linker script generation mechanism, see :component_file:`freertos/CMakeLists.txt`.
|
||||
``freertos`` uses this to place its object files to the instruction RAM for performance reasons.
|
||||
|
||||
This marks the end of the quick start guide. The following text discusses the internals of the mechanism in a little bit more detail.
|
||||
@@ -226,7 +226,7 @@ Linker Script Generation Internals
|
||||
|
||||
Linking is the last step in the process of turning C/C++ source files into an executable. It is performed by the toolchain's linker, and accepts
|
||||
linker scripts which specify code/data placements, among other things. With the linker script generation mechanism, this process is no different, except
|
||||
that the linker script passed to the linker is dynamically generated from: (1) the collected :ref:`linker fragment files<ldgen-linker-fragment-files>` and
|
||||
that the linker script passed to the linker is dynamically generated from: (1) the collected :ref:`linker fragment files<ldgen-linker-fragment-files>` and
|
||||
(2) :ref:`linker script template<ldgen-linker-script-template>`.
|
||||
|
||||
.. note::
|
||||
@@ -240,7 +240,7 @@ Linker Fragment Files
|
||||
|
||||
As mentioned in the quick start guide, fragment files are simple text files with the ``.lf`` extension containing the desired placements. This is a simplified
|
||||
description of what fragment files contain, however. What fragment files actually contain are 'fragments'. Fragments are entities which contain pieces of information which, when put together, form
|
||||
placement rules that tell where to place sections of object files in the output binary. There are three types of fragments: :ref:`sections<ldgen-sections-fragment>`,
|
||||
placement rules that tell where to place sections of object files in the output binary. There are three types of fragments: :ref:`sections<ldgen-sections-fragment>`,
|
||||
:ref:`scheme<ldgen-scheme-fragment>` and :ref:`mapping<ldgen-mapping-fragment>`.
|
||||
|
||||
Grammar
|
||||
@@ -276,7 +276,7 @@ The three fragment types share a common grammar:
|
||||
**Condition Checking**
|
||||
|
||||
Condition checking enable the linker script generation to be configuration-aware. Depending on whether expressions involving configuration values
|
||||
are true or not, a particular set of values for a key can be used. The evaluation uses ``eval_string`` from :idf_file:`tools/kconfig_new/kconfiglib.py`
|
||||
are true or not, a particular set of values for a key can be used. The evaluation uses ``eval_string`` from :idf_file:`tools/kconfig_new/kconfiglib.py`
|
||||
and adheres to its required syntax and limitations. Supported operators are as follows:
|
||||
|
||||
- comparison
|
||||
@@ -331,7 +331,7 @@ for both key values and entire fragments. The two sample fragments below are equ
|
||||
**Comments**
|
||||
|
||||
Comment in linker fragment files begin with ``#``. Like in other languages, comment are used to provide helpful descriptions and documentation
|
||||
and are ignored during processing.
|
||||
and are ignored during processing.
|
||||
|
||||
Compatibility with ESP-IDF v3.x Linker Script Fragment Files
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
@@ -426,10 +426,10 @@ will be generated for the target ``flash_text``.
|
||||
|
||||
These catch-all rules then effectively serve as fallback rules for those whose mappings were not specified.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``default scheme`` is defined in :component:`esp32/ld/esp32_fragments.lf`. The ``noflash`` and ``rtc`` scheme fragments which are
|
||||
built-in schemes referenced in the quick start guide are also defined in this file.
|
||||
The ``default scheme`` is defined in :component:`{IDF_TARGET_PATH_NAME}/ld/{IDF_TARGET_PATH_NAME}_fragments.lf`. The ``noflash`` and ``rtc`` scheme fragments which are
|
||||
built-in schemes referenced in the quick start guide are also defined in this file.
|
||||
|
||||
|
||||
.. _ldgen-mapping-fragment :
|
||||
|
||||
@@ -589,9 +589,5 @@ Then the corresponding excerpt from the generated linker script will be as follo
|
||||
it too is placed wherever ``iram0_text`` is referenced by a marker. Since it is a rule generated from the default scheme, it comes first
|
||||
among all other rules collected under the same target name.
|
||||
|
||||
.. note::
|
||||
|
||||
The linker script template currently used is :component:`esp32/ld/esp32.project.ld.in`, specified by the ``esp32`` component; the
|
||||
The linker script template currently used is :component:`{IDF_TARGET_PATH_NAME}/ld/{IDF_TARGET_PATH_NAME}.project.ld.in`, specified by the ``{IDF_TARGET_PATH_NAME}`` component; the
|
||||
generated output script is put under its build directory.
|
||||
|
||||
|
||||
|
@@ -325,7 +325,15 @@ IP layer features
|
||||
Limitations
|
||||
^^^^^^^^^^^
|
||||
|
||||
- Calling ``send()`` or ``sendto()`` repeatedly on a UDP socket may eventually fail with ``errno`` equal to ``ENOMEM``. This is a limitation of buffer sizes in the lower layer network interface drivers. If all driver transmit buffers are full then UDP transmission will fail. Applications sending a high volume of UDP datagrams who don't wish for any to be dropped by the sender should check for this error code and re-send the datagram after a short delay. Increasing the number of TX buffers in the :ref:`Wi-Fi <CONFIG_ESP32_WIFI_TX_BUFFER>` or :ref:`Ethernet <CONFIG_ETH_DMA_TX_BUFFER_NUM>` project configuration (as applicable) may also help.
|
||||
- Calling ``send()`` or ``sendto()`` repeatedly on a UDP socket may eventually fail with ``errno`` equal to ``ENOMEM``. This is a limitation of buffer sizes in the lower layer network interface drivers. If all driver transmit buffers are full then UDP transmission will fail. Applications sending a high volume of UDP datagrams who don't wish for any to be dropped by the sender should check for this error code and re-send the datagram after a short delay.
|
||||
|
||||
.. only::esp32
|
||||
|
||||
Increasing the number of TX buffers in the :ref:`Wi-Fi <CONFIG_ESP32_WIFI_TX_BUFFER>` or :ref:`Ethernet <CONFIG_ETH_DMA_TX_BUFFER_NUM>` project configuration (as applicable) may also help.
|
||||
|
||||
.. only::esp32s2
|
||||
|
||||
Increasing the number of TX buffers in the :ref:`Wi-Fi <CONFIG_ESP32_WIFI_TX_BUFFER>` project configuration may also help.
|
||||
|
||||
Performance Optimization
|
||||
------------------------
|
||||
|
@@ -5,7 +5,7 @@ Partition Tables
|
||||
Overview
|
||||
--------
|
||||
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to (:ref:`default offset <CONFIG_PARTITION_TABLE_OFFSET>`) 0x8000 in the flash.
|
||||
A single {IDF_TARGET_NAME}'s flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to (:ref:`default offset <CONFIG_PARTITION_TABLE_OFFSET>`) 0x8000 in the flash.
|
||||
|
||||
Partition table length is 0xC00 bytes (maximum 95 partition table entries). An MD5 checksum, which is used for checking the integrity of the partition table, is appended after the table data. If the partition table is signed due to `secure boot`, the signature is appended after the partition table.
|
||||
|
||||
@@ -23,7 +23,7 @@ Built-in Partition Tables
|
||||
|
||||
Here is the summary printed for the "Single factory app, no OTA" configuration::
|
||||
|
||||
# Espressif ESP32 Partition Table
|
||||
# Espressif ESP Partition Table
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x6000,
|
||||
phy_init, data, phy, 0xf000, 0x1000,
|
||||
@@ -34,7 +34,7 @@ Here is the summary printed for the "Single factory app, no OTA" configuration::
|
||||
|
||||
Here is the summary printed for the "Factory app, two OTA definitions" configuration::
|
||||
|
||||
# Espressif ESP32 Partition Table
|
||||
# Espressif ESP Partition Table
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
nvs, data, nvs, 0x9000, 0x4000,
|
||||
otadata, data, ota, 0xd000, 0x2000,
|
||||
@@ -69,7 +69,7 @@ The CSV format is the same format as printed in the summaries shown above. Howev
|
||||
Name field
|
||||
~~~~~~~~~~
|
||||
|
||||
Name field can be any meaningful name. It is not significant to the ESP32. Names longer than 16 characters will be truncated.
|
||||
Name field can be any meaningful name. It is not significant to the {IDF_TARGET_NAME}. Names longer than 16 characters will be truncated.
|
||||
|
||||
Type field
|
||||
~~~~~~~~~~
|
||||
@@ -136,7 +136,7 @@ Only one flag is currently supported, ``encrypted``. If this field is set to ``e
|
||||
Generating Binary Partition Table
|
||||
---------------------------------
|
||||
|
||||
The partition table which is flashed to the ESP32 is in a binary format, not CSV. The tool :component_file:`partition_table/gen_esp32part.py` is used to convert between CSV and binary formats.
|
||||
The partition table which is flashed to the {IDF_TARGET_NAME} is in a binary format, not CSV. The tool :component_file:`partition_table/gen_esp32part.py` is used to convert between CSV and binary formats.
|
||||
|
||||
If you configure the partition table CSV name in the project configuration (``idf.py menuconfig``) and then build the project or run ``idf.py partition_table``, this conversion is done as part of the build process.
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
*****************
|
||||
ESP32 ROM console
|
||||
*****************
|
||||
*****************************
|
||||
{IDF_TARGET_NAME} ROM console
|
||||
*****************************
|
||||
|
||||
When an ESP32 is unable to boot from flash ROM (and the fuse disabling it hasn't been blown), it boots into a rom console. The console
|
||||
is based on TinyBasic, and statements entered should be in the form of BASIC statements. As is common in the BASIC language, without a
|
||||
When an {IDF_TARGET_NAME} is unable to boot from flash ROM (and the fuse disabling it hasn't been blown), it boots into a rom console. The console
|
||||
is based on TinyBasic, and statements entered should be in the form of BASIC statements. As is common in the BASIC language, without a
|
||||
preceeding line number, commands entered are executed immediately; lines with a prefixed line number are stored as part of a program.
|
||||
|
||||
Full list of supported statements and functions
|
||||
@@ -12,7 +12,7 @@ Full list of supported statements and functions
|
||||
System
|
||||
------
|
||||
|
||||
- BYE - *exits Basic, reboots ESP32, retries booting from flash*
|
||||
- BYE - *exits Basic, reboots and retries booting from flash*
|
||||
- END - *stops execution from the program, also "STOP"*
|
||||
- MEM - *displays memory usage statistics*
|
||||
- NEW - *clears the current program*
|
||||
|
@@ -89,11 +89,11 @@ IDF Monitor adds more details to the dump::
|
||||
0x400dbf56: still_dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:47
|
||||
0x400dbf5e: dont_crash at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:42
|
||||
0x400dbf82: app_main at /home/gus/esp/32/idf/examples/get-started/hello_world/main/./hello_world_main.c:33
|
||||
0x400d071d: main_task at /home/gus/esp/32/idf/components/esp32/./cpu_start.c:254
|
||||
0x400d071d: main_task at /home/gus/esp/32/idf/components/{IDF_TARGET_PATH_NAME}/./cpu_start.c:254
|
||||
|
||||
To decode each address, IDF Monitor runs the following command in the background::
|
||||
|
||||
xtensa-esp32-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS
|
||||
xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS
|
||||
|
||||
|
||||
Launching GDB with GDBStub
|
||||
@@ -103,13 +103,13 @@ By default, if esp-idf crashes, the panic handler prints relevant registers and
|
||||
|
||||
Optionally, the panic handler can be configured to run GDBStub, the tool which can communicate with GDB_ project debugger. GDBStub allows to read memory, examine call stack frames and variables, etc. It is not as versatile as JTAG debugging, but this method does not require any special hardware.
|
||||
|
||||
To enable GDBStub, open the project configuration menu (``idf.py menuconfig``) and set :ref:`CONFIG_ESP32_PANIC` to ``Invoke GDBStub``.
|
||||
To enable GDBStub, open the project configuration menu (``idf.py menuconfig``) and set :ref:`CONFIG_{IDF_TARGET_CFG_PREFIX}_PANIC` to ``Invoke GDBStub``.
|
||||
|
||||
In this case, if the panic handler is triggered, as soon as IDF Monitor sees that GDBStub has loaded, it automatically pauses serial monitoring and runs GDB with necessary arguments. After GDB exits, the board is reset via the RTS serial line. If this line is not connected, please reset the board manually by pressing its Reset button.
|
||||
|
||||
In the background, IDF Monitor runs the following command::
|
||||
|
||||
xtensa-esp32-elf-gdb -ex "set serial baud BAUD" -ex "target remote PORT" -ex interrupt build/PROJECT.elf
|
||||
xtensa-{IDF_TARGET_TOOLCHAIN_NAME}-elf-gdb -ex "set serial baud BAUD" -ex "target remote PORT" -ex interrupt build/PROJECT.elf :idf_target:`Hello NAME chip`
|
||||
|
||||
|
||||
Output Filtering
|
||||
@@ -128,7 +128,7 @@ For example, ``PRINT_FILTER="tag1:W"`` matches and prints only the outputs writt
|
||||
which can be useful for adjusting the filtering options without
|
||||
recompiling the application.
|
||||
|
||||
Your app tags must not contain spaces, asterisks ``*``,
|
||||
Your app tags must not contain spaces, asterisks ``*``,
|
||||
and semicolons ``:`` to be compatible with the output filtering feature.
|
||||
|
||||
If the last line of the output in your app is not followed by a carriage return, the output filtering might get confused, i.e., the monitor starts to print the line and later finds out that the line should not have been written. This is a known issue and can be avoided by always adding a carriage return (especially when no output follows immediately afterwards).
|
||||
|
@@ -138,4 +138,4 @@ Although the methods above are recommended for ESP-IDF users, they are not a mus
|
||||
List of IDF Tools
|
||||
-----------------
|
||||
|
||||
.. include:: /_build/inc/idf-tools-inc.rst
|
||||
.. include-build-file:: idf-tools-inc.rst
|
||||
|
@@ -6,8 +6,8 @@ ULP Coprocessor programming
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Instruction set reference for ESP32 ULP <ulp_instruction_set>
|
||||
Instruction set reference for ESP32-S2 ULP <ulps2_instruction_set>
|
||||
:esp32: Instruction set reference for ESP32 ULP <ulp_instruction_set>
|
||||
:esp32s2: Instruction set reference for ESP32-S2 ULP <ulps2_instruction_set>
|
||||
Programming using macros (legacy) <ulp_macros>
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ The ULP coprocessor code is written in assembly and compiled using the `binutils
|
||||
|
||||
If you have already set up ESP-IDF with CMake build system according to the :doc:`Getting Started Guide <../../get-started/index>`, then the ULP toolchain will already be installed.
|
||||
|
||||
If you are using ESP-IDF with the legacy GNU Make based build system, refer to the instructions on this page: :doc:`ulp-legacy`.
|
||||
.. only:: esp32
|
||||
|
||||
If you are using ESP-IDF with the legacy GNU Make based build system, refer to the instructions on this page: :doc:`ulp-legacy`.
|
||||
|
||||
Compiling the ULP Code
|
||||
-----------------------
|
||||
@@ -29,7 +31,7 @@ To compile the ULP code as part of the component, the following steps must be ta
|
||||
|
||||
1. The ULP code, written in assembly, must be added to one or more files with `.S` extension. These files must be placed into a separate directory inside the component directory, for instance `ulp/`.
|
||||
|
||||
.. note: When registering the component (via ``idf_component_register``), this directory should not be added to the ``SRC_DIRS`` argument. The logic behind this is that the ESP-IDF build system will compile files found in ``SRC_DIRS`` based on their extensions. For ``.S`` files, ``xtensa-esp32-elf-as`` assembler is used. This is not desirable for ULP assembly files, so the easiest way to achieve the distinction is by placing ULP assembly files into a separate directory. The ULP assembly source files should also **not** be added to ``SRCS`` for the same reason. See the step below for how to properly add ULP assembly source files.
|
||||
.. note: When registering the component (via ``idf_component_register``), this directory should not be added to the ``SRC_DIRS`` argument. The logic behind this is that the ESP-IDF build system will compile files found in ``SRC_DIRS`` based on their extensions. For ``.S`` files, ``xtensa-{IDF_TARGET_NAME}-elf-as`` assembler is used. This is not desirable for ULP assembly files, so the easiest way to achieve the distinction is by placing ULP assembly files into a separate directory. The ULP assembly source files should also **not** be added to ``SRCS`` for the same reason. See the step below for how to properly add ULP assembly source files.
|
||||
|
||||
2. Call ``ulp_embed_binary`` from the component CMakeLists.txt after registration. For example::
|
||||
|
||||
@@ -42,11 +44,11 @@ To compile the ULP code as part of the component, the following steps must be ta
|
||||
|
||||
ulp_embed_binary(${ulp_app_name} ${ulp_s_sources} ${ulp_exp_dep_srcs})
|
||||
|
||||
The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used by other generated artifacts
|
||||
such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files.
|
||||
Finally, the third argument specifies the list of component source files which include the header file to be generated.
|
||||
This list is needed to build the dependencies correctly and ensure that the generated header file will be created before any of these files are compiled.
|
||||
See section below for the concept of generated header files for ULP applications.
|
||||
The first argument to ``ulp_embed_binary`` specifies the ULP binary name. The name specified here will also be used by other generated artifacts
|
||||
such as the ELF file, map file, header file and linker export file. The second argument specifies the ULP assembly source files.
|
||||
Finally, the third argument specifies the list of component source files which include the header file to be generated.
|
||||
This list is needed to build the dependencies correctly and ensure that the generated header file will be created before any of these files are compiled.
|
||||
See section below for the concept of generated header files for ULP applications.
|
||||
|
||||
3. Build the application as usual (e.g. `idf.py app`)
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
ESP32 ULP coprocessor instruction set
|
||||
=====================================
|
||||
|
||||
This document provides details about the instructions used by ESP32 ULP coprocessor assembler.
|
||||
This document provides details about the instructions used by {IDF_TARGET_NAME} ULP coprocessor assembler.
|
||||
|
||||
ULP coprocessor has 4 16-bit general purpose registers, labeled R0, R1, R2, R3. It also has an 8-bit counter register (stage_cnt) which can be used to implement loops. Stage count regiter is accessed using special instructions.
|
||||
|
||||
@@ -13,7 +13,7 @@ The instruction syntax is case insensitive. Upper and lower case letters can be
|
||||
|
||||
Note about addressing
|
||||
---------------------
|
||||
ESP32 ULP coprocessor's JUMP, ST, LD instructions which take register as an argument (jump address, store/load base address) expect the argument to be expressed in 32-bit words.
|
||||
{IDF_TARGET_NAME} ULP coprocessor's JUMP, ST, LD instructions which take register as an argument (jump address, store/load base address) expect the argument to be expressed in 32-bit words.
|
||||
|
||||
Consider the following example program::
|
||||
|
||||
@@ -160,9 +160,9 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
**Examples**::
|
||||
|
||||
1: SUB R1, R2, R3 //R1 = R2 - R3
|
||||
|
||||
|
||||
2: sub R1, R2, 0x1234 //R1 = R2 - 0x1234
|
||||
|
||||
|
||||
3: .set value1, 0x03 //constant value1=0x03
|
||||
SUB R1, R2, value1 //R1 = R2 - value1
|
||||
4: .global label //declaration of variable label
|
||||
@@ -211,7 +211,7 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
|
||||
**Syntax**
|
||||
**OR** *Rdst, Rsrc1, Rsrc2*
|
||||
|
||||
|
||||
**OR** *Rdst, Rsrc1, imm*
|
||||
|
||||
**Operands**
|
||||
@@ -222,12 +222,12 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
|
||||
**Cycles**
|
||||
2 cycles to execute, 4 cycles to fetch next instruction
|
||||
|
||||
|
||||
**Description**
|
||||
The instruction does logical OR of a source register and another source register or 16-bit signed value and stores result to the destination register.
|
||||
|
||||
**Examples**::
|
||||
|
||||
|
||||
1: OR R1, R2, R3 //R1 = R2 \| R3
|
||||
|
||||
2: OR R1, R2, 0x1234 //R1 = R2 \| 0x1234
|
||||
@@ -255,7 +255,7 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
- *Rsrc1* - Register R[0..3]
|
||||
- *Rsrc2* - Register R[0..3]
|
||||
- *Imm* - 16-bit signed value
|
||||
|
||||
|
||||
**Cycles**
|
||||
2 cycles to execute, 4 cycles to fetch next instruction
|
||||
|
||||
@@ -373,7 +373,7 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
**Examples**::
|
||||
|
||||
1: ST R1, R2, 0x12 //MEM[R2+0x12] = R1
|
||||
|
||||
|
||||
2: .data //Data section definition
|
||||
Addr1: .word 123 // Define label Addr1 16 bit
|
||||
.set offs, 0x00 // Define constant offs
|
||||
@@ -392,9 +392,9 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
|
||||
**Operands**
|
||||
*Rdst* – Register R[0..3], destination
|
||||
|
||||
|
||||
*Rsrc* – Register R[0..3], holds address of destination, in 32-bit words
|
||||
|
||||
|
||||
*Offset* – 10-bit signed value, offset in bytes
|
||||
|
||||
**Cycles**
|
||||
@@ -481,8 +481,8 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
- *EQ* (equal) – jump if value in R0 == threshold
|
||||
- *LT* (less than) – jump if value in R0 < threshold
|
||||
- *LE* (less or equal) – jump if value in R0 <= threshold
|
||||
- *GT* (greater than) – jump if value in R0 > threshold
|
||||
- *GE* (greater or equal) – jump if value in R0 >= threshold
|
||||
- *GT* (greater than) – jump if value in R0 > threshold
|
||||
- *GE* (greater or equal) – jump if value in R0 >= threshold
|
||||
|
||||
|
||||
**Cycles**
|
||||
@@ -551,7 +551,7 @@ Note that when accessing RTC memories and RTC registers, ULP coprocessor has low
|
||||
next:
|
||||
|
||||
// JUMPS target, threshold, GT is implemented as:
|
||||
|
||||
|
||||
JUMPS next, threshold, LE
|
||||
JUMPS target, threshold, GE
|
||||
next:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
Unit Testing in ESP32
|
||||
=============================
|
||||
Unit Testing in {IDF_TARGET_NAME}
|
||||
=================================
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
ESP-IDF comes with a unit test application that is based on the Unity - unit test framework. Unit tests are integrated in the ESP-IDF repository and are placed in the ``test`` subdirectories of each component respectively.
|
||||
@@ -98,7 +98,7 @@ Once the signal is sent from DUT2, you need to press "Enter" on DUT1, then DUT1
|
||||
Multi-stage Test Cases
|
||||
-----------------------
|
||||
|
||||
The normal test cases are expected to finish without reset (or only need to check if reset happens). Sometimes we expect to run some specific tests after certain kinds of reset.
|
||||
The normal test cases are expected to finish without reset (or only need to check if reset happens). Sometimes we expect to run some specific tests after certain kinds of reset.
|
||||
For example, we expect to test if the reset reason is correct after a wakeup from deep sleep. We need to create a deep-sleep reset first and then check the reset reason.
|
||||
To support this, we can define multi-stage test cases, to group a set of test functions::
|
||||
|
||||
@@ -114,7 +114,7 @@ To support this, we can define multi-stage test cases, to group a set of test fu
|
||||
TEST_ASSERT(reason == DEEPSLEEP_RESET);
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("reset reason check for deepsleep", "[esp32]", trigger_deepsleep, check_deepsleep_reset_reason);
|
||||
TEST_CASE_MULTIPLE_STAGES("reset reason check for deepsleep", "[{IDF_TARGET_PATH_NAME}]", trigger_deepsleep, check_deepsleep_reset_reason);
|
||||
|
||||
Multi-stage test cases present a group of test functions to users. It needs user interactions (select cases and select different stages) to run the case.
|
||||
|
||||
@@ -130,19 +130,19 @@ Change into ``tools/unit-test-app`` directory to configure and build it:
|
||||
* ``idf.py menuconfig`` - configure unit test app.
|
||||
|
||||
* ``idf.py -T all build`` - build unit test app with tests for each component having tests in the ``test`` subdirectory.
|
||||
* ``idf.py -T xxx build`` - build unit test app with tests for specific components.
|
||||
* ``idf.py -T xxx build`` - build unit test app with tests for specific components.
|
||||
* ``idf.py -T all -E xxxbuild`` - build unit test app with all unit tests, except for unit tests of some components. (For instance: ``idf.py -T all -E ulp mbedtls build`` - build all unit tests exludes ``ulp`` and ``mbedtls`` components).
|
||||
|
||||
When the build finishes, it will print instructions for flashing the chip. You can simply run ``idf.py flash`` to flash all build output.
|
||||
|
||||
You can also run ``idf.py -T all flash`` or ``idf.py -T xxx flash`` to build and flash. Everything needed will be rebuilt automatically before flashing.
|
||||
You can also run ``idf.py -T all flash`` or ``idf.py -T xxx flash`` to build and flash. Everything needed will be rebuilt automatically before flashing.
|
||||
|
||||
Use menuconfig to set the serial port for flashing.
|
||||
|
||||
Running Unit Tests
|
||||
------------------
|
||||
|
||||
After flashing reset the ESP32 and it will boot the unit test app.
|
||||
After flashing reset the {IDF_TARGET_NAME} and it will boot the unit test app.
|
||||
|
||||
When unit test app is idle, press "Enter" will make it print test menu with all available tests::
|
||||
|
||||
@@ -168,7 +168,7 @@ When unit test app is idle, press "Enter" will make it print test menu with all
|
||||
(17) "SPI Master no response when switch from host1 (HSPI) to host2 (VSPI)" [spi]
|
||||
(18) "SPI Master DMA test, TX and RX in different regions" [spi]
|
||||
(19) "SPI Master DMA test: length, start, not aligned" [spi]
|
||||
(20) "reset reason check for deepsleep" [esp32][test_env=UT_T2_1][multi_stage]
|
||||
(20) "reset reason check for deepsleep" [{IDF_TARGET_PATH_NAME}][test_env=UT_T2_1][multi_stage]
|
||||
(1) "trigger_deepsleep"
|
||||
(2) "check_deepsleep_reset_reason"
|
||||
|
||||
@@ -176,7 +176,7 @@ The normal case will print the case name and description. Master-slave cases wil
|
||||
|
||||
Test cases can be run by inputting one of the following:
|
||||
|
||||
- Test case name in quotation marks to run a single test case
|
||||
- Test case name in quotation marks to run a single test case
|
||||
|
||||
- Test case index to run a single test case
|
||||
|
||||
@@ -223,8 +223,8 @@ between runs and between different builds. A technique for eliminating for some
|
||||
variability is to place code and data in instruction or data RAM (IRAM/DRAM), respectively. The CPU can access IRAM and DRAM directly, eliminating the cache out of the equation.
|
||||
However, this might not always be viable as the size of IRAM and DRAM is limited.
|
||||
|
||||
The cache compensated timer is an alternative to placing the code/data to be benchmarked in IRAM/DRAM. This timer uses the processor's internal event counters in order to determine the amount
|
||||
of time spent on waiting for code/data in case of a cache miss, then subtract that from the recorded wall time.
|
||||
The cache compensated timer is an alternative to placing the code/data to be benchmarked in IRAM/DRAM. This timer uses the processor's internal event counters in order to determine the amount
|
||||
of time spent on waiting for code/data in case of a cache miss, then subtract that from the recorded wall time.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -18,4 +18,4 @@ Check :example:`bluetooth/bluedroid/hci` folder in ESP-IDF examples, which conta
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_bt.inc
|
||||
.. include-build-file:: inc/esp_bt.inc
|
||||
|
@@ -42,7 +42,7 @@ This section contains only one header file, which lists the following items of E
|
||||
* Structs used to transmit/receive messages
|
||||
* Event types and related event parameters
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_defs.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_defs.inc
|
||||
|
||||
|
||||
ESP-BLE-MESH Core API Reference
|
||||
@@ -64,37 +64,37 @@ This API reference covers six components:
|
||||
ESP-BLE-MESH Stack Initialization
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_common_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_common_api.inc
|
||||
|
||||
|
||||
Reading of Local Data Information
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_local_data_operation_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_local_data_operation_api.inc
|
||||
|
||||
|
||||
Low Power Operation (Updating)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_low_power_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_low_power_api.inc
|
||||
|
||||
|
||||
Send/Publish Messages, add Local AppKey, etc.
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_networking_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_networking_api.inc
|
||||
|
||||
|
||||
ESP-BLE-MESH Node/Provisioner Provisioning
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_provisioning_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_provisioning_api.inc
|
||||
|
||||
|
||||
ESP-BLE-MESH GATT Proxy Server
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_proxy_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_proxy_api.inc
|
||||
|
||||
|
||||
ESP-BLE-MESH Models API Reference
|
||||
@@ -120,35 +120,35 @@ There are six categories of models:
|
||||
Configuration Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_config_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_config_model_api.inc
|
||||
|
||||
|
||||
Health Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_generic_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_generic_model_api.inc
|
||||
|
||||
|
||||
Generic Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_health_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_health_model_api.inc
|
||||
|
||||
|
||||
Sensor Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_lighting_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_lighting_model_api.inc
|
||||
|
||||
|
||||
Time and Scenes Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_sensor_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_sensor_model_api.inc
|
||||
|
||||
|
||||
Lighting Client/Server Models
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_ble_mesh_time_scene_model_api.inc
|
||||
.. include-build-file:: inc/esp_ble_mesh_time_scene_model_api.inc
|
||||
|
||||
|
@@ -18,5 +18,5 @@ Check :example:`bluetooth/bluedroid/classic_bt` folder in ESP-IDF examples, whic
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_a2dp_api.inc
|
||||
.. include-build-file:: inc/esp_a2dp_api.inc
|
||||
|
||||
|
@@ -18,6 +18,6 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_avrc_api.inc
|
||||
.. include-build-file:: inc/esp_avrc_api.inc
|
||||
|
||||
|
||||
|
@@ -19,5 +19,5 @@ Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which conta
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_blufi_api.inc
|
||||
.. include-build-file:: inc/esp_blufi_api.inc
|
||||
|
||||
|
@@ -17,5 +17,5 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_bt_defs.inc
|
||||
.. include-build-file:: inc/esp_bt_defs.inc
|
||||
|
||||
|
@@ -18,4 +18,4 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_bt_device.inc
|
||||
.. include-build-file:: inc/esp_bt_device.inc
|
||||
|
@@ -17,6 +17,6 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_bt_main.inc
|
||||
.. include-build-file:: inc/esp_bt_main.inc
|
||||
|
||||
|
||||
|
@@ -26,5 +26,5 @@ Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which conta
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_gap_ble_api.inc
|
||||
.. include-build-file:: inc/esp_gap_ble_api.inc
|
||||
|
||||
|
@@ -16,5 +16,5 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_gap_bt_api.inc
|
||||
.. include-build-file:: inc/esp_gap_bt_api.inc
|
||||
|
||||
|
@@ -16,6 +16,6 @@ Application Example
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_gatt_defs.inc
|
||||
.. include-build-file:: inc/esp_gatt_defs.inc
|
||||
|
||||
|
||||
|
@@ -30,5 +30,5 @@ Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which conta
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_gattc_api.inc
|
||||
.. include-build-file:: inc/esp_gattc_api.inc
|
||||
|
||||
|
@@ -30,5 +30,5 @@ Check :example:`bluetooth/bluedroid/ble` folder in ESP-IDF examples, which conta
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_gatts_api.inc
|
||||
.. include-build-file:: inc/esp_gatts_api.inc
|
||||
|
||||
|
@@ -1,14 +1,7 @@
|
||||
HFP AG API
|
||||
==============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
`Instructions`_
|
||||
|
||||
.. _Instructions: ../template.html
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_hf_ag_api.inc
|
||||
.. include-build-file:: inc/esp_hf_ag_api.inc
|
||||
|
@@ -11,4 +11,4 @@ Overview
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_hf_client_api.inc
|
||||
.. include-build-file:: inc/esp_hf_client_api.inc
|
||||
|
@@ -11,6 +11,6 @@ Overview
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_hf_defs.inc
|
||||
.. include-build-file:: inc/esp_hf_defs.inc
|
||||
|
||||
|
||||
|
@@ -18,5 +18,5 @@ Check :example:`bluetooth/bluedroid/classic_bt` folder in ESP-IDF examples, whic
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_spp_api.inc
|
||||
.. include-build-file:: inc/esp_spp_api.inc
|
||||
|
||||
|
@@ -41,4 +41,4 @@ This documentation does not cover NimBLE APIs. Refer to `NimBLE tutorial <https:
|
||||
API Reference
|
||||
=============
|
||||
|
||||
.. include:: /_build/inc/esp_nimble_hci.inc
|
||||
.. include-build-file:: inc/esp_nimble_hci.inc
|
||||
|
@@ -5,4 +5,4 @@ This section lists various error code constants defined in ESP-IDF.
|
||||
|
||||
For general information about error codes in ESP-IDF, see :doc:`Error Handling <../api-guides/error-handling>`.
|
||||
|
||||
.. include:: /_build/inc/esp_err_defs.inc
|
||||
.. include-build-file:: inc/esp_err_defs.inc
|
||||
|
@@ -6,7 +6,7 @@ API Reference
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
Bluetooth <bluetooth/index>
|
||||
:esp32: Bluetooth <bluetooth/index>
|
||||
Networking <network/index>
|
||||
Peripherals <peripherals/index>
|
||||
Protocols <protocols/index>
|
||||
|
@@ -85,7 +85,7 @@ Subsequent sections contain the list of available ESP-IDF options, automatically
|
||||
By convention, all option names are upper case with underscores. When Kconfig generates sdkconfig and sdkconfig.h files, option names are prefixed with ``CONFIG_``. So if an option ``ENABLE_FOO`` is defined in a Kconfig file and selected in menuconfig, then sdkconfig and sdkconfig.h files will have ``CONFIG_ENABLE_FOO`` defined. In this reference, option names are also prefixed with ``CONFIG_``, same as in the source code.
|
||||
|
||||
|
||||
.. include:: /_build/inc/kconfig.inc
|
||||
.. include-build-file:: inc/kconfig.inc
|
||||
|
||||
Customisations
|
||||
==============
|
||||
|
@@ -37,24 +37,24 @@ Ethernet PHY Common Registers
|
||||
API Reference - Driver Model
|
||||
----------------------------
|
||||
|
||||
.. include:: /_build/inc/esp_eth.inc
|
||||
.. include-build-file:: inc/esp_eth.inc
|
||||
|
||||
API Reference - Common Interface
|
||||
--------------------------------
|
||||
|
||||
.. include:: /_build/inc/esp_eth_com.inc
|
||||
.. include-build-file:: inc/esp_eth_com.inc
|
||||
|
||||
API Reference - MAC Interface
|
||||
-----------------------------
|
||||
|
||||
.. include:: /_build/inc/esp_eth_mac.inc
|
||||
.. include-build-file:: inc/esp_eth_mac.inc
|
||||
|
||||
API Reference - PHY Interface
|
||||
-----------------------------
|
||||
|
||||
.. include:: /_build/inc/esp_eth_phy.inc
|
||||
.. include-build-file:: inc/esp_eth_phy.inc
|
||||
|
||||
API Reference - Glue for esp_netif
|
||||
----------------------------------
|
||||
|
||||
.. include:: /_build/inc/esp_eth_netif_glue.inc
|
||||
.. include-build-file:: inc/esp_eth_netif_glue.inc
|
||||
|
@@ -332,4 +332,4 @@ ESP-IDF contains these ESP-MESH example projects:
|
||||
API Reference
|
||||
--------------
|
||||
|
||||
.. include:: /_build/inc/esp_mesh.inc
|
||||
.. include-build-file:: inc/esp_mesh.inc
|
||||
|
@@ -168,10 +168,10 @@ configured with default settings, which as a consequence, means that:
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_netif.inc
|
||||
.. include-build-file:: inc/esp_netif.inc
|
||||
|
||||
|
||||
WiFi default API reference
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_wifi_default.inc
|
||||
.. include-build-file:: inc/esp_wifi_default.inc
|
||||
|
@@ -94,4 +94,4 @@ The packet data path functions for transmitting and freeing the rx buffer (defin
|
||||
the esp-netif, specifically from its TCP/IP stack connecting layer. The following API reference outlines these network stack
|
||||
interaction with the esp-netif.
|
||||
|
||||
.. include:: /_build/inc/esp_netif_net_stack.inc
|
||||
.. include-build-file:: inc/esp_netif_net_stack.inc
|
||||
|
@@ -84,4 +84,4 @@ Instead, post the necessary data to a queue and handle it from a lower priority
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_now.inc
|
||||
.. include-build-file:: inc/esp_now.inc
|
||||
|
@@ -6,4 +6,4 @@ SmartConfig
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_smartconfig.inc
|
||||
.. include-build-file:: inc/esp_smartconfig.inc
|
||||
|
@@ -6,11 +6,11 @@ Wi-Fi
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The WiFi libraries provide support for configuring and monitoring the ESP32 WiFi networking functionality. This includes configuration for:
|
||||
The WiFi libraries provide support for configuring and monitoring the {IDF_TARGET_NAME} WiFi networking functionality. This includes configuration for:
|
||||
|
||||
- Station mode (aka STA mode or WiFi client mode). ESP32 connects to an access point.
|
||||
- AP mode (aka Soft-AP mode or Access Point mode). Stations connect to the ESP32.
|
||||
- Combined AP-STA mode (ESP32 is concurrently an access point and a station connected to another access point).
|
||||
- Station mode (aka STA mode or WiFi client mode). {IDF_TARGET_NAME} connects to an access point.
|
||||
- AP mode (aka Soft-AP mode or Access Point mode). Stations connect to the {IDF_TARGET_NAME}.
|
||||
- Combined AP-STA mode ({IDF_TARGET_NAME} is concurrently an access point and a station connected to another access point).
|
||||
|
||||
- Various security modes for the above (WPA, WPA2, WEP, etc.)
|
||||
- Scanning for access points (active & passive scanning).
|
||||
@@ -30,7 +30,7 @@ In addition, there is a simple `esp-idf-template <https://github.com/espressif/e
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/esp_wifi.inc
|
||||
.. include:: /_build/inc/esp_wifi_types.inc
|
||||
.. include-build-file:: inc/esp_wifi.inc
|
||||
.. include-build-file:: inc/esp_wifi_types.inc
|
||||
|
||||
|
||||
|
@@ -1,34 +1,50 @@
|
||||
Analog to Digital Converter
|
||||
===========================
|
||||
|
||||
{IDF_TARGET_ADC1_CH0: default="GPIO 0", esp32="GPIO 36"}
|
||||
{IDF_TARGET_ADC2_CH7: default="GPIO 0", esp32="GPIO 27"}
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The ESP32 integrates two 12-bit SAR (`Successive Approximation Register <https://en.wikipedia.org/wiki/Successive_approximation_ADC>`_) ADCs supporting a total of 18 measurement channels (analog enabled pins).
|
||||
.. only:: esp32
|
||||
|
||||
The ADC driver API supports ADC1 (8 channels, attached to GPIOs 32 - 39), and ADC2 (10 channels, attached to GPIOs 0, 2, 4, 12 - 15 and 25 - 27). However, the usage of ADC2 has some restrictions for the application:
|
||||
The {IDF_TARGET_NAME} integrates two 12-bit SAR (`Successive Approximation Register <https://en.wikipedia.org/wiki/Successive_approximation_ADC>`_) ADCs supporting a total of 18 measurement channels (analog enabled pins).
|
||||
|
||||
1. ADC2 is used by the Wi-Fi driver. Therefore the application can only use ADC2 when the Wi-Fi driver has not started.
|
||||
2. Some of the ADC2 pins are used as strapping pins (GPIO 0, 2, 15) thus cannot be used freely. Such is the case in the following official Development Kits:
|
||||
The ADC driver API supports ADC1 (8 channels, attached to GPIOs 32 - 39), and ADC2 (10 channels, attached to GPIOs 0, 2, 4, 12 - 15 and 25 - 27). However, the usage of ADC2 has some restrictions for the application:
|
||||
|
||||
- :ref:`ESP32 DevKitC <esp-modules-and-boards-esp32-devkitc>`: GPIO 0 cannot be used due to external auto program circuits.
|
||||
- :ref:`ESP-WROVER-KIT <esp-modules-and-boards-esp-wrover-kit>`: GPIO 0, 2, 4 and 15 cannot be used due to external connections for different purposes.
|
||||
1. ADC2 is used by the Wi-Fi driver. Therefore the application can only use ADC2 when the Wi-Fi driver has not started.
|
||||
2. Some of the ADC2 pins are used as strapping pins (GPIO 0, 2, 15) thus cannot be used freely. Such is the case in the following official Development Kits:
|
||||
|
||||
- :ref:`ESP32 DevKitC <esp-modules-and-boards-esp32-devkitc>`: GPIO 0 cannot be used due to external auto program circuits.
|
||||
- :ref:`ESP-WROVER-KIT <esp-modules-and-boards-esp-wrover-kit>`: GPIO 0, 2, 4 and 15 cannot be used due to external connections for different purposes.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
The {IDF_TARGET_NAME} integrates two 12-bit SAR (`Successive Approximation Register <https://en.wikipedia.org/wiki/Successive_approximation_ADC>`_) ADCs supporting a total of 20 measurement channels (analog enabled pins).
|
||||
|
||||
The ADC driver API supports ADC1 (10 channels, attached to GPIOs 1 - 10), and ADC2 (10 channels, attached to GPIOs 11 - 20). However, the usage of ADC2 has some restrictions for the application:
|
||||
|
||||
1. ADC2 is used by the Wi-Fi driver. Therefore the application can only use ADC2 when the Wi-Fi driver has not started.
|
||||
|
||||
Configuration and Reading ADC
|
||||
-----------------------------
|
||||
|
||||
The ADC should be configured before reading is taken.
|
||||
|
||||
- For ADC1, configure desired precision and attenuation by calling functions :cpp:func:`adc1_config_width` and :cpp:func:`adc1_config_channel_atten`.
|
||||
- For ADC1, configure desired precision and attenuation by calling functions :cpp:func:`adc1_config_width` and :cpp:func:`adc1_config_channel_atten`.
|
||||
- For ADC2, configure the attenuation by :cpp:func:`adc2_config_channel_atten`. The reading width of ADC2 is configured every time you take the reading.
|
||||
|
||||
|
||||
Attenuation configuration is done per channel, see :cpp:type:`adc1_channel_t` and :cpp:type:`adc2_channel_t`, set as a parameter of above functions.
|
||||
|
||||
Then it is possible to read ADC conversion result with :cpp:func:`adc1_get_raw` and :cpp:func:`adc2_get_raw`. Reading width of ADC2 should be set as a parameter of :cpp:func:`adc2_get_raw` instead of in the configuration functions.
|
||||
|
||||
.. note:: Since the ADC2 is shared with the WIFI module, which has higher priority, reading operation of :cpp:func:`adc2_get_raw` will fail between :cpp:func:`esp_wifi_start()` and :cpp:func:`esp_wifi_stop()`. Use the return code to see whether the reading is successful.
|
||||
|
||||
It is also possible to read the internal hall effect sensor via ADC1 by calling dedicated function :cpp:func:`hall_sensor_read`. Note that even the hall sensor is internal to ESP32, reading from it uses channels 0 and 3 of ADC1 (GPIO 36 and 39). Do not connect anything else to these pins and do not change their configuration. Otherwise it may affect the measurement of low value signal from the sensor.
|
||||
.. only:: esp32
|
||||
|
||||
It is also possible to read the internal hall effect sensor via ADC1 by calling dedicated function :cpp:func:`hall_sensor_read`. Note that even the hall sensor is internal to ESP32, reading from it uses channels 0 and 3 of ADC1 (GPIO 36 and 39). Do not connect anything else to these pins and do not change their configuration. Otherwise it may affect the measurement of low value signal from the sensor.
|
||||
|
||||
This API provides convenient way to configure ADC1 for reading from :doc:`ULP <../../api-guides/ulp>`. To do so, call function :cpp:func:`adc1_ulp_enable` and then set precision and attenuation as discussed above.
|
||||
|
||||
@@ -37,7 +53,7 @@ There is another specific function :cpp:func:`adc2_vref_to_gpio` used to route i
|
||||
Application Examples
|
||||
--------------------
|
||||
|
||||
Reading voltage on ADC1 channel 0 (GPIO 36)::
|
||||
Reading voltage on ADC1 channel 0 ({IDF_TARGET_ADC1_CH0})::
|
||||
|
||||
#include <driver/adc.h>
|
||||
|
||||
@@ -50,12 +66,12 @@ Reading voltage on ADC1 channel 0 (GPIO 36)::
|
||||
The input voltage in above example is from 0 to 1.1V (0 dB attenuation). The input range can be extended by setting higher attenuation, see :cpp:type:`adc_atten_t`.
|
||||
An example using the ADC driver including calibration (discussed below) is available in esp-idf: :example:`peripherals/adc`
|
||||
|
||||
Reading voltage on ADC2 channel 7 (GPIO 27)::
|
||||
Reading voltage on ADC2 channel 7 ({IDF_TARGET_ADC2_CH7})::
|
||||
|
||||
#include <driver/adc.h>
|
||||
|
||||
...
|
||||
|
||||
|
||||
int read_raw;
|
||||
adc2_config_channel_atten( ADC2_CHANNEL_7, ADC_ATTEN_0db );
|
||||
|
||||
@@ -69,14 +85,16 @@ Reading voltage on ADC2 channel 7 (GPIO 27)::
|
||||
The reading may fail due to collision with Wi-Fi, should check it.
|
||||
An example using the ADC2 driver to read the output of DAC is available in esp-idf: :example:`peripherals/adc2`
|
||||
|
||||
Reading the internal hall effect sensor::
|
||||
.. only:: esp32
|
||||
|
||||
#include <driver/adc.h>
|
||||
Reading the internal hall effect sensor::
|
||||
|
||||
...
|
||||
#include <driver/adc.h>
|
||||
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
int val = hall_sensor_read();
|
||||
...
|
||||
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
int val = hall_sensor_read();
|
||||
|
||||
|
||||
|
||||
@@ -87,23 +105,23 @@ The value read in both these examples is 12 bits wide (range 0-4095).
|
||||
Minimizing Noise
|
||||
----------------
|
||||
|
||||
The ESP32 ADC can be sensitive to noise leading to large discrepancies in ADC readings. To minimize noise, users may connect a 0.1uF capacitor to the ADC input pad in use. Multisampling may also be used to further mitigate the effects of noise.
|
||||
The {IDF_TARGET_NAME} ADC can be sensitive to noise leading to large discrepancies in ADC readings. To minimize noise, users may connect a 0.1uF capacitor to the ADC input pad in use. Multisampling may also be used to further mitigate the effects of noise.
|
||||
|
||||
.. figure:: ../../../_static/adc-noise-graph.jpg
|
||||
:align: center
|
||||
:alt: ADC noise mitigation
|
||||
|
||||
|
||||
Graph illustrating noise mitigation using capacitor and multisampling of 64 samples.
|
||||
|
||||
ADC Calibration
|
||||
---------------
|
||||
|
||||
The :component_file:`esp_adc_cal/include/esp_adc_cal.h` API provides functions to correct for differences in measured voltages caused by variation of ADC reference voltages (Vref) between chips. Per design the ADC reference voltage is 1100mV, however the true reference voltage can range from 1000mV to 1200mV amongst different ESP32s.
|
||||
The :component_file:`esp_adc_cal/include/esp_adc_cal.h` API provides functions to correct for differences in measured voltages caused by variation of ADC reference voltages (Vref) between chips. Per design the ADC reference voltage is 1100mV, however the true reference voltage can range from 1000mV to 1200mV amongst different {IDF_TARGET_NAME}s.
|
||||
|
||||
.. figure:: ../../../_static/adc-vref-graph.jpg
|
||||
:align: center
|
||||
:alt: ADC reference voltage comparison
|
||||
|
||||
|
||||
Graph illustrating effect of differing reference voltages on the ADC voltage curve.
|
||||
|
||||
Correcting ADC readings using this API involves characterizing one of the ADCs at a given attenuation to obtain a characteristics curve (ADC-Voltage curve) that takes into account the difference in ADC reference voltage. The characteristics curve is in the form of ``y = coeff_a * x + coeff_b`` and is used to convert ADC readings to voltages in mV. Calculation of the characteristics curve is based on calibration values which can be stored in eFuse or provided by the user.
|
||||
@@ -111,48 +129,50 @@ Correcting ADC readings using this API involves characterizing one of the ADCs a
|
||||
Calibration Values
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Calibration values are used to generate characteristic curves that account for the unique ADC reference voltage of a particular ESP32. There are currently three sources of calibration values. The availability of these calibration values will depend on the type and production date of the ESP32 chip/module.
|
||||
Calibration values are used to generate characteristic curves that account for the unique ADC reference voltage of a particular {IDF_TARGET_NAME}. There are currently three sources of calibration values. The availability of these calibration values will depend on the type and production date of the {IDF_TARGET_NAME} chip/module.
|
||||
|
||||
* **Two Point** values represent each of the ADCs’ readings at 150mV and 850mV. To obtain more accurate calibration results these values should be measured by user and burned into eFuse ``BLOCK3``.
|
||||
|
||||
* **eFuse Vref** represents the true ADC reference voltage. This value is measured and burned into eFuse ``BLOCK0`` during factory calibration.
|
||||
* **eFuse Vref** represents the true ADC reference voltage. This value is measured and burned into eFuse ``BLOCK0`` during factory calibration.
|
||||
|
||||
* **Default Vref** is an estimate of the ADC reference voltage provided by the user as a parameter during characterization. If Two Point or eFuse Vref values are unavailable, **Default Vref** will be used.
|
||||
|
||||
Individual measurement and burning of the **eFuse Vref** has been applied to ESP32-D0WD and ESP32-D0WDQ6 chips produced on/after the 1st week of 2018. Such chips may be recognized by date codes on/later than 012018 (see Line 4 on figure below).
|
||||
.. only:: esp32
|
||||
|
||||
.. figure:: ../../../_static/chip_surface_marking.png
|
||||
:align: center
|
||||
:alt: ESP32 Chip Surface Marking
|
||||
|
||||
ESP32 Chip Surface Marking
|
||||
Individual measurement and burning of the **eFuse Vref** has been applied to ESP32-D0WD and ESP32-D0WDQ6 chips produced on/after the 1st week of 2018. Such chips may be recognized by date codes on/later than 012018 (see Line 4 on figure below).
|
||||
|
||||
If you would like to purchase chips or modules with calibration, double check with distributor or Espressif directly.
|
||||
.. figure:: ../../../_static/chip_surface_marking.png
|
||||
:align: center
|
||||
:alt: ESP32 Chip Surface Marking
|
||||
|
||||
.. highlight:: none
|
||||
ESP32 Chip Surface Marking
|
||||
|
||||
If you are unable to check the date code (i.e. the chip may be enclosed inside a canned module, etc.), you can still verify if **eFuse Vref** is present by running `espefuse.py <https://github.com/espressif/esptool/wiki/espefuse>`_ tool with ``adc_info`` parameter ::
|
||||
If you would like to purchase chips or modules with calibration, double check with distributor or Espressif directly.
|
||||
|
||||
$IDF_PATH/components/esptool_py/esptool/espefuse.py --port /dev/ttyUSB0 adc_info
|
||||
.. highlight:: none
|
||||
|
||||
Replace ``/dev/ttyUSB0`` with ESP32 board's port name.
|
||||
If you are unable to check the date code (i.e. the chip may be enclosed inside a canned module, etc.), you can still verify if **eFuse Vref** is present by running `espefuse.py <https://github.com/espressif/esptool/wiki/espefuse>`_ tool with ``adc_info`` parameter ::
|
||||
|
||||
A chip that has specific **eFuse Vref** value programmed (in this case 1093mV) will be reported as follows::
|
||||
$IDF_PATH/components/esptool_py/esptool/espefuse.py --port /dev/ttyUSB0 adc_info
|
||||
|
||||
ADC VRef calibration: 1093mV
|
||||
Replace ``/dev/ttyUSB0`` with {IDF_TARGET_NAME} board's port name.
|
||||
|
||||
In another example below the **eFuse Vref** is not programmed::
|
||||
A chip that has specific **eFuse Vref** value programmed (in this case 1093mV) will be reported as follows::
|
||||
|
||||
ADC VRef calibration: None (1100mV nominal)
|
||||
ADC VRef calibration: 1093mV
|
||||
|
||||
For a chip with two point calibration the message will look similar to::
|
||||
In another example below the **eFuse Vref** is not programmed::
|
||||
|
||||
ADC VRef calibration: 1149mV
|
||||
ADC readings stored in efuse BLK3:
|
||||
ADC1 Low reading (150mV): 306
|
||||
ADC1 High reading (850mV): 3153
|
||||
ADC2 Low reading (150mV): 389
|
||||
ADC2 High reading (850mV): 3206
|
||||
ADC VRef calibration: None (1100mV nominal)
|
||||
|
||||
For a chip with two point calibration the message will look similar to::
|
||||
|
||||
ADC VRef calibration: 1149mV
|
||||
ADC readings stored in efuse BLK3:
|
||||
ADC1 Low reading (150mV): 306
|
||||
ADC1 High reading (850mV): 3153
|
||||
ADC2 Low reading (150mV): 389
|
||||
ADC2 High reading (850mV): 3206
|
||||
|
||||
Application Example
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
@@ -163,9 +183,9 @@ Characterizing an ADC at a particular attenuation::
|
||||
|
||||
#include "driver/adc.h"
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
//Characterize ADC at particular atten
|
||||
esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
|
||||
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars);
|
||||
@@ -182,15 +202,15 @@ Reading an ADC then converting the reading to a voltage::
|
||||
|
||||
#include "driver/adc.h"
|
||||
#include "esp_adc_cal.h"
|
||||
|
||||
|
||||
...
|
||||
uint32_t reading = adc1_get_raw(ADC1_CHANNEL_5);
|
||||
uint32_t voltage = esp_adc_cal_raw_to_voltage(reading, adc_chars);
|
||||
|
||||
|
||||
Routing ADC reference voltage to GPIO, so it can be manually measured (for **Default Vref**)::
|
||||
|
||||
#include "driver/adc.h"
|
||||
|
||||
|
||||
...
|
||||
|
||||
esp_err_t status = adc2_vref_to_gpio(GPIO_NUM_25);
|
||||
@@ -224,18 +244,18 @@ This reference covers three components:
|
||||
ADC driver
|
||||
^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/adc.inc
|
||||
.. include-build-file:: inc/adc.inc
|
||||
|
||||
.. _adc-api-reference-adc-calibration:
|
||||
|
||||
ADC Calibration
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/esp_adc_cal.inc
|
||||
.. include-build-file:: inc/esp_adc_cal.inc
|
||||
|
||||
.. _adc-api-reference-gpio-lookup-macros:
|
||||
|
||||
GPIO Lookup Macros
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. include:: /_build/inc/adc_channel.inc
|
||||
.. include-build-file:: inc/adc_channel.inc
|
||||
|
@@ -6,22 +6,30 @@ Controller Area Network (CAN)
|
||||
Overview
|
||||
--------
|
||||
|
||||
The ESP32's peripherals contains a CAN Controller that supports Standard Frame Format (11-bit ID) and Extended Frame Format (29-bit ID) of the CAN2.0B specification.
|
||||
.. only:: esp32s2
|
||||
|
||||
.. warning::
|
||||
The ESP32 CAN controller is not compatible with CAN FD frames and will interpret such frames as errors.
|
||||
.. note::
|
||||
|
||||
This programming guide is split into the following sections:
|
||||
The CAN driver is not updated for {IDF_TARGET_NAME} and is temporarily disabled.
|
||||
|
||||
1. :ref:`basic-can-concepts`
|
||||
.. only:: esp32
|
||||
|
||||
2. :ref:`signals-lines-and-transceiver`
|
||||
The {IDF_TARGET_NAME}'s peripherals contains a CAN Controller that supports Standard Frame Format (11-bit ID) and Extended Frame Format (29-bit ID) of the CAN2.0B specification.
|
||||
|
||||
3. :ref:`configuration`
|
||||
.. warning::
|
||||
The {IDF_TARGET_NAME} CAN controller is not compatible with CAN FD frames and will interpret such frames as errors.
|
||||
|
||||
4. :ref:`driver-operation`
|
||||
This programming guide is split into the following sections:
|
||||
|
||||
5. :ref:`examples`
|
||||
1. :ref:`basic-can-concepts`
|
||||
|
||||
2. :ref:`signals-lines-and-transceiver`
|
||||
|
||||
3. :ref:`configuration`
|
||||
|
||||
4. :ref:`driver-operation`
|
||||
|
||||
5. :ref:`examples`
|
||||
|
||||
|
||||
.. --------------------------- Basic CAN Concepts ------------------------------
|
||||
@@ -168,7 +176,11 @@ The operating bit rate of the CAN controller is configured using the :cpp:type:`
|
||||
2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point
|
||||
3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point
|
||||
|
||||
The **Baudrate Prescaler** is used to determine the period of each time quanta by dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be **any even number from 2 to 128**. If the ESP32 is a revision 2 or later chip, the ``brp`` will also support **any multiple of 4 from 132 to 256**, and can be enabled by setting the :ref:`CONFIG_ESP32_REV_MIN` to revision 2 or higher.
|
||||
The **Baudrate Prescaler** is used to determine the period of each time quanta by dividing the CAN controller's source clock (80 MHz APB clock). The ``brp`` can be **any even number from 2 to 128**.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
If the ESP32 is a revision 2 or later chip, the ``brp`` will also support **any multiple of 4 from 132 to 256**, and can be enabled by setting the :ref:`CONFIG_ESP32_REV_MIN` to revision 2 or higher.
|
||||
|
||||
.. packetdiag:: ../../../_static/diagrams/can/can_bit_timing.diag
|
||||
:caption: Bit timing configuration for 500kbit/s given BRP = 8
|
||||
@@ -195,9 +207,11 @@ Bit timing **macro initializers** are also available for commonly used CAN bus b
|
||||
- ``CAN_TIMING_CONFIG_800KBITS()``
|
||||
- ``CAN_TIMING_CONFIG_1MBITS()``
|
||||
|
||||
.. note::
|
||||
The macro initializers for 12.5K, 16K, and 20K bit rates are only available
|
||||
for ESP32 revision 2 or later.
|
||||
.. only::esp32
|
||||
|
||||
.. note::
|
||||
The macro initializers for 12.5K, 16K, and 20K bit rates are only available
|
||||
for ESP32 revision 2 or later.
|
||||
|
||||
Acceptance Filter
|
||||
^^^^^^^^^^^^^^^^^
|
||||
@@ -473,7 +487,7 @@ The following example shows how the calculate the acceptance mask given multiple
|
||||
Application Examples
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
**Network Example:** The CAN Network example demonstrates communication between two ESP32s using the CAN driver API. One CAN node acts as a network master initiate and ceasing the transfer of a data from another CAN node acting as a network slave. The example can be found via :example:`peripherals/can/can_network`.
|
||||
**Network Example:** The CAN Network example demonstrates communication between two {IDF_TARGET_NAME}s using the CAN driver API. One CAN node acts as a network master initiate and ceasing the transfer of a data from another CAN node acting as a network slave. The example can be found via :example:`peripherals/can/can_network`.
|
||||
|
||||
**Alert and Recovery Example:** This example demonstrates how to use the CAN driver's alert and bus recovery API. The example purposely introduces errors on the CAN bus to put the CAN controller into the Bus-Off state. An alert is used to detect the Bus-Off state and trigger the bus recovery process. The example can be found via :example:`peripherals/can/can_alert_and_recovery`.
|
||||
|
||||
@@ -485,5 +499,5 @@ Application Examples
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/can_types.inc
|
||||
.. include:: /_build/inc/can.inc
|
||||
.. include-build-file:: inc/can_types.inc
|
||||
.. include-build-file:: inc/can.inc
|
||||
|
@@ -1,10 +1,15 @@
|
||||
Digital To Analog Converter
|
||||
===========================
|
||||
|
||||
{IDF_TARGET_DAC_CH_1: default = "GPIO25", esp32 = "GPIO25", esp32s2 = "GPIO17"}
|
||||
{IDF_TARGET_DAC_CH_2: default = "GPIO26", esp32 = "GPIO26", esp32s2 = "GPIO18"}
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
ESP32 has two 8-bit DAC (digital to analog converter) channels, connected to GPIO25 (Channel 1) and GPIO26 (Channel 2).
|
||||
{IDF_TARGET_NAME} has two 8-bit DAC (digital to analog converter) channels, connected to {IDF_TARGET_DAC_CH_1} (Channel 1) and {IDF_TARGET_DAC_CH_2} (Channel 2).
|
||||
|
||||
|
||||
|
||||
The DAC driver allows these channels to be set to arbitrary voltages.
|
||||
|
||||
@@ -16,7 +21,7 @@ For other analog output options, see the :doc:`Sigma-delta Modulation module <si
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
Setting DAC channel 1 (GPIO 25) voltage to approx 0.78 of VDD_A voltage (VDD * 200 / 255). For VDD_A 3.3V, this is 2.59V::
|
||||
Setting DAC channel 1 ({IDF_TARGET_DAC_CH_1}) voltage to approx 0.78 of VDD_A voltage (VDD * 200 / 255). For VDD_A 3.3V, this is 2.59V::
|
||||
|
||||
#include <driver/dac.h>
|
||||
|
||||
@@ -28,14 +33,14 @@ Setting DAC channel 1 (GPIO 25) voltage to approx 0.78 of VDD_A voltage (VDD * 2
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/dac.inc
|
||||
.. include-build-file:: inc/dac.inc
|
||||
|
||||
GPIO Lookup Macros
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Some useful macros can be used to specified the GPIO number of a DAC channel, or vice versa.
|
||||
e.g.
|
||||
|
||||
1. ``DAC_CHANNEL_1_GPIO_NUM`` is the GPIO number of channel 1 (25);
|
||||
2. ``DAC_GPIO26_CHANNEL`` is the channel number of GPIO 26 (channel 2).
|
||||
1. ``DAC_CHANNEL_1_GPIO_NUM`` is the GPIO number of channel 1 ({IDF_TARGET_DAC_CH_1});
|
||||
2. ``DAC_{IDF_TARGET_DAC_CH_2}_CHANNEL`` is the channel number of GPIO 26 (channel 2).
|
||||
|
||||
.. include:: /_build/inc/dac_channel.inc
|
||||
.. include-build-file:: inc/dac_channel.inc
|
||||
|
@@ -6,7 +6,7 @@ Communication with ESP SDIO Slave
|
||||
ESP SDIO slave initialization
|
||||
------------------------------
|
||||
|
||||
The host should initialize the ESP32 SDIO slave according to the standard
|
||||
The host should initialize the {IDF_TARGET_NAME} SDIO slave according to the standard
|
||||
SDIO initialization process (Sector 3.1.2 of `SDIO Simplified
|
||||
Specification <https://www.sdcard.org/downloads/pls/>`_). In this specification
|
||||
and below, the SDIO slave is also called an (SD)IO card. All the
|
||||
|
@@ -4,10 +4,20 @@ GPIO & RTC GPIO
|
||||
Overview
|
||||
--------
|
||||
|
||||
The ESP32 chip features 40 physical GPIO pads. Some GPIO pads cannot be used or do not have the corresponding pin on the chip package(refer to technical reference manual). Each pad can be used as a general purpose I/O or can be connected to an internal peripheral signal.
|
||||
.. only:: esp32
|
||||
|
||||
The {IDF_TARGET_NAME} chip features 40 physical GPIO pads. Some GPIO pads cannot be used or do not have the corresponding pin on the chip package(refer to technical reference manual). Each pad can be used as a general purpose I/O or can be connected to an internal peripheral signal.
|
||||
|
||||
- Note that GPIO6-11 are usually used for SPI flash.
|
||||
- GPIO34-39 can only be set as input mode and do not have software pullup or pulldown functions.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
The {IDF_TARGET_NAME} chip features 43 physical GPIO pads. Some GPIO pads cannot be used or do not have the corresponding pin on the chip package(refer to technical reference manual). Each pad can be used as a general purpose I/O or can be connected to an internal peripheral signal.
|
||||
|
||||
- Note that GPIO26-32 are usually used for SPI flash.
|
||||
- GPIO46 is fixed to pull-down and is input only
|
||||
|
||||
- Note that GPIO6-11 are usually used for SPI flash.
|
||||
- GPIO34-39 can only be set as input mode and do not have software pullup or pulldown functions.
|
||||
|
||||
There is also separate "RTC GPIO" support, which functions when GPIOs are routed to the "RTC" low-power and analog subsystem. These pin functions can be used when in deep sleep, when the :doc:`Ultra Low Power co-processor <../../api-guides/ulp>` is running, or when analog functions such as ADC/DAC/etc are in use.
|
||||
|
||||
@@ -19,10 +29,10 @@ GPIO output and input interrupt example: :example:`peripherals/gpio`.
|
||||
API Reference - Normal GPIO
|
||||
---------------------------
|
||||
|
||||
.. include:: /_build/inc/gpio.inc
|
||||
.. include-build-file:: inc/gpio.inc
|
||||
|
||||
API Reference - RTC GPIO
|
||||
------------------------
|
||||
|
||||
.. include:: /_build/inc/rtc_io.inc
|
||||
.. include-build-file:: inc/rtc_io.inc
|
||||
|
||||
|
@@ -8,7 +8,7 @@ I2C is a serial, synchronous, half-duplex communication protocol that allows co-
|
||||
|
||||
With such advantages as simplicity and low manufacturing cost, I2C is mostly used for communication of low-speed peripheral devices over short distances (within one foot).
|
||||
|
||||
ESP32 has two I2C controllers (also referred to as ports) which are responsible for handling communications on two I2C buses. Each I2C controller can operate as master or slave. As an example, one controller can act as a master and the other as a slave at the same time.
|
||||
{IDF_TARGET_NAME} has two I2C controllers (also referred to as ports) which are responsible for handling communications on two I2C buses. Each I2C controller can operate as master or slave. As an example, one controller can act as a master and the other as a slave at the same time.
|
||||
|
||||
|
||||
Driver Features
|
||||
@@ -50,7 +50,7 @@ To establish I2C communication, start by configuring the driver. This is done by
|
||||
- Configure **communication pins**
|
||||
|
||||
- Assign GPIO pins for SDA and SCL signals
|
||||
- Set whether to enable ESP32's internal pull-ups
|
||||
- Set whether to enable {IDF_TARGET_NAME}'s internal pull-ups
|
||||
|
||||
- (Master only) Set I2C **clock speed**
|
||||
- (Slave only) Configure the following
|
||||
@@ -81,9 +81,9 @@ After the I2C driver is configured, install it by calling the function :cpp:func
|
||||
Communication as Master
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After installing the I2C driver, ESP32 is ready to communicate with other I2C devices.
|
||||
After installing the I2C driver, {IDF_TARGET_NAME} is ready to communicate with other I2C devices.
|
||||
|
||||
ESP32's I2C controller operating as master is responsible for establishing communication with I2C slave devices and sending commands to trigger a slave to action, for example, to take a measurement and send the readings back to the master.
|
||||
{IDF_TARGET_NAME}'s I2C controller operating as master is responsible for establishing communication with I2C slave devices and sending commands to trigger a slave to action, for example, to take a measurement and send the readings back to the master.
|
||||
|
||||
For better process organization, the driver provides a container, called a "command link", that should be populated with a sequence of commands and then passed to the I2C controller for execution.
|
||||
|
||||
@@ -155,7 +155,7 @@ Likewise, the command link to read from the slave looks as follows:
|
||||
Communication as Slave
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After installing the I2C driver, ESP32 is ready to communicate with other I2C devices.
|
||||
After installing the I2C driver, {IDF_TARGET_NAME} is ready to communicate with other I2C devices.
|
||||
|
||||
The API provides the following functions for slaves
|
||||
|
||||
@@ -175,11 +175,10 @@ A code example showing how to use these functions can be found in :example:`peri
|
||||
Interrupt Handling
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
During driver installation, an interrupt handler is installed by default. However, you can register your own interrupt handler instead of the default one by calling the function :cpp:func:`i2c_isr_register`. When implementing your own interrupt handler, refer to the `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#page=292>`_ for the description of interrupts triggered by the I2C controller.
|
||||
During driver installation, an interrupt handler is installed by default. However, you can register your own interrupt handler instead of the default one by calling the function :cpp:func:`i2c_isr_register`. When implementing your own interrupt handler, refer to the `{IDF_TARGET_NAME} Technical Reference Manual (PDF) <{IDF_TARGET_TRM_EN_URL}>`_ for the description of interrupts triggered by the I2C controller.
|
||||
|
||||
To delete an interrupt handler, call :cpp:func:`i2c_isr_free`.
|
||||
|
||||
|
||||
.. _i2c-api-customized-configuration:
|
||||
|
||||
Customized Configuration
|
||||
@@ -217,7 +216,7 @@ You can also select different pins for SDA and SCL signals and alter the configu
|
||||
|
||||
.. note::
|
||||
|
||||
ESP32's internal pull-ups are in the range of tens of kOhm, which is, in most cases, insufficient for use as I2C pull-ups. Users are advised to use external pull-ups with values described in the `I2C specification <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_.
|
||||
{IDF_TARGET_NAME}'s internal pull-ups are in the range of tens of kOhm, which is, in most cases, insufficient for use as I2C pull-ups. Users are advised to use external pull-ups with values described in the `I2C specification <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_.
|
||||
|
||||
|
||||
.. _i2c-api-error-handling:
|
||||
@@ -249,4 +248,4 @@ I2C master and slave example: :example:`peripherals/i2c`.
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/i2c.inc
|
||||
.. include-build-file:: inc/i2c.inc
|
||||
|
@@ -6,7 +6,13 @@ Overview
|
||||
|
||||
I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usually used for transmitting audio data between two digital audio devices.
|
||||
|
||||
ESP32 integrates two I2S controllers, referred to as I2S0 and I2S1, both of which can be used for streaming audio and video digital data.
|
||||
.. only:: esp32
|
||||
|
||||
{IDF_TARGET_NAME} contains two I2S peripherals. These peripherals can be configured to input and output sample data via the I2S driver.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
{IDF_TARGET_NAME} contains one I2S peripheral. These peripherals can be configured to input and output sample data via the I2S driver.
|
||||
|
||||
An I2S bus consists of the following lines:
|
||||
|
||||
@@ -30,7 +36,9 @@ The I2S peripherals also support LCD mode for communicating data over a parallel
|
||||
- Camera slave receiving mode
|
||||
- ADC/DAC mode
|
||||
|
||||
For more information, see the `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#page=306>`_.
|
||||
.. only:: esp32
|
||||
|
||||
For more information, see the `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#page=306>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -198,7 +206,7 @@ Configuring I2S to use internal DAC for analog output
|
||||
i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels
|
||||
|
||||
//You can call i2s_set_dac_mode to set built-in DAC output mode.
|
||||
//i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
|
||||
//i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
|
||||
|
||||
i2s_set_sample_rates(i2s_num, 22050); //set sample rates
|
||||
|
||||
@@ -208,5 +216,5 @@ Configuring I2S to use internal DAC for analog output
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/i2s.inc
|
||||
.. include-build-file:: inc/i2s.inc
|
||||
|
||||
|
@@ -14,17 +14,17 @@ Peripherals API
|
||||
I2C <i2c>
|
||||
I2S <i2s>
|
||||
LED Control <ledc>
|
||||
MCPWM <mcpwm>
|
||||
:esp32: MCPWM <mcpwm>
|
||||
Pulse Counter <pcnt>
|
||||
Remote Control <rmt>
|
||||
SD Pull-up Requirements <sd_pullup_requirements>
|
||||
SDMMC Host <sdmmc_host>
|
||||
:esp32: SD Pull-up Requirements <sd_pullup_requirements>
|
||||
:esp32: SDMMC Host <sdmmc_host>
|
||||
SD SPI Host <sdspi_host>
|
||||
SDIO Slave <sdio_slave>
|
||||
:esp32: SDIO Slave <sdio_slave>
|
||||
Sigma-delta Modulation <sigmadelta>
|
||||
SPI Master <spi_master>
|
||||
SPI Slave <spi_slave>
|
||||
Temp sensor <temp_sensor>
|
||||
:esp32s2: Temp sensor <temp_sensor>
|
||||
Timer <timer>
|
||||
Touch Sensor <touch_pad>
|
||||
UART <uart>
|
||||
|
@@ -6,9 +6,15 @@ LED Control
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The LED control (LEDC) peripheral is primarily designed to control the intensity of LEDs, although it can also be used to generate PWM signals for other purposes as well. It has 16 channels which can generate independent waveforms that can be used, for example, to drive RGB LED devices.
|
||||
.. only:: esp32
|
||||
|
||||
A half of LEDC's channels operate in high speed mode. This mode is implemented in hardware and offers automatic and glitch-free changing of the PWM duty cycle. The other half of channels operate in low speed mode, where the moment of change depends on the application software. Each group of channels is also able to use different clock sources.
|
||||
The LED control (LEDC) peripheral is primarily designed to control the intensity of LEDs, although it can also be used to generate PWM signals for other purposes as well. It has 16 channels which can generate independent waveforms that can be used, for example, to drive RGB LED devices.
|
||||
|
||||
A half of LEDC's channels operate in high speed mode. This mode is implemented in hardware and offers automatic and glitch-free changing of the PWM duty cycle. The other half of channels operate in low speed mode, where the moment of change depends on the application software. Each group of channels is also able to use different clock sources, but this feature is not yet supported in the LEDC driver.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
A half of LEDC's channels operate in high speed mode. This mode is implemented in hardware and offers automatic and glitch-free changing of the PWM duty cycle. The other half of channels operate in low speed mode, where the moment of change depends on the application software. Each group of channels is also able to use different clock sources.
|
||||
|
||||
The PWM controller can automatically increase or decrease the duty cycle gradually, allowing for fades without any processor interference.
|
||||
|
||||
@@ -121,7 +127,7 @@ The first two functions are called "behind the scenes" by :cpp:func:`ledc_channe
|
||||
Use Interrupts
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
When configuring an LEDC channel, one of the parameters selected within :cpp:type:`ledc_channel_config_t` is :cpp:type:`ledc_intr_type_t` which triggers an interrupt on fade completion.
|
||||
When configuring an LEDC channel, one of the parameters selected within :cpp:type:`ledc_channel_config_t` is :cpp:type:`ledc_intr_type_t` which triggers an interrupt on fade completion.
|
||||
|
||||
For registration of a handler to address this interrupt, call :cpp:func:`ledc_isr_register`.
|
||||
|
||||
@@ -131,13 +137,21 @@ For registration of a handler to address this interrupt, call :cpp:func:`ledc_is
|
||||
LEDC High and Low Speed Mode
|
||||
----------------------------
|
||||
|
||||
Of the total 8 timers and 16 channels available in the LED PWM Controller, half of them are dedicated to operation in high speed mode and the other half in low speed mode. Selection of a low or high speed timer or channel is done with the parameter :cpp:type:`ledc_mode_t` that can be found in applicable function calls.
|
||||
.. only:: esp32
|
||||
|
||||
The advantage of high speed mode is glitch-free changeover of the timer settings. This means that if the timer settings are modified, the changes will be applied automatically on the next overflow interrupt of the timer. In contrast, when updating the low-speed timer, the change of settings should be explicitly triggered by software. The LEDC driver handles it in the background, e.g., when :cpp:func:`ledc_timer_config` or :cpp:func:`ledc_timer_set` is called.
|
||||
|
||||
For additional details regarding speed modes, refer to `ESP32 Technical Reference Manual <https://espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf>`_ (PDF). Please note that the support for ``SLOW_CLOCK`` mentioned in this manual is not yet supported in the LEDC driver.
|
||||
The advantage of high speed mode is hardware-supported, glitch-free changeover of the timer settings. This means that if the timer settings are modified, the changes will be applied automatically on the next overflow interrupt of the timer. In contrast, when updating the low-speed timer, the change of settings should be explicitly triggered by software. The LEDC driver handles it in the background, e.g., when :cpp:func:`ledc_timer_config` or :cpp:func:`ledc_timer_set` is called.
|
||||
|
||||
|
||||
For additional details regarding speed modes, refer to `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_ (PDF). Please note that the support for ``SLOW_CLOCK`` mentioned in this manual is not yet supported in the LEDC driver.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
.. note::
|
||||
|
||||
All the timers and channels in the {IDF_TARGET_NAME}'s LED PWM Controller only support low speed mode.
|
||||
|
||||
.. _ledc-api-supported-range-frequency-duty-resolution:
|
||||
|
||||
Supported Range of Frequency and Duty Resolutions
|
||||
@@ -163,7 +177,7 @@ The LEDC driver will also capture and report attempts to configure frequency / d
|
||||
|
||||
E (196) ledc: requested frequency and duty resolution cannot be achieved, try increasing freq_hz or duty_resolution. div_param=128000000
|
||||
|
||||
The duty resolution is normally set using :cpp:type:`ledc_timer_bit_t`. This enumeration covers the range from 10 to 15 bits. If a smaller duty resolution is required (from 10 down to 1), enter the equivalent numeric values directly.
|
||||
The duty resolution is normally set using :cpp:type:`ledc_timer_bit_t`. This enumeration covers the range from 10 to 15 bits. If a smaller duty resolution is required (from 10 down to 1), enter the equivalent numeric values directly.
|
||||
|
||||
|
||||
Application Example
|
||||
@@ -175,5 +189,5 @@ The LEDC change duty cycle and fading control example: :example:`peripherals/led
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/ledc.inc
|
||||
.. include-build-file:: inc/ledc.inc
|
||||
|
||||
|
@@ -1,6 +1,8 @@
|
||||
MCPWM
|
||||
=====
|
||||
|
||||
.. This peripheral is ESP32 only
|
||||
|
||||
ESP32 has two MCPWM units which can be used to control different types of motors. Each unit has three pairs of PWM outputs.
|
||||
|
||||
.. figure:: ../../../_static/mcpwm-overview.png
|
||||
@@ -53,7 +55,7 @@ In this case we will describe a simple configuration to control a brushed DC mot
|
||||
|
||||
Configuration covers the following steps:
|
||||
|
||||
1. Selection of a MPWn unit that will be used to drive the motor. There are two units available on-board of ESP32 and enumerated in :cpp:type:`mcpwm_unit_t`.
|
||||
1. Selection of a MPWn unit that will be used to drive the motor. There are two units available on-board of {IDF_TARGET_NAME} and enumerated in :cpp:type:`mcpwm_unit_t`.
|
||||
2. Initialization of two GPIOs as output signals within selected unit by calling :cpp:func:`mcpwm_gpio_init`. The two output signals are typically used to command the motor to rotate right or left. All available signal options are listed in :cpp:type:`mcpwm_io_signals_t`. To set more than a single pin at a time, use function :cpp:func:`mcpwm_set_pin` together with :cpp:type:`mcpwm_pin_config_t`.
|
||||
3. Selection of a timer. There are three timers available within the unit. The timers are listed in :cpp:type:`mcpwm_timer_t`.
|
||||
4. Setting of the timer frequency and initial duty within :cpp:type:`mcpwm_config_t` structure.
|
||||
@@ -89,8 +91,8 @@ There are couple of ways to adjust a signal on the outputs and changing how the
|
||||
|
||||
Synchronization signals are referred to using two different enumerations. First one :cpp:type:`mcpwm_io_signals_t` is used together with function :cpp:func:`mcpwm_gpio_init` when selecting a GPIO as the signal input source. The second one :cpp:type:`mcpwm_sync_signal_t` is used when enabling or disabling synchronization with :cpp:func:`mcpwm_sync_enable` or :cpp:func:`mcpwm_sync_disable`.
|
||||
|
||||
* Vary the pattern of the A/B output signals by getting MCPWM counters to count up, down and up/down (automatically changing the count direction). Respective configuration is done when calling :cpp:func:`mcpwm_init`, as discussed in section `Configure`_, and selecting one of counter types from :cpp:type:`mcpwm_counter_type_t`. For explanation of how A/B PWM output signals are generated please refer to `ESP32 Technical Reference Manual`_.
|
||||
|
||||
* Vary the pattern of the A/B output signals by getting MCPWM counters to count up, down and up/down (automatically changing the count direction). Respective configuration is done when calling :cpp:func:`mcpwm_init`, as discussed in section `Configure`_, and selecting one of counter types from :cpp:type:`mcpwm_counter_type_t`. For explanation of how A/B PWM output signals are generated please refer to `{IDF_TARGET_NAME} Technical Reference Manual`_.
|
||||
|
||||
Capture
|
||||
-------
|
||||
@@ -148,7 +150,7 @@ To use the carrier submodule, it should be first initialized by calling :cpp:fun
|
||||
|
||||
The carrier parameters may be then alerted at a runtime by calling dedicated functions to change individual fields of the :cpp:type:`mcpwm_carrier_config_t` structure, like :cpp:func:`mcpwm_carrier_set_period`, :cpp:func:`mcpwm_carrier_set_duty_cycle`, :cpp:func:`mcpwm_carrier_output_invert`, etc.
|
||||
|
||||
This includes enabling and setting duration of the first pulse of the career with :cpp:func:`mcpwm_carrier_oneshot_mode_enable`. For more details please refer to "PWM Carrier Submodule" section of the `ESP32 Technical Reference Manual`_.
|
||||
This includes enabling and setting duration of the first pulse of the career with :cpp:func:`mcpwm_carrier_oneshot_mode_enable`. For more details please refer to "PWM Carrier Submodule" section of the `{IDF_TARGET_NAME} Technical Reference Manual`_.
|
||||
|
||||
To disable carrier functionality call :cpp:func:`mcpwm_carrier_disable`.
|
||||
|
||||
@@ -169,12 +171,13 @@ Examples of using MCPWM for motor control: :example:`peripherals/mcpwm`:
|
||||
* Brushed DC motor control - :example:`peripherals/mcpwm/mcpwm_brushed_dc_control`
|
||||
* Servo motor control - :example:`peripherals/mcpwm/mcpwm_servo_control`
|
||||
|
||||
.. _ESP32 Technical Reference Manual: https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||
.. _{IDF_TARGET_NAME} Technical Reference Manual: {IDF_TARGET_TRM_EN_URL}
|
||||
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/mcpwm_types.inc
|
||||
.. include:: /_build/inc/mcpwm.inc
|
||||
.. include-build-file:: inc/mcpwm_types.inc
|
||||
.. include-build-file:: inc/mcpwm.inc
|
||||
|
||||
|
||||
|
@@ -13,17 +13,22 @@ Functionality Overview
|
||||
Description of functionality of this API has been broken down into four sections:
|
||||
|
||||
* :ref:`pcnt-api-configuration` - describes counter's configuration parameters and how to setup the counter.
|
||||
* :ref:`pcnt-api-operating-the-counter` - provides information on control functions to pause, measure and clear the counter.
|
||||
* :ref:`pcnt-api-operating-the-counter` - provides information on control functions to pause, measure and clear the counter.
|
||||
* :ref:`pcnt-api-filtering-pulses` - describes options to filtering pulses and the counter control signals.
|
||||
* :ref:`pcnt-api-using-interrupts` - presents how to trigger interrupts on specific states of the counter.
|
||||
* :ref:`pcnt-api-using-interrupts` - presents how to trigger interrupts on specific states of the counter.
|
||||
|
||||
|
||||
.. _pcnt-api-configuration:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
.. only:: esp32
|
||||
|
||||
The PCNT module has eight independent counting "units" numbered from 0 to 7. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
|
||||
The PCNT module has eight independent counting "units" numbered from 0 to 7. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
|
||||
|
||||
.. only:: esp32s2
|
||||
|
||||
The PCNT module has four independent counting "units" numbered from 0 to 3. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
|
||||
|
||||
The configuration is provided separately per unit's channel using :cpp:type:`pcnt_config_t` and covers:
|
||||
|
||||
@@ -78,7 +83,7 @@ There are five counter state watch events, defined in :cpp:type:`pcnt_evt_type_t
|
||||
* Threshold 0 or Threshold 1 values set using function :cpp:func:`pcnt_set_event_value`.
|
||||
* Pulse count = 0
|
||||
|
||||
To register, enable or disable an interrupt to service the above events, call :cpp:func:`pcnt_isr_register`, :cpp:func:`pcnt_intr_enable`. and :cpp:func:`pcnt_intr_disable`. To enable or disable events on reaching threshold values, you will also need to call functions :cpp:func:`pcnt_event_enable` and :cpp:func:`pcnt_event_disable`.
|
||||
To register, enable or disable an interrupt to service the above events, call :cpp:func:`pcnt_isr_register`, :cpp:func:`pcnt_intr_enable`. and :cpp:func:`pcnt_intr_disable`. To enable or disable events on reaching threshold values, you will also need to call functions :cpp:func:`pcnt_event_enable` and :cpp:func:`pcnt_event_disable`.
|
||||
|
||||
In order to check what are the threshold values currently set, use function :cpp:func:`pcnt_get_event_value`.
|
||||
|
||||
@@ -92,5 +97,5 @@ Pulse counter with control signal and event interrupt example: :example:`periphe
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include:: /_build/inc/pcnt.inc
|
||||
.. include-build-file:: inc/pcnt.inc
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user