ESP32 UART Read Bytes Function: uart_read_bytes
The function uart_read_bytes is used to read a specified number of bytes from the UART receive buffer and store them into the given buffer.
The function first checks the validity of the input parameters, then waits for available data. Once data is available, the function reads the data from the ring buffer and copies it to the given buffer. If the read data length is less than the requested length, the function continues to wait for more data. The function returns the actual length of data read.
int uart_read_bytes(uart_port_t uart_num, void *buf, uint32_t length, TickType_t ticks_to_wait)
{
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), (-1), UART_TAG, 'uart_num error');
ESP_RETURN_ON_FALSE((buf), (-1), UART_TAG, 'uart data null');
ESP_RETURN_ON_FALSE((p_uart_obj[uart_num]), (-1), UART_TAG, 'uart driver error');
uint8_t *data = NULL;
size_t size;
size_t copy_len = 0;
int len_tmp;
if (xSemaphoreTake(p_uart_obj[uart_num]->rx_mux, (TickType_t)ticks_to_wait) != pdTRUE) {
return -1;
}
while (length) {
if (p_uart_obj[uart_num]->rx_cur_remain == 0) {
data = (uint8_t *) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (TickType_t) ticks_to_wait);
if (data) {
p_uart_obj[uart_num]->rx_head_ptr = data;
p_uart_obj[uart_num]->rx_ptr = data;
p_uart_obj[uart_num]->rx_cur_remain = size;
} else {
//When using dual cores, 'rx_buffer_full_flg' may read and write on different cores at same time,
//which may lose synchronization. So we also need to call 'uart_check_buf_full' once when ringbuffer is empty
//to solve the possible asynchronous issues.
if (uart_check_buf_full(uart_num)) {
//This condition will never be true if 'uart_read_bytes'
//and 'uart_rx_intr_handler_default' are scheduled on the same core.
continue;
} else {
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
return copy_len;
}
}
}
if (p_uart_obj[uart_num]->rx_cur_remain > length) {
len_tmp = length;
} else {
len_tmp = p_uart_obj[uart_num]->rx_cur_remain;
}
memcpy((uint8_t *)buf + copy_len, p_uart_obj[uart_num]->rx_ptr, len_tmp);
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
p_uart_obj[uart_num]->rx_buffered_len -= len_tmp;
uart_pattern_queue_update(uart_num, len_tmp);
p_uart_obj[uart_num]->rx_ptr += len_tmp;
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
p_uart_obj[uart_num]->rx_cur_remain -= len_tmp;
copy_len += len_tmp;
length -= len_tmp;
if (p_uart_obj[uart_num]->rx_cur_remain == 0) {
vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr);
p_uart_obj[uart_num]->rx_head_ptr = NULL;
p_uart_obj[uart_num]->rx_ptr = NULL;
uart_check_buf_full(uart_num);
}
}
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
return copy_len;
}
原文地址: https://www.cveoy.top/t/topic/fZeC 著作权归作者所有。请勿转载和采集!