ميزات المخزن المؤقت FIFO UART في ESP32

يحتوي 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; /*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; 

بافتراض أن 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 ... 0x7FUART0 TX_FIFO
0x80 ... 0xFFUART1 TX_FIFO
0x100 ... 0x17FUART2 TX_FIFO
0x180 ... 0x1FFUART0 RX_FIFO
0x200 ... 0x27FUART1 RX_FIFO
0x280 ... 0x2FFUART2 RX_FIFO

بالإضافة إلى ذلك ، فإن سجلات الحالة الخاصة بمخازن FIFO المؤقتة لها سعة بت 11 بت ، مما يعني أن حجم الذاكرة المخصصة لمخزن FIFO المؤقت = 2 كيلو بايت ممكن. عند تعيين UART0.mem_conf.tx_size = 15 (يتم تخصيص الذاكرة في قطع بطول 128 بايت) ، سيتم تخصيص 1920 بايت ، وسيتم حساب التسجيل tx_wr حتى 1919 أثناء الإرسال وسيستمر العد حتى 0. ومع ذلك ، يتم تناول الذاكرة فقط مل. 10 بت ، أي إجمالي الذاكرة الحقيقية المخصصة لمخزن FIFO المؤقت = 1 كيلو بايت.


المجموع:

  1. لا يتطابق تخصيص الذاكرة المشتركة المخصصة لـ ESP32 لـ FIFO UART مع الدليل المرجعي الفني 3.5 ؛
  2. مقدار الذاكرة المشتركة FIFO UART = 1 كيلو بايت.

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


All Articles