i2s: deprecate confusing names

This commit is contained in:
laokaiyao 2021-11-24 13:21:13 +08:00
parent 9044374032
commit fa4e77eb44
44 changed files with 410 additions and 452 deletions

View File

@ -46,7 +46,7 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
/**
* @brief Allocates buffer for trace data.
* After data in buffer are ready to be sent off esp_apptrace_buffer_put must be called to indicate it.
* Once the data in the buffer is ready to be sent, esp_apptrace_buffer_put must be called to indicate it.
*
* @param dest Indicates HW interface to send data.
* @param size Size of data to write to trace buffer.
@ -57,8 +57,8 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32_t tmo);
/**
* @brief Indicates that the data in buffer are ready to be sent off.
* This function is a counterpart of and must be preceeded by esp_apptrace_buffer_get.
* @brief Indicates that the data in the buffer is ready to be sent.
* This function is a counterpart of and must be preceded by esp_apptrace_buffer_get.
*
* @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get.
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get.
@ -81,7 +81,7 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_t size, uint32_t tmo);
/**
* @brief vprintf-like function to sent log messages to host via specified HW interface.
* @brief vprintf-like function to send log messages to host via specified HW interface.
*
* @param dest Indicates HW interface to send data.
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
@ -93,7 +93,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
int esp_apptrace_vprintf_to(esp_apptrace_dest_t dest, uint32_t tmo, const char *fmt, va_list ap);
/**
* @brief vprintf-like function to sent log messages to host.
* @brief vprintf-like function to send log messages to host.
*
* @param fmt Address of format string.
* @param ap List of arguments.
@ -114,7 +114,7 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo);
/**
* @brief Flushes remaining data in trace buffer to host without locking internal data.
* This is special version of esp_apptrace_flush which should be called from panic handler.
* This is a special version of esp_apptrace_flush which should be called from panic handler.
*
* @param dest Indicates HW interface to flush data on.
* @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
@ -138,7 +138,7 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size
/**
* @brief Retrieves incoming data buffer if any.
* After data in buffer are processed esp_apptrace_down_buffer_put must be called to indicate it.
* Once data in the buffer is processed, esp_apptrace_down_buffer_put must be called to indicate it.
*
* @param dest Indicates HW interface to receive data.
* @param size Address to store size of available data in down buffer. Must be initialized with requested value.
@ -149,8 +149,8 @@ esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo);
/**
* @brief Indicates that the data in down buffer are processed.
* This function is a counterpart of and must be preceeded by esp_apptrace_down_buffer_get.
* @brief Indicates that the data in the down buffer is processed.
* This function is a counterpart of and must be preceded by esp_apptrace_down_buffer_get.
*
* @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get.
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get.
@ -245,7 +245,7 @@ int esp_apptrace_fseek(esp_apptrace_dest_t dest, void *stream, long offset, int
int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
/**
* @brief Indicates to the host that all file operations are completed.
* @brief Indicates to the host that all file operations are complete.
* This function should be called after all file operations are finished and
* indicate to the host that it can perform cleanup operations (close open files etc.).
*

View File

@ -112,17 +112,17 @@ esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
/**
* @brief Write OTA update data to partition
* @brief Write OTA update data to partition at an offset
*
* This function can write data in non contiguous manner.
* If flash encryption is enabled, data should be 16 byte aligned.
* This function can write data in non-contiguous manner.
* If flash encryption is enabled, data should be 16 bytes aligned.
*
* @param handle Handle obtained from esp_ota_begin
* @param data Data buffer to write
* @param size Size of data buffer in bytes
* @param offset Offset in flash partition
*
* @note While performing OTA, if the packets arrive out of order, esp_ota_write_with_offset() can be used to write data in non contiguous manner.
* @note While performing OTA, if the packets arrive out of order, esp_ota_write_with_offset() can be used to write data in non-contiguous manner.
* Use of esp_ota_write_with_offset() in combination with esp_ota_write() is not recommended.
*
* @return
@ -327,7 +327,7 @@ typedef enum {
/**
* @brief Revokes the old signature digest. To be called in the application after the rollback logic.
*
* Relevant for Secure boot v2 on ESP32-S2 where upto 3 key digests can be stored (Key #N-1, Key #N, Key #N+1).
* Relevant for Secure boot v2 on ESP32-S2, ESP32-S3, ESP32-C3, ESP32-H2 where upto 3 key digests can be stored (Key #N-1, Key #N, Key #N+1).
* When key #N-1 used to sign an app is invalidated, an OTA update is to be sent with an app signed with key #N-1 & Key #N.
* After successfully booting the OTA app should call this function to revoke Key #N-1.
*

View File

@ -311,7 +311,7 @@ struct esp_console_repl_s {
* @param[in] repl_config REPL configuration
* @param[out] ret_repl return REPL handle after initialization succeed, return NULL otherwise
*
* @note This is a all-in-one function to establish the environment needed for REPL, includes:
* @note This is an all-in-one function to establish the environment needed for REPL, includes:
* - Install the UART driver on the console UART (8n1, 115200, REF_TICK clock source)
* - Configures the stdin/stdout to go through the UART driver
* - Initializes linenoise
@ -356,7 +356,7 @@ esp_err_t esp_console_new_repl_usb_cdc(const esp_console_dev_usb_cdc_config_t *d
* @param[in] repl_config REPL configuration
* @param[out] ret_repl return REPL handle after initialization succeed, return NULL otherwise
*
* @note This is a all-in-one function to establish the environment needed for REPL, includes:
* @note This is an all-in-one function to establish the environment needed for REPL, includes:
* - Initializes linenoise
* - Spawn new thread to run REPL in the background
*
@ -374,7 +374,7 @@ esp_err_t esp_console_new_repl_usb_serial_jtag(const esp_console_dev_usb_serial_
/**
* @brief Start REPL environment
* @param[in] repl REPL handle returned from esp_console_new_repl_xxx
* @note Once the REPL got started, it won't be stopped until user call repl->del(repl) to destory the REPL environment.
* @note Once the REPL gets started, it won't be stopped until the user calls repl->del(repl) to destroy the REPL environment.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE, if repl has started already

View File

@ -84,8 +84,8 @@ typedef struct {
i2s_port_t i2s_num; /*!< I2S port number*/
int queue_size; /*!< I2S event queue size*/
QueueHandle_t i2s_queue; /*!< I2S queue handler*/
int dma_buf_count; /*!< DMA buffer count, number of buffer*/
int dma_buf_len; /*!< DMA buffer length, length of each buffer*/
int dma_desc_num; /*!< DMA buffer count, number of buffer*/
int dma_frame_num; /*!< DMA buffer length, length of each buffer*/
uint32_t last_buf_size; /*!< DMA last buffer size */
i2s_dma_t *tx; /*!< DMA Tx buffer*/
i2s_dma_t *rx; /*!< DMA Rx buffer*/
@ -662,9 +662,9 @@ static inline uint32_t i2s_get_buf_size(i2s_port_t i2s_num)
uint32_t bytes_per_sample = ((p_i2s[i2s_num]->hal_cfg.sample_bits + 15) / 16) * 2;
/* The DMA buffer limitation is 4092 bytes */
uint32_t bytes_per_frame = bytes_per_sample * p_i2s[i2s_num]->hal_cfg.active_chan;
p_i2s[i2s_num]->dma_buf_len = (p_i2s[i2s_num]->dma_buf_len * bytes_per_frame > I2S_DMA_BUFFER_MAX_SIZE) ?
I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame : p_i2s[i2s_num]->dma_buf_len;
return p_i2s[i2s_num]->dma_buf_len * bytes_per_frame;
p_i2s[i2s_num]->dma_frame_num = (p_i2s[i2s_num]->dma_frame_num * bytes_per_frame > I2S_DMA_BUFFER_MAX_SIZE) ?
I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame : p_i2s[i2s_num]->dma_frame_num;
return p_i2s[i2s_num]->dma_frame_num * bytes_per_frame;
}
/**
@ -680,7 +680,7 @@ static esp_err_t i2s_delete_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
{
ESP_RETURN_ON_FALSE(dma_obj, ESP_ERR_INVALID_ARG, TAG, "I2S DMA object can't be NULL");
/* Loop to destroy every descriptor and buffer */
for (int cnt = 0; cnt < p_i2s[i2s_num]->dma_buf_count; cnt++) {
for (int cnt = 0; cnt < p_i2s[i2s_num]->dma_desc_num; cnt++) {
if (dma_obj->desc && dma_obj->desc[cnt]) {
free(dma_obj->desc[cnt]);
dma_obj->desc[cnt] = NULL;
@ -707,7 +707,7 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
esp_err_t ret = ESP_OK;
ESP_GOTO_ON_FALSE(dma_obj, ESP_ERR_INVALID_ARG, err, TAG, "I2S DMA object can't be NULL");
uint32_t buf_cnt = p_i2s[i2s_num]->dma_buf_count;
uint32_t buf_cnt = p_i2s[i2s_num]->dma_desc_num;
for (int cnt = 0; cnt < buf_cnt; cnt++) {
/* Allocate DMA buffer */
dma_obj->buf[cnt] = (char *) heap_caps_calloc(dma_obj->buf_size, sizeof(char), MALLOC_CAP_DMA);
@ -733,7 +733,7 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
/* Link to the next descriptor */
dma_obj->desc[cnt]->empty = (uint32_t)((cnt < (buf_cnt - 1)) ? (dma_obj->desc[cnt + 1]) : dma_obj->desc[0]);
}
ESP_LOGI(TAG, "DMA Malloc info, datalen=blocksize=%d, dma_buf_count=%d", dma_obj->buf_size, buf_cnt);
ESP_LOGI(TAG, "DMA Malloc info, datalen=blocksize=%d, dma_desc_num=%d", dma_obj->buf_size, buf_cnt);
return ESP_OK;
err:
/* Delete DMA buffer if failed to allocate memory */
@ -819,7 +819,7 @@ static esp_err_t i2s_create_dma_object(i2s_port_t i2s_num, i2s_dma_t **dma)
{
ESP_RETURN_ON_FALSE(dma, ESP_ERR_INVALID_ARG, TAG, "DMA object secondary pointer is NULL");
ESP_RETURN_ON_FALSE((*dma == NULL), ESP_ERR_INVALID_ARG, TAG, "DMA object has been created");
uint32_t buf_cnt = p_i2s[i2s_num]->dma_buf_count;
uint32_t buf_cnt = p_i2s[i2s_num]->dma_desc_num;
/* Allocate new DMA structure */
*dma = (i2s_dma_t *) malloc(sizeof(i2s_dma_t));
ESP_RETURN_ON_FALSE(*dma, ESP_ERR_NO_MEM, TAG, "DMA object allocate failed");
@ -866,7 +866,7 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num)
/* Clear I2S RX DMA buffer */
if (p_i2s[i2s_num]->rx && p_i2s[i2s_num]->rx->buf != NULL && p_i2s[i2s_num]->rx->buf_size != 0) {
for (int i = 0; i < p_i2s[i2s_num]->dma_buf_count; i++) {
for (int i = 0; i < p_i2s[i2s_num]->dma_desc_num; i++) {
memset(p_i2s[i2s_num]->rx->buf[i], 0, p_i2s[i2s_num]->rx->buf_size);
}
}
@ -879,7 +879,7 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num)
size_t zero_bytes = 0, bytes_written;
i2s_write(i2s_num, (void *)&zero_bytes, bytes_left, &bytes_written, portMAX_DELAY);
}
for (int i = 0; i < p_i2s[i2s_num]->dma_buf_count; i++) {
for (int i = 0; i < p_i2s[i2s_num]->dma_desc_num; i++) {
memset(p_i2s[i2s_num]->tx->buf[i], 0, p_i2s[i2s_num]->tx->buf_size);
}
}
@ -1808,8 +1808,8 @@ static esp_err_t i2s_driver_init(i2s_port_t i2s_num, const i2s_config_t *i2s_con
/* I2S driver configuration assignment */
p_i2s[i2s_num]->i2s_num = i2s_num;
p_i2s[i2s_num]->dma_buf_count = i2s_config->dma_buf_count;
p_i2s[i2s_num]->dma_buf_len = i2s_config->dma_buf_len;
p_i2s[i2s_num]->dma_desc_num = i2s_config->dma_desc_num;
p_i2s[i2s_num]->dma_frame_num = i2s_config->dma_frame_num;
p_i2s[i2s_num]->last_buf_size = 0;
p_i2s[i2s_num]->use_apll = i2s_config->use_apll;
p_i2s[i2s_num]->fixed_mclk = i2s_config->fixed_mclk;
@ -1918,8 +1918,8 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error");
ESP_RETURN_ON_FALSE(i2s_config, ESP_ERR_INVALID_ARG, TAG, "I2S configuration must not be NULL");
/* Check the size of DMA buffer */
ESP_RETURN_ON_FALSE((i2s_config->dma_buf_count >= 2 && i2s_config->dma_buf_count <= 128), ESP_ERR_INVALID_ARG, TAG, "I2S buffer count less than 128 and more than 2");
ESP_RETURN_ON_FALSE((i2s_config->dma_buf_len >= 8 && i2s_config->dma_buf_len <= 1024), ESP_ERR_INVALID_ARG, TAG, "I2S buffer length at most 1024 and more than 8");
ESP_RETURN_ON_FALSE((i2s_config->dma_desc_num >= 2 && i2s_config->dma_desc_num <= 128), ESP_ERR_INVALID_ARG, TAG, "I2S buffer count less than 128 and more than 2");
ESP_RETURN_ON_FALSE((i2s_config->dma_frame_num >= 8 && i2s_config->dma_frame_num <= 1024), ESP_ERR_INVALID_ARG, TAG, "I2S buffer length at most 1024 and more than 8");
/* Step 2: Allocate driver object and register to platform */
i2s_obj_t *pre_alloc_i2s_obj = calloc(1, sizeof(i2s_obj_t));

View File

@ -96,8 +96,15 @@ typedef struct {
i2s_channel_fmt_t channel_format; /*!< I2S channel format.*/
i2s_comm_format_t communication_format; /*!< I2S communication format */
int intr_alloc_flags; /*!< Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info */
int dma_buf_count; /*!< I2S DMA Buffer Count */
int dma_buf_len; /*!< I2S DMA Buffer Length */
union {
int dma_desc_num; /*!< The total number of descriptors used by I2S DMA to receive/transmit data */
int dma_buf_count __attribute__((deprecated)); /*!< This is an alias to 'dma_desc_num' for backward compatibility */
};
union {
int dma_frame_num; /*!< Frame number for one-time sampling. Frame here means the total data from all the channels in a WS cycle */
int dma_buf_len __attribute__((deprecated)); /*!< This is an alias to 'dma_frame_num' for backward compatibility */
};
bool use_apll; /*!< I2S using APLL as main I2S clock, enable it to get accurate clock */
bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability) */
int fixed_mclk; /*!< I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value. If fixed_mclk set, mclk_multiple won't take effect */

View File

@ -59,8 +59,8 @@ static void example_i2s_init(void)
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
.channel_format = EXAMPLE_I2S_FORMAT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.use_apll = 0,
};

View File

@ -61,8 +61,8 @@ static void example_i2s_init(void)
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
.channel_format = EXAMPLE_I2S_FORMAT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.use_apll = 0,
};
//install and start i2s driver

View File

@ -228,8 +228,8 @@ static void i2s_adc_init(void)
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.use_apll = 0,
};
// install and start I2S driver

