fix(spi_master): release temporary memory when queue new trans timeout.

This commit is contained in:
michael 2017-11-17 11:25:44 +08:00
parent 13d38f10ee
commit 02573a8dc9

View file

@ -627,6 +627,7 @@ static void IRAM_ATTR spi_intr(void *arg)
esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait)
{
esp_err_t ret = ESP_OK;
BaseType_t r;
SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG);
//check transmission length
@ -662,7 +663,10 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
//if rxbuf in the desc not DMA-capable, malloc a new one. The rx buffer need to be length of multiples of 32 bits to avoid heap corruption.
ESP_LOGV( SPI_TAG, "Allocate RX buffer for DMA" );
trans_buf.buffer_to_rcv = heap_caps_malloc((trans_desc->rxlength+31)/8, MALLOC_CAP_DMA);
if ( trans_buf.buffer_to_rcv==NULL ) return ESP_ERR_NO_MEM;
if ( trans_buf.buffer_to_rcv==NULL ) {
ret = ESP_ERR_NO_MEM;
goto clean_up;
}
}
const uint32_t *txdata;
@ -678,25 +682,40 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
ESP_LOGV( SPI_TAG, "Allocate TX buffer for DMA" );
trans_buf.buffer_to_send = heap_caps_malloc((trans_desc->length+7)/8, MALLOC_CAP_DMA);
if ( trans_buf.buffer_to_send==NULL ) {
// free malloc-ed buffer (if needed) before return.
if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
free( trans_buf.buffer_to_rcv );
}
return ESP_ERR_NO_MEM;
ret = ESP_ERR_NO_MEM;
goto clean_up;
}
memcpy( trans_buf.buffer_to_send, txdata, (trans_desc->length+7)/8 );
} else {
// else use the original buffer (forced-conversion) or assign to NULL
trans_buf.buffer_to_send = (uint32_t*)txdata;
}
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_acquire(handle->host->pm_lock);
#endif
r=xQueueSend(handle->trans_queue, (void*)&trans_buf, ticks_to_wait);
if (!r) return ESP_ERR_TIMEOUT;
if (!r) {
ret = ESP_ERR_TIMEOUT;
#ifdef CONFIG_PM_ENABLE
//Release APB frequency lock
esp_pm_lock_release(handle->host->pm_lock);
#endif
goto clean_up;
}
esp_intr_enable(handle->host->intr);
return ESP_OK;
clean_up:
// free malloc-ed buffer (if needed) before return.
if ( (void*)trans_buf.buffer_to_rcv != trans_desc->rx_buffer && (void*)trans_buf.buffer_to_rcv != &trans_desc->rx_data[0] ) {
free( trans_buf.buffer_to_rcv );
}
if ( (void*)trans_buf.buffer_to_send!= trans_desc->tx_buffer && (void*)trans_buf.buffer_to_send != &trans_desc->tx_data[0] ) {
free( trans_buf.buffer_to_send );
}
assert( ret != ESP_OK );
return ret;
}
esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait)