O ESP32 possui três UARTs. Cada um dos quais coloca o buffer FIFO do receptor e o buffer FIFO do transmissor em uma memória compartilhada de 1024 bytes (manual de referência técnica ESP32 3.5):
No entanto, quando tentei aumentar o tamanho do buffer FIFO do transmissor UART2 de 128 para 256 bytes, recebi um efeito inesperado - os dados transmitidos estragaram o buffer FIFO do receptor UART0, que, de acordo com a documentação, não deveria ser.
Infelizmente na documentação (manual de referência técnica ESP32 3.5) não há descrição dos registros de buffer FIFO. No entanto, nos arquivos de cabeçalho esp-idf (em uart_struct.h) foram encontrados:
1) Registro de status FIFO do buffer do transmissor (deslocamento relativo ao endereço base 0x5c):
union { struct { uint32_t status:24; uint32_t reserved24: 8; }; uint32_t val; } mem_tx_status;
2) Registro de status FIFO do buffer do receptor (deslocamento relativo ao endereço base 0x60):
union { struct { uint32_t status: 24; uint32_t reserved24: 8; }; struct { uint32_t reserved0: 2; uint32_t rd_addr: 11; uint32_t wr_addr: 11; uint32_t reserved: 8; }; uint32_t val; } mem_rx_status;
Supondo que mem_tx_status corresponda à finalidade dos bits mem_rx_status, escrevemos o código a seguir para obter os endereços dos buffers FIFO:
#include "freertos/FreeRTOS.h" #include "freertos/task.h" #include <driver/uart.h> void print_uart_st(uart_dev_t *u,int num) { printf("UART%d:\n",num); printf("rx_st=0x%X\n",(unsigned int)u->mem_rx_status.val); printf("rx_rd=0x%X\n",(unsigned int)u->mem_rx_status.rd_addr); printf("rx_wr=0x%X\n",(unsigned int)u->mem_rx_status.wr_addr); uint32_t tx_s = u->mem_tx_status.val; printf("tx_st=0x%X\n",tx_s); printf("tx_rd=0x%X\n",(tx_s>>2)&2047); printf("tx_wr=0x%X\n",(tx_s>>13)&2047); } uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; void UARTtest(void * param) { uart_param_config(UART_NUM_1,&uart_config); uart_param_config(UART_NUM_2,&uart_config); uart_driver_install(UART_NUM_1, 256, 0, 0, NULL, 0); uart_driver_install(UART_NUM_2, 256, 0, 0, NULL, 0); uart_set_pin(UART_NUM_1, UART_PIN_NO_CHANGE, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_set_pin(UART_NUM_2, UART_PIN_NO_CHANGE, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); vTaskDelay(1000/portTICK_PERIOD_MS); while (1) { print_uart_st(&UART0,0); print_uart_st(&UART1,1); print_uart_st(&UART2,2); vTaskDelay(2000/portTICK_PERIOD_MS); char s[256]; uart_write_bytes(UART_NUM_1, s, 1); uart_write_bytes(UART_NUM_2, s, 2); if(gets(s)!=NULL) { printf("recived=%s\n",s); } } } void app_main(void) { xTaskCreate(UARTtest, "UARTtest", 4096, NULL, 5, NULL); }
Após o início, obtemos:
UART0:
rx_st = 0x300600
rx_rd = 0x180
rx_wr = 0x180
tx_st = 0xCE058
tx_rd = 0x16
tx_wr = 0x67
UART1:
rx_st = 0x400800
rx_rd = 0x200
rx_wr = 0x200
tx_st = 0x100200
tx_rd = 0x80
tx_wr = 0x80
UART2:
rx_st = 0x500A00
rx_rd = 0x280
rx_wr = 0x280
tx_st = 0x200400
tx_rd = 0x100
tx_wr = 0x100
A saída é realizada através do UART0, portanto tx_wr e tx_rd são diferentes de 0. De acordo com os resultados obtidos, a alocação de memória entre os buffers FIFO UART0,1,2 é a seguinte:
Endereços | UART |
---|
0x00 ... 0x7F | UART0 TX_FIFO |
0x80 ... 0xFF | UART1 TX_FIFO |
0x100 ... 0x17F | UART2 TX_FIFO |
0x180 ... 0x1FF | UART0 RX_FIFO |
0x200 ... 0x27F | UART1 RX_FIFO |
0x280 ... 0x2FF | UART2 RX_FIFO |
Além disso, os registros de status dos buffers FIFO têm uma capacidade de 11 bits, o que significa que o tamanho da memória alocada para o buffer FIFO = 2 KB é possível. Ao definir UART0.mem_conf.tx_size = 15 (a memória é alocada em pedaços de 128 bytes), 1920 bytes serão alocados e o registro tx_wr será contado até 1919 durante a transmissão e continuará contando até 0. No entanto, a memória é endereçada apenas em ml. 10 bits, isto é, memória total real alocada para o buffer FIFO = 1Kb.
Total:
- A alocação de memória compartilhada alocada para ESP32 para FIFO UART não corresponde ao manual de referência técnica 3.5;
- A quantidade de memória compartilhada FIFO UART = 1Kb.