View File

@ -143,8 +143,8 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -174,9 +174,9 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]")
//error param test
TEST_ASSERT(i2s_driver_install(I2S_NUM_MAX, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG);
TEST_ASSERT(i2s_driver_install(I2S_NUM_0, NULL, 0, NULL) == ESP_ERR_INVALID_ARG);
i2s_config.dma_buf_count = 1;
i2s_config.dma_desc_num = 1;
TEST_ASSERT(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG);
i2s_config.dma_buf_count = 129;
i2s_config.dma_desc_num = 129;
TEST_ASSERT(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL) == ESP_ERR_INVALID_ARG);
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_uninstall(I2S_NUM_0));
}
@ -190,8 +190,8 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -265,8 +265,8 @@ TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s]")
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.total_chan = 4,
.chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1 | I2S_TDM_ACTIVE_CH2 | I2S_TDM_ACTIVE_CH3,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
};
@ -332,8 +332,8 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -363,8 +363,8 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -436,8 +436,8 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 1,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -467,8 +467,8 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 1,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -541,8 +541,8 @@ TEST_CASE("I2S memory leaking test", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 100,
.dma_desc_num = 6,
.dma_frame_num = 100,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
#if SOC_I2S_SUPPORTS_TDM
@ -599,8 +599,8 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.use_apll = true,
.intr_alloc_flags = 0,
#if SOC_I2S_SUPPORTS_TDM
@ -650,8 +650,8 @@ TEST_CASE("I2S adc test", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.use_apll = 0,
};
// install and start I2S driver
@ -717,8 +717,8 @@ TEST_CASE("I2S dac test", "[i2s]")
.bits_per_sample = SAMPLE_BITS,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.use_apll = 0,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
};

View File

