Recursos do buffer FIFO UART no ESP32

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; /*This register stores the rx mem read address.*/ uint32_t wr_addr: 11; /*This register stores the rx mem write address.*/ 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çosUART
0x00 ... 0x7FUART0 TX_FIFO
0x80 ... 0xFFUART1 TX_FIFO
0x100 ... 0x17FUART2 TX_FIFO
0x180 ... 0x1FFUART0 RX_FIFO
0x200 ... 0x27FUART1 RX_FIFO
0x280 ... 0x2FFUART2 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:

  1. 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;
  2. A quantidade de memória compartilhada FIFO UART = 1Kb.

Source: https://habr.com/ru/post/pt419955/


All Articles