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; uint32_t wr_addr: 11; 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:
Adresses | 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 |
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:
- 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;
- La quantité de mémoire partagée FIFO UART = 1 Ko.