@ -1,16 +1,8 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_EVENT_H_
#define ESP_EVENT_H_
@ -92,16 +84,16 @@ esp_err_t esp_event_loop_delete_default(void);
/**
* @brief Dispatch events posted to an event loop.
*
* This function is used to dispatch events posted to a loop with no dedicated task, i.e task name was set to NULL
* This function is used to dispatch events posted to a loop with no dedicated task, i.e. task name was set to NULL
* in event_loop_args argument during loop creation. This function includes an argument to limit the amount of time
* it runs, returning control to the caller when that time expires (or some time afterwards). There is no guarantee
* that a call to this function will exit at exactly the time of expiry. There is also no guarantee that events have
* been dispatched during the call, as the function might have spent all of the alloted time waiting on the event queue.
* Once an event has been unqueued, however, it is guaranteed to be dispatched. This guarantee contributes to not being
* able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the unqueued
* event, and (2) during dispatch of the unqueued event there is no way to control the time occupied by handler code
* execution. The guaranteed time of exit is therefore the alloted time + amount of time required to dispatch
* the last unqueued event.
* been dispatched during the call, as the function might have spent all the allotted time waiting on the event queue.
* Once an event has been dequeued, however, it is guaranteed to be dispatched. This guarantee contributes to not being
* able to exit exactly at time of expiry as (1) blocking on internal mutexes is necessary for dispatching the dequeued
* event, and (2) during dispatch of the dequeued event there is no way to control the time occupied by handler code
* execution. The guaranteed time of exit is therefore the allotted time + amount of time required to dispatch
* the last dequeued event.
*
* In cases where waiting on the queue times out, ESP_OK is returned and not ESP_ERR_TIMEOUT, since it is
* normal behavior.
@ -134,8 +126,8 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
* also possible. However, registering the same handler to the same event multiple times would cause the
* previous registrations to be overwritten.
*
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_base the base ID of the event to register the handler for
* @param[in] event_id the ID of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
*
@ -145,7 +137,7 @@ esp_err_t esp_event_loop_run(esp_event_loop_handle_t event_loop, TickType_t tick
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_handler_register(esp_event_base_t event_base,
@ -163,8 +155,8 @@ esp_err_t esp_event_handler_register(esp_event_base_t event_base,
* specification of the event loop to register the handler to.
*
* @param[in] event_loop the event loop to register this handler function to, must not be NULL
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_base the base ID of the event to register the handler for
* @param[in] event_id the ID of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
*
@ -174,7 +166,7 @@ esp_err_t esp_event_handler_register(esp_event_base_t event_base,
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
@ -202,15 +194,15 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
* lifetime.
*
* @param[in] event_loop the event loop to register this handler function to, must not be NULL
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_base the base ID of the event to register the handler for
* @param[in] event_id the ID of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
* @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
* This needs to be kept if the specific callback instance should be unregistered before deleting the whole
* event loop. Registering the same event handler multiple times is possible and yields distinct instance
* objects. The data can be the same for all registrations.
* If no unregistration is needed but the handler should be deleted when the event loop is deleted,
* If no unregistration is needed, but the handler should be deleted when the event loop is deleted,
* instance can be NULL.
*
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
@ -219,7 +211,7 @@ esp_err_t esp_event_handler_register_with(esp_event_loop_handle_t event_loop,
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL
* - Others: Fail
*/
esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event_loop,
@ -235,15 +227,15 @@ esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event
* This function does the same as esp_event_handler_instance_register_with, except that it registers the
* handler to the default event loop.
*
* @param[in] event_base the base id of the event to register the handler for
* @param[in] event_id the id of the event to register the handler for
* @param[in] event_base the base ID of the event to register the handler for
* @param[in] event_id the ID of the event to register the handler for
* @param[in] event_handler the handler function which gets called when the event is dispatched
* @param[in] event_handler_arg data, aside from event data, that is passed to the handler when it is called
* @param[out] instance An event handler instance object related to the registered event handler and data, can be NULL.
* This needs to be kept if the specific callback instance should be unregistered before deleting the whole
* event loop. Registering the same event handler multiple times is possible and yields distinct instance
* objects. The data can be the same for all registrations.
* If no unregistration is needed but the handler should be deleted when the event loop is deleted,
* If no unregistration is needed, but the handler should be deleted when the event loop is deleted,
* instance can be NULL.
*
* @note the event loop library does not maintain a copy of event_handler_arg, therefore the user should
@ -252,7 +244,7 @@ esp_err_t esp_event_handler_instance_register_with(esp_event_loop_handle_t event
* @return
* - ESP_OK: Success
* - ESP_ERR_NO_MEM: Cannot allocate memory for the handler
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id or instance is NULL
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID or instance is NULL
* - Others: Fail
*/
esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
@ -267,7 +259,7 @@ esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
* @note This function is obsolete and will be deprecated soon, please use esp_event_handler_instance_unregister()
* instead.
*
* Unregisters a handler so it will no longer be called during dispatch.
* Unregisters a handler, so it will no longer be called during dispatch.
* Handlers can be unregistered for any combination of event_base and event_id which were previously registered.
* To unregister a handler, the event_base and event_id arguments must match exactly the arguments passed to
* esp_event_handler_register() when that handler was registered. Passing ESP_EVENT_ANY_BASE and/or ESP_EVENT_ANY_ID
@ -278,11 +270,11 @@ esp_err_t esp_event_handler_instance_register(esp_event_base_t event_base,
* unregistered. This avoids accidental unregistration of handlers registered by other users or components.
*
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_id the ID of the event with which to unregister the handler
* @param[in] event_handler the handler to unregister
*
* @return ESP_OK success
* @return ESP_ERR_INVALID_ARG invalid combination of event base and event id
* @return ESP_ERR_INVALID_ARG invalid combination of event base and event ID
* @return others fail
*/
esp_err_t esp_event_handler_unregister(esp_event_base_t event_base,
@ -300,12 +292,12 @@ esp_err_t esp_event_handler_unregister(esp_event_base_t event_base,
*
* @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_id the ID of the event with which to unregister the handler
* @param[in] event_handler the handler to unregister
*
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
@ -316,7 +308,7 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
/**
* @brief Unregister a handler instance from a specific event loop.
*
* Unregisters a handler instance so it will no longer be called during dispatch.
* Unregisters a handler instance, so it will no longer be called during dispatch.
* Handler instances can be unregistered for any combination of event_base and event_id which were previously
* registered. To unregister a handler instance, the event_base and event_id arguments must match exactly the
* arguments passed to esp_event_handler_instance_register() when that handler instance was registered.
@ -329,12 +321,12 @@ esp_err_t esp_event_handler_unregister_with(esp_event_loop_handle_t event_loop,
*
* @param[in] event_loop the event loop with which to unregister this handler function, must not be NULL
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_id the ID of the event with which to unregister the handler
* @param[in] instance the instance object of the registration to be unregistered
*
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_handler_instance_unregister_with(esp_event_loop_handle_t event_loop,
@ -349,12 +341,12 @@ esp_err_t esp_event_handler_instance_unregister_with(esp_event_loop_handle_t eve
* handler instance from the default event loop.
*
* @param[in] event_base the base of the event with which to unregister the handler
* @param[in] event_id the id of the event with which to unregister the handler
* @param[in] event_id the ID of the event with which to unregister the handler
* @param[in] instance the instance object of the registration to be unregistered
*
* @return
* - ESP_OK: Success
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
@ -364,11 +356,11 @@ esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
/**
* @brief Posts an event to the system default event loop. The event loop library keeps a copy of event_data and manages
* the copy's lifetime automatically (allocation + deletion); this ensures that the data the
* handler recieves is always valid.
* handler receives is always valid.
*
* @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
* @param[in] event_id the event ID that identifies the event
* @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[in] ticks_to_wait number of ticks to block on a full event queue
*
@ -376,7 +368,7 @@ esp_err_t esp_event_handler_instance_unregister(esp_event_base_t event_base,
* - ESP_OK: Success
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
* queue full when posting from ISR
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_post(esp_event_base_t event_base,
@ -388,15 +380,15 @@ esp_err_t esp_event_post(esp_event_base_t event_base,
/**
* @brief Posts an event to the specified event loop. The event loop library keeps a copy of event_data and manages
* the copy's lifetime automatically (allocation + deletion); this ensures that the data the
* handler recieves is always valid.
* handler receives is always valid.
*
* This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop
* to post the event to.
*
* @param[in] event_loop the event loop to post to, must not be NULL
* @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
* @param[in] event_id the event ID that identifies the event
* @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[in] ticks_to_wait number of ticks to block on a full event queue
*
@ -404,7 +396,7 @@ esp_err_t esp_event_post(esp_event_base_t event_base,
* - ESP_OK: Success
* - ESP_ERR_TIMEOUT: Time to wait for event queue to unblock expired,
* queue full when posting from ISR
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID
* - Others: Fail
*/
esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
@ -419,8 +411,8 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
* @brief Special variant of esp_event_post for posting events from interrupt handlers.
*
* @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
* @param[in] event_id the event ID that identifies the event
* @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
* @param[in] event_data_size the size of the event data; max is 4 bytes
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
* higher priority than currently running task has been unblocked by the posted event;
@ -433,7 +425,7 @@ esp_err_t esp_event_post_to(esp_event_loop_handle_t event_loop,
* @return
* - ESP_OK: Success
* - ESP_FAIL: Event queue for the default event loop full
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID,
* data size of more than 4 bytes
* - Others: Fail
*/
@ -448,8 +440,8 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
*
* @param[in] event_loop the event loop to post to, must not be NULL
* @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
* @param[in] event_id the event ID that identifies the event
* @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[out] task_unblocked an optional parameter (can be NULL) which indicates that an event task with
* higher priority than currently running task has been unblocked by the posted event;
@ -462,7 +454,7 @@ esp_err_t esp_event_isr_post(esp_event_base_t event_base,
* @return
* - ESP_OK: Success
* - ESP_FAIL: Event queue for the loop full
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event id,
* - ESP_ERR_INVALID_ARG: Invalid combination of event base and event ID,
* data size of more than 4 bytes
* - Others: Fail
*/
@ -492,18 +484,18 @@ esp_err_t esp_event_isr_post_to(esp_event_loop_handle_t event_loop,
where:
event loop
format: address,name rx:total_recieved dr:total_dropped
format: address,name rx:total_received dr:total_dropped
where:
address - memory address of the event loop
name - name of the event loop, 'none' if no dedicated task
total_recieved - number of successfully posted events
total_received - number of successfully posted events
total_dropped - number of events unsuccessfully posted due to queue being full
handler
format: address ev:base,id inv:total_invoked run:total_runtime
where:
address - address of the handler function
base,id - the event specified by event base and id this handler executes
base,id - the event specified by event base and ID this handler executes
total_invoked - number of times this handler has been invoked
total_runtime - total amount of time used for invoking this handler

View File

@ -1,16 +1,8 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
@ -27,7 +19,7 @@ extern "C" {
/** System event types enumeration */
typedef enum {
SYSTEM_EVENT_WIFI_READY = 0, /*!< ESP32 WiFi ready */
SYSTEM_EVENT_WIFI_READY = 0, /*!< ESP32 Wi-Fi ready */
SYSTEM_EVENT_SCAN_DONE, /*!< ESP32 finish scanning AP */
SYSTEM_EVENT_STA_START, /*!< ESP32 station start */
SYSTEM_EVENT_STA_STOP, /*!< ESP32 station stop */
@ -142,7 +134,7 @@ typedef esp_err_t (*system_event_handler_t)(esp_event_base_t event_base,
TickType_t ticks_to_wait);
/**
* @brief Send a event to event task
* @brief Send an event to event task
*
* @note This API is part of the legacy event system. New code should use event library API in esp_event.h
*
@ -156,15 +148,15 @@ typedef esp_err_t (*system_event_handler_t)(esp_event_base_t event_base,
esp_err_t esp_event_send(system_event_t *event) __attribute__ ((deprecated));
/**
* @brief Send a event to event task
* @brief Send an event to event task
*
* @note This API is used by WiFi Driver only.
* @note This API is used by Wi-Fi Driver only.
*
* Other task/modules, such as the tcpip_adapter, can call this API to send an event to event task
*
* @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
* @param[in] event_id the event ID that identifies the event
* @param[in] event_data the data, specific to the event occurrence, that gets passed to the handler
* @param[in] event_data_size the size of the event data
* @param[in] ticks_to_wait number of ticks to block on a full event queue
*

View File

@ -591,8 +591,8 @@ TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]")
.bits_per_sample = 16,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
};
// I2S driver won't be installed as the same I2S port has been used by LCD
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_install(0, &i2s_config, 0, NULL));

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef FREERTOS_RINGBUF_H
#define FREERTOS_RINGBUF_H
@ -82,7 +74,7 @@ typedef struct xSTATIC_RINGBUFFER {
* @brief Create a ring buffer
*
* @param[in] xBufferSize Size of the buffer in bytes. Note that items require
* space for overhead in no-split/allow-split buffers
* space for a header in no-split/allow-split buffers
* @param[in] xBufferType Type of ring buffer, see documentation.
*
* @note xBufferSize of no-split/allow-split buffers will be rounded up to the nearest 32-bit aligned size.
@ -111,7 +103,7 @@ RingbufHandle_t xRingbufferCreateNoSplit(size_t xItemSize, size_t xItemNum);
* @param[in] xBufferSize Size of the buffer in bytes.
* @param[in] xBufferType Type of ring buffer, see documentation
* @param[in] pucRingbufferStorage Pointer to the ring buffer's storage area.
* Storage area must of the same size as specified by xBufferSize
* Storage area must have the same size as specified by xBufferSize
* @param[in] pxStaticRingbuffer Pointed to a struct of type StaticRingbuffer_t
* which will be used to hold the ring buffer's data structure
*
@ -182,7 +174,7 @@ BaseType_t xRingbufferSendFromISR(RingbufHandle_t xRingbuffer,
*
* Attempt to allocate buffer for an item to be sent into the ring buffer. This
* function will block until enough free space is available or until it
* timesout.
* times out.
*
* The item, as well as the following items ``SendAcquire`` or ``Send`` after it,
* will not be able to be read from the ring buffer until this item is actually
@ -407,7 +399,7 @@ void vRingbufferDelete(RingbufHandle_t xRingbuffer);
*
* @note The max item size for a no-split buffer is limited to
* ((buffer_size/2)-header_size). This limit is imposed so that an item
* of max item size can always be sent to the an empty no-split buffer
* of max item size can always be sent to an empty no-split buffer
* regardless of the internal positions of the buffer's read/write/free
* pointers.
*
@ -486,8 +478,8 @@ BaseType_t xRingbufferRemoveFromQueueSetRead(RingbufHandle_t xRingbuffer, QueueS
/**
* @brief Get information about ring buffer status
*
* Get information of the a ring buffer's current status such as
* free/read/write pointer positions, and number of items waiting to be retrieved.
* Get information of a ring buffer's current status such as
* free/read/write/acquire pointer positions, and number of items waiting to be retrieved.
* Arguments can be set to NULL if they are not required.
*
* @param[in] xRingbuffer Ring buffer to remove from the queue set

View File

@ -1,16 +1,8 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_SYSTEM_H__
#define __ESP_SYSTEM_H__
@ -86,7 +78,7 @@ esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handle);
*
* This function can be called both from PRO and APP CPUs.
* After successful restart, CPU reset reason will be SW_CPU_RESET.
* Peripherals (except for WiFi, BT, UART0, SPI1, and legacy timers) are not reset.
* Peripherals (except for Wi-Fi, BT, UART0, SPI1, and legacy timers) are not reset.
* This function does not return.
*/
void esp_restart(void) __attribute__ ((noreturn));
@ -100,7 +92,7 @@ esp_reset_reason_t esp_reset_reason(void);
/**
* @brief Get the size of available heap.
*
* Note that the returned value may be larger than the maximum contiguous block
* @note Note that the returned value may be larger than the maximum contiguous block
* which can be allocated.
*
* @return Available heap size, in bytes.
@ -110,7 +102,7 @@ uint32_t esp_get_free_heap_size(void);
/**
* @brief Get the size of available internal heap.
*
* Note that the returned value may be larger than the maximum contiguous block
* @note Note that the returned value may be larger than the maximum contiguous block
* which can be allocated.
*
* @return Available internal heap size, in bytes.

View File

@ -39,9 +39,9 @@ extern "C" {
#define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker
/**
* @brief callback called when a allocation operation fails, if registered
* @brief callback called when an allocation operation fails, if registered
* @param size in bytes of failed allocation
* @param caps capabillites requested of failed allocation
* @param caps capabilities requested of failed allocation
* @param function_name function which generated the failure
*/
typedef void (*esp_alloc_failed_hook_t) (size_t size, uint32_t caps, const char * function_name);
@ -100,7 +100,7 @@ void heap_caps_free( void *ptr);
void *heap_caps_realloc( void *ptr, size_t size, uint32_t caps);
/**
* @brief Allocate a aligned chunk of memory which has the given capabilities
* @brief Allocate an aligned chunk of memory which has the given capabilities
*
* Equivalent semantics to libc aligned_alloc(), for capability-aware memory.
* @param alignment How the pointer received needs to be aligned
@ -119,12 +119,12 @@ void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps);
* @brief Used to deallocate memory previously allocated with heap_caps_aligned_alloc
*
* @param ptr Pointer to the memory allocated
* @note This function is deprecated, plase consider using heap_caps_free() instead
* @note This function is deprecated, please consider using heap_caps_free() instead
*/
void __attribute__((deprecated)) heap_caps_aligned_free(void *ptr);
/**
* @brief Allocate a aligned chunk of memory which has the given capabilities. The initialized value in the memory is set to zero.
* @brief Allocate an aligned chunk of memory which has the given capabilities. The initialized value in the memory is set to zero.
*
* @param alignment How the pointer received needs to be aligned
* must be a power of two
@ -175,7 +175,7 @@ size_t heap_caps_get_total_size(uint32_t caps);
* This function takes all regions capable of having the given capabilities allocated in them
* and adds up the free space they have.
*
* Note that because of heap fragmentation it is probably not possible to allocate a single block of memory
* @note Note that because of heap fragmentation it is probably not possible to allocate a single block of memory
* of this size. Use heap_caps_get_largest_free_block() for this purpose.
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
@ -189,11 +189,11 @@ size_t heap_caps_get_free_size( uint32_t caps );
/**
* @brief Get the total minimum free memory of all regions with the given capabilities
*
* This adds all the low water marks of the regions capable of delivering the memory
* This adds all the low watermarks of the regions capable of delivering the memory
* with the given capabilities.
*
* Note the result may be less than the global all-time minimum available heap of this kind, as "low water marks" are
* tracked per-region. Individual regions' heaps may have reached their "low water marks" at different points in time. However
* @note Note the result may be less than the global all-time minimum available heap of this kind, as "low watermarks" are
* tracked per-region. Individual regions' heaps may have reached their "low watermarks" at different points in time. However,
* this result still gives a "worst case" indication for all-time minimum free heap.
*
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
@ -211,7 +211,7 @@ size_t heap_caps_get_minimum_free_size( uint32_t caps );
* @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type
* of memory
*
* @return Size of largest free block in bytes.
* @return Size of the largest free block in bytes.
*/
size_t heap_caps_get_largest_free_block( uint32_t caps );
@ -219,8 +219,8 @@ size_t heap_caps_get_largest_free_block( uint32_t caps );
/**
* @brief Get heap info for all regions with the given capabilities.
*
* Calls multi_heap_info() on all heaps which share the given capabilities. The information returned is an aggregate
* across all matching heaps. The meanings of fields are the same as defined for multi_heap_info_t, except that
* Calls multi_heap_info() on all heaps which share the given capabilities. The information returned is an aggregate
* across all matching heaps. The meanings of fields are the same as defined for multi_heap_info_t, except that
* ``minimum_free_bytes`` has the same caveats described in heap_caps_get_minimum_free_size().
*
* @param info Pointer to a structure which will be filled with relevant
@ -285,7 +285,7 @@ bool heap_caps_check_integrity(uint32_t caps, bool print_errors);
* This can be useful if debugging heap integrity for corruption at a known address,
* as it has a lower overhead than checking all heap regions. Note that if the corrupt
* address moves around between runs (due to timing or other factors) then this approach
* won't work and you should call heap_caps_check_integrity or
* won't work, and you should call heap_caps_check_integrity or
* heap_caps_check_integrity_all instead.
*
* @note The entire heap region around the address is checked, not only the adjacent
@ -321,14 +321,14 @@ void heap_caps_malloc_extmem_enable(size_t limit);
* or fail to allocate memories with any of the parameters.
*
* @param size Size, in bytes, of the amount of memory to allocate
* @param num Number of variable paramters
* @param num Number of variable parameters
*
* @return A pointer to the memory allocated on success, NULL on failure
*/
void *heap_caps_malloc_prefer( size_t size, size_t num, ... );
/**
* @brief Allocate a chunk of memory as preference in decreasing order.
* @brief Reallocate a chunk of memory as preference in decreasing order.
*
* @param ptr Pointer to previously allocated memory, or NULL for a new allocation.
* @param size Size of the new buffer requested, or 0 to free the buffer.
@ -382,7 +382,7 @@ void heap_caps_dump_all(void);
* @brief Return the size that a particular pointer was allocated with.
*
* @param ptr Pointer to currently allocated heap memory. Must be a pointer value previously
* returned by heap_caps_malloc,malloc,calloc, etc. and not yet freed.
* returned by heap_caps_malloc, malloc, calloc, etc. and not yet freed.
*
* @note The app will crash with an assertion failure if the pointer is not valid.
*

View File

@ -1,16 +1,8 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
@ -55,7 +47,7 @@ void *multi_heap_malloc(multi_heap_handle_t heap, size_t size);
*
* @param heap Handle to a registered heap.
* @param p NULL, or a pointer previously returned from multi_heap_aligned_alloc() for the same heap.
* @note This function is deprecated, consider using multi_heap_free() instead
* @note This function is deprecated, consider using multi_heap_free() instead
*/
void __attribute__((deprecated)) multi_heap_aligned_free(multi_heap_handle_t heap, void *p);
@ -130,7 +122,7 @@ void multi_heap_dump(multi_heap_handle_t heap);
/** @brief Check heap integrity
*
* Walks the heap and checks all heap data structures are valid. If any errors are detected, an error-specific message
* can be optionally printed to stderr. Print behaviour can be overriden at compile time by defining
* can be optionally printed to stderr. Print behaviour can be overridden at compile time by defining
* MULTI_CHECK_FAIL_PRINTF in multi_heap_platform.h.
*
* @param heap Handle to a registered heap.
@ -157,7 +149,7 @@ size_t multi_heap_free_size(multi_heap_handle_t heap);
*
* Equivalent to the minimum_free_bytes member returned by multi_heap_get_info().
*
* Returns the lifetime "low water mark" of possible values returned from multi_free_heap_size(), for the specified
* Returns the lifetime "low watermark" of possible values returned from multi_free_heap_size(), for the specified
* heap.
*
* @param heap Handle to a registered heap.
@ -169,7 +161,7 @@ size_t multi_heap_minimum_free_size(multi_heap_handle_t heap);
typedef struct {
size_t total_free_bytes; ///< Total free bytes in the heap. Equivalent to multi_free_heap_size().
size_t total_allocated_bytes; ///< Total bytes allocated to data in the heap.
size_t largest_free_block; ///< Size of largest free block in the heap. This is the largest malloc-able size.
size_t largest_free_block; ///< Size of the largest free block in the heap. This is the largest malloc-able size.
size_t minimum_free_bytes; ///< Lifetime minimum free heap size. Equivalent to multi_minimum_free_heap_size().
size_t allocated_blocks; ///< Number of (variable size) blocks allocated in the heap.
size_t free_blocks; ///< Number of (variable size) free blocks in the heap.

View File

@ -58,9 +58,8 @@ extern esp_log_level_t esp_log_default_level;
*
* If logging for given component has already been enabled, changes previous setting.
*
* Note that this function can not raise log level above the level set using
* @note Note that this function can not raise log level above the level set using
* CONFIG_LOG_MAXIMUM_LEVEL setting in menuconfig.
*
* To raise log level above the default one for a given file, define
* LOG_LOCAL_LEVEL to one of the ESP_LOG_* values, before including
* esp_log.h in this file.
@ -74,7 +73,7 @@ extern esp_log_level_t esp_log_default_level;
void esp_log_level_set(const char* tag, esp_log_level_t level);
/**
* @brief Get log level for given tag, can be used to avoid expensive log statements
* @brief Get log level for a given tag, can be used to avoid expensive log statements
*
* @param tag Tag of the log to query current level. Must be a non-NULL zero terminated
* string.
@ -121,8 +120,8 @@ uint32_t esp_log_timestamp(void);
* 0 on startup, this can be set to the correct time with an SNTP sync,
* or manually with standard POSIX time functions.
*
* Currently this will not get used in logging from binary blobs
* (i.e WiFi & Bluetooth libraries), these will still print the RTOS tick time.
* Currently, this will not get used in logging from binary blobs
* (i.e. Wi-Fi & Bluetooth libraries), these will still print the RTOS tick time.
*
* @return timestamp, in "HH:MM:SS.sss"
*/
@ -212,7 +211,7 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
* W (195) log_example: 0x3ffb4290 77 6f 72 6b 69 6e 67 20 61 6c 6f 6e 67 20 77 69 |working along wi|
* W (205) log_example: 0x3ffb42a0 74 68 20 74 68 65 20 49 44 46 2e 00 |th the IDF..|
*
* It is highly recommend to use terminals with over 102 text width.
* It is highly recommended to use terminals with over 102 text width.
*
* @param tag description tag
* @param buffer Pointer to the buffer array
@ -297,7 +296,8 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
/** @endcond */
/// macro to output logs in startup code, before heap allocator and syscalls have been initialized. log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE``,``ESP_DRAM_LOGE``
/// macro to output logs in startup code, before heap allocator and syscalls have been initialized.
/// Log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE``,``ESP_DRAM_LOGE``
#define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count
/**
@ -394,8 +394,8 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
*
* @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime.
* @param level level of the output log.
* @param format format of the output log. see ``printf``
* @param ... variables to be replaced into the log. see ``printf``
* @param format format of the output log. See ``printf``
* @param ... variables to be replaced into the log. See ``printf``
*
* @see ``printf``
*/
@ -447,7 +447,7 @@ void esp_log_writev(esp_log_level_t level, const char* tag, const char* format,
/**
* @brief Macro to output logs when the cache is disabled. log at ``ESP_LOG_ERROR`` level.
* @brief Macro to output logs when the cache is disabled. Log at ``ESP_LOG_ERROR`` level.
*
* @note Unlike normal logging macros, it's possible to use this macro when interrupts are
* disabled or inside an ISR.

View File

@ -1,16 +1,8 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_SNTP_H__
#define __ESP_SNTP_H__
@ -28,7 +20,7 @@ extern "C" {
* The user has the ability to redefine this function in order
* to re-define its functionality. This function has two time update modes,
* which can be set via the sntp_set_sync_mode() function.
* Two modes are available:
* Two available modes are as follows:
* - the first is an immediate update when receiving time from the sntp server,
* - the second is a smooth time update (if the time error is no more than 35 minutes,
* and an immediate update if the error is more than 35 minutes).
@ -83,7 +75,7 @@ void sntp_sync_time(struct timeval *tv);
/**
* @brief Set the sync mode
*
* Allowable two mode: SNTP_SYNC_MODE_IMMED and SNTP_SYNC_MODE_SMOOTH.
* Modes allowed: SNTP_SYNC_MODE_IMMED and SNTP_SYNC_MODE_SMOOTH.
* @param sync_mode Sync mode.
*/
void sntp_set_sync_mode(sntp_sync_mode_t sync_mode);

View File

@ -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 {IDF_TARGET_NAME} via JTAG interface with small overhead on program execution.
IDF provides a useful feature for program behavior analysis called **Application Level Tracing**. The feature can be enabled in menuconfig and allows transfer of arbitrary data between the host and {IDF_TARGET_NAME} via JTAG interface with minimal 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:
@ -29,10 +29,9 @@ Modes of Operation
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 {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.
**Post-mortem mode**. This is the default mode. The mode does not need interaction with the host side. In this mode, the tracing module does not check whether host has read all the data from the *HW UP BUFFER* and overwrites it with new data. This mode is useful when only the latest trace data is interesting to the user, e.g. for analyzing the program's behavior just before a crash. Host can read the data later upon user request, e.g. via a special OpenOCD command in case of working via JTAG interface.
**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*, the 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. When an application tries to write data to the trace buffer with a finite wait time, it is possible that the data will be dropped. This is especially true when tracing from time critical code (ISRs, OS scheduler code etc.) where infinite timeouts can lead to a 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 such scenarios. This option can also help to overcome a 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 the average bitrate of the trace data stream exceeds the HW interface capabilities.
Configuration Options and Dependencies
--------------------------------------
@ -45,28 +44,27 @@ Using of this feature depends on two components:
.. note::
In order to achieve higher data rates and minimize number of dropped packets it is recommended to optimize setting of JTAG clock frequency, so it is at maximum and still provides stable operation of JTAG, see :ref:`jtag-debugging-tip-optimize-jtag-speed`.
In order to achieve higher data rates and minimize the number of dropped packets, it is recommended to optimize the setting of the JTAG clock frequency, so it is at maximum and still provides stable operation of JTAG, see :ref:`jtag-debugging-tip-optimize-jtag-speed`.
There are two additional menuconfig options not mentioned above:
1. *Threshold for flushing last trace data to host on panic* (:ref:`CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH`). This option is necessary due to the nature of working over JTAG. In that mode trace data are exposed to the host in 16 KB blocks. In post-mortem mode when one block is filled it is exposed to the host and the previous one becomes unavailable. In other words trace data are overwritten in 16 KB granularity. On panic the latest data from the current input block are exposed to host and host can read them for post-analysis. System panic may occur when very small amount of data are not exposed to the host yet. In this case the previous 16 KB of collected data will be lost and host will see the latest, but very small piece of the trace. It can be insufficient to diagnose the problem. This menuconfig option allows avoiding such situations. It controls the threshold for flushing data in case of panic. For example user can decide that it needs not less then 512 bytes of the recent trace data, so if there is less then 512 bytes of pending data at the moment of panic they will not be flushed and will not overwrite previous 16 KB. The option is only meaningful in post-mortem mode and when working over JTAG.
There are two additional menuconfig options that are available to users:
1. *Threshold for flushing last trace data to host on panic* (:ref:`CONFIG_APPTRACE_POSTMORTEM_FLUSH_THRESH`). This option is useful when working over JTAG wherein the trace data is exposed to the host in 16 KB blocks. In post-mortem mode, when one block is filled it is exposed to the host and the previous one becomes unavailable. In other words, the trace data is overwritten in 16 KB granularity. On panic, the latest data from the current input block is exposed to the host and the host can read it for post-analysis. System panic may occur when a very small amount of data has been accumulated but not yet exposed to the host. In this case the previous 16 KB of collected data will be lost and the host will see the latest, very small piece of the trace. This data may be insufficient to diagnose the problem. Thus, this menuconfig option allows avoiding such situations. It controls the threshold for flushing data in case of a panic. For example, users can decide that they need no less than 512 bytes of the recent trace data for meaningful analysis. If there is less than 512 bytes of pending data at the moment of panic, it will not be flushed and will not overwrite the previous 16 KB. The option is only meaningful in post-mortem mode and when working over JTAG.
2. *Timeout for flushing last trace data to host on panic* (:ref:`CONFIG_APPTRACE_ONPANIC_HOST_FLUSH_TMO`). The option is only meaningful in streaming mode and controls the maximum time tracing module will wait for the host to read the last data in case of panic.
How to use this library
-----------------------
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.
This library provides APIs for transferring arbitrary data between the host and {IDF_TARGET_NAME}. When enabled in menuconfig, target application tracing module is initialized automatically at the system startup. All that the user needs to do is to call corresponding APIs to send, receive or flush the data.
.. _app_trace-application-specific-tracing:
Application Specific Tracing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In general user should decide what type of data should be transferred in every direction and how these data must be interpreted (processed). The following steps must be performed to transfer data between target and host:
In general the user should decide what type of data should be transferred in either direction and how this data must be interpreted (processed). The following steps must be performed to transfer data between {IDF_TARGET_NAME} and the host:
1. On target side user should implement algorithms for writing trace data to the host. Piece of code below shows an example how to do this.
1. On target side user should implement algorithms for writing trace data to the host. The following piece of code demonstrates an example of how to do this.
.. code-block:: c
@ -99,7 +97,7 @@ In general user should decide what type of data should be transferred in every d
return res;
}
Also according to his needs user may want to receive data from the host. Piece of code below shows an example how to do this.
The user may also want to receive data from the host. The following piece of code shows an example of how to do this.
.. code-block:: c
@ -162,13 +160,13 @@ In general user should decide what type of data should be transferred in every d
OpenOCD Application Level Tracing Commands
""""""""""""""""""""""""""""""""""""""""""
*HW UP BUFFER* is shared between user data blocks and filling of the allocated memory is performed on behalf of the API caller (in task or ISR context). In multithreading environment it can happen that task/ISR which fills the buffer is preempted by another high priority task/ISR. So it is possible situation that user data preparation process is not completed at the moment when that chunk is read by the host. To handle such conditions tracing module prepends all user data chunks with header which contains allocated user buffer size (2 bytes) and length of actually written data (2 bytes). So total length of the header is 4 bytes. OpenOCD command which reads trace data reports error when it reads incomplete user data chunk, but in any case it puts contents of the whole user chunk (including unfilled area) to output file.
*HW UP BUFFER* is shared between user data blocks and filling of the allocated memory is performed on behalf of the API caller (in task or ISR context). In a multithreaded environment, it can happen that the task/ISR which fills the buffer is preempted by another high priority task/ISR. It is possible that the user data preparation process is not complete when that chunk is read by the host. To handle such scenarios, the tracing module prepends all user data chunks with a header that contains allocated user buffer size (2 bytes) and the length of the actual written data (2 bytes). So total length of the header is 4 bytes. OpenOCD command which reads trace data reports an error when it reads an incomplete user data chunk. In any case, it puts the contents of the whole user chunk (including unfilled area) to the output file.
Below is the description of available OpenOCD application tracing commands.
.. note::
Currently OpenOCD does not provide commands to send arbitrary user data to the target.
Currently, OpenOCD does not provide commands to send arbitrary user data to the target.
Command usage:
@ -194,15 +192,15 @@ 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``
Idle timeout (in sec). Tracing is stopped if there is no data for specified period of time. By default -1 (disable this stop trigger). Optionally set it to value longer than longest pause between tracing commands from target.
Idle timeout (in sec). Tracing is stopped if there is no data for a specified period of time. By default -1 (disable this stop trigger). Optionally set it to a value longer than the longest pause between tracing commands from the target.
``wait4halt``
If 0 start tracing immediately, otherwise command waits for the target to be halted (after reset, by breakpoint etc.) and then automatically resumes it and starts tracing. By default 0.
If 0 start tracing immediately, otherwise command waits for the target to be halted (after reset, by breakpoint etc.) and then automatically resumes it and starts tracing. By default, 0.
``skip_size``
Number of bytes to skip at the start. By default 0.
Number of bytes to skip at the start. By default, 0.
.. note::
@ -222,7 +220,7 @@ Command usage examples:
.. note::
Tracing data is buffered before it is made available to OpenOCD. If you see "Data timeout!" message, then the target is likely sending not enough data to empty the buffer to OpenOCD before expiration of timeout. Either increase the timeout or use a function ``esp_apptrace_flush()`` to flush the data on specific intervals.
Tracing data is buffered before it is made available to OpenOCD. If you see a "Data timeout!" message, it is likely that the target is not sending enough data to empty the buffer to OpenOCD before the timeout. Either increase the timeout or use a function ``esp_apptrace_flush()`` to flush the data on specific intervals.
2. Retrieve tracing data indefinitely in non-blocking mode.
@ -230,7 +228,7 @@ Command usage examples:
esp apptrace start file://trace.log 1 -1 -1 0 0
There is no limitation on the size of collected data and there is no any data timeout set. This process may be stopped by issuing ``esp apptrace stop`` command on OpenOCD telnet prompt, or by pressing Ctrl+C in OpenOCD window.
There is no limitation on the size of collected data and there is no data timeout set. This process may be stopped by issuing ``esp apptrace stop`` command on OpenOCD telnet prompt, or by pressing Ctrl+C in OpenOCD window.
3. Retrieve tracing data and save them indefinitely.
@ -254,20 +252,19 @@ Command usage examples:
Logging to Host
^^^^^^^^^^^^^^^
IDF implements useful feature: logging to host via application level tracing library. This is a kind of semihosting when all `ESP_LOGx` calls send strings to be printed to the host instead of UART. This can be useful because "printing to host" eliminates some steps performed when logging to UART. The most part of work is done on the host.
IDF implements a useful feature: logging to host via application level tracing library. This is a kind of semihosting when all `ESP_LOGx` calls are redirected to the host instead of UART. This can be useful because "printing to host" eliminates some steps performed when logging to UART. Most part of the work is done on the host.
By default IDF's logging library uses vprintf-like function to write formatted output to dedicated UART. In general it involves the following steps:
By default, IDF's logging library uses a vprintf-like function to write formatted output to dedicated UART. In general, it involves the following steps:
1. Format string is parsed to obtain type of each argument.
2. According to its type every argument is converted to string representation.
3. Format string combined with converted arguments is sent to UART.
Though implementation of vprintf-like function can be optimized to a certain level, all steps above have to be performed in any case and every step takes some time (especially item 3). So it frequently occurs that with additional log added to the program to identify the problem, the program behavior is changed and the problem cannot be reproduced or in the worst cases the program cannot work normally at all and ends up with an error or even hangs.
Though the implementation of a vprintf-like function can be optimized to a certain level, all steps above have to be performed in any case and every step takes some time (especially item 3). Hence, it is quite common to observe that with additional logging added to a program for debugging, the program behavior changes and the problem is not reproduced. In the worst case, the program may not work normally at all and ends up with an error or even hangs.
Possible ways to overcome this problem are to use higher UART bitrates (or another faster interface) and/or move string formatting procedure to the host.
Application level tracing feature can be used to transfer log information to host using ``esp_apptrace_vprintf`` function. This function does not perform full parsing of the format string and arguments, instead it just calculates number of arguments passed and sends them along with the format string address to the host. On the host log data are processed and printed out by a special Python script.
Application level tracing feature can be used to transfer log information to the host using ``esp_apptrace_vprintf`` function. This function does not perform full parsing of the format string and arguments, and instead just calculates the number of arguments passed and sends them along with the format string address to the host. On the host, log data are processed and printed out by a special Python script.
Limitations
"""""""""""
@ -285,7 +282,7 @@ How To Use It
In order to use logging via trace module user needs to perform the following steps:
1. On target side special vprintf-like function needs to be installed. As it was mentioned earlier this function is ``esp_apptrace_vprintf``. It sends log data to the host. Example code is provided in :example:`system/app_trace_to_host`.
1. On target side, the user must use the :cpp:func:`esp_apptrace_vprintf` function to send log data to the host. Example code is provided in :example:`system/app_trace_to_host`.
2. Follow instructions in items 2-5 in `Application Specific Tracing`_.
3. To print out collected log records, run the following command in terminal: ``$IDF_PATH/tools/esp_app_trace/logtrace_proc.py /path/to/trace/file /path/to/program/elf/file``.
@ -320,7 +317,7 @@ Another useful IDF feature built on top of application tracing library is the sy
.. note::
Currently IDF-based application is able to generate SystemView compatible traces in form of files to be opened in SystemView application. The tracing process cannot yet be controlled using that tool.
Currently, IDF based applications are able to generate SystemView compatible traces in form of files to be opened in the SystemView application. The tracing process cannot yet be controlled using that tool.
How To Use It
@ -373,7 +370,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 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``
@ -407,13 +404,13 @@ 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.
After trace data is collected, users can use a special tool to visualize the results and inspect behavior of the program.
.. only:: not CONFIG_FREERTOS_UNICORE
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.
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. Users can load both files into separate instances 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.
It is uneasy and awkward to analyze data for every core in separate instance of the tool. Fortunately there is an 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.
Good instruction on how to install, configure and visualize data in Impulse from one core can be found `here <https://mcuoneclipse.com/2016/07/31/impulse-segger-systemview-in-eclipse/>`_.
@ -441,7 +438,7 @@ Good instruction on how to install, configure and visualize data in Impulse from
.. note::
If you have problems with visualization (no data are shown or strange behavior of zoom action is observed) you can try to delete current signal hierarchy and double click on the necessary file or port. Eclipse will ask you to create new signal hierarchy.
If you have problems with visualization (no data are shown or strange behavior of zoom action is observed) you can try to delete current signal hierarchy and double-click on the necessary file or port. Eclipse will ask you to create new signal hierarchy.
.. _app_trace-gcov-source-code-coverage:
@ -465,7 +462,7 @@ Generally, using Gcov to compile and run programs on the Host will undergo these
Gcov and Gcovr in ESP-IDF
"""""""""""""""""""""""""""
Using Gcov in ESP-IDF is complicated by the fact that the program is running remotely from the Host (i.e., on the target). The code coverage data (i.e., the ``.gcda`` files) is initially stored on the target itself. OpenOCD is then used to dump the code coverage data from the target to the host via JTAG during runtime. Using Gcov in ESP-IDF can be split into the following steps.
Using Gcov in ESP-IDF is complicated due to the fact that the program is running remotely and not on the host (i.e., on the target). The code coverage data (i.e., the ``.gcda`` files) is initially stored on the target itself. OpenOCD is then used to dump the code coverage data from the target to the host via JTAG during runtime. Using Gcov in ESP-IDF can be split into the following steps.
1. :ref:`app_trace-gcov-setup-project`
2. :ref:`app_trace-gcov-dumping-data`
@ -499,23 +496,23 @@ Before building a project with source code coverage, ensure that the following p
Dumping Code Coverage Data
""""""""""""""""""""""""""
Once a project has been complied with the ``--coverage`` option and flashed onto the target, code coverage data will be stored internally on the target (i.e., in trace memory) whilst the application runs. The process of transferring code coverage data from the target to the Host is know as dumping.
Once a project has been complied with the ``--coverage`` option and flashed onto the target, code coverage data will be stored internally on the target (i.e., in trace memory) whilst the application runs. The process of transferring code coverage data from the target to the Host is known as dumping.
The dumping of coverage data is done via OpenOCD (see :doc:`JTAG Debugging <../api-guides/jtag-debugging/index>` on how to setup and run OpenOCD). A dump is triggered by issuing commands to OpenOCD, therefore a telnet session to OpenOCD must be opened to issue such commands (run ``telnet localhost 4444``). Note that GDB could be used instead of telnet to issue commands to OpenOCD, however all commands issued from GDB will need to be prefixed as ``mon <oocd_command>``.
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``. 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 lifetime. 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:
* Instant Run-Time Dumpgit
* Instant Run-Time Dump
* Hard-coded Dump
Instant Run-Time Dump
~~~~~~~~~~~~~~~~~~~~~
An Instant Run-Time Dump is triggered by calling the ``{IDF_TARGET_NAME} 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.
An Instant Run-Time Dump is triggered by calling the ``{IDF_TARGET_NAME} 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 its current state.
Hard-coded Dump
~~~~~~~~~~~~~~~
@ -548,10 +545,10 @@ Once the code coverage data has been dumped, the ``.gcno``, ``.gcda`` and the so
Both Gcov and Gcovr can be used to generate code coverage reports. Gcov is provided along with the Xtensa toolchain, whilst Gcovr may need to be installed separately. For details on how to use Gcov or Gcovr, refer to `Gcov documentation <https://gcc.gnu.org/onlinedocs/gcc/Gcov.html>`_ and `Gcovr documentation <http://gcovr.com/>`_.
Adding Gcovr Build Target to Project
Adding Gcov Build Target to Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To make report generation more convenient, users can define additional build targets in their projects such report generation can be done with a single build command.
To make report generation more convenient, users can define additional build targets in their projects such that the report generation can be done with a single build command.
Add the following lines to the ``CMakeLists.txt`` file of your project.

View File

@ -80,8 +80,8 @@ Configuration example:
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S
.tx_desc_auto_clear = false,
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.use_apll = false,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0
};
@ -101,8 +101,8 @@ Configuration example:
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.tx_desc_auto_clear = false,
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.bits_per_chan = I2S_BITS_PER_SAMPLE_16BIT
};
@ -194,8 +194,8 @@ Example for general usage.
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S
.tx_desc_auto_clear = false,
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.use_apll = false,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0
};
@ -238,8 +238,8 @@ Example for general usage.
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S
.tx_desc_auto_clear = false,
.dma_buf_count = 8,
.dma_buf_len = 64
.dma_desc_num = 8,
.dma_frame_num = 64
};
static const i2s_pin_config_t pin_config = {
@ -282,8 +282,8 @@ Example for general usage.
.channel_format = I2S_CHANNEL_FMT_MULTIPLE,
.communication_format = I2S_COMM_FORMAT_STAND_I2S
.tx_desc_auto_clear = false,
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH2
};
@ -328,8 +328,8 @@ Example for general usage.
.bits_per_sample = 16, /* the DAC module will only take the 8bits from MSB */
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.intr_alloc_flags = 0, // default interrupt priority
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.use_apll = false
};

View File

@ -62,12 +62,12 @@ You can also see the information on segments in the IDF logs while your applicat
For more details on the type of memory segments and their address ranges, see *{IDF_TARGET_NAME} Technical Reference Manual* > *System and Memory* > *Embedded Memory* [`PDF <{IDF_TARGET_TRM_EN_URL}#sysmem>`__].
.. only:: esp32s2 or esp32c3
.. only:: esp32s2 or esp32s3 or esp32c3
For more details on the type of memory segments and their address ranges, see *{IDF_TARGET_NAME} Technical Reference Manual* > *System and Memory* > *Internal Memory* [`PDF <{IDF_TARGET_TRM_EN_URL}#sysmem>`__].
3. The image has a single checksum byte after the last segment. This byte is written on a sixteen byte padded boundary, so the application image might need padding.
4. If the ``hash_appended`` field from :cpp:type:`esp_image_header_t` is set then a SHA256 checksum will be appended. The value of SHA256 is calculated on the range from first byte and up to this field. The length of this field is 32 bytes.
4. If the ``hash_appended`` field from :cpp:type:`esp_image_header_t` is set then a SHA256 checksum will be appended. The value of SHA256 is calculated on the range from the first byte and up to this field. The length of this field is 32 bytes.
5. If the options :ref:`CONFIG_SECURE_SIGNED_APPS_SCHEME` is set to ECDSA then the application image will have additional 68 bytes for an ECDSA signature, which includes:
* version word (4 bytes),
@ -78,6 +78,7 @@ Application Description
The ``DROM`` segment starts with the :cpp:type:`esp_app_desc_t` structure which carries specific fields describing the application:
* ``magic_word`` - the magic word for the esp_app_desc structure.
* ``secure_version`` - see :doc:`Anti-rollback</api-reference/system/ota>`.
* ``version`` - see :doc:`App version</api-reference/system/system>`. ``*``
* ``project_name`` is filled from ``PROJECT_NAME``. ``*``
@ -92,7 +93,7 @@ This structure is useful for identification of images uploaded OTA because it ha
Adding a Custom Structure to an Application
-------------------------------------------
Customer also has the opportunity to have similar structure with a fixed offset relative to the beginning of the image.
Users also have the opportunity to have similar structure with a fixed offset relative to the beginning of the image.
The following pattern can be used to add a custom structure to your image:
::

View File

@ -4,7 +4,7 @@ Application Level Tracing
Overview
--------
IDF provides useful feature for program behaviour analysis: application level tracing. It is implemented in the corresponding library and can be enabled via menuconfig. This feature allows to transfer arbitrary data between host and {IDF_TARGET_NAME} via JTAG interface with small overhead on program execution.
IDF provides a useful feature for program behavior analysis called **Application Level Tracing**. The feature can be enabled in menuconfig and allows transfer of arbitrary data between the host and {IDF_TARGET_NAME} via JTAG interface with minimal 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:
1. Collecting application specific data, see :ref:`app_trace-application-specific-tracing`

View File

@ -7,7 +7,7 @@ Overview
The event loop library allows components to declare events to which other components can register handlers -- code which will
execute when those events occur. This allows loosely coupled components to attach desired behavior to changes in state of other components
without application involvement. For instance, a high level connection handling library may subscribe to events produced
by the wifi subsystem directly and act on those events. This also simplifies event processing by serializing and deferring
by the Wi-Fi subsystem directly and act on those events. This also simplifies event processing by serializing and deferring
code execution to another context.
Using ``esp_event`` APIs
@ -15,7 +15,7 @@ Using ``esp_event`` APIs
There are two objects of concern for users of this library: events and event loops.
Events are occurrences of note. For example, for WiFi, a successful connection to the access point may be an event.
Events are occurrences of note. For example, for Wi-Fi, a successful connection to the access point may be an event.
Events are referenced using a two part identifier which are discussed more :ref:`here <esp-event-declaring-defining-events>`.
Event loops are the vehicle by which events get posted by event sources and handled by event handler functions.
These two appear prominently in the event loop library APIs.
@ -84,7 +84,7 @@ In code, the flow above may look like as follows:
Declaring and defining events
-----------------------------
As mentioned previously, events consists of two-part identifers: the event base and the event ID. The event base identifies an independent group
As mentioned previously, events consists of two-part identifiers: the event base and the event ID. The event base identifies an independent group
of events; the event ID identifies the event within that group. Think of the event base and event ID as a
person's last name and first name, respectively. A last name identifies a family, and the first name identifies a person within that family.
@ -104,7 +104,7 @@ Event base definition:
.. note::
In IDF, the base identifiers for system events are uppercase and are postfixed with ``_EVENT``. For example, the base for wifi events is declared and defined
In IDF, the base identifiers for system events are uppercase and are postfixed with ``_EVENT``. For example, the base for Wi-Fi events is declared and defined
as ``WIFI_EVENT``, the ethernet event base ``ETHERNET_EVENT``, and so on. The purpose is to have event bases look like constants (although
they are global variables considering the defintions of macros ``ESP_EVENT_DECLARE_BASE`` and ``ESP_EVENT_DEFINE_BASE``).
@ -126,7 +126,7 @@ Event ID:
Default Event Loop
------------------
The default event loop is a special type of loop used for system events (WiFi events, for example). The handle for this
The default event loop is a special type of loop used for system events (Wi-Fi events, for example). The handle for this
loop is hidden from the user. The creation, deletion, handler registration/unregistration and posting of events is done
through a variant of the APIs for user event loops. The table below enumerates those variants, and the user event
loops equivalent.

View File

@ -15,16 +15,18 @@ passing that function as parameter
Usage
-----
:cpp:func:`esp_execute_shared_stack_function` takes four arguments,
a mutex object allocated by the caller, which is used to protect if
the same function shares its allocated stack, a pointer to the top
of stack used to that fuction, the size in bytes of stack and, a pointer
to a user function where the shared stack space will reside, after calling
the function, the user defined function will be deferred as a callback
where functions can be called using the user allocated space without
taking space from current task stack.
:cpp:func:`esp_execute_shared_stack_function` takes four arguments:
The usage may looks like the code below:
- a mutex object allocated by the caller, which is used to protect if the same function shares its allocated stack
- a pointer to the top of stack used for that fuction
- the size of stack in bytes
- a pointer to the shared stack function
The user defined function will be deferred as a callback
and can be called using the user allocated space without
taking space from current task stack.
The usage may look like the code below:
.. code-block:: c
@ -33,8 +35,8 @@ The usage may looks like the code below:
printf("Executing this printf from external stack! \n");
}
//Let's suppose we wanting to call printf using a separated stack space
//allowing app to reduce its stack size.
//Let's suppose we want to call printf using a separated stack space
//allowing the app to reduce its stack size.
void app_main()
{
//Allocate a stack buffer, from heap or as a static form:

View File

@ -40,7 +40,7 @@ This option is useful while fetching image from a service like AWS S3, where mbe
can be set to lower value which is not possible without enabling this configuration.
Default value of mbedTLS Rx buffer size is set to 16K. By using partial_http_download with max_http_request_size of 4K,
size of mbedTLS Rx buffer can be reduced to 4K. With this confiuration, memory saving of around 12K is expected.
size of mbedTLS Rx buffer can be reduced to 4K. With this configuration, memory saving of around 12K is expected.
Signature Verification
----------------------

View File

@ -15,7 +15,7 @@ An interrupt level of the handler depends on the :ref:`CONFIG_ESP_TIMER_INTERRUP
``esp_timer`` set of APIs provides one-shot and periodic timers, microsecond time resolution, and 64-bit range.
Internally, ``esp_timer`` uses a 64-bit hardware timer, where the implemention depends on :ref:`CONFIG_ESP_TIMER_IMPL`. Available options are:
Internally, ``esp_timer`` uses a 64-bit hardware timer, where the implementation depends on :ref:`CONFIG_ESP_TIMER_IMPL`. Available options are:
.. list::
@ -27,18 +27,18 @@ Internally, ``esp_timer`` uses a 64-bit hardware timer, where the implemention d
.. note:: The FRC2 is a legacy option for ESP32 until v4.2, a 32-bit hardware timer was used. Starting at v4.2, use the new LAC timer option instead, it has a simpler implementation, and has smaller run time overhead because software handling of timer overflow is not needed.
Timer callbacks can dispatched by two methods:
Timer callbacks can be dispatched by two methods:
- ``ESP_TIMER_TASK``
- ``ESP_TIMER_ISR``. Available only if :ref:`CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD` is enabled (by default disabled).
``ESP_TIMER_TASK``. Timer callbacks are dispatched from a high-priority ``esp_timer`` task. Because all the callbacks are dispatched from the same task, it is recommended to only do the minimal possible amount of work from the callback itself, posting an event to a lower priority task using a queue instead.
If other tasks with priority higher than ``esp_timer`` are running, callback dispatching will be delayed until ``esp_timer`` task has a chance to run. For example, this will happen if a SPI Flash operation is in progress.
If other tasks with priority higher than ``esp_timer`` are running, callback dispatching will be delayed until ``esp_timer`` task has a chance to run. For example, this will happen if an SPI Flash operation is in progress.
``ESP_TIMER_ISR``. Timer callbacks are dispatched directly from the timer interrupt handler. This method is useful for some simple callbacks which aim for lower latency.
Creating and starting a timer, and dispatching the callback takes some time. Therefore there is a lower limit to the timeout value of one-shot ``esp_timer``. If :cpp:func:`esp_timer_start_once` is called with a timeout value less than 20us, the callback will be dispatched only after approximately 20us.
Creating and starting a timer, and dispatching the callback takes some time. Therefore, there is a lower limit to the timeout value of one-shot ``esp_timer``. If :cpp:func:`esp_timer_start_once` is called with a timeout value less than 20us, the callback will be dispatched only after approximately 20us.
Periodic ``esp_timer`` also imposes a 50us restriction on the minimal timer period. Periodic software timers with period of less than 50us are not practical since they would consume most of the CPU time. Consider using dedicated hardware peripherals or DMA features if you find that a timer with small period is required.
@ -61,7 +61,7 @@ Note that the timer must not be running when :cpp:func:`esp_timer_start_once` or
Callback functions
------------------
.. note: Keep the callback functions as short as possible otherwise it will affect all timers.
.. note:: Keep the callback functions as short as possible otherwise it will affect all timers.
Timer callbacks which are processed by ``ESP_TIMER_ISR`` method should not call the context switch call - ``portYIELD_FROM_ISR()``, instead of this you should use the :cpp:func:`esp_timer_isr_dispatch_need_yield` function.
The context switch will be done after all ISR dispatch timers have been processed, if required by the system.

View File

@ -7,7 +7,7 @@ Overview
This section contains documentation of FreeRTOS types, functions, and macros. It is automatically generated from FreeRTOS header files.
.. note::
ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.2.0,
ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.4.3
For more information about FreeRTOS features specific to ESP-IDF, see :doc:`ESP-IDF FreeRTOS SMP Changes<../../api-guides/freertos-smp>`
and :doc:`ESP-IDF FreeRTOS Additions<freertos_additions>`.

View File

@ -4,9 +4,9 @@ FreeRTOS Additions
Overview
--------
ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.2.0 with significant modifications
ESP-IDF FreeRTOS is based on the Xtensa port of FreeRTOS v10.4.3 with significant modifications
for SMP compatibility (see :doc:`ESP-IDF FreeRTOS SMP Changes<../../api-guides/freertos-smp>`).
However various features specific to ESP-IDF FreeRTOS have been added. The features are as follows:
However, various features specific to ESP-IDF FreeRTOS have been added. The features are as follows:
:ref:`ring-buffers`: Ring buffers were added to provide a form of buffer that could accept
entries of arbitrary lengths.
@ -32,35 +32,35 @@ For efficiency reasons,
items *must also be returned* to the ring buffer by using :cpp:func:`vRingbufferReturnItem` or :cpp:func:`vRingbufferReturnItemFromISR`, in order for them to be removed from the ring buffer completely.
The ring buffers are split into the three following types:
**No-Split** buffers will guarantee that an item is stored in contiguous memory and will not
attempt to split an item under any circumstances. Use no-split buffers when items must occupy
contiguous memory. *Only this buffer type allows you getting the data item address and writting
to the item by yourself.*
**No-Split buffers** will guarantee that an item is stored in contiguous memory and will not
attempt to split an item under any circumstances. Use No-Split buffers when items must occupy
contiguous memory. *Only this buffer type allows you to get the data item address and write
to the item by yourself.* Refer the documentation of the functions :cpp:func:`xRingbufferSendAcquire` and :cpp:func:`xRingbufferSendComplete` for more details.
**Allow-Split** buffers will allow an item to be split when wrapping around if doing so will allow
the item to be stored. Allow-split buffers are more memory efficient than no-split buffers but
can return an item in two parts when retrieving.
**Allow-Split buffers** will allow an item to be split in two parts when wrapping around the end of the buffer if there
is enough space at the tail and the head of the buffer combined to store the item. Allow-Split buffers are more memory
efficient than No-Split buffers but can return an item in two parts when retrieving.
**Byte buffers** do not store data as separate items. All data is stored as a sequence of bytes,
and any number of bytes and be sent or retrieved each time. Use byte buffers when separate items
and any number of bytes can be sent or retrieved each time. Use byte buffers when separate items
do not need to be maintained (e.g. a byte stream).
.. note::
No-split/allow-split buffers will always store items at 32-bit aligned addresses. Therefore when
No-Split buffers and Allow-Split buffers will always store items at 32-bit aligned addresses. Therefore, when
retrieving an item, the item pointer is guaranteed to be 32-bit aligned. This is useful
especially when you need to send some data to the DMA.
.. note::
Each item stored in no-split/allow-split buffers will **require an additional 8 bytes for a header**.
Each item stored in No-Split or Allow-Split buffers will **require an additional 8 bytes for a header**.
Item sizes will also be rounded up to a 32-bit aligned size (multiple of 4 bytes), however the true
item size is recorded within the header. The sizes of no-split/allow-split buffers will also
item size is recorded within the header. The sizes of No-Split and Allow-Split buffers will also
be rounded up when created.
Usage
^^^^^
The following example demonstrates the usage of :cpp:func:`xRingbufferCreate`
and :cpp:func:`xRingbufferSend` to create a ring buffer then send an item to it.
and :cpp:func:`xRingbufferSend` to create a ring buffer and then send an item to it.
.. code-block:: c
@ -83,8 +83,8 @@ and :cpp:func:`xRingbufferSend` to create a ring buffer then send an item to it.
}
The following example demonstrates the usage of :cpp:func:`xRingbufferSendAcquire` and
:cpp:func:`xRingbufferSendComplete` instead of :cpp:func:`xRingbufferSend` to apply for the
memory on the ring buffer (of type `RINGBUF_TYPE_NOSPLIT`) and then send an item to it. This way
:cpp:func:`xRingbufferSendComplete` instead of :cpp:func:`xRingbufferSend` to acquire
memory on the ring buffer (of type `RINGBUF_TYPE_NOSPLIT`) and then send an item to it. This
adds one more step, but allows getting the address of the memory to write to, and writing to the
memory yourself.
@ -103,7 +103,7 @@ memory yourself.
...
//Retrieve space for DMA descriptor and corresponding data buffer
//This has to be done with SendAcquire, or the address may be different when copy
//This has to be done with SendAcquire, or the address may be different when we copy
dma_item_t item;
UBaseType_t res = xRingbufferSendAcquire(buf_handle,
&item, DMA_ITEM_SIZE(buffer_size), pdMS_TO_TICKS(1000));
@ -123,7 +123,7 @@ memory yourself.
printf("Failed to send item\n");
}
The following example demonstrates retrieving and returning an item from a **no-split ring buffer**
The following example demonstrates retrieving and returning an item from a **No-Split ring buffer**
using :cpp:func:`xRingbufferReceive` and :cpp:func:`vRingbufferReturnItem`
.. code-block:: c
@ -149,7 +149,7 @@ using :cpp:func:`xRingbufferReceive` and :cpp:func:`vRingbufferReturnItem`
}
The following example demonstrates retrieving and returning an item from an **allow-split ring buffer**
The following example demonstrates retrieving and returning an item from an **Allow-Split ring buffer**
using :cpp:func:`xRingbufferReceiveSplit` and :cpp:func:`vRingbufferReturnItem`
.. code-block:: c
@ -217,17 +217,17 @@ For ISR safe versions of the functions used above, call :cpp:func:`xRingbufferSe
Sending to Ring Buffer
^^^^^^^^^^^^^^^^^^^^^^
The following diagrams illustrate the differences between no-split/allow-split buffers
and byte buffers with regards to sending items/data. The diagrams assume that three
The following diagrams illustrate the differences between No-Split and Allow-Split buffers as compared to
byte buffers with regard to sending items/data. The diagrams assume that three
items of sizes **18, 3, and 27 bytes** are sent respectively to a **buffer of 128 bytes**.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_send_non_byte_buf.diag
:caption: Sending items to no-split/allow-split ring buffers
:caption: Sending items to No-Split or Allow-Split ring buffers
:align: center
For no-split/allow-split buffers, a header of 8 bytes precedes every data item. Furthermore, the space
For No-Split and Allow-Split buffers, a header of 8 bytes precedes every data item. Furthermore, the space
occupied by each item is **rounded up to the nearest 32-bit aligned size** in order to maintain overall
32-bit alignment. However the true size of the item is recorded inside the header which will be
32-bit alignment. However, the true size of the item is recorded inside the header which will be
returned when the item is retrieved.
Referring to the diagram above, the 18, 3, and 27 byte items are **rounded up to 20, 4, and 28 bytes**
@ -246,67 +246,67 @@ byte buffer and **merged into a single item of 48 bytes**.
Using SendAcquire and SendComplete
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Items in no-split buffers are acquired (by SendAcquire) in strict FIFO order and must be sent to
the buffer by SendComplete for the data to be accessible by the consumer. Multiple items can be
sent or acquired without calling SendComplete, and the items do not necessarily need to be
completed in the order they were acquired. However the receiving of data items must occur in FIFO
order, therefore not calling SendComplete the earliest acquired item will prevent the subsequent
Items in No-Split buffers are acquired (by ``SendAcquire``) in strict FIFO order and must be sent to
the buffer by ``SendComplete`` for the data to be accessible by the consumer. Multiple items can be
sent or acquired without calling ``SendComplete``, and the items do not necessarily need to be
completed in the order they were acquired. However, the receiving of data items must occur in FIFO
order, therefore not calling ``SendComplete`` for the earliest acquired item will prevent the subsequent
items from being received.
The following diagrams illustrate what will happen when SendAcquire/SendComplete don't happen in
the same order. At the beginning, there is already an data item of 16 bytes sent to the ring
buffer. Then SendAcquire is called to acquire space of 20, 8, 24 bytes on the ring buffer.
The following diagrams illustrate what will happen when ``SendAcquire`` and ``SendComplete`` don't happen in
the same order. At the beginning, there is already a data item of 16 bytes sent to the ring
buffer. Then ``SendAcquire`` is called to acquire space of 20, 8, 24 bytes on the ring buffer.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_send_acquire_complete.diag
:caption: SendAcquire/SendComplete items in no-split ring buffers
:caption: SendAcquire/SendComplete items in No-Split ring buffers
:align: center
After that, we fill (use) the buffers, and send them to the ring buffer by SendComplete in the
After that, we fill (use) the buffers, and send them to the ring buffer by ``SendComplete`` in the
order of 8, 24, 20. When 8 bytes and 24 bytes data are sent, the consumer still can only get the
16 bytes data item. Due to the usage if 20 bytes item is not complete, it's not available, nor
the following data items.
16 bytes data item. Hence, if ``SendComplete`` is not called for the 20 bytes, it will not be available, nor will
the data items following the 20 bytes item.
When the 20 bytes item is finally completed, all the 3 data items can be received now, in the
order of 20, 8, 24 bytes, right after the 16 bytes item existing in the buffer at the beginning.
Allow-split/byte buffers do not allow using SendAcquire/SendComplete since acquired buffers are
Allow-Split buffers and byte buffers do not allow using ``SendAcquire`` or ``SendComplete`` since acquired buffers are
required to be complete (not wrapped).
Wrap around
^^^^^^^^^^^
The following diagrams illustrate the differences between no-split, allow-split, and byte
buffers when a sent item requires a wrap around. The diagrams assumes a buffer of **128 bytes**
The following diagrams illustrate the differences between No-Split, Allow-Split, and byte
buffers when a sent item requires a wrap around. The diagrams assume a buffer of **128 bytes**
with **56 bytes of free space that wraps around** and a sent item of **28 bytes**.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_wrap_no_split.diag
:caption: Wrap around in no-split buffers
:caption: Wrap around in No-Split buffers
:align: center
No-split buffers will **only store an item in continuous free space and will not split
No-Split buffers will **only store an item in continuous free space and will not split
an item under any circumstances**. When the free space at the tail of the buffer is insufficient
to completely store the item and its header, the free space at the tail will be **marked as dummy data**.
The buffer will then wrap around and store the item in the free space at the head of the buffer.
Referring to the diagram above, the 16 bytes of free space at the tail of the buffer is
insufficient to store the 28 byte item. Therefore the 16 bytes is marked as dummy data and
insufficient to store the 28 byte item. Therefore, the 16 bytes is marked as dummy data and
the item is written to the free space at the head of the buffer instead.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_wrap_allow_split.diag
:caption: Wrap around in allow-split buffers
:caption: Wrap around in Allow-Split buffers
:align: center
Allow-split buffers will attempt to **split the item into two parts** when the free space at the tail
Allow-Split buffers will attempt to **split the item into two parts** when the free space at the tail
of the buffer is insufficient to store the item data and its header. Both parts of the
split item will have their own headers (therefore incurring an extra 8 bytes of overhead).
Referring to the diagram above, the 16 bytes of free space at the tail of the buffer is insufficient
to store the 28 byte item. Therefore the item is split into two parts (8 and 20 bytes) and written
to store the 28 byte item. Therefore, the item is split into two parts (8 and 20 bytes) and written
as two parts to the buffer.
.. note::
Allow-split buffers treats the both parts of the split item as two separate items, therefore call
Allow-Split buffers treat both parts of the split item as two separate items, therefore call
:cpp:func:`xRingbufferReceiveSplit` instead of :cpp:func:`xRingbufferReceive` to receive both
parts of a split item in a thread safe manner.
@ -319,30 +319,30 @@ data will then be stored in the free space at the head of the buffer. No overhea
around in byte buffers.
Referring to the diagram above, the 16 bytes of free space at the tail of the buffer is insufficient to
completely store the 28 bytes of data. Therefore the 16 bytes of free space is filled with data, and the
completely store the 28 bytes of data. Therefore, the 16 bytes of free space is filled with data, and the
remaining 12 bytes are written to the free space at the head of the buffer. The buffer now contains
data in two separate continuous parts, and each part continuous will be treated as a separate item by the
data in two separate continuous parts, and each continuous part will be treated as a separate item by the
byte buffer.
Retrieving/Returning
^^^^^^^^^^^^^^^^^^^^
The following diagrams illustrates the differences between no-split/allow-split and
The following diagrams illustrate the differences between No-Split and Allow-Split buffers as compared to
byte buffers in retrieving and returning data.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_read_ret_non_byte_buf.diag
:caption: Retrieving/Returning items in no-split/allow-split ring buffers
:caption: Retrieving/Returning items in No-Split and Allow-Split ring buffers
:align: center
Items in no-split/allow-split buffers are **retrieved in strict FIFO order** and **must be returned**
Items in No-Split buffers and Allow-Split buffers are **retrieved in strict FIFO order** and **must be returned**
for the occupied space to be freed. Multiple items can be retrieved before returning, and the items
do not necessarily need to be returned in the order they were retrieved. However the freeing of space
do not necessarily need to be returned in the order they were retrieved. However, the freeing of space
must occur in FIFO order, therefore not returning the earliest retrieved item will prevent the space
of subsequent items from being freed.
Referring to the diagram above, the **16, 20, and 8 byte items are retrieved in FIFO order**. However the items
are not returned in they were retrieved (20, 8, 16). As such, the space is not freed until the first item
(16 byte) is returned.
Referring to the diagram above, the **16, 20, and 8 byte items are retrieved in FIFO order**. However, the items
are not returned in the order they were retrieved. First, the 20 byte item is returned followed by the 8 byte and the 16
byte items. The space is not freed until the first item, i.e., the 16 byte item is returned.
.. packetdiag:: ../../../_static/diagrams/ring-buffer/ring_buffer_read_ret_byte_buf.diag
:caption: Retrieving/Returning data in byte buffers
@ -408,7 +408,7 @@ Ring Buffers with Static Allocation
The :cpp:func:`xRingbufferCreateStatic` can be used to create ring buffers with specific memory requirements (such as a ring buffer being allocated in external RAM). All blocks of memory used by a ring buffer must be manually allocated beforehand then passed to the :cpp:func:`xRingbufferCreateStatic` to be initialized as a ring buffer. These blocks include the following:
- The ring buffer's data structure of type :cpp:type:`StaticRingbuffer_t`
- The ring buffer's storage area of size ``xBufferSize``. Note that ``xBufferSize`` must be 32-bit aligned for no-split/allow-split buffers.
- The ring buffer's storage area of size ``xBufferSize``. Note that ``xBufferSize`` must be 32-bit aligned for No-Split and Allow-Split buffers.
The manner in which these blocks are allocated will depend on the users requirements (e.g. all blocks being statically declared, or dynamically allocated with specific capabilities such as external RAM).
@ -460,11 +460,11 @@ Ring Buffer API Reference
this should prevent any lower priority tasks from being serviced as the semaphore should
always be given to the highest priority task.
However in between iterations of acquiring the semaphore, there is a **gap in the critical
However, in between iterations of acquiring the semaphore, there is a **gap in the critical
section** which may permit another task (on the other core or with an even higher priority) to
free some space on the ring buffer and as a result give the semaphore. Therefore the semaphore
free some space on the ring buffer and as a result give the semaphore. Therefore, the semaphore
will be given before the highest priority task can re-acquire the semaphore. This will result
in the **semaphore being acquired by the second highest priority task** waiting to send, hence
in the **semaphore being acquired by the second-highest priority task** waiting to send, hence
causing priority inversion.
This side effect will not affect ring buffer performance drastically given if the number
@ -482,7 +482,7 @@ Hooks
FreeRTOS consists of Idle Hooks and Tick Hooks which allow for application
specific functionality to be added to the Idle Task and Tick Interrupt.
ESP-IDF provides its own Idle and Tick Hook API in addition to the hooks
provided by Vanilla FreeRTOS. ESP-IDF hooks have the added benefit of
provided by vanilla FreeRTOS. ESP-IDF hooks have the added benefit of
being run time configurable and asymmetrical.
Vanilla FreeRTOS Hooks
@ -501,7 +501,7 @@ in :doc:`project configuration menu </api-reference/kconfig>`.
.. only:: not CONFIG_FREERTOS_UNICORE
Due to vanilla FreeRTOS being designed for single core, ``vApplicationIdleHook()``
and ``vApplicationTickHook()`` can only be defined once. However, the {IDF_TARGET_NAME} is dual core
and ``vApplicationTickHook()`` can only be defined once. However, the {IDF_TARGET_NAME} is dual-core
in nature, therefore same Idle Hook and Tick Hook are used for both cores (in other words,
the hooks are symmetrical for both cores).
@ -513,15 +513,15 @@ that are configurable at run time.
.. only:: not CONFIG_FREERTOS_UNICORE
Furthermore, due to the the dual core nature of the {IDF_TARGET_NAME}, it may be necessary for some
Furthermore, due to the dual-core nature of the {IDF_TARGET_NAME}, it may be necessary for some
applications to have separate hooks for each core.
Therefore the ESP-IDF provides it's own hooks API in addition to the legacy hooks provided
by Vanilla FreeRTOS.
Therefore, ESP-IDF provides its own hooks API in addition to the legacy hooks provided
by vanilla FreeRTOS.
The ESP-IDF tick/idle hooks are registered at run time, and each tick/idle hook
must be registered to a specific CPU. When the idle task runs/tick Interrupt
occurs on a particular CPU, the CPU will run each of its registered idle/tick hooks
The ESP-IDF tick and idle hooks are registered at run time. Each tick hook and idle hook
must be registered to a specific CPU. When the idle task runs or a tick interrupt
occurs on a particular CPU, the CPU will run each of its registered idle hook and tick hook
in turn.
.. note:: Tick interrupt stays active whilst cache is disabled and hence ``vApplicationTickHook()`` (legacy case) or ESP-IDF tick hooks must be placed in internal RAM. Please refer to the :ref:`SPI flash API documentation <iram-safe-interrupt-handlers>` for more details.
@ -538,6 +538,6 @@ Hooks API Reference
Component Specific Properties
-----------------------------
Besides standard component variables that could be gotten with basic cmake build properties FreeRTOS component also provides an arguments (only one so far) for simpler integration with other modules:
Besides standard component variables that are available with basic cmake build properties, FreeRTOS component also provides arguments (only one so far) for simpler integration with other modules:
- `ORIG_INCLUDE_PATH` - contains an absolute path to freertos root include folder. Thus instead of `#include "freertos/FreeRTOS.h"` you can refer to headers directly: `#include "FreeRTOS.h"`.

View File

@ -18,7 +18,7 @@ To obtain information about the state of the heap:
- :cpp:func:`xPortGetFreeHeapSize` is a FreeRTOS function which returns the number of free bytes in the (data memory) heap. This is equivalent to calling ``heap_caps_get_free_size(MALLOC_CAP_8BIT)``.
- :cpp:func:`heap_caps_get_free_size` can also be used to return the current free memory for different memory capabilities.
- :cpp:func:`heap_caps_get_largest_free_block` can be used to return the largest free block in the heap. This is the largest single allocation which is currently possible. Tracking this value and comparing to total free heap allows you to detect heap fragmentation.
- :cpp:func:`xPortGetMinimumEverFreeHeapSize` and the related :cpp:func:`heap_caps_get_minimum_free_size` can be used to track the heap "low water mark" since boot.
- :cpp:func:`xPortGetMinimumEverFreeHeapSize` and the related :cpp:func:`heap_caps_get_minimum_free_size` can be used to track the heap "low watermark" since boot.
- :cpp:func:`heap_caps_get_info` returns a :cpp:class:`multi_heap_info_t` structure which contains the information from the above functions, plus some additional heap-specific data (number of allocations, etc.).
- :cpp:func:`heap_caps_print_heap_info` prints a summary to stdout of the information returned by :cpp:func:`heap_caps_get_info`.
- :cpp:func:`heap_caps_dump` and :cpp:func:`heap_caps_dump_all` will output detailed information about the structure of each block in the heap. Note that this can be large amount of output.
@ -47,13 +47,13 @@ It's also possible to manually check heap integrity by calling :cpp:func:`heap_c
Memory Allocation Failed Hook
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Users can use :cpp:func:`heap_caps_register_failed_alloc_callback` to register a callback that will be invoked every time a allocation
Users can use :cpp:func:`heap_caps_register_failed_alloc_callback` to register a callback that will be invoked every time an allocation
operation fails.
Additionaly user can enable a generation of a system abort if allocation operation fails by following the steps below:
Additionally, users can enable the generation of a system abort if an allocation operation fails by following the steps below:
- In the project configuration menu, navigate to ``Component config`` -> ``Heap Memory Debugging`` and select ``Abort if memory allocation fails`` option (see :ref:`CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS`).
The example below show how to register a allocation failure callback::
The example below shows how to register an allocation failure callback::
#include "esp_heap_caps.h"
@ -80,7 +80,7 @@ Memory corruption can be one of the hardest classes of bugs to find and fix, as
- Increasing the Heap memory debugging `Configuration`_ level to "Light impact" or "Comprehensive" can give you a more accurate message with the first corrupt memory address.
- Adding regular calls to :cpp:func:`heap_caps_check_integrity_all` or :cpp:func:`heap_caps_check_integrity_addr` in your code will help you pin down the exact time that the corruption happened. You can move these checks around to "close in on" the section of code that corrupted the heap.
- Based on the memory address which is being corrupted, you can use :ref:`JTAG debugging <jtag-debugging-introduction>` to set a watchpoint on this address and have the CPU halt when it is written to.
- If you don't have JTAG, but you do know roughly when the corruption happens, then you can set a watchpoint in software just beforehand via :cpp:func:`esp_cpu_set_watchpoint`. A fatal exception will occur when the watchpoint triggers. For example ``esp_cpu_set_watchpoint(0, (void *)addr, 4, ESP_WATCHPOINT_STORE``. Note that watchpoints are per-CPU and are set on the current running CPU only, so if you don't know which CPU is corrupting memory then you will need to call this function on both CPUs.
- If you don't have JTAG, but you do know roughly when the corruption happens, then you can set a watchpoint in software just beforehand via :cpp:func:`esp_cpu_set_watchpoint`. A fatal exception will occur when the watchpoint triggers. The following is an example of how to use the function - ``esp_cpu_set_watchpoint(0, (void *)addr, 4, ESP_WATCHPOINT_STORE)``. Note that watchpoints are per-CPU and are set on the current running CPU only, so if you don't know which CPU is corrupting memory then you will need to call this function on both CPUs.
- For buffer overflows, `heap tracing`_ in ``HEAP_TRACE_ALL`` mode lets you see which callers are allocating which addresses from the heap. See `Heap Tracing To Find Heap Corruption`_ for more details. If you can find the function which allocates memory with an address immediately before the address which is corrupted, this will probably be the function which overflows the buffer.
- Calling :cpp:func:`heap_caps_dump` or :cpp:func:`heap_caps_dump_all` can give an indication of what heap blocks are surrounding the corrupted region and may have overflowed/underflowed/etc.
@ -125,7 +125,7 @@ Comprehensive
This level incorporates the "light impact" detection features plus additional checks for uninitialised-access and use-after-free bugs. In this mode, all freshly allocated memory is filled with the pattern 0xCE, and all freed memory is filled with the pattern 0xFE.
Enabling "Comprehensive" detection has a substantial runtime performance impact (as all memory needs to be set to the allocation patterns each time a malloc/free completes, and the memory also needs to be checked each time.) However it allows easier detection of memory corruption bugs which are much more subtle to find otherwise. It is recommended to only enable this mode when debugging, not in production.
Enabling "Comprehensive" detection has a substantial runtime performance impact (as all memory needs to be set to the allocation patterns each time a malloc/free completes, and the memory also needs to be checked each time.) However, it allows easier detection of memory corruption bugs which are much more subtle to find otherwise. It is recommended to only enable this mode when debugging, not in production.
Crashes in Comprehensive Mode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -251,7 +251,7 @@ In ``HEAP_TRACE_LEAKS`` mode, for each traced memory allocation which has not al
.. list::
- ``XX bytes`` is number of bytes allocated
- ``XX bytes`` is the number of bytes allocated
- ``@ 0x...`` is the heap address returned from malloc/calloc.
- ``CPU x`` is the CPU (0 or 1) running when the allocation was made.
- ``ccount 0x...`` is the CCOUNT (CPU cycle count) register value when the allocation was mode. Is different for CPU 0 vs CPU 1.
@ -276,7 +276,7 @@ Once you've identified the code which you think is leaking:
- In the project configuration menu, navigate to ``Component settings`` -> ``Application Level Tracing`` -> ``FreeRTOS SystemView Tracing`` and enable :ref:`CONFIG_APPTRACE_SV_ENABLE`.
- Call the function :cpp:func:`heap_trace_init_tohost` early in the program, to initialize JTAG heap tracing module.
- Call the function :cpp:func:`heap_trace_start` to begin recording all mallocs/frees in the system. Call this immediately before the piece of code which you suspect is leaking memory.
In host-based mode argument to this function is ignored and heap tracing module behaves like ``HEAP_TRACE_ALL`` was passed: all allocations and deallocations are sent to the host.
In host-based mode, the argument to this function is ignored, and the heap tracing module behaves like ``HEAP_TRACE_ALL`` was passed: all allocations and deallocations are sent to the host.
- Call the function :cpp:func:`heap_trace_stop` to stop the trace once the suspect piece of code has finished executing.
An example::
@ -428,7 +428,7 @@ Heap Tracing To Find Heap Corruption
Heap tracing can also be used to help track down heap corruption. When a region in heap is corrupted, it may be from some other part of the program which allocated memory at a nearby address.
If you have some idea at what time the corruption occurred, enabling heap tracing in ``HEAP_TRACE_ALL`` mode allows you to record all of the functions which allocated memory, and the addresses of the allocations.
If you have some idea at what time the corruption occurred, enabling heap tracing in ``HEAP_TRACE_ALL`` mode allows you to record all the functions which allocated memory, and the addresses of the allocations.
Using heap tracing in this way is very similar to memory leak detection as described above. For memory which is allocated and not freed, the output is the same. However, records will also be shown for memory which has been freed.
@ -448,7 +448,7 @@ Not everything printed by :cpp:func:`heap_trace_dump` is necessarily a memory le
- Allocations may be made by other tasks in the system. Depending on the timing of these tasks, it's quite possible this memory is freed after :cpp:func:`heap_trace_stop` is called.
- The first time a task uses stdio - for example, when it calls ``printf()`` - a lock (RTOS mutex semaphore) is allocated by the libc. This allocation lasts until the task is deleted.
- Certain uses of ``printf()``, such as printing floating point numbers, will allocate some memory from the heap on demand. These allocations last until the task is deleted.
- The Bluetooth, WiFi, and TCP/IP libraries will allocate heap memory buffers to handle incoming or outgoing data. These memory buffers are usually short lived, but some may be shown in the heap leak trace if the data was received/transmitted by the lower levels of the network while the leak trace was running.
- The Bluetooth, Wi-Fi, and TCP/IP libraries will allocate heap memory buffers to handle incoming or outgoing data. These memory buffers are usually short-lived, but some may be shown in the heap leak trace if the data was received/transmitted by the lower levels of the network while the leak trace was running.
- TCP connections will continue to use some memory after they are closed, because of the ``TIME_WAIT`` state. After the ``TIME_WAIT`` period has completed, this memory will be freed.
One way to differentiate between "real" and "false positive" memory leaks is to call the suspect code multiple times while tracing is running, and look for patterns (multiple matching allocations) in the heap trace output.

View File

@ -3,7 +3,7 @@
Application Example
-------------------
The logging library is commonly used by most esp-idf components and examples. For demonstration of log functionality, check ESP-IDF's :idf:`examples` directory. The most revelant examples that deal with logging are the following:
The logging library is commonly used by most esp-idf components and examples. For demonstration of log functionality, check ESP-IDF's :idf:`examples` directory. The most relevant examples that deal with logging are the following:
* :example:`system/ota`
* :example:`storage/sd_card`

View File

@ -18,7 +18,7 @@ OTA Data Partition
An OTA data partition (type ``data``, subtype ``ota``) must be included in the :doc:`Partition Table <../../api-guides/partition-tables>` of any project which uses the OTA functions.
For factory boot settings, the OTA data partition should contain no data (all bytes erased to 0xFF). In this case the esp-idf software bootloader will boot the factory app if it is present in the the partition table. If no factory app is included in the partition table, the first available OTA slot (usually ``ota_0``) is booted.
For factory boot settings, the OTA data partition should contain no data (all bytes erased to 0xFF). In this case the esp-idf software bootloader will boot the factory app if it is present in the partition table. If no factory app is included in the partition table, the first available OTA slot (usually ``ota_0``) is booted.
After the first OTA update, the OTA data partition is updated to specify which OTA app slot partition should be booted next.
@ -35,7 +35,7 @@ The main purpose of the application rollback is to keep the device working after
* The application has critical errors and further work is not possible, a rollback to the previous application is required, :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` marks the running application with the state ``ESP_OTA_IMG_INVALID`` and reset. This application will not be selected by the bootloader for boot and will boot the previously working application.
* If the :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set, and a reset occurs without calling either function then the application is rolled back.
Note: The state is not written to the binary image of the application it is written to the ``otadata`` partition. The partition contains a ``ota_seq`` counter which is a pointer to the slot (ota_0, ota_1, ...) from which the application will be selected for boot.
.. note:: The state is not written to the binary image of the application but rather to the ``otadata`` partition. The partition contains a ``ota_seq`` counter which is a pointer to the slot (ota_0, ota_1, ...) from which the application will be selected for boot.
App OTA State
^^^^^^^^^^^^^
@ -53,7 +53,7 @@ States control the process of selecting a boot app:
be selected only once. In bootloader the state immediately changes to
``ESP_OTA_IMG_PENDING_VERIFY``.
ESP_OTA_IMG_PENDING_VERIFY If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is set it will
not be selected and the state will change to ``ESP_OTA_IMG_ABORTED``.
not be selected, and the state will change to ``ESP_OTA_IMG_ABORTED``.
============================= ======================================================================
If :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is not enabled (by default), then the use of the following functions :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` and :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` are optional, and ``ESP_OTA_IMG_NEW`` and ``ESP_OTA_IMG_PENDING_VERIFY`` states are not used.
@ -65,11 +65,11 @@ Rollback Process
The description of the rollback process when :ref:`CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE` option is enabled:
* The new application successfully downloaded and :cpp:func:`esp_ota_set_boot_partition` function makes this partition bootable and sets the state ``ESP_OTA_IMG_NEW``. This state means that the application is new and should be monitored for its first boot.
* The new application is successfully downloaded and :cpp:func:`esp_ota_set_boot_partition` function makes this partition bootable and sets the state ``ESP_OTA_IMG_NEW``. This state means that the application is new and should be monitored for its first boot.
* Reboot :cpp:func:`esp_restart`.
* The bootloader checks for the ``ESP_OTA_IMG_PENDING_VERIFY`` state if it is set, then it will be written to ``ESP_OTA_IMG_ABORTED``.
* The bootloader selects a new application to boot so that the state is not set as ``ESP_OTA_IMG_INVALID`` or ``ESP_OTA_IMG_ABORTED``.
* The bootloader checks the selected application for ``ESP_OTA_IMG_NEW`` state if it is set, then it will be written to ``ESP_OTA_IMG_PENDING_VERIFY``. This state means that the application requires confirmation of its operability, if this does not happen and a reboot occurs, this state will be overwritten to ``ESP_OTA_IMG_ABORTED`` (see above) and this application will no longer be able to start, i.e. there will be a rollback to the previous work application.
* The bootloader checks the selected application for ``ESP_OTA_IMG_NEW`` state if it is set, then it will be written to ``ESP_OTA_IMG_PENDING_VERIFY``. This state means that the application requires confirmation of its operability, if this does not happen and a reboot occurs, this state will be overwritten to ``ESP_OTA_IMG_ABORTED`` (see above) and this application will no longer be able to start, i.e. there will be a rollback to the previous working application.
* A new application has started and should make a self-test.
* If the self-test has completed successfully, then you must call the function :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` because the application is awaiting confirmation of operability (``ESP_OTA_IMG_PENDING_VERIFY`` state).
* If the self-test fails then call :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` function to roll back to the previous working application, while the invalid application is set ``ESP_OTA_IMG_INVALID`` state.
@ -128,12 +128,12 @@ A typical anti-rollback scheme is
- To make it bootable, run the function :cpp:func:`esp_ota_set_boot_partition`. If the security version of the new application is smaller than the version in the chip, the new application will be erased. Update to new firmware is not possible.
- Reboot.
- In the bootloader, an application with a security version greater than or equal to the version in the chip will be selected. If otadata is in the initial state, and one firmware was loaded via a serial channel, whose secure version is higher than the chip, then the secure version of efuse will be immediately updated in the bootloader.
- New application booted. Then the application should perform diagnostics of the operation and if it is completed successfully, you should call :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` function to mark the running application with the ``ESP_OTA_IMG_VALID`` state and update the secure version on chip. Note that if was called :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` function a rollback may not happend due to the device may not have any bootable apps then it will return ``ESP_ERR_OTA_ROLLBACK_FAILED`` error and stay in the ``ESP_OTA_IMG_PENDING_VERIFY`` state.
- New application booted. Then the application should perform diagnostics of the operation and if it is completed successfully, you should call :cpp:func:`esp_ota_mark_app_valid_cancel_rollback` function to mark the running application with the ``ESP_OTA_IMG_VALID`` state and update the secure version on chip. Note that if was called :cpp:func:`esp_ota_mark_app_invalid_rollback_and_reboot` function a rollback may not happen as the device may not have any bootable apps. It will then return ``ESP_ERR_OTA_ROLLBACK_FAILED`` error and stay in the ``ESP_OTA_IMG_PENDING_VERIFY`` state.
- The next update of app is possible if a running app is in the ``ESP_OTA_IMG_VALID`` state.
Recommendation:
If you want to avoid the download/erase overhead in case of the app from the server has security version lower then running app, you have to get ``new_app_info.secure_version`` from the first package of an image and compare it with the secure version of efuse. Use ``esp_efuse_check_secure_version(new_app_info.secure_version)`` function if it is true then continue downloading otherwise abort.
If you want to avoid the download/erase overhead in case of the app from the server has security version lower than the running app, you have to get ``new_app_info.secure_version`` from the first package of an image and compare it with the secure version of efuse. Use ``esp_efuse_check_secure_version(new_app_info.secure_version)`` function if it is true then continue downloading otherwise abort.
.. code-block:: c

View File

@ -21,7 +21,7 @@ Unlike many operating systems using POSIX Threads, ESP-IDF is a real-time operat
If calling a standard libc or C++ sleep function, such as ``usleep`` defined in ``unistd.h``, then the task will only block and yield the CPU if the sleep time is longer than :ref:`one FreeRTOS tick period <CONFIG_FREERTOS_HZ>`. If the time is shorter, the thread will busy-wait instead of yielding to another RTOS task.
By default all POSIX Threads have the same RTOS priority, but it is possible to change this by calling a :ref:`custom API <esp-pthread>`.
By default, all POSIX Threads have the same RTOS priority, but it is possible to change this by calling a :ref:`custom API <esp-pthread>`.
Standard features
-----------------
@ -98,6 +98,20 @@ Static initializer constant ``PTHREAD_COND_INITIALIZER`` is supported.
.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs
Read/Write Locks
^^^^^^^^^^^^^^^^^^^
* ``pthread_rwlock_init()``
- The ``attr`` argument is not implemented and is ignored.
* ``pthread_rwlock_destroy()``
* ``pthread_rwlock_rdlock()``
* ``pthread_rwlock_wrlock()``
* ``pthread_rwlock_unlock()``
Static initializer constant ``PTHREAD_RWLOCK_INITIALIZER`` is supported.
.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs
Thread-Specific Data
^^^^^^^^^^^^^^^^^^^^
@ -125,7 +139,7 @@ Other POSIX Threads functions (not listed here) are not implemented and will pro
ESP-IDF Extensions
------------------
The API :cpp:func:`esp_pthread_set_cfg` defined in the ``esp_pthreads.h`` header offers custom extensions to control how subsequent calls to ``pthread_create()`` will behave. Currently the following configuration can be set:
The API :cpp:func:`esp_pthread_set_cfg` defined in the ``esp_pthreads.h`` header offers custom extensions to control how subsequent calls to ``pthread_create()`` will behave. Currently, the following configuration can be set:
.. list::
- Default stack size of new threads, if not specified when calling ``pthread_create()`` (overrides :ref:`CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT`).

View File

@ -89,7 +89,7 @@ In ESP-IDF these addresses are calculated from a single *Base MAC address*. By d
.. only:: not SOC_EMAC_SUPPORTED
.. note:: {IDF_TARGET_NAME} has no integrated Ethernet MAC, but it's still possible to calculate an Ethernet MAC address. This MAC address can only be used with an external interface such as a SPI-Ethernet device, see :doc:`/api-reference/network/esp_eth`.
.. note:: {IDF_TARGET_NAME} has no integrated Ethernet MAC, but it's still possible to calculate an Ethernet MAC address. This MAC address can only be used with an external interface such as an SPI-Ethernet device, see :doc:`/api-reference/network/esp_eth`.
Custom Base MAC
^^^^^^^^^^^^^^^
@ -147,7 +147,7 @@ Once MAC address has been obtained using :cpp:func:`esp_efuse_mac_get_custom`, c
Local vs Universal MAC addresses
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} comes pre-programmed with enough valid Espressif universally administered MAC addresses for all internal interfaces. The specific calculations to derive an interface's MAC address from the base MAC address is shown in the table above..
{IDF_TARGET_NAME} comes pre-programmed with enough valid Espressif universally administered MAC addresses for all internal interfaces. The specific calculations to derive an interface's MAC address from the base MAC address is shown in the table above.
When using a custom MAC address scheme, it's possible that not all interfaces can be assigned a universally administered MAC address. In these cases, a locally administered MAC address is assigned. Note that these addresses are intended for use on a single local network, only.
@ -196,7 +196,7 @@ To set version in your project manually you need to set ``PROJECT_VER`` variable
* In application CMakeLists.txt put ``set(PROJECT_VER "0.1.0.1")`` before including ``project.cmake``.
If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise if ``PROJECT_VER`` variable is not set in the project then it will be retrieved from either ``$(PROJECT_PATH)/version.txt`` file (if present) else using git command ``git describe``. If neither is available then ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions.
If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. Otherwise, if ``PROJECT_VER`` variable is not set in the project then it will be retrieved from either ``$(PROJECT_PATH)/version.txt`` file (if present) else using git command ``git describe``. If neither is available then ``PROJECT_VER`` will be set to "1". Application can make use of this by calling :cpp:func:`esp_ota_get_app_description` or :cpp:func:`esp_ota_get_partition_description` functions.
API Reference
-------------

View File

@ -2,7 +2,7 @@ System Time
===========
{IDF_TARGET_RTC_CLK_FRE:default="150kHz", esp32s2="90kHz"}
{IDF_TARGET_HARDWARE_DESIGN_URL:default="`ESP32 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32_hardware_design_guidelines_en.pdf#page=10>`_", esp32="`ESP32 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32_hardware_design_guidelines_en.pdf#page=10>`_", esp32s2="`ESP32-S2 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32-s2_hardware_design_guidelines_en.pdf#page=10>`_"}
{IDF_TARGET_HARDWARE_DESIGN_URL:default="`ESP32 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32_hardware_design_guidelines_en.pdf#page=10>`_", esp32="`ESP32 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32_hardware_design_guidelines_en.pdf#page=10>`_", esp32s2="`ESP32-S2 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32-s2_hardware_design_guidelines_en.pdf#page=10>`_", esp32s3="`ESP32-S3 Hardware Design Guidelines <https://www.espressif.com/sites/default/files/documentation/esp32-s3_hardware_design_guidelines_en.pdf#page=11>`"}
Overview
--------
@ -30,7 +30,7 @@ RTC Clock Source
The RTC timer has the following clock sources:
- ``Internal {IDF_TARGET_RTC_CLK_FRE} RC oscillator`` (default): Features lowest deep sleep current consumption and no dependence on any external components. However, as frequency stability is affected by temperature fluctuations, time may drift in both Deep and Light sleep modes.
- ``Internal {IDF_TARGET_RTC_CLK_FRE} RC oscillator`` (default): Features the lowest deep sleep current consumption and no dependence on any external components. However, as frequency stability is affected by temperature fluctuations, time may drift in both Deep and Light sleep modes.
- ``External 32kHz crystal``: Requires a 32kHz crystal to be connected to the 32K_XP and 32K_XN pins. Provides better frequency stability at the expense of slightly higher (by 1 uA) Deep sleep current consumption.
@ -99,7 +99,7 @@ To set the current time, you can use the POSIX functions ``settimeofday()`` and
A function to use inside the lwIP SNTP library depends on a sync mode for system time. Use the function :cpp:func:`sntp_set_sync_mode` to set one of the following sync modes:
- ``SNTP_SYNC_MODE_IMMED`` (default) updates system time immediately upon receiving a response from the SNTP server after using ``settimeofday()``.
- ``SNTP_SYNC_MODE_SMOOTH`` updates time smoothly by gradually reducing time error using the funcion ``adjtime()``. If the difference between the SNTP response time and system time is more than 35 minutes, update system time immediately by using ``settimeofday()``.
- ``SNTP_SYNC_MODE_SMOOTH`` updates time smoothly by gradually reducing time error using the function ``adjtime()``. If the difference between the SNTP response time and system time is more than 35 minutes, update system time immediately by using ``settimeofday()``.
The lwIP SNTP library has API functions for setting a callback function for a certain event. You might need the following functions:

View File

@ -1,16 +1,8 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
@ -62,8 +54,8 @@ void app_main(void)
.bits_per_sample = 16,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
.communication_format = I2S_COMM_FORMAT_STAND_MSB,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.intr_alloc_flags = 0, //Default interrupt priority
.tx_desc_auto_clear = true //Auto clear tx descriptor on underflow
};

View File

@ -693,8 +693,8 @@ void app_main(void)
.sample_rate = 44100,
.bits_per_sample = 16,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.intr_alloc_flags = 0, //Default interrupt priority
.tx_desc_auto_clear = true //Auto clear tx descriptor on underflow
};

View File

@ -69,8 +69,8 @@ void example_i2s_init(void)
.communication_format = I2S_COMM_FORMAT_STAND_MSB,
.channel_format = EXAMPLE_I2S_FORMAT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.use_apll = 1,
};
//install and start i2s driver

View File

@ -75,7 +75,7 @@ Running this example, you will see the Bits per Sample changes every 5 seconds a
```
I (361) pdm_rec_example: PDM microphone recording Example start
I (371) I2S: DMA Malloc info, datalen=blocksize=2048, dma_buf_count=64
I (371) I2S: DMA Malloc info, datalen=blocksize=2048, dma_desc_num=64
I (401) I2S: APLL: Req RATE: 44100, real rate: 88199.977, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 22579194.000, SCLK: 2822399.250000, diva: 1, divb: 0
I (431) I2S: APLL: Req RATE: 44100, real rate: 88199.977, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 22579194.000, SCLK: 2822399.250000, diva: 1, divb: 0
I (431) pdm_rec_example: Initializing SD card

View File

@ -173,8 +173,8 @@ void init_microphone(void)
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2,
.dma_buf_count = 8,
.dma_buf_len = 200,
.dma_desc_num = 8,
.dma_frame_num = 200,
.use_apll = 0,
};

View File

@ -38,15 +38,15 @@ Running this example, you will see the Bits per Sample changes every 5 seconds a
```
Test bits=24 free mem=293780, written data=2880
I2S: DMA Malloc info, datalen=blocksize=480, dma_buf_count=6
I2S: DMA Malloc info, datalen=blocksize=480, dma_desc_num=6
I2S: PLL_D2: Req RATE: 36000, real rate: 37878.000, BITS: 24, CLKM: 11, BCK: 8, MCLK: 13837837.838, SCLK: 1818144.000000, diva: 64, divb: 36
Test bits=32 free mem=292336, written data=2880
I2S: DMA Malloc info, datalen=blocksize=480, dma_buf_count=6
I2S: DMA Malloc info, datalen=blocksize=480, dma_desc_num=6
I2S: PLL_D2: Req RATE: 36000, real rate: 36764.000, BITS: 32, CLKM: 17, BCK: 4, MCLK: 9216921.692, SCLK: 2352896.000000, diva: 64, divb: 23
Test bits=16 free mem=293772, written data=1440
I2S: DMA Malloc info, datalen=blocksize=240, dma_buf_count=6
I2S: DMA Malloc info, datalen=blocksize=240, dma_desc_num=6
I2S: PLL_D2: Req RATE: 36000, real rate: 36764.000, BITS: 16, CLKM: 17, BCK: 8, MCLK: 9216921.692, SCLK: 1176448.000000, diva: 64, divb: 23
```

View File

@ -96,8 +96,8 @@ void app_main(void)
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_MSB,
.dma_buf_count = 6,
.dma_buf_len = 60,
.dma_desc_num = 6,
.dma_frame_num = 60,
.use_apll = false,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1
};

View File

@ -94,8 +94,8 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
Running this example in music mode, you can hear a piece of music (canon), the log is shown as follow:
```
I (348) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=6
I (348) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=6
I (348) I2S: DMA Malloc info, datalen=blocksize=1200, dma_desc_num=6
I (348) I2S: DMA Malloc info, datalen=blocksize=1200, dma_desc_num=6
I (358) I2S: I2S0, MCLK output by GPIO0
I (368) DRV8311: ES8311 in Slave mode
I (378) gpio: GPIO[10]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
@ -106,8 +106,8 @@ I (7948) i2s_es8311: I2S music played, 213996 bytes are written.
Running this example in echo mode, you can hear the sound in earphone that collected by mic.
```
I (312) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=6
I (312) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=6
I (312) I2S: DMA Malloc info, datalen=blocksize=1200, dma_desc_num=6
I (312) I2S: DMA Malloc info, datalen=blocksize=1200, dma_desc_num=6
I (322) I2S: I2S0, MCLK output by GPIO0
I (332) DRV8311: ES8311 in Slave mode
I (342) gpio: GPIO[10]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0

View File

@ -100,8 +100,8 @@ static esp_err_t i2s_driver_init(void)
.bit_order_msb = false,
.skip_msk = false,
#endif
.dma_buf_count = 8,
.dma_buf_len = 64,
.dma_desc_num = 8,
.dma_frame_num = 64,
.use_apll = false,
.mclk_multiple = EXAMPLE_MCLK_MULTIPLE,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,

View File

@ -598,9 +598,7 @@ components/esp_event/event_loop_legacy.c
components/esp_event/event_send.c
components/esp_event/host_test/esp_event_unit_test/main/esp_event_test.cpp
components/esp_event/host_test/fixtures.hpp
components/esp_event/include/esp_event.h
components/esp_event/include/esp_event_base.h
components/esp_event/include/esp_event_legacy.h
components/esp_event/include/esp_event_loop.h
components/esp_event/private_include/esp_event_internal.h
components/esp_event/private_include/esp_event_private.h
@ -697,7 +695,6 @@ components/esp_pm/include/esp_private/pm_impl.h
components/esp_pm/include/esp_private/pm_trace.h
components/esp_pm/pm_locks.c
components/esp_pm/test/test_pm.c
components/esp_ringbuf/include/freertos/ringbuf.h
components/esp_rom/esp32/esp_rom_caps.h
components/esp_rom/esp32/ld/esp32.rom.api.ld
components/esp_rom/esp32/ld/esp32.rom.eco3.ld
@ -908,7 +905,6 @@ components/esp_system/include/esp_private/panic_internal.h
components/esp_system/include/esp_private/startup_internal.h
components/esp_system/include/esp_private/system_internal.h
components/esp_system/include/esp_private/usb_console.h
components/esp_system/include/esp_system.h
components/esp_system/include/esp_task.h
components/esp_system/include/esp_task_wdt.h
components/esp_system/port/arch/riscv/expression_with_stack.c
@ -1389,7 +1385,6 @@ components/heap/include/esp_heap_caps_init.h
components/heap/include/esp_heap_task_info.h
components/heap/include/esp_heap_trace.h
components/heap/include/heap_memory_layout.h
components/heap/include/multi_heap.h
components/heap/include/soc/soc_memory_layout.h
components/heap/multi_heap_config.h
components/heap/multi_heap_internal.h
@ -1424,7 +1419,6 @@ components/lwip/apps/sntp/sntp.c
components/lwip/include/apps/dhcpserver/dhcpserver.h
components/lwip/include/apps/dhcpserver/dhcpserver_options.h
components/lwip/include/apps/esp_ping.h
components/lwip/include/apps/esp_sntp.h
components/lwip/include/apps/ping/ping.h
components/lwip/include/apps/ping/ping_sock.h
components/lwip/include/apps/sntp/sntp.h
@ -2794,7 +2788,6 @@ examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.h
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.h
examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c
examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.c
examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/bt_app_core.h
examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c