Funktionen des FIFO-UART-Puffers in ESP32

ESP32 verfügt über drei UARTs. Jeder von ihnen legt den FIFO-Puffer des Empfängers und den FIFO-Puffer des Senders in einem gemeinsamen Speicher von 1024 Bytes ab (ESP32 Technisches Referenzhandbuch 3.5):



Als ich jedoch versuchte, den FIFO-Puffer des UART2-Senders von 128 auf 256 Byte zu vergrößern, erhielt ich einen unerwarteten Effekt - die übertragenen Daten verdarben den FIFO-Puffer des UART0-Empfängers, was laut Dokumentation nicht der Fall sein sollte.


Leider gibt es in der Dokumentation (ESP32 Technisches Referenzhandbuch 3.5) keine Beschreibung der FIFO-Pufferregister. In den esp-idf-Header-Dateien (in uart_struct.h) wurden jedoch gefunden:


1) FIFO-Statusregister des Senderpuffers (Versatz relativ zur Basisadresse 0x5c):


union { struct { uint32_t status:24; uint32_t reserved24: 8; }; uint32_t val; } mem_tx_status; 

2) FIFO-Statusregister des Empfängerpuffers (Versatz relativ zur Basisadresse 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; 

Unter der Annahme, dass mem_tx_status dem Zweck der mem_rx_status-Bits entspricht, schreiben wir den folgenden Code, um die Adressen der FIFO-Puffer zu erhalten:


 #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); } 

Nach dem Start erhalten wir:


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

Die Ausgabe erfolgt über UART0, daher unterscheiden sich tx_wr und tx_rd von 0. Gemäß den erhaltenen Ergebnissen ist die Speicherzuordnung zwischen den FIFO-Puffern UART0,1,2 wie folgt:


AdressenUART
0x00 ... 0x7FUART0 TX_FIFO
0x80 ... 0xFFUART1 TX_FIFO
0x100 ... 0x17FUART2 TX_FIFO
0x180 ... 0x1FFUART0 RX_FIFO
0x200 ... 0x27FUART1 RX_FIFO
0x280 ... 0x2FFUART2 RX_FIFO

Zusätzlich haben die Statusregister von FIFO-Puffern eine Bitkapazität von 11 Bit, was bedeutet, dass die Größe des für den FIFO-Puffer zugewiesenen Speichers = 2 KB möglich ist. Wenn Sie UART0.mem_conf.tx_size = 15 setzen (der Speicher wird in 128 Byte langen Stücken zugewiesen), werden 1920 Byte zugewiesen, und das Register tx_wr wird während der Übertragung bis 1919 gezählt und zählt weiterhin bis 0. Der Speicher ist jedoch nur ml adressiert. 10 Bits, d.h. Realer Gesamtspeicher für FIFO-Puffer = 1 KB.


Gesamt:

  1. Die Zuweisung des gemeinsam genutzten Speichers, der ESP32 für FIFO UART zugewiesen wurde, entspricht nicht dem technischen Referenzhandbuch 3.5.
  2. Die Größe des gemeinsam genutzten Speichers FIFO UART = 1 KB.

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


All Articles