mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'master' into feature/btdm_avrc
This commit is contained in:
commit
dbd4e0522e
@ -18,6 +18,7 @@
|
|||||||
#include "future.h"
|
#include "future.h"
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "btc_config.h"
|
#include "btc_config.h"
|
||||||
|
#include "alarm.h"
|
||||||
|
|
||||||
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
|
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
|
||||||
|
|
||||||
@ -51,6 +52,8 @@ void btc_init_callback(void)
|
|||||||
|
|
||||||
static void btc_init_bluetooth(void)
|
static void btc_init_bluetooth(void)
|
||||||
{
|
{
|
||||||
|
osi_alarm_create_mux();
|
||||||
|
osi_alarm_init();
|
||||||
btc_config_init();
|
btc_config_init();
|
||||||
bte_main_boot_entry(btc_init_callback);
|
bte_main_boot_entry(btc_init_callback);
|
||||||
}
|
}
|
||||||
@ -60,6 +63,8 @@ static void btc_deinit_bluetooth(void)
|
|||||||
{
|
{
|
||||||
bte_main_shutdown();
|
bte_main_shutdown();
|
||||||
btc_config_clean_up();
|
btc_config_clean_up();
|
||||||
|
osi_alarm_deinit();
|
||||||
|
osi_alarm_delete_mux();
|
||||||
future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);
|
future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +144,6 @@ int bte_main_boot_entry(bluedroid_init_done_cb_t cb)
|
|||||||
//data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);
|
//data_dispatcher_register_default(hci->event_dispatcher, btu_hci_msg_queue);
|
||||||
hci->set_data_queue(btu_hci_msg_queue);
|
hci->set_data_queue(btu_hci_msg_queue);
|
||||||
|
|
||||||
osi_alarm_init();
|
|
||||||
|
|
||||||
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
|
#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
|
||||||
//bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
|
//bte_load_ble_conf(BTE_BLE_STACK_CONF_FILE);
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,11 +36,73 @@
|
|||||||
#define BT_ALARM_FREE_WAIT_TICKS 100
|
#define BT_ALARM_FREE_WAIT_TICKS 100
|
||||||
#define BT_ALARM_CHG_PERIOD_WAIT_TICKS 100
|
#define BT_ALARM_CHG_PERIOD_WAIT_TICKS 100
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ALARM_STATE_IDLE,
|
||||||
|
ALARM_STATE_OPEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static osi_mutex_t alarm_mutex;
|
||||||
|
static int alarm_state;
|
||||||
|
|
||||||
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
|
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
|
||||||
|
|
||||||
|
static int alarm_free(osi_alarm_t *alarm);
|
||||||
|
|
||||||
|
int osi_alarm_create_mux(void)
|
||||||
|
{
|
||||||
|
if (alarm_state != ALARM_STATE_IDLE) {
|
||||||
|
LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
osi_mutex_new(&alarm_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int osi_alarm_delete_mux(void)
|
||||||
|
{
|
||||||
|
if (alarm_state != ALARM_STATE_IDLE) {
|
||||||
|
LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
osi_mutex_free(&alarm_mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void osi_alarm_init(void)
|
void osi_alarm_init(void)
|
||||||
{
|
{
|
||||||
memset(&alarm_cbs[0], 0x00, sizeof(alarm_cbs));
|
assert(alarm_mutex != NULL);
|
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_IDLE) {
|
||||||
|
LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
memset(alarm_cbs, 0x00, sizeof(alarm_cbs));
|
||||||
|
alarm_state = ALARM_STATE_OPEN;
|
||||||
|
|
||||||
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void osi_alarm_deinit(void)
|
||||||
|
{
|
||||||
|
assert(alarm_mutex != NULL);
|
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_OPEN) {
|
||||||
|
LOG_WARN("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ALARM_CBS_NUM; i++) {
|
||||||
|
if (alarm_cbs[i].alarm_hdl != NULL) {
|
||||||
|
alarm_free(&alarm_cbs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alarm_state = ALARM_STATE_IDLE;
|
||||||
|
|
||||||
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alarm_t *alarm_cbs_lookfor_available(void)
|
static struct alarm_t *alarm_cbs_lookfor_available(void)
|
||||||
@ -75,88 +137,141 @@ static void alarm_cb_handler(TimerHandle_t xTimer)
|
|||||||
|
|
||||||
osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire)
|
osi_alarm_t *osi_alarm_new(char *alarm_name, osi_alarm_callback_t callback, void *data, period_ms_t timer_expire)
|
||||||
{
|
{
|
||||||
struct alarm_t *timer_id;
|
assert(alarm_mutex != NULL);
|
||||||
TimerHandle_t t;
|
|
||||||
|
struct alarm_t *timer_id = NULL;
|
||||||
|
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_OPEN) {
|
||||||
|
LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
timer_id = NULL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_id = alarm_cbs_lookfor_available();
|
||||||
|
|
||||||
|
if (!timer_id) {
|
||||||
|
LOG_ERROR("%s alarm_cbs exhausted\n", __func__);
|
||||||
|
timer_id = NULL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (timer_expire == 0) {
|
if (timer_expire == 0) {
|
||||||
timer_expire = 1000;
|
timer_expire = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO mutex lock */
|
TimerHandle_t t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, pdFALSE, timer_id, alarm_cb_handler);
|
||||||
timer_id = alarm_cbs_lookfor_available();
|
|
||||||
if (!timer_id) {
|
|
||||||
LOG_ERROR("%s full\n", __func__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = xTimerCreate(alarm_name, timer_expire / portTICK_PERIOD_MS, pdFALSE, timer_id, alarm_cb_handler);
|
|
||||||
if (!t) {
|
if (!t) {
|
||||||
LOG_ERROR("%s error\n", __func__);
|
LOG_ERROR("%s failed to create timer\n", __func__);
|
||||||
return NULL;
|
timer_id = NULL;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_id->alarm_hdl = t;
|
timer_id->alarm_hdl = t;
|
||||||
timer_id->cb = callback;
|
timer_id->cb = callback;
|
||||||
timer_id->cb_data = data;
|
timer_id->cb_data = data;
|
||||||
/* TODO mutex unlock */
|
|
||||||
|
|
||||||
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
return timer_id;
|
return timer_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
int osi_alarm_free(osi_alarm_t *alarm)
|
static int alarm_free(osi_alarm_t *alarm)
|
||||||
{
|
{
|
||||||
if (!alarm) {
|
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||||
LOG_ERROR("%s null\n", __func__);
|
LOG_ERROR("%s null\n", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xTimerDelete(alarm->alarm_hdl, BT_ALARM_FREE_WAIT_TICKS) != pdPASS) {
|
if (xTimerDelete(alarm->alarm_hdl, BT_ALARM_FREE_WAIT_TICKS) != pdPASS) {
|
||||||
LOG_ERROR("%s error\n", __func__);
|
LOG_ERROR("%s alarm delete error\n", __func__);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO mutex lock */
|
memset(alarm, 0, sizeof(osi_alarm_t));
|
||||||
memset(alarm, 0x00, sizeof(osi_alarm_t));
|
|
||||||
/* TODO mutex unlock */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int osi_alarm_free(osi_alarm_t *alarm)
|
||||||
|
{
|
||||||
|
assert(alarm_mutex != NULL);
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_OPEN) {
|
||||||
|
LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
ret = -3;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
alarm_free(alarm);
|
||||||
|
|
||||||
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
|
int osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
|
||||||
{
|
{
|
||||||
if (!alarm) {
|
assert(alarm_mutex != NULL);
|
||||||
LOG_ERROR("%s null\n", __func__);
|
|
||||||
return -1;
|
int ret = 0;
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_OPEN) {
|
||||||
|
LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
ret = -3;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||||
|
LOG_ERROR("%s null\n", __func__);
|
||||||
|
ret = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (xTimerChangePeriod(alarm->alarm_hdl, timeout / portTICK_PERIOD_MS, BT_ALARM_CHG_PERIOD_WAIT_TICKS) != pdPASS) {
|
if (xTimerChangePeriod(alarm->alarm_hdl, timeout / portTICK_PERIOD_MS, BT_ALARM_CHG_PERIOD_WAIT_TICKS) != pdPASS) {
|
||||||
LOG_ERROR("%s chg period error\n", __func__);
|
LOG_ERROR("%s chg period error\n", __func__);
|
||||||
return -2;
|
ret = -2;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xTimerStart(alarm->alarm_hdl, BT_ALARM_START_WAIT_TICKS) != pdPASS) {
|
if (xTimerStart(alarm->alarm_hdl, BT_ALARM_START_WAIT_TICKS) != pdPASS) {
|
||||||
LOG_ERROR("%s start error\n", __func__);
|
LOG_ERROR("%s start error\n", __func__);
|
||||||
return -3;
|
ret = -2;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int osi_alarm_cancel(osi_alarm_t *alarm)
|
int osi_alarm_cancel(osi_alarm_t *alarm)
|
||||||
{
|
{
|
||||||
if (!alarm) {
|
int ret = 0;
|
||||||
|
osi_mutex_lock(&alarm_mutex);
|
||||||
|
if (alarm_state != ALARM_STATE_OPEN) {
|
||||||
|
LOG_ERROR("%s, invalid state %d\n", __func__, alarm_state);
|
||||||
|
ret = -3;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alarm || alarm->alarm_hdl == NULL) {
|
||||||
LOG_ERROR("%s null\n", __func__);
|
LOG_ERROR("%s null\n", __func__);
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xTimerStop(alarm->alarm_hdl, BT_ALARM_STOP_WAIT_TICKS) != pdPASS) {
|
if (xTimerStop(alarm->alarm_hdl, BT_ALARM_STOP_WAIT_TICKS) != pdPASS) {
|
||||||
LOG_ERROR("%s error\n", __func__);
|
LOG_ERROR("%s failed to stop timer\n", __func__);
|
||||||
return -2;
|
ret = -2;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
end:
|
||||||
|
osi_mutex_unlock(&alarm_mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t alarm_current_tick(void)
|
static uint32_t alarm_current_tick(void)
|
||||||
|
@ -35,7 +35,10 @@ typedef struct alarm_t {
|
|||||||
void *cb_data;
|
void *cb_data;
|
||||||
} osi_alarm_t;
|
} osi_alarm_t;
|
||||||
|
|
||||||
|
int osi_alarm_create_mux(void);
|
||||||
|
int osi_alarm_delete_mux(void);
|
||||||
void osi_alarm_init(void);
|
void osi_alarm_init(void);
|
||||||
|
void osi_alarm_deinit(void);
|
||||||
|
|
||||||
// Creates a new alarm object. The returned object must be freed by calling
|
// Creates a new alarm object. The returned object must be freed by calling
|
||||||
// |alarm_free|. Returns NULL on failure.
|
// |alarm_free|. Returns NULL on failure.
|
||||||
|
@ -79,6 +79,8 @@ extern "C" {
|
|||||||
#include <xtensa/config/core.h>
|
#include <xtensa/config/core.h>
|
||||||
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
||||||
#include <xtensa/xtruntime.h>
|
#include <xtensa/xtruntime.h>
|
||||||
|
#include "esp_crosscore_int.h"
|
||||||
|
|
||||||
|
|
||||||
//#include "xtensa_context.h"
|
//#include "xtensa_context.h"
|
||||||
|
|
||||||
@ -261,6 +263,18 @@ void vPortYield( void );
|
|||||||
void _frxt_setup_switch( void );
|
void _frxt_setup_switch( void );
|
||||||
#define portYIELD() vPortYield()
|
#define portYIELD() vPortYield()
|
||||||
#define portYIELD_FROM_ISR() _frxt_setup_switch()
|
#define portYIELD_FROM_ISR() _frxt_setup_switch()
|
||||||
|
|
||||||
|
static inline uint32_t xPortGetCoreID();
|
||||||
|
|
||||||
|
/* Yielding within an API call (when interrupts are off), means the yield should be delayed
|
||||||
|
until interrupts are re-enabled.
|
||||||
|
|
||||||
|
To do this, we use the "cross-core" interrupt as a trigger to yield on this core when interrupts are re-enabled.This
|
||||||
|
is the same interrupt & code path which is used to trigger a yield between CPUs, although in this case the yield is
|
||||||
|
happening on the same CPU.
|
||||||
|
*/
|
||||||
|
#define portYIELD_WITHIN_API() esp_crosscore_int_send_yield(xPortGetCoreID())
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
/* Task function macros as described on the FreeRTOS.org WEB site. */
|
||||||
|
@ -123,15 +123,9 @@ zero. */
|
|||||||
#if( configUSE_PREEMPTION == 0 )
|
#if( configUSE_PREEMPTION == 0 )
|
||||||
/* If the cooperative scheduler is being used then a yield should not be
|
/* If the cooperative scheduler is being used then a yield should not be
|
||||||
performed just because a higher priority task has been woken. */
|
performed just because a higher priority task has been woken. */
|
||||||
#define queueYIELD_IF_USING_PREEMPTION_MUX()
|
|
||||||
#define queueYIELD_IF_USING_PREEMPTION()
|
#define queueYIELD_IF_USING_PREEMPTION()
|
||||||
#else
|
#else
|
||||||
#define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
#define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||||
#define queueYIELD_IF_USING_PREEMPTION_MUX(mux) { \
|
|
||||||
taskEXIT_CRITICAL(mux); \
|
|
||||||
portYIELD_WITHIN_API(); \
|
|
||||||
taskENTER_CRITICAL(mux); \
|
|
||||||
} while(0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -290,7 +284,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
|
||||||
{
|
{
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -753,7 +747,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
/* The queue is a member of a queue set, and posting
|
/* The queue is a member of a queue set, and posting
|
||||||
to the queue set caused a higher priority task to
|
to the queue set caused a higher priority task to
|
||||||
unblock. A context switch is required. */
|
unblock. A context switch is required. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -772,7 +766,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
our own so yield immediately. Yes it is ok to
|
our own so yield immediately. Yes it is ok to
|
||||||
do this from within the critical section - the
|
do this from within the critical section - the
|
||||||
kernel takes care of that. */
|
kernel takes care of that. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -785,7 +779,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
executed if the task was holding multiple mutexes
|
executed if the task was holding multiple mutexes
|
||||||
and the mutexes were given back in an order that is
|
and the mutexes were given back in an order that is
|
||||||
different to that in which they were taken. */
|
different to that in which they were taken. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -805,7 +799,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
our own so yield immediately. Yes it is ok to do
|
our own so yield immediately. Yes it is ok to do
|
||||||
this from within the critical section - the kernel
|
this from within the critical section - the kernel
|
||||||
takes care of that. */
|
takes care of that. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -818,7 +812,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
executed if the task was holding multiple mutexes and
|
executed if the task was holding multiple mutexes and
|
||||||
the mutexes were given back in an order that is
|
the mutexes were given back in an order that is
|
||||||
different to that in which they were taken. */
|
different to that in which they were taken. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1493,7 +1487,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
|
||||||
{
|
{
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1522,7 +1516,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The task waiting has a higher priority than this task. */
|
/* The task waiting has a higher priority than this task. */
|
||||||
queueYIELD_IF_USING_PREEMPTION_MUX(&pxQueue->mux);
|
queueYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -120,14 +120,8 @@ functions but without including stdio.h here. */
|
|||||||
/* If the cooperative scheduler is being used then a yield should not be
|
/* If the cooperative scheduler is being used then a yield should not be
|
||||||
performed just because a higher priority task has been woken. */
|
performed just because a higher priority task has been woken. */
|
||||||
#define taskYIELD_IF_USING_PREEMPTION()
|
#define taskYIELD_IF_USING_PREEMPTION()
|
||||||
#define queueYIELD_IF_USING_PREEMPTION_MUX(mux)
|
|
||||||
#else
|
#else
|
||||||
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
#define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||||
#define taskYIELD_IF_USING_PREEMPTION_MUX(mux) { \
|
|
||||||
taskEXIT_CRITICAL(mux); \
|
|
||||||
portYIELD_WITHIN_API(); \
|
|
||||||
taskENTER_CRITICAL(mux); \
|
|
||||||
} while(0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -1166,7 +1160,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||||||
{
|
{
|
||||||
if( xCoreID == xPortGetCoreID() )
|
if( xCoreID == xPortGetCoreID() )
|
||||||
{
|
{
|
||||||
taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex);
|
taskYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
taskYIELD_OTHER_CORE(xCoreID, pxNewTCB->uxPriority);
|
taskYIELD_OTHER_CORE(xCoreID, pxNewTCB->uxPriority);
|
||||||
@ -1703,7 +1697,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||||||
|
|
||||||
if( xYieldRequired == pdTRUE )
|
if( xYieldRequired == pdTRUE )
|
||||||
{
|
{
|
||||||
taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex);
|
taskYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1895,7 +1889,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||||||
/* This yield may not cause the task just resumed to run,
|
/* This yield may not cause the task just resumed to run,
|
||||||
but will leave the lists in the correct state for the
|
but will leave the lists in the correct state for the
|
||||||
next yield. */
|
next yield. */
|
||||||
taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex);
|
taskYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else if( pxTCB->xCoreID != xPortGetCoreID() )
|
else if( pxTCB->xCoreID != xPortGetCoreID() )
|
||||||
{
|
{
|
||||||
@ -2206,7 +2200,7 @@ BaseType_t xAlreadyYielded = pdFALSE;
|
|||||||
xAlreadyYielded = pdTRUE;
|
xAlreadyYielded = pdTRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex);
|
taskYIELD_IF_USING_PREEMPTION();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -52,14 +52,15 @@ TEST_CASE("FreeRTOS Event Groups", "[freertos]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Tasks all start instantly, but this task will resume running at the same time as the higher priority tasks on the
|
/* Tasks all start instantly, but this task will resume running at the same time as the higher priority tasks on the
|
||||||
other processor may still be setting up, so give a tick for them to also block on BIT_CALL... */
|
other processor may still be setting up, so allow time for them to also block on BIT_CALL... */
|
||||||
vTaskDelay(1);
|
vTaskDelay(10);
|
||||||
|
|
||||||
for (int i = 0; i < COUNT; i++) {
|
for (int i = 0; i < COUNT; i++) {
|
||||||
/* signal all tasks with "CALL" bit... */
|
/* signal all tasks with "CALL" bit... */
|
||||||
xEventGroupSetBits(eg, BIT_CALL);
|
xEventGroupSetBits(eg, BIT_CALL);
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_HEX16(ALL_RESPONSE_BITS, xEventGroupWaitBits(eg, ALL_RESPONSE_BITS, true, true, 100 / portMAX_DELAY));
|
/* Only wait for 1 tick, the wakeup should be immediate... */
|
||||||
|
TEST_ASSERT_EQUAL_HEX16(ALL_RESPONSE_BITS, xEventGroupWaitBits(eg, ALL_RESPONSE_BITS, true, true, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure all tasks cleaned up correctly */
|
/* Ensure all tasks cleaned up correctly */
|
||||||
|
108
components/freertos/test/test_preemption.c
Normal file
108
components/freertos/test/test_preemption.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
Unit tests for FreeRTOS preemption
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp_types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "rom/ets_sys.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "freertos/xtensa_api.h"
|
||||||
|
#include "unity.h"
|
||||||
|
#include "soc/cpu.h"
|
||||||
|
|
||||||
|
static volatile bool trigger;
|
||||||
|
static volatile bool flag;
|
||||||
|
|
||||||
|
/* Task:
|
||||||
|
- Waits for 'trigger' variable to be set
|
||||||
|
- Reads the cycle count on this CPU
|
||||||
|
- Pushes it into a queue supplied as a param
|
||||||
|
- Busy-waits until the main task terminates it
|
||||||
|
*/
|
||||||
|
static void task_send_to_queue(void *param)
|
||||||
|
{
|
||||||
|
QueueHandle_t queue = (QueueHandle_t) param;
|
||||||
|
uint32_t ccount;
|
||||||
|
|
||||||
|
while(!trigger) {}
|
||||||
|
|
||||||
|
RSR(CCOUNT, ccount);
|
||||||
|
flag = true;
|
||||||
|
xQueueSendToBack(queue, &ccount, 0);
|
||||||
|
/* This is to ensure that higher priority task
|
||||||
|
won't wake anyhow, due to this task terminating.
|
||||||
|
|
||||||
|
The task runs until terminated by the main task.
|
||||||
|
*/
|
||||||
|
while(1) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Yield from lower priority task, same CPU", "[freertos]")
|
||||||
|
{
|
||||||
|
/* Do this 3 times, mostly for the benchmark value - the first
|
||||||
|
run includes a cache miss so uses more cycles than it should. */
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
TaskHandle_t sender_task;
|
||||||
|
QueueHandle_t queue = xQueueCreate(1, sizeof(uint32_t));
|
||||||
|
flag = false;
|
||||||
|
trigger = false;
|
||||||
|
|
||||||
|
/* "yield" task sits on our CPU, lower priority to us */
|
||||||
|
xTaskCreatePinnedToCore(task_send_to_queue, "YIELD", 2048, (void *)queue, UNITY_FREERTOS_PRIORITY - 1, &sender_task, UNITY_FREERTOS_CPU);
|
||||||
|
|
||||||
|
vTaskDelay(1); /* make sure everything is set up */
|
||||||
|
trigger = true;
|
||||||
|
|
||||||
|
uint32_t yield_ccount, now_ccount, delta;
|
||||||
|
TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
|
||||||
|
RSR(CCOUNT, now_ccount);
|
||||||
|
TEST_ASSERT( flag );
|
||||||
|
|
||||||
|
delta = now_ccount - yield_ccount;
|
||||||
|
printf("Yielding from lower priority task took %u cycles\n", delta);
|
||||||
|
TEST_ASSERT(delta < 10000);
|
||||||
|
|
||||||
|
vQueueDelete(queue);
|
||||||
|
vTaskDelete(sender_task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Yield from lower priority task, other CPU", "[freertos]")
|
||||||
|
{
|
||||||
|
uint32_t trigger_ccount, yield_ccount, now_ccount, delta;
|
||||||
|
|
||||||
|
/* Do this 3 times, mostly for the benchmark value - the first
|
||||||
|
run includes a cache miss so uses more cycles than it should. */
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
TaskHandle_t sender_task;
|
||||||
|
QueueHandle_t queue = xQueueCreate(1, sizeof(uint32_t));
|
||||||
|
trigger = false;
|
||||||
|
flag = false;
|
||||||
|
|
||||||
|
/* "send_to_queue" task sits on the other CPU, lower priority to us */
|
||||||
|
xTaskCreatePinnedToCore(task_send_to_queue, "YIELD", 2048, (void *)queue, UNITY_FREERTOS_PRIORITY - 1,
|
||||||
|
&sender_task, !UNITY_FREERTOS_CPU);
|
||||||
|
|
||||||
|
vTaskDelay(2); /* make sure everything is set up */
|
||||||
|
trigger = true;
|
||||||
|
RSR(CCOUNT, trigger_ccount);
|
||||||
|
|
||||||
|
// yield_ccount is not useful in this test as it's the other core's CCOUNT
|
||||||
|
// so we use trigger_ccount instead
|
||||||
|
TEST_ASSERT( xQueueReceive(queue, &yield_ccount, 100 / portTICK_PERIOD_MS) );
|
||||||
|
RSR(CCOUNT, now_ccount);
|
||||||
|
TEST_ASSERT( flag );
|
||||||
|
|
||||||
|
delta = now_ccount - trigger_ccount;
|
||||||
|
printf("Yielding from task on other core took %u cycles\n", delta);
|
||||||
|
TEST_ASSERT(delta < 10000);
|
||||||
|
|
||||||
|
vQueueDelete(queue);
|
||||||
|
vTaskDelete(sender_task);
|
||||||
|
}
|
||||||
|
}
|
@ -59,6 +59,7 @@
|
|||||||
static tcpip_init_done_fn tcpip_init_done;
|
static tcpip_init_done_fn tcpip_init_done;
|
||||||
static void *tcpip_init_done_arg;
|
static void *tcpip_init_done_arg;
|
||||||
static sys_mbox_t mbox;
|
static sys_mbox_t mbox;
|
||||||
|
sys_thread_t g_lwip_task = NULL;
|
||||||
|
|
||||||
#if LWIP_TCPIP_CORE_LOCKING
|
#if LWIP_TCPIP_CORE_LOCKING
|
||||||
/** The global semaphore to lock the stack. */
|
/** The global semaphore to lock the stack. */
|
||||||
@ -498,11 +499,11 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg)
|
|||||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||||
|
|
||||||
|
|
||||||
sys_thread_t xLwipTaskHandle = sys_thread_new(TCPIP_THREAD_NAME
|
g_lwip_task = sys_thread_new(TCPIP_THREAD_NAME
|
||||||
, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||||
|
|
||||||
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n",
|
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n",
|
||||||
(u32_t)xLwipTaskHandle,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE));
|
(u32_t)g_lwip_task,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,6 +539,8 @@ static void
|
|||||||
dhcp_t1_timeout(struct netif *netif)
|
dhcp_t1_timeout(struct netif *netif)
|
||||||
{
|
{
|
||||||
struct dhcp *dhcp = netif->dhcp;
|
struct dhcp *dhcp = netif->dhcp;
|
||||||
|
int half_t2_timeout;
|
||||||
|
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n"));
|
||||||
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
|
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
|
||||||
(dhcp->state == DHCP_STATE_RENEWING)) {
|
(dhcp->state == DHCP_STATE_RENEWING)) {
|
||||||
@ -550,15 +552,16 @@ dhcp_t1_timeout(struct netif *netif)
|
|||||||
DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
|
DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
|
||||||
dhcp_renew(netif);
|
dhcp_renew(netif);
|
||||||
/* Calculate next timeout */
|
/* Calculate next timeout */
|
||||||
|
half_t2_timeout = (netif->dhcp->t2_timeout - dhcp->lease_used) / 2;
|
||||||
#if ESP_DHCP_TIMER
|
#if ESP_DHCP_TIMER
|
||||||
if (((netif->dhcp->t2_timeout - dhcp->lease_used) / 2) >= (60 + DHCP_COARSE_TIMER_SECS / 2) )
|
if (half_t2_timeout*DHCP_COARSE_TIMER_SECS >= 3)
|
||||||
{
|
{
|
||||||
netif->dhcp->t1_renew_time = (netif->dhcp->t2_timeout - dhcp->lease_used) / 2;
|
netif->dhcp->t1_renew_time = half_t2_timeout;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (((netif->dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
|
if (half_t2_timeout >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
|
||||||
{
|
{
|
||||||
netif->dhcp->t1_renew_time = ((netif->dhcp->t2_timeout - dhcp->lease_used) / 2);
|
netif->dhcp->t1_renew_time = half_t2_timeout;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -573,6 +576,7 @@ static void
|
|||||||
dhcp_t2_timeout(struct netif *netif)
|
dhcp_t2_timeout(struct netif *netif)
|
||||||
{
|
{
|
||||||
struct dhcp *dhcp = netif->dhcp;
|
struct dhcp *dhcp = netif->dhcp;
|
||||||
|
int half_t0_timeout;
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
|
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n"));
|
||||||
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
|
if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) ||
|
||||||
(dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
|
(dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) {
|
||||||
@ -583,15 +587,16 @@ dhcp_t2_timeout(struct netif *netif)
|
|||||||
DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
|
DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
|
||||||
dhcp_rebind(netif);
|
dhcp_rebind(netif);
|
||||||
/* Calculate next timeout */
|
/* Calculate next timeout */
|
||||||
|
half_t0_timeout = (netif->dhcp->t0_timeout - dhcp->lease_used) / 2;
|
||||||
#if ESP_DHCP_TIMER
|
#if ESP_DHCP_TIMER
|
||||||
if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= (60 + DHCP_COARSE_TIMER_SECS / 2))
|
if (half_t0_timeout*DHCP_COARSE_TIMER_SECS >= 3)
|
||||||
{
|
{
|
||||||
netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2);
|
netif->dhcp->t2_rebind_time = half_t0_timeout;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
|
if (half_t0_timeout >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
|
||||||
{
|
{
|
||||||
netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2);
|
netif->dhcp->t2_rebind_time = half_t0_timeout;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,13 @@
|
|||||||
#include "lwip/mem.h"
|
#include "lwip/mem.h"
|
||||||
#include "arch/sys_arch.h"
|
#include "arch/sys_arch.h"
|
||||||
#include "lwip/stats.h"
|
#include "lwip/stats.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
/* This is the number of threads that can be started with sys_thread_new() */
|
/* This is the number of threads that can be started with sys_thread_new() */
|
||||||
#define SYS_THREAD_MAX 4
|
#define SYS_THREAD_MAX 4
|
||||||
|
#define TAG "lwip_arch"
|
||||||
|
|
||||||
static bool g_lwip_in_critical_section = false;
|
static sys_mutex_t g_lwip_protect_mutex = NULL;
|
||||||
static BaseType_t g_lwip_critical_section_needs_taskswitch;
|
|
||||||
|
|
||||||
#if !LWIP_COMPAT_MUTEX
|
#if !LWIP_COMPAT_MUTEX
|
||||||
/** Create a new mutex
|
/** Create a new mutex
|
||||||
@ -125,18 +126,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
|
|||||||
void
|
void
|
||||||
sys_sem_signal(sys_sem_t *sem)
|
sys_sem_signal(sys_sem_t *sem)
|
||||||
{
|
{
|
||||||
if (g_lwip_in_critical_section){
|
|
||||||
/* In function event_callback in sockets.c, lwip signals a semaphore inside a critical
|
|
||||||
* section. According to the FreeRTOS documentation for FreertosTaskEnterCritical, it's
|
|
||||||
* not allowed to call any FreeRTOS API function within a critical region. Unfortunately,
|
|
||||||
* it's not feasible to rework the affected region in LWIP. As a solution, when in a
|
|
||||||
* critical region, we call xSemaphoreGiveFromISR. This routine is hand-vetted to work
|
|
||||||
* in a critical region and it will not cause a task switch.
|
|
||||||
*/
|
|
||||||
xSemaphoreGiveFromISR(*sem, &g_lwip_critical_section_needs_taskswitch);
|
|
||||||
} else {
|
|
||||||
xSemaphoreGive(*sem);
|
xSemaphoreGive(*sem);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -394,7 +384,7 @@ sys_mbox_free(sys_mbox_t *mbox)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count == (MAX_POLL_CNT-1)){
|
if (count == (MAX_POLL_CNT-1)){
|
||||||
printf("WARNING: mbox %p had a consumer who never unblocked. Leaking!\n", (*mbox)->os_mbox);
|
ESP_LOGW(TAG, "WARNING: mbox %p had a consumer who never unblocked. Leaking!\n", (*mbox)->os_mbox);
|
||||||
}
|
}
|
||||||
sys_delay_ms(PER_POLL_DELAY);
|
sys_delay_ms(PER_POLL_DELAY);
|
||||||
}
|
}
|
||||||
@ -440,6 +430,9 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize
|
|||||||
void
|
void
|
||||||
sys_init(void)
|
sys_init(void)
|
||||||
{
|
{
|
||||||
|
if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) {
|
||||||
|
ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -449,7 +442,6 @@ sys_now(void)
|
|||||||
return xTaskGetTickCount();
|
return xTaskGetTickCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
static portMUX_TYPE g_lwip_mux = portMUX_INITIALIZER_UNLOCKED;
|
|
||||||
/*
|
/*
|
||||||
This optional function does a "fast" critical region protection and returns
|
This optional function does a "fast" critical region protection and returns
|
||||||
the previous protection level. This function is only called during very short
|
the previous protection level. This function is only called during very short
|
||||||
@ -466,8 +458,7 @@ static portMUX_TYPE g_lwip_mux = portMUX_INITIALIZER_UNLOCKED;
|
|||||||
sys_prot_t
|
sys_prot_t
|
||||||
sys_arch_protect(void)
|
sys_arch_protect(void)
|
||||||
{
|
{
|
||||||
portENTER_CRITICAL(&g_lwip_mux);
|
sys_mutex_lock(&g_lwip_protect_mutex);
|
||||||
g_lwip_in_critical_section = true;
|
|
||||||
return (sys_prot_t) 1;
|
return (sys_prot_t) 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,13 +472,7 @@ sys_arch_protect(void)
|
|||||||
void
|
void
|
||||||
sys_arch_unprotect(sys_prot_t pval)
|
sys_arch_unprotect(sys_prot_t pval)
|
||||||
{
|
{
|
||||||
(void) pval;
|
sys_mutex_unlock(&g_lwip_protect_mutex);
|
||||||
g_lwip_in_critical_section = false;
|
|
||||||
portEXIT_CRITICAL(&g_lwip_mux);
|
|
||||||
if (g_lwip_critical_section_needs_taskswitch){
|
|
||||||
g_lwip_critical_section_needs_taskswitch = 0;
|
|
||||||
portYIELD();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -497,7 +482,7 @@ sys_arch_unprotect(sys_prot_t pval)
|
|||||||
void
|
void
|
||||||
sys_arch_assert(const char *file, int line)
|
sys_arch_assert(const char *file, int line)
|
||||||
{
|
{
|
||||||
printf("\nAssertion: %d in %s\n", line, file);
|
ESP_LOGE(TAG, "\nAssertion: %d in %s\n", line, file);
|
||||||
|
|
||||||
// vTaskEnterCritical();
|
// vTaskEnterCritical();
|
||||||
while(1);
|
while(1);
|
||||||
@ -537,14 +522,14 @@ sys_sem_t* sys_thread_sem_init(void)
|
|||||||
sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
|
sys_sem_t *sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
|
||||||
|
|
||||||
if (!sem){
|
if (!sem){
|
||||||
printf("sem f1\n");
|
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sem = xSemaphoreCreateBinary();
|
*sem = xSemaphoreCreateBinary();
|
||||||
if (!(*sem)){
|
if (!(*sem)){
|
||||||
free(sem);
|
free(sem);
|
||||||
printf("sem f2\n");
|
ESP_LOGE(TAG, "thread_sem_init: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,12 @@ void IRAM_ATTR spi_flash_op_block_func(void* arg)
|
|||||||
uint32_t cpuid = (uint32_t) arg;
|
uint32_t cpuid = (uint32_t) arg;
|
||||||
// Disable cache so that flash operation can start
|
// Disable cache so that flash operation can start
|
||||||
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
||||||
|
// s_flash_op_complete flag is cleared on *this* CPU, otherwise the other
|
||||||
|
// CPU may reset the flag back to false before IPC task has a chance to check it
|
||||||
|
// (if it is preempted by an ISR taking non-trivial amount of time)
|
||||||
|
s_flash_op_complete = false;
|
||||||
s_flash_op_can_start = true;
|
s_flash_op_can_start = true;
|
||||||
while (!s_flash_op_complete) {
|
while (!s_flash_op_complete) {
|
||||||
// until we have a way to use interrupts for inter-CPU communication,
|
|
||||||
// busy loop here and wait for the other CPU to finish flash operation
|
// busy loop here and wait for the other CPU to finish flash operation
|
||||||
}
|
}
|
||||||
// Flash operation is complete, re-enable cache
|
// Flash operation is complete, re-enable cache
|
||||||
@ -105,7 +108,6 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
|||||||
// Signal to the spi_flash_op_block_task on the other CPU that we need it to
|
// Signal to the spi_flash_op_block_task on the other CPU that we need it to
|
||||||
// disable cache there and block other tasks from executing.
|
// disable cache there and block other tasks from executing.
|
||||||
s_flash_op_can_start = false;
|
s_flash_op_can_start = false;
|
||||||
s_flash_op_complete = false;
|
|
||||||
esp_err_t ret = esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid);
|
esp_err_t ret = esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid);
|
||||||
assert(ret == ESP_OK);
|
assert(ret == ESP_OK);
|
||||||
while (!s_flash_op_can_start) {
|
while (!s_flash_op_can_start) {
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <unity.h>
|
#include <unity.h>
|
||||||
#include <esp_spi_flash.h>
|
#include <esp_spi_flash.h>
|
||||||
#include <esp_attr.h>
|
#include <esp_attr.h>
|
||||||
|
#include "driver/timer.h"
|
||||||
|
#include "esp_intr_alloc.h"
|
||||||
|
|
||||||
struct flash_test_ctx {
|
struct flash_test_ctx {
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
@ -87,3 +89,81 @@ TEST_CASE("flash write and erase work both on PRO CPU and on APP CPU", "[spi_fla
|
|||||||
vSemaphoreDelete(done);
|
vSemaphoreDelete(done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t buf_size;
|
||||||
|
uint8_t* buf;
|
||||||
|
size_t flash_addr;
|
||||||
|
size_t repeat_count;
|
||||||
|
SemaphoreHandle_t done;
|
||||||
|
} read_task_arg_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t delay_time_us;
|
||||||
|
size_t repeat_count;
|
||||||
|
} block_task_arg_t;
|
||||||
|
|
||||||
|
static void IRAM_ATTR timer_isr(void* varg) {
|
||||||
|
block_task_arg_t* arg = (block_task_arg_t*) varg;
|
||||||
|
TIMERG0.int_clr_timers.t0 = 1;
|
||||||
|
TIMERG0.hw_timer[0].config.alarm_en = 1;
|
||||||
|
ets_delay_us(arg->delay_time_us);
|
||||||
|
arg->repeat_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void read_task(void* varg) {
|
||||||
|
read_task_arg_t* arg = (read_task_arg_t*) varg;
|
||||||
|
for (size_t i = 0; i < arg->repeat_count; ++i) {
|
||||||
|
ESP_ERROR_CHECK( spi_flash_read(arg->flash_addr, arg->buf, arg->buf_size) );
|
||||||
|
}
|
||||||
|
xSemaphoreGive(arg->done);
|
||||||
|
vTaskDelay(1);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("spi flash functions can run along with IRAM interrupts", "[spi_flash]")
|
||||||
|
{
|
||||||
|
const size_t size = 128;
|
||||||
|
read_task_arg_t read_arg = {
|
||||||
|
.buf_size = size,
|
||||||
|
.buf = (uint8_t*) malloc(size),
|
||||||
|
.flash_addr = 0,
|
||||||
|
.repeat_count = 1000,
|
||||||
|
.done = xSemaphoreCreateBinary()
|
||||||
|
};
|
||||||
|
|
||||||
|
timer_config_t config = {
|
||||||
|
.alarm_en = true,
|
||||||
|
.counter_en = false,
|
||||||
|
.intr_type = TIMER_INTR_LEVEL,
|
||||||
|
.counter_dir = TIMER_COUNT_UP,
|
||||||
|
.auto_reload = true,
|
||||||
|
.divider = 80
|
||||||
|
};
|
||||||
|
|
||||||
|
block_task_arg_t block_arg = {
|
||||||
|
.repeat_count = 0,
|
||||||
|
.delay_time_us = 100
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK( timer_init(TIMER_GROUP_0, TIMER_0, &config) );
|
||||||
|
timer_pause(TIMER_GROUP_0, TIMER_0);
|
||||||
|
ESP_ERROR_CHECK( timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 120) );
|
||||||
|
intr_handle_t handle;
|
||||||
|
ESP_ERROR_CHECK( timer_isr_register(TIMER_GROUP_0, TIMER_0, &timer_isr, &block_arg, ESP_INTR_FLAG_IRAM, &handle) );
|
||||||
|
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
|
||||||
|
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
|
||||||
|
timer_start(TIMER_GROUP_0, TIMER_0);
|
||||||
|
|
||||||
|
xTaskCreatePinnedToCore(read_task, "r", 2048, &read_arg, 3, NULL, 1);
|
||||||
|
xSemaphoreTake(read_arg.done, portMAX_DELAY);
|
||||||
|
|
||||||
|
timer_pause(TIMER_GROUP_0, TIMER_0);
|
||||||
|
timer_disable_intr(TIMER_GROUP_0, TIMER_0);
|
||||||
|
esp_intr_free(handle);
|
||||||
|
vSemaphoreDelete(read_arg.done);
|
||||||
|
free(read_arg.buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,39 @@ typedef enum{
|
|||||||
TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52, /**< request IP address retry counter */
|
TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52, /**< request IP address retry counter */
|
||||||
} tcpip_adapter_option_id_t;
|
} tcpip_adapter_option_id_t;
|
||||||
|
|
||||||
|
struct tcpip_adapter_api_msg_s;
|
||||||
|
typedef int (*tcpip_adapter_api_fn)(struct tcpip_adapter_api_msg_s *msg);
|
||||||
|
typedef struct tcpip_adapter_api_msg_s {
|
||||||
|
int type; /**< The first field MUST be int */
|
||||||
|
int ret;
|
||||||
|
tcpip_adapter_api_fn api_fn;
|
||||||
|
tcpip_adapter_if_t tcpip_if;
|
||||||
|
tcpip_adapter_ip_info_t *ip_info;
|
||||||
|
uint8_t *mac;
|
||||||
|
const char *hostname;
|
||||||
|
} tcpip_adapter_api_msg_t;
|
||||||
|
|
||||||
|
#define TCPIP_ADAPTER_TRHEAD_SAFE 1
|
||||||
|
#define TCPIP_ADAPTER_IPC_LOCAL 0
|
||||||
|
#define TCPIP_ADAPTER_IPC_REMOTE 1
|
||||||
|
|
||||||
|
#define TCPIP_ADAPTER_IPC_CALL(_if, _mac, _ip, _hostname, _fn) do {\
|
||||||
|
tcpip_adapter_api_msg_t msg;\
|
||||||
|
memset(&msg, 0, sizeof(msg));\
|
||||||
|
msg.tcpip_if = (_if);\
|
||||||
|
msg.mac = (_mac);\
|
||||||
|
msg.ip_info = (_ip);\
|
||||||
|
msg.hostname = (_hostname);\
|
||||||
|
msg.api_fn = (_fn);\
|
||||||
|
if (TCPIP_ADAPTER_IPC_REMOTE == tcpip_adapter_ipc_check(&msg)) {\
|
||||||
|
ESP_LOGD(TAG, "check: remote, if=%d fn=%p\n", (_if), (_fn));\
|
||||||
|
return msg.ret;\
|
||||||
|
} else {\
|
||||||
|
ESP_LOGD(TAG, "check: local, if=%d fn=%p\n", (_if), (_fn));\
|
||||||
|
}\
|
||||||
|
}while(0)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize tcpip adapter
|
* @brief Initialize tcpip adapter
|
||||||
*
|
*
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/ip6_addr.h"
|
#include "lwip/ip6_addr.h"
|
||||||
#include "lwip/nd6.h"
|
#include "lwip/nd6.h"
|
||||||
|
#include "lwip/priv/tcpip_priv.h"
|
||||||
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
||||||
#include "lwip/dns.h"
|
#include "lwip/dns.h"
|
||||||
#endif
|
#endif
|
||||||
@ -34,6 +35,7 @@
|
|||||||
#include "apps/dhcpserver.h"
|
#include "apps/dhcpserver.h"
|
||||||
|
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
|
static struct netif *esp_netif[TCPIP_ADAPTER_IF_MAX];
|
||||||
static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX];
|
static tcpip_adapter_ip_info_t esp_ip[TCPIP_ADAPTER_IF_MAX];
|
||||||
@ -41,13 +43,42 @@ static tcpip_adapter_ip6_info_t esp_ip6[TCPIP_ADAPTER_IF_MAX];
|
|||||||
|
|
||||||
static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
static tcpip_adapter_dhcp_status_t dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
||||||
static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT};
|
static tcpip_adapter_dhcp_status_t dhcpc_status[TCPIP_ADAPTER_IF_MAX] = {TCPIP_ADAPTER_DHCP_INIT};
|
||||||
|
static esp_err_t tcpip_adapter_start_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg);
|
||||||
|
static sys_sem_t api_sync_sem = NULL;
|
||||||
|
extern sys_thread_t g_lwip_task;
|
||||||
|
|
||||||
#define TCPIP_ADAPTER_DEBUG(...)
|
#define TAG "tcpip_adapter"
|
||||||
//#define TCPIP_ADAPTER_DEBUG printf
|
|
||||||
|
static void tcpip_adapter_api_cb(void* api_msg)
|
||||||
|
{
|
||||||
|
tcpip_adapter_api_msg_t *msg = (tcpip_adapter_api_msg_t*)api_msg;
|
||||||
|
|
||||||
|
if (!msg || !msg->api_fn) {
|
||||||
|
ESP_LOGD(TAG, "null msg/api_fn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg->ret = msg->api_fn(msg);
|
||||||
|
ESP_LOGD(TAG, "call api in lwip: ret=0x%x, give sem", msg->ret);
|
||||||
|
sys_sem_signal(&api_sync_sem);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void tcpip_adapter_init(void)
|
void tcpip_adapter_init(void)
|
||||||
{
|
{
|
||||||
static bool tcpip_inited = false;
|
static bool tcpip_inited = false;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (tcpip_inited == false) {
|
if (tcpip_inited == false) {
|
||||||
tcpip_inited = true;
|
tcpip_inited = true;
|
||||||
@ -57,6 +88,10 @@ void tcpip_adapter_init(void)
|
|||||||
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
|
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].ip, 192, 168 , 4, 1);
|
||||||
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
|
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].gw, 192, 168 , 4, 1);
|
||||||
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
|
IP4_ADDR(&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, 255, 255 , 255, 0);
|
||||||
|
ret = sys_sem_new(&api_sync_sem, 0);
|
||||||
|
if (ERR_OK != ret) {
|
||||||
|
ESP_LOGD(TAG, "tcpip adatper api sync sem init fail");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,10 +112,29 @@ static netif_init_fn tcpip_if_to_netif_init_fn(tcpip_adapter_if_t tcpip_if)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tcpip_adapter_ipc_check(tcpip_adapter_api_msg_t *msg)
|
||||||
|
{
|
||||||
|
#if TCPIP_ADAPTER_TRHEAD_SAFE
|
||||||
|
xTaskHandle local_task = xTaskGetCurrentTaskHandle();
|
||||||
|
|
||||||
|
if (local_task == g_lwip_task) {
|
||||||
|
return TCPIP_ADAPTER_IPC_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcpip_send_api_msg((tcpip_callback_fn)tcpip_adapter_api_cb, msg, &api_sync_sem);
|
||||||
|
|
||||||
|
return TCPIP_ADAPTER_IPC_REMOTE;
|
||||||
|
#else
|
||||||
|
return TCPIP_ADAPTER_IPC_LOCAL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
|
esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
|
||||||
{
|
{
|
||||||
netif_init_fn netif_init;
|
netif_init_fn netif_init;
|
||||||
|
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, mac, ip_info, 0, tcpip_adapter_start_api);
|
||||||
|
|
||||||
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) {
|
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || mac == NULL || ip_info == NULL) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
@ -103,7 +157,7 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a
|
|||||||
if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
|
if (dhcps_status == TCPIP_ADAPTER_DHCP_INIT) {
|
||||||
dhcps_start(esp_netif[tcpip_if], ip_info->ip);
|
dhcps_start(esp_netif[tcpip_if], ip_info->ip);
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")\n",
|
ESP_LOGD(TAG, "dhcp server start:(ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR ")",
|
||||||
IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
|
IP2STR(&ip_info->ip), IP2STR(&ip_info->netmask), IP2STR(&ip_info->gw));
|
||||||
|
|
||||||
dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
|
dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
|
||||||
@ -122,8 +176,15 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_start_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_start(msg->tcpip_if, msg->mac, msg->ip_info);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_stop_api);
|
||||||
|
|
||||||
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
@ -162,8 +223,16 @@ esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_stop_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
msg->ret = tcpip_adapter_stop(msg->tcpip_if);
|
||||||
|
return msg->ret;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_up_api);
|
||||||
|
|
||||||
if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
|
if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
|
||||||
if (esp_netif[tcpip_if] == NULL) {
|
if (esp_netif[tcpip_if] == NULL) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
||||||
@ -177,8 +246,16 @@ esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_up_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
msg->ret = tcpip_adapter_up(msg->tcpip_if);
|
||||||
|
return msg->ret;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_down_api);
|
||||||
|
|
||||||
if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
|
if (tcpip_if == TCPIP_ADAPTER_IF_STA || tcpip_if == TCPIP_ADAPTER_IF_ETH ) {
|
||||||
if (esp_netif[tcpip_if] == NULL) {
|
if (esp_netif[tcpip_if] == NULL) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
||||||
@ -203,6 +280,11 @@ esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_down_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_down(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
|
esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
|
||||||
{
|
{
|
||||||
struct netif *p_netif;
|
struct netif *p_netif;
|
||||||
@ -233,6 +315,8 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i
|
|||||||
struct netif *p_netif;
|
struct netif *p_netif;
|
||||||
tcpip_adapter_dhcp_status_t status;
|
tcpip_adapter_dhcp_status_t status;
|
||||||
|
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, ip_info, 0, tcpip_adapter_set_ip_info_api);
|
||||||
|
|
||||||
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL ||
|
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL ||
|
||||||
ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask)) {
|
ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask)) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
@ -271,12 +355,17 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_set_ip_info_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_set_ip_info(msg->tcpip_if, msg->ip_info);
|
||||||
|
}
|
||||||
|
|
||||||
static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
|
static void tcpip_adapter_nd6_cb(struct netif *p_netif, uint8_t ip_idex)
|
||||||
{
|
{
|
||||||
tcpip_adapter_ip6_info_t *ip6_info;
|
tcpip_adapter_ip6_info_t *ip6_info;
|
||||||
|
|
||||||
if (!p_netif) {
|
if (!p_netif) {
|
||||||
TCPIP_ADAPTER_DEBUG("null p_netif=%p\n", p_netif);
|
ESP_LOGD(TAG, "null p_netif=%p", p_netif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +391,8 @@ esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
|
|||||||
{
|
{
|
||||||
struct netif *p_netif;
|
struct netif *p_netif;
|
||||||
|
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_create_ip6_linklocal_api);
|
||||||
|
|
||||||
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
@ -317,6 +408,11 @@ esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_create_ip6_linklocal_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_create_ip6_linklocal(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
|
esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
|
||||||
{
|
{
|
||||||
struct netif *p_netif;
|
struct netif *p_netif;
|
||||||
@ -474,9 +570,11 @@ esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adap
|
|||||||
|
|
||||||
esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_start_api);
|
||||||
|
|
||||||
/* only support ap now */
|
/* only support ap now */
|
||||||
if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server invalid if=%d\n", tcpip_if);
|
ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if);
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,24 +586,32 @@ esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
|
|||||||
tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip);
|
tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &default_ip);
|
||||||
dhcps_start(p_netif, default_ip.ip);
|
dhcps_start(p_netif, default_ip.ip);
|
||||||
dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
|
dhcps_status = TCPIP_ADAPTER_DHCP_STARTED;
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server start successfully\n");
|
ESP_LOGD(TAG, "dhcp server start successfully");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server re init\n");
|
ESP_LOGD(TAG, "dhcp server re init");
|
||||||
dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
dhcps_status = TCPIP_ADAPTER_DHCP_INIT;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server already start\n");
|
ESP_LOGD(TAG, "dhcp server already start");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
|
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_dhcps_start_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_dhcps_start(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcps_stop_api);
|
||||||
|
|
||||||
/* only support ap now */
|
/* only support ap now */
|
||||||
if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if (tcpip_if != TCPIP_ADAPTER_IF_AP || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server invalid if=%d\n", tcpip_if);
|
ESP_LOGD(TAG, "dhcp server invalid if=%d", tcpip_if);
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,19 +621,24 @@ esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
|
|||||||
if (p_netif != NULL) {
|
if (p_netif != NULL) {
|
||||||
dhcps_stop(p_netif);
|
dhcps_stop(p_netif);
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server if not ready\n");
|
ESP_LOGD(TAG, "dhcp server if not ready");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
||||||
}
|
}
|
||||||
} else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
|
} else if (dhcps_status == TCPIP_ADAPTER_DHCP_STOPPED) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server already stoped\n");
|
ESP_LOGD(TAG, "dhcp server already stoped");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
|
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp server stop successfully\n");
|
ESP_LOGD(TAG, "dhcp server stop successfully");
|
||||||
dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED;
|
dhcps_status = TCPIP_ADAPTER_DHCP_STOPPED;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_dhcps_stop_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_dhcps_stop(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len)
|
esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_adapter_option_id_t opt_id, void *opt_val, uint32_t opt_len)
|
||||||
{
|
{
|
||||||
// TODO: when dhcp request timeout,change the retry count
|
// TODO: when dhcp request timeout,change the retry count
|
||||||
@ -537,12 +648,12 @@ esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_option_mode_t opt_op, tcpip_a
|
|||||||
static void tcpip_adapter_dhcpc_cb(struct netif *netif)
|
static void tcpip_adapter_dhcpc_cb(struct netif *netif)
|
||||||
{
|
{
|
||||||
if (!netif) {
|
if (!netif) {
|
||||||
TCPIP_ADAPTER_DEBUG("null netif=%p\n", netif);
|
ESP_LOGD(TAG, "null netif=%p", netif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netif != esp_netif[TCPIP_ADAPTER_IF_STA] && netif != esp_netif[TCPIP_ADAPTER_IF_ETH]) {
|
if (netif != esp_netif[TCPIP_ADAPTER_IF_STA] && netif != esp_netif[TCPIP_ADAPTER_IF_ETH]) {
|
||||||
TCPIP_ADAPTER_DEBUG("err netif=%p\n", netif);
|
ESP_LOGD(TAG, "err netif=%p", netif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +686,7 @@ static void tcpip_adapter_dhcpc_cb(struct netif *netif)
|
|||||||
|
|
||||||
esp_event_send(&evt);
|
esp_event_send(&evt);
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("ip unchanged\n");
|
ESP_LOGD(TAG, "ip unchanged");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,9 +702,11 @@ esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adap
|
|||||||
|
|
||||||
esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_start_api);
|
||||||
|
|
||||||
/* only support sta now, need to support ethernet */
|
/* only support sta now, need to support ethernet */
|
||||||
if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if ((tcpip_if != TCPIP_ADAPTER_IF_STA && tcpip_if != TCPIP_ADAPTER_IF_ETH) || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client invalid if=%d\n", tcpip_if);
|
ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if);
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,42 +719,49 @@ esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
|
|||||||
|
|
||||||
if (p_netif != NULL) {
|
if (p_netif != NULL) {
|
||||||
if (netif_is_up(p_netif)) {
|
if (netif_is_up(p_netif)) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client init ip/mask/gw to all-0\n");
|
ESP_LOGD(TAG, "dhcp client init ip/mask/gw to all-0");
|
||||||
ip_addr_set_zero(&p_netif->ip_addr);
|
ip_addr_set_zero(&p_netif->ip_addr);
|
||||||
ip_addr_set_zero(&p_netif->netmask);
|
ip_addr_set_zero(&p_netif->netmask);
|
||||||
ip_addr_set_zero(&p_netif->gw);
|
ip_addr_set_zero(&p_netif->gw);
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
|
ESP_LOGD(TAG, "dhcp client re init");
|
||||||
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
|
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dhcp_start(p_netif) != ERR_OK) {
|
if (dhcp_start(p_netif) != ERR_OK) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client start failed\n");
|
ESP_LOGD(TAG, "dhcp client start failed");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED;
|
return ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb);
|
dhcp_set_cb(p_netif, tcpip_adapter_dhcpc_cb);
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client start successfully\n");
|
ESP_LOGD(TAG, "dhcp client start successfully");
|
||||||
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED;
|
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STARTED;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client re init\n");
|
ESP_LOGD(TAG, "dhcp client re init");
|
||||||
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
|
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_INIT;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client already started\n");
|
ESP_LOGD(TAG, "dhcp client already started");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
|
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_dhcpc_start_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_dhcpc_start(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
|
esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
|
||||||
{
|
{
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, 0, tcpip_adapter_dhcpc_stop_api);
|
||||||
|
|
||||||
/* only support sta now, need to support ethernet */
|
/* only support sta now, need to support ethernet */
|
||||||
if (tcpip_if != TCPIP_ADAPTER_IF_STA || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
if (tcpip_if != TCPIP_ADAPTER_IF_STA || tcpip_if >= TCPIP_ADAPTER_IF_MAX) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client invalid if=%d\n", tcpip_if);
|
ESP_LOGD(TAG, "dhcp client invalid if=%d", tcpip_if);
|
||||||
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,19 +775,24 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
|
|||||||
ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
|
ip4_addr_set_zero(&esp_ip[tcpip_if].gw);
|
||||||
ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
|
ip4_addr_set_zero(&esp_ip[tcpip_if].netmask);
|
||||||
} else {
|
} else {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client if not ready\n");
|
ESP_LOGD(TAG, "dhcp client if not ready");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
return ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY;
|
||||||
}
|
}
|
||||||
} else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) {
|
} else if (dhcpc_status[tcpip_if] == TCPIP_ADAPTER_DHCP_STOPPED) {
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client already stoped\n");
|
ESP_LOGD(TAG, "dhcp client already stoped");
|
||||||
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
|
return ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPIP_ADAPTER_DEBUG("dhcp client stop successfully\n");
|
ESP_LOGD(TAG, "dhcp client stop successfully");
|
||||||
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
|
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_dhcpc_stop_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_dhcpc_stop(msg->tcpip_if);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
|
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
|
||||||
{
|
{
|
||||||
ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len);
|
ethernetif_input(esp_netif[TCPIP_ADAPTER_IF_ETH], buffer, len);
|
||||||
@ -730,6 +855,7 @@ esp_err_t tcpip_adapter_get_sta_list(wifi_sta_list_t *wifi_sta_list, tcpip_adapt
|
|||||||
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
|
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
|
||||||
{
|
{
|
||||||
#if LWIP_NETIF_HOSTNAME
|
#if LWIP_NETIF_HOSTNAME
|
||||||
|
TCPIP_ADAPTER_IPC_CALL(tcpip_if, 0, 0, hostname, tcpip_adapter_set_hostname_api);
|
||||||
struct netif *p_netif;
|
struct netif *p_netif;
|
||||||
static char hostinfo[TCPIP_ADAPTER_IF_MAX][TCPIP_HOSTNAME_MAX_SIZE + 1];
|
static char hostinfo[TCPIP_ADAPTER_IF_MAX][TCPIP_HOSTNAME_MAX_SIZE + 1];
|
||||||
|
|
||||||
@ -755,6 +881,11 @@ esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *ho
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t tcpip_adapter_set_hostname_api(tcpip_adapter_api_msg_t * msg)
|
||||||
|
{
|
||||||
|
return tcpip_adapter_set_hostname(msg->tcpip_if, msg->hostname);
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
|
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
|
||||||
{
|
{
|
||||||
#if LWIP_NETIF_HOSTNAME
|
#if LWIP_NETIF_HOSTNAME
|
||||||
|
@ -56,7 +56,7 @@ You can also find a range of example projects under the "examples" directory in
|
|||||||
Step 4: Configuring the project
|
Step 4: Configuring the project
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
Open an MSYS2 terminal window by running ``C:\msys32\msys2_shell.cmd``. The environment in this window is a bash shell.
|
Open an MSYS2 terminal window by running ``C:\msys32\mingw32.exe``. The environment in this window is a bash shell.
|
||||||
|
|
||||||
Type a command like this to set the path to ESP-IDF directory: ``export IDF_PATH="C:/path/to/esp-idf"`` (note the forward-slashes not back-slashes for the path). If you don't want to run this command every time you open an MSYS2 window, create a new file in ``C:/msys32/etc/profile.d/`` and paste this line in - then it will be run each time you open an MYS2 terminal.
|
Type a command like this to set the path to ESP-IDF directory: ``export IDF_PATH="C:/path/to/esp-idf"`` (note the forward-slashes not back-slashes for the path). If you don't want to run this command every time you open an MSYS2 window, create a new file in ``C:/msys32/etc/profile.d/`` and paste this line in - then it will be run each time you open an MYS2 terminal.
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
|
|
||||||
|
/* Some definitions applicable to Unity running in FreeRTOS */
|
||||||
|
#define UNITY_FREERTOS_PRIORITY 5
|
||||||
|
#define UNITY_FREERTOS_CPU 0
|
||||||
|
|
||||||
#define UNITY_EXCLUDE_FLOAT
|
#define UNITY_EXCLUDE_FLOAT
|
||||||
#define UNITY_EXCLUDE_DOUBLE
|
#define UNITY_EXCLUDE_DOUBLE
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
#include "unity_config.h"
|
||||||
|
|
||||||
|
void unityTask(void *pvParameters)
|
||||||
void unityTask(void *pvParameters)
|
|
||||||
{
|
{
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
unity_run_menu();
|
unity_run_menu();
|
||||||
@ -15,6 +15,6 @@ void app_main()
|
|||||||
{
|
{
|
||||||
// Note: if unpinning this task, change the way run times are calculated in
|
// Note: if unpinning this task, change the way run times are calculated in
|
||||||
// unity_platform
|
// unity_platform
|
||||||
xTaskCreatePinnedToCore(unityTask, "unityTask", 4096, NULL, 5, NULL, 0);
|
xTaskCreatePinnedToCore(unityTask, "unityTask", 4096, NULL,
|
||||||
|
UNITY_FREERTOS_PRIORITY, NULL, UNITY_FREERTOS_CPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user