ethernet: bugfix and optimize
1. check frame length before pass to stack 2. replace semaphore with task notify
This commit is contained in:
parent
e659f1b15a
commit
305a4a1b57
3 changed files with 25 additions and 26 deletions
|
@ -114,7 +114,7 @@ menu "Ethernet"
|
||||||
|
|
||||||
config ETH_DMA_RX_BUFFER_NUM
|
config ETH_DMA_RX_BUFFER_NUM
|
||||||
int "Amount of Ethernet DMA Rx buffers"
|
int "Amount of Ethernet DMA Rx buffers"
|
||||||
range 3 20
|
range 3 30
|
||||||
default 10
|
default 10
|
||||||
help
|
help
|
||||||
Number of DMA receive buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
|
Number of DMA receive buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
|
||||||
|
@ -122,7 +122,7 @@ menu "Ethernet"
|
||||||
|
|
||||||
config ETH_DMA_TX_BUFFER_NUM
|
config ETH_DMA_TX_BUFFER_NUM
|
||||||
int "Amount of Ethernet DMA Tx buffers"
|
int "Amount of Ethernet DMA Tx buffers"
|
||||||
range 3 20
|
range 3 30
|
||||||
default 10
|
default 10
|
||||||
help
|
help
|
||||||
Number of DMA transmit buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
|
Number of DMA transmit buffers. Each buffer's size is ETH_DMA_BUFFER_SIZE.
|
||||||
|
|
|
@ -511,10 +511,14 @@ static void emac_dm9051_task(void *arg)
|
||||||
buffer = (uint8_t *)heap_caps_malloc(ETH_MAX_PACKET_SIZE, MALLOC_CAP_DMA);
|
buffer = (uint8_t *)heap_caps_malloc(ETH_MAX_PACKET_SIZE, MALLOC_CAP_DMA);
|
||||||
if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) {
|
if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) {
|
||||||
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
||||||
|
if (length) {
|
||||||
emac->eth->stack_input(emac->eth, buffer, length);
|
emac->eth->stack_input(emac->eth, buffer, length);
|
||||||
} else {
|
} else {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
} while (emac->packets_remain);
|
} while (emac->packets_remain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ typedef struct {
|
||||||
esp_eth_mediator_t *eth;
|
esp_eth_mediator_t *eth;
|
||||||
emac_hal_context_t hal;
|
emac_hal_context_t hal;
|
||||||
intr_handle_t intr_hdl;
|
intr_handle_t intr_hdl;
|
||||||
SemaphoreHandle_t rx_counting_sem;
|
|
||||||
TaskHandle_t rx_task_hdl;
|
TaskHandle_t rx_task_hdl;
|
||||||
uint32_t sw_reset_timeout_ms;
|
uint32_t sw_reset_timeout_ms;
|
||||||
uint32_t frames_remain;
|
uint32_t frames_remain;
|
||||||
|
@ -237,18 +236,20 @@ static void emac_esp32_rx_task(void *arg)
|
||||||
uint8_t *buffer = NULL;
|
uint8_t *buffer = NULL;
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (xSemaphoreTake(emac->rx_counting_sem, pdMS_TO_TICKS(RX_QUEUE_WAIT_MS)) == pdTRUE) {
|
if (ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(RX_QUEUE_WAIT_MS))) {
|
||||||
|
do {
|
||||||
buffer = (uint8_t *)malloc(ETH_MAX_PACKET_SIZE);
|
buffer = (uint8_t *)malloc(ETH_MAX_PACKET_SIZE);
|
||||||
if (emac_esp32_receive(&emac->parent, buffer, &length) == ESP_OK) {
|
if (emac_esp32_receive(&emac->parent, buffer, &length) == ESP_OK) {
|
||||||
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
||||||
|
if (length) {
|
||||||
emac->eth->stack_input(emac->eth, buffer, length);
|
emac->eth->stack_input(emac->eth, buffer, length);
|
||||||
} else {
|
} else {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
free(buffer);
|
||||||
}
|
}
|
||||||
/* there might be some frames left in DMA buffer */
|
} while (emac->frames_remain);
|
||||||
else if (emac->frames_remain) {
|
|
||||||
xSemaphoreGive(emac->rx_counting_sem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
|
@ -331,7 +332,6 @@ static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
|
||||||
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
|
||||||
esp_intr_free(emac->intr_hdl);
|
esp_intr_free(emac->intr_hdl);
|
||||||
vTaskDelete(emac->rx_task_hdl);
|
vTaskDelete(emac->rx_task_hdl);
|
||||||
vSemaphoreDelete(emac->rx_counting_sem);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
|
for (i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) {
|
||||||
free(emac->hal.rx_buf[i]);
|
free(emac->hal.rx_buf[i]);
|
||||||
|
@ -416,17 +416,12 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
|
||||||
MAC_CHECK(esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, emac_esp32_isr_handler,
|
MAC_CHECK(esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, emac_esp32_isr_handler,
|
||||||
&emac->hal, &(emac->intr_hdl)) == ESP_OK,
|
&emac->hal, &(emac->intr_hdl)) == ESP_OK,
|
||||||
"alloc emac interrupt failed", err_intr, NULL);
|
"alloc emac interrupt failed", err_intr, NULL);
|
||||||
/* create counting semaphore */
|
|
||||||
emac->rx_counting_sem = xSemaphoreCreateCounting(config->queue_len, 0);
|
|
||||||
MAC_CHECK(emac->rx_counting_sem, "create semaphore failed", err_sem, NULL);
|
|
||||||
/* create rx task */
|
/* create rx task */
|
||||||
BaseType_t xReturned = xTaskCreate(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac,
|
BaseType_t xReturned = xTaskCreate(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac,
|
||||||
config->rx_task_prio, &emac->rx_task_hdl);
|
config->rx_task_prio, &emac->rx_task_hdl);
|
||||||
MAC_CHECK(xReturned == pdPASS, "create emac_rx task failed", err_task, NULL);
|
MAC_CHECK(xReturned == pdPASS, "create emac_rx task failed", err_task, NULL);
|
||||||
return &(emac->parent);
|
return &(emac->parent);
|
||||||
err_task:
|
err_task:
|
||||||
vSemaphoreDelete(emac->rx_counting_sem);
|
|
||||||
err_sem:
|
|
||||||
esp_intr_free(emac->intr_hdl);
|
esp_intr_free(emac->intr_hdl);
|
||||||
err_intr:
|
err_intr:
|
||||||
for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
for (int i = 0; i < CONFIG_ETH_DMA_TX_BUFFER_NUM; i++) {
|
||||||
|
@ -448,8 +443,8 @@ void emac_hal_rx_complete_cb(void *arg)
|
||||||
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
|
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
|
||||||
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
|
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
|
||||||
BaseType_t high_task_wakeup;
|
BaseType_t high_task_wakeup;
|
||||||
/* send message to rx thread */
|
/* notify receive task */
|
||||||
xSemaphoreGiveFromISR(emac->rx_counting_sem, &high_task_wakeup);
|
vTaskNotifyGiveFromISR(emac->rx_task_hdl, &high_task_wakeup);
|
||||||
if (high_task_wakeup == pdTRUE) {
|
if (high_task_wakeup == pdTRUE) {
|
||||||
emac->isr_need_yield = true;
|
emac->isr_need_yield = true;
|
||||||
}
|
}
|
||||||
|
@ -460,8 +455,8 @@ void emac_hal_rx_unavail_cb(void *arg)
|
||||||
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
|
emac_hal_context_t *hal = (emac_hal_context_t *)arg;
|
||||||
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
|
emac_esp32_t *emac = __containerof(hal, emac_esp32_t, hal);
|
||||||
BaseType_t high_task_wakeup;
|
BaseType_t high_task_wakeup;
|
||||||
/* send message to rx thread */
|
/* notify receive task */
|
||||||
xSemaphoreGiveFromISR(emac->rx_counting_sem, &high_task_wakeup);
|
vTaskNotifyGiveFromISR(emac->rx_task_hdl, &high_task_wakeup);
|
||||||
if (high_task_wakeup == pdTRUE) {
|
if (high_task_wakeup == pdTRUE) {
|
||||||
emac->isr_need_yield = true;
|
emac->isr_need_yield = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue