Caractéristiques du tampon FIFO UART dans ESP32

ESP32 a trois UART. Chacun d'entre eux place la mémoire tampon FIFO du récepteur et la mémoire tampon FIFO de l'émetteur dans une mémoire partagée de 1024 octets (manuel de référence technique ESP32 3.5):



Cependant, lorsque j'ai essayé d'augmenter la taille du tampon FIFO de l'émetteur UART2 de 128 à 256 octets, j'ai reçu un effet inattendu - les données transmises ont gâché le tampon FIFO du récepteur UART0, ce qui, selon la documentation, ne devrait pas l'être.


Malheureusement dans la documentation (manuel de référence technique ESP32 3.5), il n'y a pas de description des registres de tampon FIFO. Cependant, dans les fichiers d'en-tête esp-idf (dans uart_struct.h) ont été trouvés:


1) Registre d'état FIFO de la mémoire tampon de l'émetteur (décalage par rapport à l'adresse de base 0x5c):


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

2) Registre d'état FIFO du tampon récepteur (décalage par rapport à l'adresse de 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; 

En supposant que mem_tx_status correspond au but des bits mem_rx_status, nous écrivons le code suivant pour obtenir les adresses des tampons 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); } 

Après le démarrage, nous obtenons:


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

La sortie s'effectue via UART0, donc tx_wr et tx_rd sont différents de 0. Selon les résultats obtenus, l'allocation de mémoire entre les tampons FIFO UART0,1,2 est la suivante:


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

De plus, les registres d'état des tampons FIFO ont une capacité en bits de 11 bits, ce qui signifie que la taille de la mémoire allouée pour le tampon FIFO = 2Kb est possible. Lorsque vous définissez UART0.mem_conf.tx_size = 15 (la mémoire est allouée en morceaux de 128 octets de long), 1920 octets seront alloués et le registre tx_wr sera compté jusqu'en 1919 pendant la transmission et continuera à compter jusqu'à 0. Cependant, la mémoire n'est adressée que ml. 10 bits, c'est-à-dire mémoire totale réelle allouée au tampon FIFO = 1 Ko.


Total:

  1. L'allocation de mémoire partagée allouée à ESP32 pour FIFO UART ne correspond pas au manuel de référence technique 3.5;
  2. La quantité de mémoire partagée FIFO UART = 1 Ko.

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


All Articles