ESP32 memiliki tiga UART. Masing-masing menempatkan buffer FIFO penerima dan buffer FIFO pemancar dalam memori bersama 1024 byte (ESP32 manual referensi teknis 3.5):
Namun, ketika saya mencoba meningkatkan ukuran buffer FIFO dari pemancar UART2 dari 128 menjadi 256 byte, saya menerima efek yang tidak terduga - data yang dikirim merusak buffer FIFO dari penerima UART0, yang, menurut dokumentasi, seharusnya tidak.
Sayangnya dalam dokumentasi (ESP32 manual referensi teknis 3.5) tidak ada deskripsi register buffer FIFO. Namun, dalam file header esp-idf (di uart_struct.h) ditemukan:
1) Register status FIFO buffer buffer (offset relatif terhadap alamat dasar 0x5c):
union { struct { uint32_t status:24; uint32_t reserved24: 8; }; uint32_t val; } mem_tx_status;
2) Register status FIFO dari buffer penerima (diimbangi relatif terhadap alamat dasar 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;
Dengan asumsi bahwa mem_tx_status sesuai dengan tujuan bit mem_rx_status, kami menulis kode berikut untuk mendapatkan alamat buffer 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); }
Setelah memulai, kami mendapatkan:
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
Output dilakukan melalui UART0, oleh karena itu tx_wr dan tx_rd berbeda dari 0. Menurut hasil yang diperoleh, alokasi memori antara buffer FIFO UART0, 1,2 adalah sebagai berikut:
Alamat | 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 |
Selain itu, register status buffer FIFO memiliki kapasitas bit 11 bit, yang berarti bahwa ukuran memori yang dialokasikan untuk buffer FIFO = 2Kb dimungkinkan. Saat mengatur UART0.mem_conf.tx_size = 15 (memori dialokasikan dalam panjang 128 byte), 1920 byte akan dialokasikan, dan register tx_wr akan dihitung hingga 1919 selama transmisi dan akan terus dihitung hingga 0. Namun, memori hanya ditangani ml. 10 bit yaitu total memori nyata yang dialokasikan untuk buffer FIFO = 1Kb.
Total:
- Alokasi memori bersama yang dialokasikan untuk ESP32 untuk FIFO UART tidak cocok dengan manual referensi teknis 3.5;
- Jumlah memori bersama FIFO UART = 1Kb.