يحتوي ESP32 على ثلاثة UARTs. كل منها يضع المخزن المؤقت FIFO للمستقبل والمخزن المؤقت FIFO للمرسل في ذاكرة مشتركة من 1024 بايت (دليل مرجعي فني 3.5 ESP32):
ومع ذلك ، عندما حاولت زيادة حجم المخزن المؤقت FIFO لجهاز إرسال UART2 من 128 إلى 256 بايت ، تلقيت تأثيرًا غير متوقع - فقد أفسدت البيانات المرسلة المخزن المؤقت FIFO لمستقبل UART0 ، والذي ، وفقًا للوثائق ، لا ينبغي أن يكون.
لسوء الحظ في الوثائق (دليل المرجع الفني 3.5 ESP32) لا يوجد وصف لسجلات المخزن المؤقت FIFO. ومع ذلك ، في ملفات رأس esp-idf (في uart_struct.h) تم العثور على:
1) سجل حالة FIFO للمخزن المؤقت للمرسل (التخالف بالنسبة إلى العنوان الأساسي 0x5c):
union { struct { uint32_t status:24; uint32_t reserved24: 8; }; uint32_t val; } mem_tx_status;
2) سجل حالة FIFO للمخزن المؤقت للمستقبِل (التخالف بالنسبة إلى العنوان الأساسي 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;
بافتراض أن mem_tx_status يتطابق مع الغرض من بتات mem_rx_status ، نكتب الكود التالي للحصول على عناوين المخازن المؤقتة 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); }
بعد البدء نحصل على:
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
يتم تنفيذ الإخراج من خلال UART0 ، لذلك تختلف tx_wr و tx_rd عن 0. وفقًا للنتائج التي تم الحصول عليها ، فإن تخصيص الذاكرة بين مخازن FIFO المؤقتة UART0،1،2 هو كما يلي:
العناوين | 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 |
بالإضافة إلى ذلك ، فإن سجلات الحالة الخاصة بمخازن FIFO المؤقتة لها سعة بت 11 بت ، مما يعني أن حجم الذاكرة المخصصة لمخزن FIFO المؤقت = 2 كيلو بايت ممكن. عند تعيين UART0.mem_conf.tx_size = 15 (يتم تخصيص الذاكرة في قطع بطول 128 بايت) ، سيتم تخصيص 1920 بايت ، وسيتم حساب التسجيل tx_wr حتى 1919 أثناء الإرسال وسيستمر العد حتى 0. ومع ذلك ، يتم تناول الذاكرة فقط مل. 10 بت ، أي إجمالي الذاكرة الحقيقية المخصصة لمخزن FIFO المؤقت = 1 كيلو بايت.
المجموع:
- لا يتطابق تخصيص الذاكرة المشتركة المخصصة لـ ESP32 لـ FIFO UART مع الدليل المرجعي الفني 3.5 ؛
- مقدار الذاكرة المشتركة FIFO UART = 1 كيلو بايت.