bool "SOURCE"
endchoice
+config A2DP_SINK_TASK_STACK_SIZE
+ int "A2DP sink (audio stream decoding) task stack size"
+ depends on A2DP_ENABLE && A2DP_SINK_ENABLE
+ default 2048
+
+config A2DP_SOURCE_TASK_STACK_SIZE
+ int "A2DP source (audio stream encoding) task stack size"
+ depends on A2DP_ENABLE && A2DP_SRC_ENABLE
+ default 2048
+
config BT_SPP_ENABLED
bool "SPP"
depends on CLASSIC_BT_ENABLED
/**
* @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
* from SBC format. This function should be called only after esp_bluedroid_enable()
- * completes successfully, used only by A2DP sink.
+ * completes successfully, used only by A2DP sink. The callback is invoked in the context
+ * of A2DP sink task whose stack size is configurable through menuconfig
*
* @param[in] callback: A2DP sink data callback function
*
/**
* @brief Register A2DP source data input function; For now the input is PCM data stream.
* This function should be called only after esp_bluedroid_enable() completes
- * successfully
+ * successfully. The callback is invoked in the context of A2DP source task whose
+ * stack size is configurable through menuconfig
*
* @param[in] callback: A2DP source data callback function
*
hdr.layer_specific = xx + 1;
bta_av_api_deregister((tBTA_AV_DATA *)&hdr);
}
+
+ bta_sys_free_timer(&p_cb->sig_tmr);
+ memset(&p_cb->sig_tmr, 0, sizeof(TIMER_LIST_ENT));
+ bta_sys_free_timer(&p_cb->acp_sig_tmr);
+ memset(&p_cb->acp_sig_tmr, 0, sizeof(TIMER_LIST_ENT));
}
/*******************************************************************************
}
}
+/*******************************************************************************
+ *
+ * Function bta_dm_init_cb
+ *
+ * Description Initializes the bta_dm_cb control block
+ *
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void bta_dm_init_cb(void)
+{
+ memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
+}
+
+/*******************************************************************************
+ *
+ * Function bta_dm_deinit_cb
+ *
+ * Description De-initializes the bta_dm_cb control block
+ *
+ *
+ * Returns void
+ *
+ ******************************************************************************/
+void bta_dm_deinit_cb(void)
+{
+ bta_sys_free_timer(&bta_dm_cb.disable_timer);
+#if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
+ bta_sys_free_timer(&bta_dm_cb.app_ready_timer);
+#endif
+#if BTM_SSR_INCLUDED == TRUE
+ for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
+ for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
+ bta_sys_free_timer(&bta_dm_cb.pm_timer[i].timer[j]);
+ }
+ }
+#endif
+ memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
+}
+
/*******************************************************************************
**
** Function bta_dm_sys_hw_cback
}
/* reinitialize the control block */
- memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
+ bta_dm_deinit_cb();
+
+ bta_sys_free_timer(&bta_dm_search_cb.search_timer);
+#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
+ bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
+#endif
+#endif
+ memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
/* unregister from SYS */
bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
/* save security callback */
temp_cback = bta_dm_cb.p_sec_cback;
/* make sure the control block is properly initialized */
- memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
+ bta_dm_init_cb();
+
/* and retrieve the callback */
bta_dm_cb.p_sec_cback = temp_cback;
bta_dm_cb.is_bta_dm_active = TRUE;
+ bta_sys_free_timer(&bta_dm_search_cb.search_timer);
+#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
+#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
+ bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
+#endif
+#endif
/* hw is ready, go on with BTA DM initialization */
memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
#if (BTM_SSR_INCLUDED == TRUE)
#if GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE
-static osi_mutex_t write_ccc_mutex;
-
/*****************************************************************************
** Constants
*****************************************************************************/
memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
p_cb->state = BTA_GATTC_STATE_ENABLED;
// Create a write ccc mutex when the gatt client enable
- osi_mutex_new(&write_ccc_mutex);
+ osi_mutex_new(&bta_gattc_cb.write_ccc_mutex);
} else {
- APPL_TRACE_DEBUG("GATTC is arelady enabled");
+ APPL_TRACE_DEBUG("GATTC is already enabled");
}
}
return;
}
// Free the write ccc mutex when the gatt client disable
- osi_mutex_free(&write_ccc_mutex);
+ osi_mutex_free(&bta_gattc_cb.write_ccc_mutex);
for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
if (p_cb->cl_rcb[i].in_use) {
else if ((transport == BT_TRANSPORT_LE) && (connected == FALSE) && (p_conn != NULL)){
p_conn->service_change_ccc_written = FALSE;
if (p_conn->ccc_timer_used == TRUE){
- assert(write_ccc_mutex != NULL);
- osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ assert(bta_gattc_cb.write_ccc_mutex != NULL);
+ osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
if (p_conn->service_change_ccc_timer.param != 0) {
osi_free((void *)p_conn->service_change_ccc_timer.param);
}
bta_sys_stop_timer(&(p_conn->service_change_ccc_timer));
p_conn->ccc_timer_used = FALSE;
- osi_mutex_unlock(&write_ccc_mutex);
+ osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
}
}
BOOLEAN start_ccc_timer = FALSE;
UINT32 new_timeout;
- assert(write_ccc_mutex != NULL);
- osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ assert(bta_gattc_cb.write_ccc_mutex != NULL);
+ osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) p_tle->param;
p_tle->param = (TIMER_PARAM_TYPE)0;
if (p_timer_param == NULL){
APPL_TRACE_ERROR("p_timer_param is NULL in %s\n", __func__);
- osi_mutex_unlock(&write_ccc_mutex);
+ osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return;
}
if (p_conn == NULL){
APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
osi_free(p_timer_param);
- osi_mutex_unlock(&write_ccc_mutex);
+ osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return;
}
}
osi_free(p_timer_param);
- osi_mutex_unlock(&write_ccc_mutex);
+ osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
}
#endif
if (p_conn != NULL) {
p_conn->in_use = FALSE;
memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
+ osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
+ bta_sys_free_timer(&p_conn->service_change_ccc_timer);
+ p_conn->ccc_timer_used = FALSE;
+ osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return TRUE;
}
return FALSE;
#include "bta_gattc_ci.h"
#include "bta_gattc_co.h"
#include "fixed_queue.h"
+#include "mutex.h"
/*****************************************************************************
** Constants and data types
};
typedef struct {
- UINT8 state;
-
+ UINT8 state;
+ osi_mutex_t write_ccc_mutex;
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
extern void bta_sys_sendmsg(void *p_msg);
extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms);
extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle);
+extern void bta_sys_free_timer(TIMER_LIST_ENT *p_tle);
extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle);
osi_alarm_cancel(alarm);
}
+/*******************************************************************************
+**
+** Function bta_sys_free_timer
+**
+** Description Stop and free a BTA timer.
+**
+** Returns void
+**
+*******************************************************************************/
+void bta_sys_free_timer(TIMER_LIST_ENT *p_tle)
+{
+ assert(p_tle != NULL);
+
+ osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
+ if (alarm == NULL) {
+ LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
+ return;
+ }
+ osi_alarm_cancel(alarm);
+ hash_map_erase(bta_alarm_hash_map, p_tle);
+}
+
/*******************************************************************************
**
** Function bta_sys_disable
APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
- btc_aa_snk_queue_set = xQueueCreateSet(BTC_MEDIA_TASK_QUEUE_SET_LEN);
+ btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN);
configASSERT(btc_aa_snk_queue_set);
- btc_aa_snk_data_queue = xQueueCreate(BTC_MEDIA_DATA_QUEUE_LEN, sizeof(int32_t));
+ btc_aa_snk_data_queue = xQueueCreate(BTC_A2DP_SINK_DATA_QUEUE_LEN, sizeof(int32_t));
configASSERT(btc_aa_snk_data_queue);
xQueueAddToSet(btc_aa_snk_data_queue, btc_aa_snk_queue_set);
- btc_aa_snk_ctrl_queue = xQueueCreate(BTC_MEDIA_CTRL_QUEUE_LEN, sizeof(void *));
+ btc_aa_snk_ctrl_queue = xQueueCreate(BTC_A2DP_SINK_CTRL_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_snk_ctrl_queue);
xQueueAddToSet(btc_aa_snk_ctrl_queue, btc_aa_snk_queue_set);
goto error_exit;
}
- xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_MEDIA_TASK_NAME, BTC_MEDIA_TASK_STACK_SIZE, NULL, BTC_MEDIA_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_MEDIA_TASK_PINNED_TO_CORE);
+ xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
if (btc_aa_snk_task_hdl == NULL) {
goto error_exit;
}
APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##");
- btc_aa_src_queue_set = xQueueCreateSet(BTC_MEDIA_TASK_QUEUE_SET_LEN);
+ btc_aa_src_queue_set = xQueueCreateSet(BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN);
configASSERT(btc_aa_src_queue_set);
- btc_aa_src_data_queue = xQueueCreate(BTC_MEDIA_DATA_QUEUE_LEN, sizeof(void *));
+ btc_aa_src_data_queue = xQueueCreate(BTC_A2DP_SOURCE_DATA_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_src_data_queue);
xQueueAddToSet(btc_aa_src_data_queue, btc_aa_src_queue_set);
- btc_aa_src_ctrl_queue = xQueueCreate(BTC_MEDIA_CTRL_QUEUE_LEN, sizeof(void *));
+ btc_aa_src_ctrl_queue = xQueueCreate(BTC_A2DP_SOURCE_CTRL_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_src_ctrl_queue);
xQueueAddToSet(btc_aa_src_ctrl_queue, btc_aa_src_queue_set);
goto error_exit;
}
- xTaskCreatePinnedToCore(btc_a2dp_source_task_handler, BTC_MEDIA_TASK_NAME, BTC_MEDIA_TASK_STACK_SIZE, NULL, BTC_MEDIA_TASK_PRIO, &btc_aa_src_task_hdl, BTC_MEDIA_TASK_PINNED_TO_CORE);
+ xTaskCreatePinnedToCore(btc_a2dp_source_task_handler, BTC_A2DP_SOURCE_TASK_NAME, BTC_A2DP_SOURCE_TASK_STACK_SIZE, NULL, BTC_A2DP_SOURCE_TASK_PRIO, &btc_aa_src_task_hdl, BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE);
if (btc_aa_src_task_hdl == NULL) {
goto error_exit;
}
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
#define BTC_TASK_QUEUE_LEN 60
-#define BTC_MEDIA_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
-#define BTC_MEDIA_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
-#define BTC_MEDIA_TASK_NAME "BtcMediaT"
-#define BTC_MEDIA_TASK_PRIO (configMAX_PRIORITIES - 3)
-#define BTC_MEDIA_DATA_QUEUE_LEN (3)
-#define BTC_MEDIA_CTRL_QUEUE_LEN (5)
-#define BTC_MEDIA_TASK_QUEUE_SET_LEN (BTC_MEDIA_DATA_QUEUE_LEN + BTC_MEDIA_CTRL_QUEUE_LEN)
+#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
+#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
+#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
+#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3)
+#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5)
+#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN)
+
+#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
+#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
+#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
+#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
+#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (3)
+#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5)
+#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN)
#define TASK_POST_NON_BLOCKING (0)
#define TASK_POST_BLOCKING (portMAX_DELAY)
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_ccb_dealloc %d\n", avdt_ccb_to_idx(p_ccb));
- btu_stop_timer(&p_ccb->timer_entry);
+ btu_free_timer(&p_ccb->timer_entry);
fixed_queue_free(p_ccb->cmd_q, NULL);
fixed_queue_free(p_ccb->rsp_q, NULL);
memset(p_ccb, 0, sizeof(tAVDT_CCB));
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d\n", avdt_scb_to_hdl(p_scb));
- btu_stop_timer(&p_scb->timer_entry);
+ btu_free_timer(&p_scb->timer_entry);
#if AVDT_MULTIPLEXING == TRUE
/* free fragments we're holding, if any; it shouldn't happen */
BTM_TRACE_DEBUG("%s", __func__);
+ btu_free_timer(&p_cb->obs_timer_ent);
+ btu_free_timer(&p_cb->scan_timer_ent);
+ btu_free_timer(&p_cb->inq_var.fast_adv_timer);
memset(p_cb, 0, sizeof(tBTM_BLE_CB));
memset(&(btm_cb.cmn_ble_vsc_cb), 0 , sizeof(tBTM_BLE_VSC_CB));
btm_cb.cmn_ble_vsc_cb.values_read = FALSE;
UINT8 status;
UNUSED(evt_len);
- btu_stop_timer (&btm_cb.devcb.rln_timer);
+ btu_free_timer (&btm_cb.devcb.rln_timer);
/* If there was a callback address for read local name, call it */
btm_cb.devcb.p_rln_cmpl_cb = NULL;
#if 0 /* cleared in btm_init; put back in if called from anywhere else! */
memset (&btm_cb.btm_inq_vars, 0, sizeof (tBTM_INQUIRY_VAR_ST));
#endif
+
+ btu_free_timer(&btm_cb.btm_inq_vars.rmt_name_timer_ent);
+ memset(&btm_cb.btm_inq_vars.rmt_name_timer_ent, 0, sizeof(TIMER_LIST_ENT));
+ btu_free_timer(&btm_cb.btm_inq_vars.inq_timer_ent);
+ memset(&btm_cb.btm_inq_vars.inq_timer_ent, 0, sizeof(TIMER_LIST_ENT));
+
btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
}
{
assert(p_tle != NULL);
- if (p_tle->in_use == FALSE) {
- return;
- }
p_tle->in_use = FALSE;
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
if (alarm == NULL) {
- LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
+ LOG_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
return;
}
osi_alarm_cancel(alarm);
}
osi_alarm_cancel(alarm);
}
+
+void btu_free_quick_timer(TIMER_LIST_ENT *p_tle)
+{
+ assert(p_tle != NULL);
+
+ p_tle->in_use = FALSE;
+
+ // Get the alarm for the timer list entry.
+ osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
+ if (alarm == NULL) {
+ LOG_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
+ return;
+ }
+ osi_alarm_cancel(alarm);
+ hash_map_erase(btu_l2cap_alarm_hash_map, p_tle);
+}
+
#endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
void btu_oneshot_alarm_cb(void *data)
fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
gatt_cb.tcb[i].pending_ind_q = NULL;
+
+ btu_free_timer(&gatt_cb.tcb[i].conf_timer_ent);
+ memset(&gatt_cb.tcb[i].conf_timer_ent, 0, sizeof(TIMER_LIST_ENT));
+
+ btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent);
+ memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT));
+
#if (GATTS_INCLUDED == TRUE)
fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
{
if (p_clcb && p_clcb->in_use) {
+ btu_free_timer(&p_clcb->rsp_timer_ent);
memset(p_clcb, 0, sizeof(tGATT_CLCB));
}
}
}
}
- btu_stop_timer (&p_tcb->ind_ack_timer_ent);
- btu_stop_timer (&p_tcb->conf_timer_ent);
+ btu_free_timer (&p_tcb->ind_ack_timer_ent);
+ btu_free_timer (&p_tcb->conf_timer_ent);
gatt_free_pending_ind(p_tcb);
gatt_free_pending_enc_queue(p_tcb);
gatt_free_pending_prepare_write_queue(p_tcb);
#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
void btu_start_quick_timer (TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout);
void btu_stop_quick_timer (TIMER_LIST_ENT *p_tle);
+void btu_free_quick_timer (TIMER_LIST_ENT *p_tle);
void btu_process_quick_timer_evt (void);
#endif
extern UINT8 l2c_fcr_process_peer_cfg_req(tL2C_CCB *p_ccb, tL2CAP_CFG_INFO *p_cfg);
extern void l2c_fcr_adj_monitor_retran_timeout (tL2C_CCB *p_ccb);
extern void l2c_fcr_stop_timer (tL2C_CCB *p_ccb);
-
+extern void l2c_fcr_free_timer (tL2C_CCB *p_ccb);
/* Functions provided by l2c_ble.c
************************************
*/
}
}
+/*******************************************************************************
+**
+** Function l2c_fcr_free_timer
+**
+** Description This function releases the (monitor or transmission) timer.
+**
+** Returns -
+**
+*******************************************************************************/
+void l2c_fcr_free_timer (tL2C_CCB *p_ccb)
+{
+ assert(p_ccb != NULL);
+ btu_free_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
+}
+
/*******************************************************************************
**
** Function l2c_fcr_cleanup
fixed_queue_free(p_fcrb->retrans_q, osi_free_func);
p_fcrb->retrans_q = NULL;
- btu_stop_quick_timer (&p_fcrb->ack_timer);
- btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
-
+ btu_free_quick_timer (&p_fcrb->ack_timer);
+ memset(&p_fcrb->ack_timer, 0, sizeof(TIMER_LIST_ENT));
+
+ btu_free_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
+ memset(&p_fcrb->mon_retrans_timer, 0, sizeof(TIMER_LIST_ENT));
+
#if (L2CAP_ERTM_STATS == TRUE)
if ( (p_ccb->local_cid >= L2CAP_BASE_APPL_CID) && (p_ccb->peer_cfg.fcr.mode == L2CAP_FCR_ERTM_MODE) ) {
UINT32 dur = osi_time_get_os_boottime_ms() - p_ccb->fcrb.connect_tick_count;
for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {
if (!p_lcb->in_use) {
+ btu_free_timer(&p_lcb->timer_entry);
+ btu_free_timer(&p_lcb->info_timer_entry);
+ btu_free_timer(&p_lcb->upda_con_timer);
+
memset (p_lcb, 0, sizeof (tL2C_LCB));
-
memcpy (p_lcb->remote_bd_addr, p_bd_addr, BD_ADDR_LEN);
p_lcb->in_use = TRUE;
p_lcb->in_use = FALSE;
p_lcb->is_bonding = FALSE;
- /* Stop timers */
- btu_stop_timer (&p_lcb->timer_entry);
- btu_stop_timer (&p_lcb->info_timer_entry);
-
+ /* Stop and release timers */
+ btu_free_timer (&p_lcb->timer_entry);
+ memset(&p_lcb->timer_entry, 0, sizeof(TIMER_LIST_ENT));
+ btu_free_timer (&p_lcb->info_timer_entry);
+ memset(&p_lcb->info_timer_entry, 0, sizeof(TIMER_LIST_ENT));
+ btu_free_timer(&p_lcb->upda_con_timer);
+ memset(&p_lcb->upda_con_timer, 0, sizeof(TIMER_LIST_ENT));
+
/* Release any unfinished L2CAP packet on this link */
if (p_lcb->p_hcit_rcv_acl) {
osi_free(p_lcb->p_hcit_rcv_acl);
memset (&p_ccb->ertm_info, 0, sizeof(tL2CAP_ERTM_INFO));
p_ccb->peer_cfg_already_rejected = FALSE;
p_ccb->fcr_cfg_tries = L2CAP_MAX_FCR_CFG_TRIES;
- p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb;
-
- /* if timer is running, remove it from timer list */
- if (p_ccb->fcrb.ack_timer.in_use) {
- btu_stop_quick_timer (&p_ccb->fcrb.ack_timer);
- }
+ /* stop and release timers */
+ btu_free_quick_timer(&p_ccb->fcrb.ack_timer);
+ memset(&p_ccb->fcrb.ack_timer, 0, sizeof(TIMER_LIST_ENT));
+ p_ccb->fcrb.ack_timer.param = (TIMER_PARAM_TYPE)p_ccb;
+
+ btu_free_quick_timer(&p_ccb->fcrb.mon_retrans_timer);
+ memset(&p_ccb->fcrb.mon_retrans_timer, 0, sizeof(TIMER_LIST_ENT));
p_ccb->fcrb.mon_retrans_timer.param = (TIMER_PARAM_TYPE)p_ccb;
// btla-specific ++
/* CSP408639 Fix: When L2CAP send amp move channel request or receive
* L2CEVT_AMP_MOVE_REQ do following sequence. Send channel move
* request -> Stop retrans/monitor timer -> Change channel state to CST_AMP_MOVING. */
- if (p_ccb->fcrb.mon_retrans_timer.in_use) {
- btu_stop_quick_timer (&p_ccb->fcrb.mon_retrans_timer);
- }
// btla-specific --
+
#if (CLASSIC_BT_INCLUDED == TRUE)
- l2c_fcr_stop_timer (p_ccb);
+ l2c_fcr_free_timer (p_ccb);
#endif ///CLASSIC_BT_INCLUDED == TRUE
p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */
p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC; /* Default mode for channel is basic mode */
p_ccb->is_flushable = FALSE;
#endif
+ btu_free_timer(&p_ccb->timer_entry);
+ memset(&p_ccb->timer_entry, 0, sizeof(TIMER_LIST_ENT));
p_ccb->timer_entry.param = (TIMER_PARAM_TYPE)p_ccb;
p_ccb->timer_entry.in_use = 0;
btm_sec_clr_temp_auth_service (p_lcb->remote_bd_addr);
}
- /* Stop the timer */
- btu_stop_timer (&p_ccb->timer_entry);
-
+ /* Stop and free the timer */
+ btu_free_timer (&p_ccb->timer_entry);
fixed_queue_free(p_ccb->xmit_hold_q, osi_free_func);
p_ccb->xmit_hold_q = NULL;
extern void rfc_release_multiplexer_channel (tRFC_MCB *p_rfc_mcb);
extern void rfc_timer_start (tRFC_MCB *p_rfc_mcb, UINT16 timeout);
extern void rfc_timer_stop (tRFC_MCB *p_rfc_mcb);
+extern void rfc_timer_free (tRFC_MCB *p_rfc_mcb);
extern void rfc_port_timer_start (tPORT *p_port, UINT16 tout);
extern void rfc_port_timer_stop (tPORT *p_port);
+extern void rfc_port_timer_free (tPORT *p_port);
BOOLEAN rfc_check_uih_fcs (UINT8 dlci, UINT8 received_fcs);
BOOLEAN rfc_check_fcs (UINT16 len, UINT8 *p, UINT8 received_fcs);
memcpy (p_port->bd_addr, BT_BD_ANY, BD_ADDR_LEN);
} else {
RFCOMM_TRACE_DEBUG ("port_release_port:Clean-up handle:%d", p_port->inx);
+ rfc_port_timer_free (p_port);
memset (p_port, 0, sizeof (tPORT));
}
}
}
-#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
\ No newline at end of file
+#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
if (rfc_cb.port.rfc_mcb[j].state == RFC_MX_STATE_IDLE) {
/* New multiplexer control block */
fixed_queue_free(p_mcb->cmd_q, NULL);
+ rfc_timer_free(p_mcb);
memset (p_mcb, 0, sizeof (tRFC_MCB));
memcpy (p_mcb->bd_addr, bd_addr, BD_ADDR_LEN);
RFCOMM_TRACE_DEBUG("rfc_alloc_multiplexer_channel:is_initiator:%d, create new p_mcb:%p, index:%d",
void rfc_release_multiplexer_channel (tRFC_MCB *p_mcb)
{
- rfc_timer_stop (p_mcb);
+ rfc_timer_free (p_mcb);
fixed_queue_free(p_mcb->cmd_q, osi_free_fun);
btu_start_timer (p_tle, BTU_TTYPE_RFCOMM_MFC, timeout);
}
-
/*******************************************************************************
**
** Function rfc_timer_stop
btu_stop_timer (&p_mcb->tle);
}
+/*******************************************************************************
+**
+** Function rfc_timer_free
+**
+** Description Stop and free RFC Timer
+**
+*******************************************************************************/
+void rfc_timer_free (tRFC_MCB *p_mcb)
+{
+ RFCOMM_TRACE_EVENT ("rfc_timer_free");
+
+ btu_free_timer (&p_mcb->tle);
+ memset(&p_mcb->tle, 0, sizeof(TIMER_LIST_ENT));
+}
/*******************************************************************************
**
btu_start_timer (p_tle, BTU_TTYPE_RFCOMM_PORT, timeout);
}
-
/*******************************************************************************
**
** Function rfc_port_timer_stop
{
RFCOMM_TRACE_EVENT ("rfc_port_timer_stop");
- btu_free_timer (&p_port->rfc.tle);
+ btu_stop_timer (&p_port->rfc.tle);
}
+/*******************************************************************************
+**
+** Function rfc_port_timer_free
+**
+** Description Stop and free RFC Timer
+**
+*******************************************************************************/
+void rfc_port_timer_free (tPORT *p_port)
+{
+ RFCOMM_TRACE_EVENT ("rfc_port_timer_stop");
+
+ btu_free_timer (&p_port->rfc.tle);
+ memset(&p_port->rfc.tle, 0, sizeof(TIMER_LIST_ENT));
+}
/*******************************************************************************
**
}
-#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
\ No newline at end of file
+#endif ///(defined RFCOMM_INCLUDED && RFCOMM_INCLUDED == TRUE)
/* Look through each connection control block for a free one */
for (xx = 0, p_ccb = sdp_cb.ccb; xx < SDP_MAX_CONNECTIONS; xx++, p_ccb++) {
if (p_ccb->con_state == SDP_STATE_IDLE) {
+ btu_free_timer(&p_ccb->timer_entry);
memset (p_ccb, 0, sizeof (tCONN_CB));
p_ccb->timer_entry.param = (UINT32) p_ccb;
*******************************************************************************/
void sdpu_release_ccb (tCONN_CB *p_ccb)
{
- /* Ensure timer is stopped */
- btu_stop_timer (&p_ccb->timer_entry);
+ /* Ensure timer is stopped and released */
+ btu_free_timer(&p_ccb->timer_entry);
/* Drop any response pointer we may be holding */
p_ccb->con_state = SDP_STATE_IDLE;
-Subproject commit 429496d568d4dd052d9659545dd3f0936d5529ca
+Subproject commit 0575731e349ca54b46cfc084a752790c1ddcdbba
}
const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
- GPIO_PIN_REG_0,
- GPIO_PIN_REG_1,
- GPIO_PIN_REG_2,
- GPIO_PIN_REG_3,
- GPIO_PIN_REG_4,
- GPIO_PIN_REG_5,
- GPIO_PIN_REG_6,
- GPIO_PIN_REG_7,
- GPIO_PIN_REG_8,
- GPIO_PIN_REG_9,
- GPIO_PIN_REG_10,
- GPIO_PIN_REG_11,
- GPIO_PIN_REG_12,
- GPIO_PIN_REG_13,
- GPIO_PIN_REG_14,
- GPIO_PIN_REG_15,
- GPIO_PIN_REG_16,
- GPIO_PIN_REG_17,
- GPIO_PIN_REG_18,
- GPIO_PIN_REG_19,
+ IO_MUX_GPIO0_REG,
+ IO_MUX_GPIO1_REG,
+ IO_MUX_GPIO2_REG,
+ IO_MUX_GPIO3_REG,
+ IO_MUX_GPIO4_REG,
+ IO_MUX_GPIO5_REG,
+ IO_MUX_GPIO6_REG,
+ IO_MUX_GPIO7_REG,
+ IO_MUX_GPIO8_REG,
+ IO_MUX_GPIO9_REG,
+ IO_MUX_GPIO10_REG,
+ IO_MUX_GPIO11_REG,
+ IO_MUX_GPIO12_REG,
+ IO_MUX_GPIO13_REG,
+ IO_MUX_GPIO14_REG,
+ IO_MUX_GPIO15_REG,
+ IO_MUX_GPIO16_REG,
+ IO_MUX_GPIO17_REG,
+ IO_MUX_GPIO18_REG,
+ IO_MUX_GPIO19_REG,
0,
- GPIO_PIN_REG_21,
- GPIO_PIN_REG_22,
- GPIO_PIN_REG_23,
+ IO_MUX_GPIO21_REG,
+ IO_MUX_GPIO22_REG,
+ IO_MUX_GPIO23_REG,
0,
- GPIO_PIN_REG_25,
- GPIO_PIN_REG_26,
- GPIO_PIN_REG_27,
+ IO_MUX_GPIO25_REG,
+ IO_MUX_GPIO26_REG,
+ IO_MUX_GPIO27_REG,
0,
0,
0,
0,
- GPIO_PIN_REG_32,
- GPIO_PIN_REG_33,
- GPIO_PIN_REG_34,
- GPIO_PIN_REG_35,
- GPIO_PIN_REG_36,
- GPIO_PIN_REG_37,
- GPIO_PIN_REG_38,
- GPIO_PIN_REG_39
+ IO_MUX_GPIO32_REG,
+ IO_MUX_GPIO33_REG,
+ IO_MUX_GPIO34_REG,
+ IO_MUX_GPIO35_REG,
+ IO_MUX_GPIO36_REG,
+ IO_MUX_GPIO37_REG,
+ IO_MUX_GPIO38_REG,
+ IO_MUX_GPIO39_REG,
};
typedef struct {
#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /*!< Pin 38 selected */
#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /*!< Pin 39 selected */
-#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
-#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
-#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
-#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
-#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
-#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
-#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
-#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
-#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
-#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
-#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
-#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
-#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
-#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
-#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
-#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
-#define GPIO_PIN_REG_16 PERIPHS_IO_MUX_GPIO16_U
-#define GPIO_PIN_REG_17 PERIPHS_IO_MUX_GPIO17_U
-#define GPIO_PIN_REG_18 PERIPHS_IO_MUX_GPIO18_U
-#define GPIO_PIN_REG_19 PERIPHS_IO_MUX_GPIO19_U
-#define GPIO_PIN_REG_20 PERIPHS_IO_MUX_GPIO20_U
-#define GPIO_PIN_REG_21 PERIPHS_IO_MUX_GPIO21_U
-#define GPIO_PIN_REG_22 PERIPHS_IO_MUX_GPIO22_U
-#define GPIO_PIN_REG_23 PERIPHS_IO_MUX_GPIO23_U
-#define GPIO_PIN_REG_25 PERIPHS_IO_MUX_GPIO25_U
-#define GPIO_PIN_REG_26 PERIPHS_IO_MUX_GPIO26_U
-#define GPIO_PIN_REG_27 PERIPHS_IO_MUX_GPIO27_U
-#define GPIO_PIN_REG_32 PERIPHS_IO_MUX_GPIO32_U
-#define GPIO_PIN_REG_33 PERIPHS_IO_MUX_GPIO33_U
-#define GPIO_PIN_REG_34 PERIPHS_IO_MUX_GPIO34_U
-#define GPIO_PIN_REG_35 PERIPHS_IO_MUX_GPIO35_U
-#define GPIO_PIN_REG_36 PERIPHS_IO_MUX_GPIO36_U
-#define GPIO_PIN_REG_37 PERIPHS_IO_MUX_GPIO37_U
-#define GPIO_PIN_REG_38 PERIPHS_IO_MUX_GPIO38_U
-#define GPIO_PIN_REG_39 PERIPHS_IO_MUX_GPIO39_U
+#define GPIO_PIN_REG_0 IO_MUX_GPIO0_REG
+#define GPIO_PIN_REG_1 IO_MUX_GPIO1_REG
+#define GPIO_PIN_REG_2 IO_MUX_GPIO2_REG
+#define GPIO_PIN_REG_3 IO_MUX_GPIO3_REG
+#define GPIO_PIN_REG_4 IO_MUX_GPIO4_REG
+#define GPIO_PIN_REG_5 IO_MUX_GPIO5_REG
+#define GPIO_PIN_REG_6 IO_MUX_GPIO6_REG
+#define GPIO_PIN_REG_7 IO_MUX_GPIO7_REG
+#define GPIO_PIN_REG_8 IO_MUX_GPIO8_REG
+#define GPIO_PIN_REG_9 IO_MUX_GPIO9_REG
+#define GPIO_PIN_REG_10 IO_MUX_GPIO10_REG
+#define GPIO_PIN_REG_11 IO_MUX_GPIO11_REG
+#define GPIO_PIN_REG_12 IO_MUX_GPIO12_REG
+#define GPIO_PIN_REG_13 IO_MUX_GPIO13_REG
+#define GPIO_PIN_REG_14 IO_MUX_GPIO14_REG
+#define GPIO_PIN_REG_15 IO_MUX_GPIO15_REG
+#define GPIO_PIN_REG_16 IO_MUX_GPIO16_REG
+#define GPIO_PIN_REG_17 IO_MUX_GPIO17_REG
+#define GPIO_PIN_REG_18 IO_MUX_GPIO18_REG
+#define GPIO_PIN_REG_19 IO_MUX_GPIO19_REG
+#define GPIO_PIN_REG_20 IO_MUX_GPIO20_REG
+#define GPIO_PIN_REG_21 IO_MUX_GPIO21_REG
+#define GPIO_PIN_REG_22 IO_MUX_GPIO22_REG
+#define GPIO_PIN_REG_23 IO_MUX_GPIO23_REG
+#define GPIO_PIN_REG_25 IO_MUX_GPIO25_REG
+#define GPIO_PIN_REG_26 IO_MUX_GPIO26_REG
+#define GPIO_PIN_REG_27 IO_MUX_GPIO27_REG
+#define GPIO_PIN_REG_32 IO_MUX_GPIO32_REG
+#define GPIO_PIN_REG_33 IO_MUX_GPIO33_REG
+#define GPIO_PIN_REG_34 IO_MUX_GPIO34_REG
+#define GPIO_PIN_REG_35 IO_MUX_GPIO35_REG
+#define GPIO_PIN_REG_36 IO_MUX_GPIO36_REG
+#define GPIO_PIN_REG_37 IO_MUX_GPIO37_REG
+#define GPIO_PIN_REG_38 IO_MUX_GPIO38_REG
+#define GPIO_PIN_REG_39 IO_MUX_GPIO39_REG
#define GPIO_APP_CPU_INTR_ENA (BIT(0))
#define GPIO_APP_CPU_NMI_INTR_ENA (BIT(1))
*libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
*libapp_trace.a:(.literal .text .literal.* .text.*)
*libxtensa-debug-module.a:eri.o(.literal .text .literal.* .text.*)
- *libphy.a:(.literal .text .literal.* .text.*)
*librtc.a:(.literal .text .literal.* .text.*)
*libsoc.a:(.literal .text .literal.* .text.*)
*libhal.a:(.literal .text .literal.* .text.*)
*(.jcr)
*(.dram1 .dram1.*)
*libesp32.a:panic.o(.rodata .rodata.*)
- *libphy.a:(.rodata .rodata.*)
*libsoc.a:rtc_clk.o(.rodata .rodata.*)
*libapp_trace.a:(.rodata .rodata.*)
*libgcov.a:(.rodata .rodata.*)
-Subproject commit b35fc86bbc5f96e8d52cc32527dbfbabaed0d6fc
+Subproject commit 32402930b3b2d28bf894cba918d08446b04a38e6
/* declare the performance here */
-#define IDF_PERFORMANCE_MAX_HTTPS_REQUEST_BIN_SIZE 610
+#define IDF_PERFORMANCE_MAX_HTTPS_REQUEST_BIN_SIZE 800
#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP 200
#define IDF_PERFORMANCE_MAX_FREERTOS_SPINLOCK_CYCLES_PER_OP_UNICORE 130
#define IDF_PERFORMANCE_MAX_ESP_TIMER_GET_TIME_PER_CALL 1000
Please make sure you fully understand the impact of this feature before
enabling it.
+config LWIP_IRAM_OPTIMIZATION
+ bool "Enable LWIP IRAM optimization"
+ default n
+ help
+ If this feature is enabled, some functions relating to RX/TX in LWIP will be
+ put into IRAM, it can improve UDP/TCP throughput by >10% for single core mode,
+ it doesn't help too much for dual core mode. On the other hand, it needs about
+ 10KB IRAM for these optimizations.
+
+ If this feature is disabled, all lwip functions will be put into FLASH.
+
config LWIP_MAX_SOCKETS
int "Max number of open sockets"
range 1 32
* @param apimsg a struct containing the function to call and its parameters
* @return ERR_OK if the function was called, another err_t if not
*/
-static err_t
+static err_t ESP_IRAM_ATTR
tcpip_apimsg(struct api_msg *apimsg)
{
#if LWIP_DEBUG
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
-static err_t
+static err_t ESP_IRAM_ATTR
netconn_recv_data(struct netconn *conn, void **new_buf)
{
void *buf = NULL;
* @return ERR_OK if data has been received, an error code otherwise (timeout,
* memory error or another error)
*/
-err_t
+err_t ESP_IRAM_ATTR
netconn_recv(struct netconn *conn, struct netbuf **new_buf)
{
#if LWIP_TCP
* @param buf a netbuf containing the data to send
* @return ERR_OK if data was sent, any other err_t on error
*/
-err_t
+err_t ESP_IRAM_ATTR
netconn_send(struct netconn *conn, struct netbuf *buf)
{
API_MSG_VAR_DECLARE(msg);
*
* @param msg the api_msg_msg pointing to the connection
*/
-void
+void ESP_IRAM_ATTR
lwip_netconn_do_send(void *m)
{
struct api_msg_msg *msg = (struct api_msg_msg*)m;
* @return pointer to the allocated memory
* NULL if no memory could be allocated
*/
-void *
+void * ESP_IRAM_ATTR
netbuf_alloc(struct netbuf *buf, u16_t size)
{
LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;);
*
* @param buf pointer to the netbuf which contains the packet buffer to free
*/
-void
+void ESP_IRAM_ATTR
netbuf_free(struct netbuf *buf)
{
LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;);
* @param s externally used socket index
* @return struct lwip_sock for the socket or NULL if not found
*/
-static struct lwip_sock *
+static struct lwip_sock * ESP_IRAM_ATTR
get_socket(int s)
{
struct lwip_sock *sock;
return 0;
}
-int
+int ESP_IRAM_ATTR
lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
#endif /* LWIP_UDP || LWIP_RAW */
}
-int
+int ESP_IRAM_ATTR
lwip_sendto(int s, const void *data, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen)
{
* Callback registered in the netconn layer for each socket-netconn.
* Processes recvevent (data available) and wakes up tasks waiting for select.
*/
-static void
+static void ESP_IRAM_ATTR
event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
{
int s;
#if ESP_THREAD_SAFE
-int
+int ESP_IRAM_ATTR
lwip_sendto_r(int s, const void *data, size_t size, int flags,
const struct sockaddr *to, socklen_t tolen)
{
LWIP_API_UNLOCK();
}
-int
+int ESP_IRAM_ATTR
lwip_recvfrom_r(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
*
* @param arg unused argument
*/
-static void
+static void ESP_IRAM_ATTR
tcpip_thread(void *arg)
{
* @param inp the network interface on which the packet was received
* @param input_fn input function to call
*/
-err_t
+err_t ESP_IRAM_ATTR
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
* NETIF_FLAG_ETHERNET flags)
* @param inp the network interface on which the packet was received
*/
-err_t
+err_t ESP_IRAM_ATTR
tcpip_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_ETHERNET
* @param sem semaphore to wait on
* @return ERR_OK if the function was called, another err_t if not
*/
-err_t
+err_t ESP_IRAM_ATTR
tcpip_send_api_msg(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem)
{
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
#endif
/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
-static u16_t
+static u16_t ESP_IRAM_ATTR
inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
{
struct pbuf *q;
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
-u16_t
+u16_t ESP_IRAM_ATTR
inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip4_addr_t *src, const ip4_addr_t *dest)
{
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
-u16_t
+u16_t ESP_IRAM_ATTR
ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip_addr_t *src, const ip_addr_t *dest)
{
* Source based IPv4 routing hook function. This function works only
* when destination IP is broadcast IP.
*/
-struct netif *
+struct netif * ESP_IRAM_ATTR
ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src)
{
struct netif *netif = NULL;
* Source based IPv4 routing must be fully implemented in
* LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides the parameters.
*/
-struct netif *
+struct netif * ESP_IRAM_ATTR
ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
{
if (src != NULL) {
* @param dest the destination IP address for which to find the route
* @return the netif on which to send to reach dest
*/
-struct netif *
+struct netif * ESP_IRAM_ATTR
ip4_route(const ip4_addr_t *dest)
{
struct netif *netif;
* @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
* processed, but currently always returns ERR_OK)
*/
-err_t
+err_t ESP_IRAM_ATTR
ip4_input(struct pbuf *p, struct netif *inp)
{
struct ip_hdr *iphdr;
* Same as ip_output_if() but 'src' address is not replaced by netif address
* when it is 'any'.
*/
-err_t
+err_t ESP_IRAM_ATTR
ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
u8_t ttl, u8_t tos,
u8_t proto, struct netif *netif)
* Same as ip_output_if_opt() but 'src' address is not replaced by netif address
* when it is 'any'.
*/
-err_t
+err_t ESP_IRAM_ATTR
ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
u16_t optlen)
* @param netif the network interface against which the address is checked
* @return returns non-zero if the address is a broadcast address
*/
-u8_t
+u8_t ESP_IRAM_ATTR
ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
{
ip4_addr_t ipaddr;
* @return non-zero on failure, zero on success.
*
*/
-static u8_t
+static u8_t ESP_IRAM_ATTR
pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force)
{
u16_t type;
* @return non-zero on failure, zero on success.
*
*/
-u8_t
+u8_t ESP_IRAM_ATTR
pbuf_header(struct pbuf *p, s16_t header_size_increment)
{
return pbuf_header_impl(p, header_size_increment, 0);
* @param mbox the mbox to fetch the message from
* @param msg the place to store the message
*/
-void
+void ESP_IRAM_ATTR
sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
u32_t time_needed;
* @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4)
* @return 1 on match, 0 otherwise
*/
-static u8_t
+static u8_t ESP_IRAM_ATTR
udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast)
{
LWIP_UNUSED_ARG(inp); /* in IPv6 only case */
* @param inp network interface on which the datagram was received.
*
*/
-void
+void ESP_IRAM_ATTR
udp_input(struct pbuf *p, struct netif *inp)
{
struct udp_hdr *udphdr;
*
* @see udp_disconnect() udp_sendto()
*/
-err_t
+err_t ESP_IRAM_ATTR
udp_send(struct udp_pcb *pcb, struct pbuf *p)
{
if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) {
*
* @see udp_disconnect() udp_send()
*/
-err_t
+err_t ESP_IRAM_ATTR
udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *dst_ip, u16_t dst_port)
{
*
* @see udp_disconnect() udp_send()
*/
-err_t
+err_t ESP_IRAM_ATTR
udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
{
}
/** Same as udp_sendto_if(), but with source address */
-err_t
+err_t ESP_IRAM_ATTR
udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p,
const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip)
{
#define ESP_LWIP_LOGI(...) ESP_LOGI("lwip", __VA_ARGS__)
#define ESP_PING 1
+#if CONFIG_LWIP_IRAM_OPTIMIZATION
+#define ESP_IRAM_ATTR IRAM_ATTR
+#else
+#define ESP_IRAM_ATTR
+#endif
+
#define TCP_WND_DEFAULT CONFIG_TCP_WND_DEFAULT
#define TCP_SND_BUF_DEFAULT CONFIG_TCP_SND_BUF_DEFAULT
* @params dst the destination MAC address to be copied into the ethernet header
* @return ERR_OK if the packet was sent, any other err_t on failure
*/
-static err_t
+static err_t ESP_IRAM_ATTR
etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, const struct eth_addr *dst)
{
struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;
/** Just a small helper function that sends a pbuf to an ethernet address
* in the arp_table specified by the index 'arp_idx'.
*/
-static err_t
+static err_t ESP_IRAM_ATTR
etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx)
{
LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE",
* - ERR_RTE No route to destination (no gateway to external networks),
* or the return type of either etharp_query() or etharp_send_ip().
*/
-err_t
+err_t ESP_IRAM_ATTR
etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
{
const struct eth_addr *dest;
* @param p the received packet, p->payload pointing to the ethernet header
* @param netif the network interface on which the packet was received
*/
-err_t
+err_t ESP_IRAM_ATTR
ethernet_input(struct pbuf *p, struct netif *netif)
{
struct eth_hdr* ethhdr;
/** Lock a mutex
* @param mutex the mutex to lock */
-void
+void ESP_IRAM_ATTR
sys_mutex_lock(sys_mutex_t *pxMutex)
{
while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
/** Unlock a mutex
* @param mutex the mutex to unlock */
-void
+void ESP_IRAM_ATTR
sys_mutex_unlock(sys_mutex_t *pxMutex)
{
xSemaphoreGive(*pxMutex);
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
-void
+void ESP_IRAM_ATTR
sys_sem_signal(sys_sem_t *sem)
{
xSemaphoreGive(*sem);
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
-u32_t
+u32_t ESP_IRAM_ATTR
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
portTickType StartTime, EndTime, Elapsed;
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
-void
+void ESP_IRAM_ATTR
sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
while (xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY) != pdTRUE);
}
/*-----------------------------------------------------------------------------------*/
-err_t
+err_t ESP_IRAM_ATTR
sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
err_t xReturn;
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
-u32_t
+u32_t ESP_IRAM_ATTR
sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
void *dummyptr;
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
-static err_t
+static err_t ESP_IRAM_ATTR
low_level_output(struct netif *netif, struct pbuf *p)
{
wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif);
*
* @param netif the lwip network interface structure for this ethernetif
*/
-void
+void ESP_IRAM_ATTR
wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
{
struct pbuf *p;
#define CLK_OUT1_S 0
#define PERIPHS_IO_MUX_GPIO0_U (DR_REG_IO_MUX_BASE +0x44)
+#define IO_MUX_GPIO0_REG PERIPHS_IO_MUX_GPIO0_U
#define FUNC_GPIO0_EMAC_TX_CLK 5
#define FUNC_GPIO0_GPIO0 2
#define FUNC_GPIO0_CLK_OUT1 1
#define FUNC_GPIO0_GPIO0_0 0
#define PERIPHS_IO_MUX_U0TXD_U (DR_REG_IO_MUX_BASE +0x88)
+#define IO_MUX_GPIO1_REG PERIPHS_IO_MUX_U0TXD_U
#define FUNC_U0TXD_EMAC_RXD2 5
#define FUNC_U0TXD_GPIO1 2
#define FUNC_U0TXD_CLK_OUT3 1
#define FUNC_U0TXD_U0TXD 0
#define PERIPHS_IO_MUX_GPIO2_U (DR_REG_IO_MUX_BASE +0x40)
+#define IO_MUX_GPIO2_REG PERIPHS_IO_MUX_GPIO2_U
#define FUNC_GPIO2_SD_DATA0 4
#define FUNC_GPIO2_HS2_DATA0 3
#define FUNC_GPIO2_GPIO2 2
#define FUNC_GPIO2_GPIO2_0 0
#define PERIPHS_IO_MUX_U0RXD_U (DR_REG_IO_MUX_BASE +0x84)
+#define IO_MUX_GPIO3_REG PERIPHS_IO_MUX_U0RXD_U
#define FUNC_U0RXD_GPIO3 2
#define FUNC_U0RXD_CLK_OUT2 1
#define FUNC_U0RXD_U0RXD 0
#define PERIPHS_IO_MUX_GPIO4_U (DR_REG_IO_MUX_BASE +0x48)
+#define IO_MUX_GPIO4_REG PERIPHS_IO_MUX_GPIO4_U
#define FUNC_GPIO4_EMAC_TX_ER 5
#define FUNC_GPIO4_SD_DATA1 4
#define FUNC_GPIO4_HS2_DATA1 3
#define FUNC_GPIO4_GPIO4_0 0
#define PERIPHS_IO_MUX_GPIO5_U (DR_REG_IO_MUX_BASE +0x6c)
+#define IO_MUX_GPIO5_REG PERIPHS_IO_MUX_GPIO5_U
#define FUNC_GPIO5_EMAC_RX_CLK 5
#define FUNC_GPIO5_HS1_DATA6 3
#define FUNC_GPIO5_GPIO5 2
#define FUNC_GPIO5_GPIO5_0 0
#define PERIPHS_IO_MUX_SD_CLK_U (DR_REG_IO_MUX_BASE +0x60)
+#define IO_MUX_GPIO6_REG PERIPHS_IO_MUX_SD_CLK_U
#define FUNC_SD_CLK_U1CTS 4
#define FUNC_SD_CLK_HS1_CLK 3
#define FUNC_SD_CLK_GPIO6 2
#define FUNC_SD_CLK_SD_CLK 0
#define PERIPHS_IO_MUX_SD_DATA0_U (DR_REG_IO_MUX_BASE +0x64)
+#define IO_MUX_GPIO7_REG PERIPHS_IO_MUX_SD_DATA0_U
#define FUNC_SD_DATA0_U2RTS 4
#define FUNC_SD_DATA0_HS1_DATA0 3
#define FUNC_SD_DATA0_GPIO7 2
#define FUNC_SD_DATA0_SD_DATA0 0
#define PERIPHS_IO_MUX_SD_DATA1_U (DR_REG_IO_MUX_BASE +0x68)
+#define IO_MUX_GPIO8_REG PERIPHS_IO_MUX_SD_DATA1_U
#define FUNC_SD_DATA1_U2CTS 4
#define FUNC_SD_DATA1_HS1_DATA1 3
#define FUNC_SD_DATA1_GPIO8 2
#define FUNC_SD_DATA1_SD_DATA1 0
#define PERIPHS_IO_MUX_SD_DATA2_U (DR_REG_IO_MUX_BASE +0x54)
+#define IO_MUX_GPIO9_REG PERIPHS_IO_MUX_SD_DATA2_U
#define FUNC_SD_DATA2_U1RXD 4
#define FUNC_SD_DATA2_HS1_DATA2 3
#define FUNC_SD_DATA2_GPIO9 2
#define FUNC_SD_DATA2_SD_DATA2 0
#define PERIPHS_IO_MUX_SD_DATA3_U (DR_REG_IO_MUX_BASE +0x58)
+#define IO_MUX_GPIO10_REG PERIPHS_IO_MUX_SD_DATA3_U
#define FUNC_SD_DATA3_U1TXD 4
#define FUNC_SD_DATA3_HS1_DATA3 3
#define FUNC_SD_DATA3_GPIO10 2
#define FUNC_SD_DATA3_SD_DATA3 0
#define PERIPHS_IO_MUX_SD_CMD_U (DR_REG_IO_MUX_BASE +0x5c)
+#define IO_MUX_GPIO11_REG PERIPHS_IO_MUX_SD_CMD_U
#define FUNC_SD_CMD_U1RTS 4
#define FUNC_SD_CMD_HS1_CMD 3
#define FUNC_SD_CMD_GPIO11 2
#define FUNC_SD_CMD_SD_CMD 0
#define PERIPHS_IO_MUX_MTDI_U (DR_REG_IO_MUX_BASE +0x34)
+#define IO_MUX_GPIO12_REG PERIPHS_IO_MUX_MTDI_U
#define FUNC_MTDI_EMAC_TXD3 5
#define FUNC_MTDI_SD_DATA2 4
#define FUNC_MTDI_HS2_DATA2 3
#define FUNC_MTDI_MTDI 0
#define PERIPHS_IO_MUX_MTCK_U (DR_REG_IO_MUX_BASE +0x38)
+#define IO_MUX_GPIO13_REG PERIPHS_IO_MUX_MTCK_U
#define FUNC_MTCK_EMAC_RX_ER 5
#define FUNC_MTCK_SD_DATA3 4
#define FUNC_MTCK_HS2_DATA3 3
#define FUNC_MTCK_MTCK 0
#define PERIPHS_IO_MUX_MTMS_U (DR_REG_IO_MUX_BASE +0x30)
+#define IO_MUX_GPIO14_REG PERIPHS_IO_MUX_MTMS_U
#define FUNC_MTMS_EMAC_TXD2 5
#define FUNC_MTMS_SD_CLK 4
#define FUNC_MTMS_HS2_CLK 3
#define FUNC_MTMS_MTMS 0
#define PERIPHS_IO_MUX_MTDO_U (DR_REG_IO_MUX_BASE +0x3c)
+#define IO_MUX_GPIO15_REG PERIPHS_IO_MUX_MTDO_U
#define FUNC_MTDO_EMAC_RXD3 5
#define FUNC_MTDO_SD_CMD 4
#define FUNC_MTDO_HS2_CMD 3
#define FUNC_MTDO_MTDO 0
#define PERIPHS_IO_MUX_GPIO16_U (DR_REG_IO_MUX_BASE +0x4c)
+#define IO_MUX_GPIO16_REG PERIPHS_IO_MUX_GPIO16_U
#define FUNC_GPIO16_EMAC_CLK_OUT 5
#define FUNC_GPIO16_U2RXD 4
#define FUNC_GPIO16_HS1_DATA4 3
#define FUNC_GPIO16_GPIO16_0 0
#define PERIPHS_IO_MUX_GPIO17_U (DR_REG_IO_MUX_BASE +0x50)
+#define IO_MUX_GPIO17_REG PERIPHS_IO_MUX_GPIO17_U
#define FUNC_GPIO17_EMAC_CLK_OUT_180 5
#define FUNC_GPIO17_U2TXD 4
#define FUNC_GPIO17_HS1_DATA5 3
#define FUNC_GPIO17_GPIO17_0 0
#define PERIPHS_IO_MUX_GPIO18_U (DR_REG_IO_MUX_BASE +0x70)
+#define IO_MUX_GPIO18_REG PERIPHS_IO_MUX_GPIO18_U
#define FUNC_GPIO18_HS1_DATA7 3
#define FUNC_GPIO18_GPIO18 2
#define FUNC_GPIO18_VSPICLK 1
#define FUNC_GPIO18_GPIO18_0 0
#define PERIPHS_IO_MUX_GPIO19_U (DR_REG_IO_MUX_BASE +0x74)
+#define IO_MUX_GPIO19_REG PERIPHS_IO_MUX_GPIO19_U
#define FUNC_GPIO19_EMAC_TXD0 5
#define FUNC_GPIO19_U0CTS 3
#define FUNC_GPIO19_GPIO19 2
#define FUNC_GPIO19_GPIO19_0 0
#define PERIPHS_IO_MUX_GPIO20_U (DR_REG_IO_MUX_BASE +0x78)
+#define IO_MUX_GPIO20_REG PERIPHS_IO_MUX_GPIO20_U
#define FUNC_GPIO20_GPIO20 2
#define FUNC_GPIO20_GPIO20_0 0
#define PERIPHS_IO_MUX_GPIO21_U (DR_REG_IO_MUX_BASE +0x7c)
+#define IO_MUX_GPIO21_REG PERIPHS_IO_MUX_GPIO21_U
#define FUNC_GPIO21_EMAC_TX_EN 5
#define FUNC_GPIO21_GPIO21 2
#define FUNC_GPIO21_VSPIHD 1
#define FUNC_GPIO21_GPIO21_0 0
#define PERIPHS_IO_MUX_GPIO22_U (DR_REG_IO_MUX_BASE +0x80)
+#define IO_MUX_GPIO22_REG PERIPHS_IO_MUX_GPIO22_U
#define FUNC_GPIO22_EMAC_TXD1 5
#define FUNC_GPIO22_U0RTS 3
#define FUNC_GPIO22_GPIO22 2
#define FUNC_GPIO22_GPIO22_0 0
#define PERIPHS_IO_MUX_GPIO23_U (DR_REG_IO_MUX_BASE +0x8c)
+#define IO_MUX_GPIO23_REG PERIPHS_IO_MUX_GPIO23_U
#define FUNC_GPIO23_HS1_STROBE 3
#define FUNC_GPIO23_GPIO23 2
#define FUNC_GPIO23_VSPID 1
#define FUNC_GPIO23_GPIO23_0 0
#define PERIPHS_IO_MUX_GPIO24_U (DR_REG_IO_MUX_BASE +0x90)
+#define IO_MUX_GPIO24_REG PERIPHS_IO_MUX_GPIO24_U
#define FUNC_GPIO24_GPIO24 2
#define FUNC_GPIO24_GPIO24_0 0
#define PERIPHS_IO_MUX_GPIO25_U (DR_REG_IO_MUX_BASE +0x24)
+#define IO_MUX_GPIO25_REG PERIPHS_IO_MUX_GPIO25_U
#define FUNC_GPIO25_EMAC_RXD0 5
#define FUNC_GPIO25_GPIO25 2
#define FUNC_GPIO25_GPIO25_0 0
#define PERIPHS_IO_MUX_GPIO26_U (DR_REG_IO_MUX_BASE +0x28)
+#define IO_MUX_GPIO26_REG PERIPHS_IO_MUX_GPIO26_U
#define FUNC_GPIO26_EMAC_RXD1 5
#define FUNC_GPIO26_GPIO26 2
#define FUNC_GPIO26_GPIO26_0 0
#define PERIPHS_IO_MUX_GPIO27_U (DR_REG_IO_MUX_BASE +0x2c)
+#define IO_MUX_GPIO27_REG PERIPHS_IO_MUX_GPIO27_U
#define FUNC_GPIO27_EMAC_RX_DV 5
#define FUNC_GPIO27_GPIO27 2
#define FUNC_GPIO27_GPIO27_0 0
#define PERIPHS_IO_MUX_GPIO32_U (DR_REG_IO_MUX_BASE +0x1c)
+#define IO_MUX_GPIO32_REG PERIPHS_IO_MUX_GPIO32_U
#define FUNC_GPIO32_GPIO32 2
#define FUNC_GPIO32_GPIO32_0 0
#define PERIPHS_IO_MUX_GPIO33_U (DR_REG_IO_MUX_BASE +0x20)
+#define IO_MUX_GPIO33_REG PERIPHS_IO_MUX_GPIO33_U
#define FUNC_GPIO33_GPIO33 2
#define FUNC_GPIO33_GPIO33_0 0
#define PERIPHS_IO_MUX_GPIO34_U (DR_REG_IO_MUX_BASE +0x14)
+#define IO_MUX_GPIO34_REG PERIPHS_IO_MUX_GPIO34_U
#define FUNC_GPIO34_GPIO34 2
#define FUNC_GPIO34_GPIO34_0 0
#define PERIPHS_IO_MUX_GPIO35_U (DR_REG_IO_MUX_BASE +0x18)
+#define IO_MUX_GPIO35_REG PERIPHS_IO_MUX_GPIO35_U
#define FUNC_GPIO35_GPIO35 2
#define FUNC_GPIO35_GPIO35_0 0
#define PERIPHS_IO_MUX_GPIO36_U (DR_REG_IO_MUX_BASE +0x04)
+#define IO_MUX_GPIO36_REG PERIPHS_IO_MUX_GPIO36_U
#define FUNC_GPIO36_GPIO36 2
#define FUNC_GPIO36_GPIO36_0 0
#define PERIPHS_IO_MUX_GPIO37_U (DR_REG_IO_MUX_BASE +0x08)
+#define IO_MUX_GPIO37_REG PERIPHS_IO_MUX_GPIO37_U
#define FUNC_GPIO37_GPIO37 2
#define FUNC_GPIO37_GPIO37_0 0
#define PERIPHS_IO_MUX_GPIO38_U (DR_REG_IO_MUX_BASE +0x0c)
+#define IO_MUX_GPIO38_REG PERIPHS_IO_MUX_GPIO38_U
#define FUNC_GPIO38_GPIO38 2
#define FUNC_GPIO38_GPIO38_0 0
#define PERIPHS_IO_MUX_GPIO39_U (DR_REG_IO_MUX_BASE +0x10)
+#define IO_MUX_GPIO39_REG PERIPHS_IO_MUX_GPIO39_U
#define FUNC_GPIO39_GPIO39 2
#define FUNC_GPIO39_GPIO39_0 0
default 3
range 1 10
help
- Define maximum number of partitions
- that can be mounted.
+ Define maximum number of partitions that can be mounted.
menu "SPIFFS Cache Configuration"
config SPIFFS_CACHE
bool "Enable SPIFFS Cache"
default "y"
help
- Enables/disable memory read
- caching of nucleus file system
+ Enables/disable memory read caching of nucleus file system
operations.
config SPIFFS_CACHE_WR
default "y"
depends on SPIFFS_CACHE
help
- Enables memory write caching for
- file descriptors in hydrogen.
+ Enables memory write caching for file descriptors in hydrogen.
config SPIFFS_CACHE_STATS
bool "Enable SPIFFS Cache Statistics"
default "n"
depends on SPIFFS_CACHE
help
- Enable/disable statistics on caching.
- Debug/test purpose only.
+ Enable/disable statistics on caching. Debug/test purpose only.
endmenu
bool "Enable SPIFFS Page Check"
default "y"
help
- Always check header of each
- accessed page to ensure consistent state.
- If enabled it will increase number
- of reads, will increase flash.
+ Always check header of each accessed page to ensure consistent state.
+ If enabled it will increase number of reads from flash, especially
+ if cache is disabled.
config SPIFFS_GC_MAX_RUNS
int "Set Maximum GC Runs"
default 10
range 1 255
help
- Define maximum number of gc runs to
- perform to reach desired free pages.
+ Define maximum number of GC runs to perform to reach desired free pages.
config SPIFFS_GC_STATS
bool "Enable SPIFFS GC Statistics"
default "n"
help
- Enable/disable statistics on gc.
- Debug/test purpose only.
+ Enable/disable statistics on gc. Debug/test purpose only.
+
+config SPIFFS_PAGE_SIZE
+ int "SPIFFS logical page size"
+ default 256
+ range 256 1024
+ help
+ Logical page size of SPIFFS partition, in bytes. Must be multiple
+ of flash page size (which is usually 256 bytes).
+ Larger page sizes reduce overhead when storing large files, and
+ improve filesystem performance when reading large files.
+ Smaller page sizes reduce overhead when storing small (< page size)
+ files.
config SPIFFS_OBJ_NAME_LEN
int "Set SPIFFS Maximum Name Length"
default 32
range 1 256
help
- Object name maximum length. Note that this length
- include the zero-termination character,
- meaning maximum string of characters can at most be
- SPIFFS_OBJ_NAME_LEN - 1.
+ Object name maximum length. Note that this length include the
+ zero-termination character, meaning maximum string of characters
+ can at most be SPIFFS_OBJ_NAME_LEN - 1.
+
+ SPIFFS_OBJ_NAME_LEN + SPIFFS_META_LENGTH should not exceed
+ SPIFFS_PAGE_SIZE - 64.
config SPIFFS_USE_MAGIC
bool "Enable SPIFFS Filesystem Magic"
default "y"
help
Enable this to have an identifiable spiffs filesystem.
- This will look for a magic in all sectors
- to determine if this is a valid spiffs system
- or not on mount point.
+ This will look for a magic in all sectors to determine if this
+ is a valid spiffs system or not at mount time.
config SPIFFS_USE_MAGIC_LENGTH
bool "Enable SPIFFS Filesystem Length Magic"
These bytes can be used in an application-specific manner.
Set this to at least 4 bytes to enable support for saving file
modification time.
+
+ SPIFFS_OBJ_NAME_LEN + SPIFFS_META_LENGTH should not exceed
+ SPIFFS_PAGE_SIZE - 64.
config SPIFFS_USE_MTIME
bool "Save file modification time"
bool "Enable general SPIFFS debug"
default "n"
help
- Enabling this option will print
- general debug mesages to the console
+ Enabling this option will print general debug mesages to the console.
config SPIFFS_API_DBG
bool "Enable SPIFFS API debug"
default "n"
help
- Enabling this option will print
- API debug mesages to the console
+ Enabling this option will print API debug mesages to the console.
config SPIFFS_GC_DBG
bool "Enable SPIFFS Garbage Cleaner debug"
default "n"
help
- Enabling this option will print
- GC debug mesages to the console
+ Enabling this option will print GC debug mesages to the console.
config SPIFFS_CACHE_DBG
bool "Enable SPIFFS Cache debug"
default "n"
depends on SPIFFS_CACHE
help
- Enabling this option will print
- Cache debug mesages to the console
+ Enabling this option will print cache debug mesages to the console.
config SPIFFS_CHECK_DBG
bool "Enable SPIFFS Filesystem Check debug"
default "n"
help
- Enabling this option will print
- Filesystem Check debug mesages
- to the console
+ Enabling this option will print Filesystem Check debug mesages
+ to the console.
config SPIFFS_TEST_VISUALISATION
bool "Enable SPIFFS Filesystem Visualization"
default "n"
help
- Enable this option to enable SPIFFS_vis function
- in the api.
+ Enable this option to enable SPIFFS_vis function in the API.
endmenu
return ESP_ERR_INVALID_STATE;
}
+ uint32_t flash_page_size = g_rom_flashchip.page_size;
+ uint32_t log_page_size = CONFIG_SPIFFS_PAGE_SIZE;
+ if (log_page_size % flash_page_size != 0) {
+ ESP_LOGE(TAG, "SPIFFS_PAGE_SIZE is not multiple of flash chip page size (%d)",
+ flash_page_size);
+ return ESP_ERR_INVALID_ARG;
+ }
+
esp_partition_subtype_t subtype = conf->partition_label ?
ESP_PARTITION_SUBTYPE_ANY : ESP_PARTITION_SUBTYPE_DATA_SPIFFS;
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
efs->cfg.hal_read_f = spiffs_api_read;
efs->cfg.hal_write_f = spiffs_api_write;
efs->cfg.log_block_size = g_rom_flashchip.sector_size;
- efs->cfg.log_page_size = g_rom_flashchip.page_size;
+ efs->cfg.log_page_size = log_page_size;
efs->cfg.phys_addr = 0;
efs->cfg.phys_erase_block = g_rom_flashchip.sector_size;
efs->cfg.phys_size = partition->size;
esp_err_t esp_spiffs_format(const char* partition_label)
{
- bool mount_on_success = false;
+ bool partition_was_mounted = false;
int index;
+ /* If the partition is not mounted, need to create SPIFFS structures
+ * and mount the partition, unmount, format, delete SPIFFS structures.
+ * See SPIFFS wiki for the reason why.
+ */
esp_err_t err = esp_spiffs_by_label(partition_label, &index);
if (err != ESP_OK) {
esp_vfs_spiffs_conf_t conf = {
return err;
}
err = esp_spiffs_by_label(partition_label, &index);
- if (err != ESP_OK) {
- return err;
- }
- esp_spiffs_free(&_efs[index]);
- return ESP_OK;
+ assert(err == ESP_OK && "failed to get index of the partition just mounted");
} else if (SPIFFS_mounted(_efs[index]->fs)) {
- SPIFFS_unmount(_efs[index]->fs);
- mount_on_success = true;
+ partition_was_mounted = true;
}
+
+ SPIFFS_unmount(_efs[index]->fs);
+
s32_t res = SPIFFS_format(_efs[index]->fs);
if (res != SPIFFS_OK) {
ESP_LOGE(TAG, "format failed, %i", SPIFFS_errno(_efs[index]->fs));
SPIFFS_clearerr(_efs[index]->fs);
+ /* If the partition was previously mounted, but format failed, don't
+ * try to mount the partition back (it will probably fail). On the
+ * other hand, if it was not mounted, need to clean up.
+ */
+ if (!partition_was_mounted) {
+ esp_spiffs_free(&_efs[index]);
+ }
return ESP_FAIL;
}
- if (mount_on_success) {
+ if (partition_was_mounted) {
res = SPIFFS_mount(_efs[index]->fs, &_efs[index]->cfg, _efs[index]->work,
_efs[index]->fds, _efs[index]->fds_sz, _efs[index]->cache,
_efs[index]->cache_sz, spiffs_api_check);
SPIFFS_clearerr(_efs[index]->fs);
return ESP_FAIL;
}
+ } else {
+ esp_spiffs_free(&_efs[index]);
}
return ESP_OK;
}
// changes the on-disk format, so the change is not backward-compatible.
//
// Do note: the meta length must never exceed
-// logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64)
+// logical_page_size - (SPIFFS_OBJ_NAME_LEN + SPIFFS_PAGE_EXTRA_SIZE)
//
// This is derived from following:
// logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) +
// spiffs_object_ix_header fields + at least some LUT entries)
#define SPIFFS_OBJ_META_LEN (CONFIG_SPIFFS_META_LENGTH)
+#define SPIFFS_PAGE_EXTRA_SIZE (64)
+_Static_assert(SPIFFS_OBJ_META_LEN + SPIFFS_OBJ_NAME_LEN + SPIFFS_PAGE_EXTRA_SIZE
+ <= CONFIG_SPIFFS_PAGE_SIZE, "SPIFFS_OBJ_META_LEN or SPIFFS_OBJ_NAME_LEN too long");
// Size of buffer allocated on stack used when copying data.
// Lower value generates more read/writes. No meaning having it bigger
TEST_ESP_OK(esp_vfs_spiffs_unregister(spiffs_test_partition_label));
}
-TEST_CASE("can format partition", "[spiffs]")
+TEST_CASE("can initialize SPIFFS in erased partition", "[spiffs]")
{
const esp_partition_t* part = get_test_data_partition();
TEST_ASSERT_NOT_NULL(part);
test_teardown();
}
+TEST_CASE("can format mounted partition", "[spiffs]")
+{
+ // Mount SPIFFS, create file, format, check that the file does not exist.
+ const esp_partition_t* part = get_test_data_partition();
+ TEST_ASSERT_NOT_NULL(part);
+ test_setup();
+ const char* filename = "/spiffs/hello.txt";
+ test_spiffs_create_file_with_text(filename, spiffs_test_hello_str);
+ esp_spiffs_format(part->label);
+ FILE* f = fopen(filename, "r");
+ TEST_ASSERT_NULL(f);
+ test_teardown();
+}
+
+TEST_CASE("can format unmounted partition", "[spiffs]")
+{
+ // Mount SPIFFS, create file, unmount. Format. Mount again, check that
+ // the file does not exist.
+ const esp_partition_t* part = get_test_data_partition();
+ TEST_ASSERT_NOT_NULL(part);
+ test_setup();
+ const char* filename = "/spiffs/hello.txt";
+ test_spiffs_create_file_with_text(filename, spiffs_test_hello_str);
+ test_teardown();
+ esp_spiffs_format(part->label);
+ // Don't use test_setup here, need to mount without formatting
+ esp_vfs_spiffs_conf_t conf = {
+ .base_path = "/spiffs",
+ .partition_label = spiffs_test_partition_label,
+ .max_files = 5,
+ .format_if_mount_failed = false
+ };
+ TEST_ESP_OK(esp_vfs_spiffs_register(&conf));
+ FILE* f = fopen(filename, "r");
+ TEST_ASSERT_NULL(f);
+ test_teardown();
+}
+
TEST_CASE("can create and write file", "[spiffs]")
{
test_setup();
--- /dev/null
+ESP32-DevKitC V2 Getting Started Guide\r
+======================================\r
+\r
+This user guide shows how to get started with ESP32-DevKitC development board.\r
+\r
+\r
+What You Need\r
+-------------\r
+\r
+* 1 × :ref:`ESP32-DevKitC V2 board <get-started-esp32-devkitc-v2-board-front>`\r
+* 1 × USB A / micro USB B cable \r
+* 1 × PC loaded with Windows, Linux or Mac OS\r
+\r
+\r
+Overview\r
+--------\r
+\r
+ESP32-DevKitC is a small-sized ESP32-based development board produced by `Espressif <https://espressif.com>`_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can connect these pins to peripherals as needed. Standard headers also make development easy and convenient when using a breadboard.\r
+\r
+\r
+Functional Description\r
+----------------------\r
+\r
+The following list and figure below describe key components, interfaces and controls of ESP32-DevKitC board.\r
+\r
+ESP-WROOM-32\r
+ Standard `ESP-WROOM-32 <https://www.espressif.com/sites/default/files/documentation/esp-wroom-32_datasheet_en.pdf>`_ module soldered to the ESP32-DevKitC board.\r
+EN\r
+ Reset button: pressing this button resets the system.\r
+Boot\r
+ Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port.\r
+USB\r
+ USB interface. It functions as the power supply for the board and the communication interface between PC and ESP-WROOM-32.\r
+I/O\r
+ Most of the pins on the ESP-WROOM-32 are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc.\r
+\r
+.. _get-started-esp32-devkitc-v2-board-front:\r
+\r
+.. figure:: ../_static/esp32-devkitc-v2-functional-overview.png\r
+ :align: center\r
+ :alt: ESP32-DevKitC V2 board layout\r
+ :figclass: align-center\r
+\r
+ ESP32-DevKitC V2 board layout\r
+\r
+\r
+Power Supply Options\r
+--------------------\r
+\r
+There following options are available to provide power supply to this board:\r
+\r
+1. Micro USB port, this is default power supply connection\r
+2. 5V / GND header pins\r
+3. 3V3 / GND header pins\r
+\r
+.. warning::\r
+\r
+ Above options are mutually exclusive, i.e. the power supply may be provided using only one of the above options. Attempt to power the board using more than one connection at a time may damage the board and/or the power supply source.\r
+\r
+\r
+Start Application Development\r
+------------------------------\r
+\r
+Before powering up the ESP32-DevKitC, please make sure that the board has been received in good condition with no obvious signs of damage.\r
+\r
+To start development of applications, proceed to section :doc:`index`, that will walk you through the following steps:\r
+\r
+* :ref:`get-started-setup-toolchain` in your PC to develop applications for ESP32 in C language\r
+* :ref:`get-started-connect` the module to the PC and verify if it is accessible\r
+* :ref:`get-started-build-flash` an example application to the ESP32\r
+* :ref:`get-started-build-monitor` instantly what the application is doing\r
+\r
+\r
+Related Documents\r
+-----------------\r
+\r
+* `ESP32-DevKitC schematic <https://dl.espressif.com/dl/schematics/ESP32-Core-Board-V2_sch.pdf>`_ (PDF)\r
+* `ESP32 Datasheet <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_ (PDF)\r
+* `ESP-WROOM-32 Datasheet <https://espressif.com/sites/default/files/documentation/esp-wroom-32_datasheet_en.pdf>`_ (PDF)\r
Overview\r
--------\r
\r
-ESP32-DevKitC is a small-sized ESP32-based development board produced by `Espressif <https://espressif.com>`_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can connect these pins to peripherals as needed. Standard headers also make development easy and convenient when using a breadboard.\r
+ESP32-DevKitC is a small-sized ESP32-based development board produced by `Espressif <https://espressif.com>`_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can connect these pins to peripherals as needed. Standard headers also make development easy and convenient when using a breadboard. \r
+\r
+The board comes in two versions, either with :ref:`esp-modules-and-boards-esp-wroom-32` or :ref:`esp-modules-and-boards-esp32-wrover` module soldered.\r
\r
\r
Functional Description\r
The following list and figure below describe key components, interfaces and controls of ESP32-DevKitC board.\r
\r
ESP-WROOM-32\r
- Standard `ESP-WROOM-32 <https://www.espressif.com/sites/default/files/documentation/esp-wroom-32_datasheet_en.pdf>`_ module soldered to the ESP32-DevKitC board.\r
-EN\r
- Reset button: pressing this button resets the system.\r
+ :ref:`esp-modules-and-boards-esp-wroom-32` module soldered to the ESP32-DevKitC board.\r
+ESP32-WROVER\r
+ Optionally :ref:`esp-modules-and-boards-esp32-wrover` module may be soldered instead of the ESP-WROOM-32.\r
+USB-UART Bridge\r
+ A single chip USB-UART bridge provides up to 3 Mbps transfers rates.\r
Boot\r
Download button: holding down the **Boot** button and pressing the **EN** button initiates the firmware download mode. Then user can download firmware through the serial port.\r
-USB\r
- USB interface. It functions as the power supply for the board and the communication interface between PC and ESP-WROOM-32.\r
+Micro USB Port\r
+ USB interface. It functions as the power supply for the board and the communication interface between PC and the ESP module.\r
+5V Power On LED\r
+ This LED lights when the USB or an external 5V power supply is applied to the board. For details see schematic in `Related Documents`_.\r
+EN\r
+ Reset button: pressing this button resets the system.\r
I/O\r
- Most of the pins on the ESP-WROOM-32 are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM,ADC, DAC, I2C, I2S, SPI, etc.\r
+ Most of the pins on the ESP module are broken out to the pin headers on the board. Users can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc.\r
+\r
+ .. note::\r
+\r
+ Some of broken out pins are used internally be the ESP32 module to communicate with SPI memory. They are grouped on one side of the board besides the USB connector and labeled D0, D1, D2, D3, CMD and CLK. In general these pins should be left unconnected or access to the SPI flash memory / SPI RAM may be disturbed. \r
+\r
+ .. note::\r
+\r
+ GPIO16 and 17 are used internally by the ESP32-WROVER module. They are broken out and avialable for use only for boards that have the ESP-WROOM-32 module installed.\r
+\r
\r
.. _get-started-esp32-devkitc-board-front:\r
\r
-.. figure:: ../_static/esp32-devkitc-functional-overview.png\r
+.. figure:: ../_static/esp32-devkitc-functional-overview.jpg\r
:align: center\r
- :alt: ESP32-DevKitC board layout\r
+ :alt: ESP32-DevKitC with ESP-WROOM-32 module soldered\r
:figclass: align-center\r
\r
- ESP32-DevKitC board layout\r
+ ESP32-DevKitC with ESP-WROOM-32 module soldered\r
\r
\r
Power Supply Options\r
--------------------\r
\r
-There following options are available to provide power supply to the ESP32-PICO-KIT V4:\r
+There following options are available to provide power supply to this board:\r
\r
1. Micro USB port, this is default power supply connection\r
2. 5V / GND header pins\r
* :ref:`get-started-build-monitor` instantly what the application is doing\r
\r
\r
+Board Dimensions\r
+----------------\r
+\r
+.. figure:: ../_static/esp32-devkitc-dimensions-back.jpg\r
+ :align: center\r
+ :alt: ESP32 DevKitC board dimensions - back\r
+ :figclass: align-center\r
+\r
+ ESP32 DevKitC board dimensions - back\r
+\r
+\r
Related Documents\r
-----------------\r
\r
-* `ESP32-DevKitC schematic <https://dl.espressif.com/dl/schematics/ESP32-Core-Board-V2_sch.pdf>`_ (PDF)\r
+* `ESP32-DevKitC schematic <https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch.pdf>`_ (PDF)\r
* `ESP32 Datasheet <https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf>`_ (PDF)\r
* `ESP-WROOM-32 Datasheet <https://espressif.com/sites/default/files/documentation/esp-wroom-32_datasheet_en.pdf>`_ (PDF)\r
+* `ESP32-WROVER Datasheet <https://espressif.com/sites/default/files/documentation/esp32-wrover_datasheet_en.pdf>`_ (PDF)\r
+\r
+.. toctree::\r
+ :hidden:\r
+\r
+ get-started-devkitc-v2
\ No newline at end of file
* `ESP32-PICO-D4 Datasheet <http://espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf>`_ (PDF)
+.. _esp-modules-and-boards-esp32-devkitc-v2:
+
+ESP32 Core Board V2 / ESP32 DevKitC
+-----------------------------------
+
+Small and convenient development board with :ref:`esp-modules-and-boards-esp-wroom-32` module installed, break out pin headers and minimum additional components. Includes USB to serial programming interface, that also provides power supply for the board. Has pushbuttons to reset the board and put it in upload mode.
+
+.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-core-board-v2.png
+ :align: center
+ :alt: ESP32 Core Board V2 / ESP32 DevKitC board
+ :width: 50%
+
+ ESP32 Core Board V2 / ESP32 DevKitC board
+
+Documentation
+"""""""""""""
+
+* :doc:`../get-started/get-started-devkitc-v2`
+* `ESP32 DevKitC V2 Schematic <https://dl.espressif.com/dl/schematics/ESP32-Core-Board-V2_sch.pdf>`__ (PDF)
+* `CP210x USB to UART Bridge VCP Drivers <https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers>`_
+
+
.. _esp-modules-and-boards-esp-wrover-kit-v1:
ESP-WROVER-KIT V1 / ESP32 DevKitJ V1
* `ESP32-WROVER Datasheet <https://espressif.com/sites/default/files/documentation/esp32-wrover_datasheet_en.pdf>`__ (PDF)
* `ESP-PSRAM32 Datasheet <https://espressif.com/sites/default/files/documentation/esp-psram32_datasheet_en.pdf>`__ (PDF)
+* `ESP32-WROVER Reference Design <http://www.espressif.com/sites/default/files/documentation/esp32-wrover_reference_design.zip>`_ PDF containing OrCAD schematic, PCB layout, gerbers and BOM
.. _esp-modules-and-boards-esp32-pico-pit-v4:
.. _esp-modules-and-boards-esp32-devkitc:
-ESP32 Core Board V2 / ESP32 DevKitC
-===================================
+ESP32 DevKitC V4
+================
-Small and convenient development board with :ref:`esp-modules-and-boards-esp-wroom-32` module installed, break out pin headers and minimum additional components. Includes USB to serial programming interface, that also provides power supply for the board. Has pushbuttons to reset the board and put it in upload mode.
+Small and convenient development board with :ref:`esp-modules-and-boards-esp-wroom-32` module installed, break out pin headers and minimum additional components. Includes USB to serial programming interface, that also provides power supply for the board. Has pushbuttons to reset the board and put it in upload mode. Comparing to the previous :ref:`esp-modules-and-boards-esp32-devkitc-v2`, instead of ESP-WROOM-32 it can accommodate :ref:`esp-modules-and-boards-esp32-wrover` module and has CP2102N chip that supports faster baud rates.
-.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-core-board-v2.png
+.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-devkitc-v4-front.jpg
:align: center
- :alt: ESP32 Core Board V2 / ESP32 DevKitC board
+ :alt: ESP32 DevKitC V4 board
:width: 50%
- ESP32 Core Board V2 / ESP32 DevKitC board
+ ESP32 DevKitC V4 board
Documentation
-------------
* :doc:`../get-started/get-started-devkitc`
-* `ESP32 DevKitC Schematic <https://dl.espressif.com/dl/schematics/ESP32-Core-Board-V2_sch.pdf>`__ (PDF)
-* `ESP32 Development Board Reference Design <https://espressif.com/sites/default/files/documentation/esp32_development_board_reference_design.zip>`_ (ZIP) containing OrCAD schematic, PCB layout, gerbers and BOM
+* `ESP32-DevKitC schematic <https://dl.espressif.com/dl/schematics/esp32_devkitc_v4-sch.pdf>`_ (PDF)
+* `ESP32-DevKitC Reference Design <http://www.espressif.com/sites/default/files/documentation/esp32-devkitc-v4_reference_design_0.zip>`_ (ZIP) containing OrCAD schematic, PCB layout, gerbers and BOM
* `CP210x USB to UART Bridge VCP Drivers <https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers>`_
+Previous Versions
+-----------------
+
+* :ref:`esp-modules-and-boards-esp32-devkitc-v2`
+
.. _esp-modules-and-boards-esp-wrover-kit-v3:
{
int ret;
- ret = xTaskCreate(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, IPERF_REPORT_TASK_PRIORITY, NULL);
+ ret = xTaskCreatePinnedToCore(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, IPERF_REPORT_TASK_PRIORITY, NULL, portNUM_PROCESSORS-1);
+
if (ret != pdPASS) {
ESP_LOGE(TAG, "create task %s failed", IPERF_REPORT_TASK_NAME);
return ESP_FAIL;
return ESP_OK;
}
-esp_err_t iperf_run_udp_server(void)
+esp_err_t IRAM_ATTR iperf_run_udp_server(void)
{
socklen_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
esp_err_t iperf_run_tcp_client(void)
{
- struct sockaddr_in addr;
+ struct sockaddr_in local_addr;
+ struct sockaddr_in remote_addr;
int actual_send = 0;
int want_send = 0;
uint8_t *buffer;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr.s_addr = s_iperf_ctrl.cfg.sip;
- if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
+ memset(&local_addr, 0, sizeof(local_addr));
+ local_addr.sin_family = AF_INET;
+ local_addr.sin_port = 0;
+ local_addr.sin_addr.s_addr = s_iperf_ctrl.cfg.sip;
+ if (bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) != 0) {
iperf_show_socket_error_reason("tcp client bind", sockfd);
return ESP_FAIL;
}
- addr.sin_family = AF_INET;
- addr.sin_port = htons(s_iperf_ctrl.cfg.dport);
- addr.sin_addr.s_addr = s_iperf_ctrl.cfg.dip;
- if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ memset(&remote_addr, 0, sizeof(remote_addr));
+ remote_addr.sin_family = AF_INET;
+ remote_addr.sin_port = htons(s_iperf_ctrl.cfg.dport);
+ remote_addr.sin_addr.s_addr = s_iperf_ctrl.cfg.dip;
+ if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) {
iperf_show_socket_error_reason("tcp client connect", sockfd);
return ESP_FAIL;
}
while (!s_iperf_ctrl.finish) {
actual_send = send(sockfd, buffer, want_send, 0);
if (actual_send <= 0) {
- vTaskDelay(1);
+ iperf_show_socket_error_reason("tcp client send", sockfd);
+ break;
} else {
s_iperf_ctrl.total_len += actual_send;
}
ESP_LOGE(TAG, "create buffer: out of memory");
return ESP_FAIL;
}
+ memset(s_iperf_ctrl.buffer, 0, s_iperf_ctrl.buffer_len);
- ret = xTaskCreate(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, IPERF_TRAFFIC_TASK_PRIORITY, NULL);
+ ret = xTaskCreatePinnedToCore(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, IPERF_TRAFFIC_TASK_PRIORITY, NULL, portNUM_PROCESSORS-1);
if (ret != pdPASS) {
ESP_LOGE(TAG, "create task %s failed", IPERF_TRAFFIC_TASK_NAME);
free(s_iperf_ctrl.buffer);
#define IPERF_DEFAULT_TIME 30
#define IPERF_TRAFFIC_TASK_NAME "iperf_traffic"
-#define IPERF_TRAFFIC_TASK_PRIORITY 19
+#define IPERF_TRAFFIC_TASK_PRIORITY 10
#define IPERF_TRAFFIC_TASK_STACK 4096
#define IPERF_REPORT_TASK_NAME "iperf_report"
-#define IPERF_REPORT_TASK_PRIORITY 10
+#define IPERF_REPORT_TASK_PRIORITY 20
#define IPERF_REPORT_TASK_STACK 4096
#define IPERF_REPORT_TASK_NAME "iperf_report"
#define IPERF_UDP_TX_LEN (1472)
-#define IPERF_UDP_RX_LEN (32<<10)
-#define IPERF_TCP_TX_LEN (32<<10)
-#define IPERF_TCP_RX_LEN (32<<10)
+#define IPERF_UDP_RX_LEN (16<<10)
+#define IPERF_TCP_TX_LEN (16<<10)
+#define IPERF_TCP_RX_LEN (16<<10)
#define IPERF_MAX_DELAY 64
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=64
CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
-CONFIG_ESP32_WIFI_TX_BA_WIN=12
+CONFIG_ESP32_WIFI_TX_BA_WIN=32
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
-CONFIG_ESP32_WIFI_RX_BA_WIN=12
+CONFIG_ESP32_WIFI_RX_BA_WIN=32
CONFIG_FREERTOS_UNICORE=
CONFIG_FREERTOS_HZ=1000
CONFIG_TCPIP_RECVMBOX_SIZE=64
CONFIG_LWIP_ETHARP_TRUST_IP_MAC=
+CONFIG_FLASHMODE_QIO=y
+CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
+CONFIG_LWIP_IRAM_OPTIMIZATION=y
+