DMA UART Receive without predefined length

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

DMA UART Receive without predefined length

1,424件の閲覧回数
Raghul_NM
Contributor I

Hi,

We are using i.MX RT1020 to establish RS485 communication with another processor. The UART transactions are encrypted using mbedtls library using aes256 encryption. This mbedtls library requires exact length of the received encrypted data to decrypt it. The decrypt function is,

int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,int mode,size_t length,

unsigned char iv[16],const unsigned char *input,unsigned char *output);

 

Currently,we have fixed the data length as 32 and receiving fixed 32 bytes

from the external processor (as mentioned below) and also passing 32 as

length to the decrypt function. It's working good.

 

receiveXfer.dataSize = 32;

LPUART_ReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &receiveXfer);

 

But our requirement is the data received from the external processor through UART DMA function will be of different lengths. Is there any other API to receive UART data in DMA without requesting for a fixed length but rather the API gives us no. of bytes present in the UART buffer (or no. of bytes received)? So that, each transaction can be of different length and the API gives us the length of the payload.

 

Thank You for your time and support. 

ラベル(1)
タグ(2)
0 件の賞賛
返信
2 返答(返信)

1,372件の閲覧回数
mjbcswitzerland
Specialist V

Hi

A simple method to receive random message lengths via DMA is to use free-running DMA. That is, simple receive to a circular buffer with effectively infinite reception length. A task then polls the amount of data that is in the buffer and handles it.


As long as the polling task checks at a rate that ensures that the circular buffer doesn't overwrite data that hasn't yet been read there is no data loss. Typically a low priority polling or timer event driven task is adequate.

The polling rate can be selected as compromise between the checking overhead and the reaction time to a completed message and the circular buffer length is also defined to be adequately large to avoid overflow after a worst case polling interval delay. Since the polling rate is not related to the necessary reaction time to ensure no Rx data loss at the UART itself MByte data rates are possible without data loss (the advantage of the DMA).

This technique is used in the uTasker project on various platforms including Kinetis and i.MX RT and the interface and behavior is equivalent. The i.MX RT has a better DMA controller than in some Kinetis parts (like the KL range) and can easily do this. Some KL parts can only do modulo reception lengths up to a certain number of DMA transactions but, with the RX memory set up accordingly, can be used in the same way by simply re-initialising the Rx DMA count to its max. value at each polling interval. Therefore such projects can be made fully portable across various families.

Regards

Mark

Below is, by way of example, the code used in the uTasker project's ESP32 AT mode WIFI interface (to configure the interface) that has been used on various families. It uses DMA on UART TX and RX (when the define is set) and is fully compatible on various platforms - note that the user adds a flag when KL parts (with modulo DMA buffer requirement) and the UART driver does the rest.

extern int fnConfigSerialESP32(unsigned char ucSpeed, unsigned char ucDriverMode)
{
    TTYTABLE tInterfaceParameters;                                       // table for passing information to driver
    tInterfaceParameters.Channel = ESP32_S2_AT_UART;                     // the UART connected to the ESP32
    tInterfaceParameters.ucSpeed = ucSpeed;                              // fixed baud rate
    tInterfaceParameters.Config = (CHAR_8 | NO_PARITY | ONE_STOP | CHAR_MODE); // fixed settings
    tInterfaceParameters.Task_to_wake = OWN_TASK;                        // wake self when messages have been received
    #if defined SERIAL_SUPPORT_DMA
        #if (defined ESP32_AT_FREERUN_RX_DMA && defined SERIAL_SUPPORT_DMA_RX && defined SERIAL_SUPPORT_DMA_RX_FREERUN)
            #if defined KINETIS_KL
    tInterfaceParameters.ucDMAConfig = (UART_TX_DMA | UART_RX_DMA | UART_RX_MODULO); // activate DMA on transmission and reception
            #else
    tInterfaceParameters.ucDMAConfig = (UART_TX_DMA | UART_RX_DMA);      // activate DMA on transmission and reception
            #endif
        #else
    tInterfaceParameters.ucDMAConfig = (UART_TX_DMA);                    // activate DMA on transmission
        #endif
    #endif
    tInterfaceParameters.Rx_tx_sizes.RxQueueSize = ESP32_UART_RX_BUFFER_SIZE; // input buffer size
    tInterfaceParameters.Rx_tx_sizes.TxQueueSize = ESP32_UART_TX_BUFFER_SIZE; // output buffer size

    ESP32_S2_PortID = fnSetNewSerialMode(&tInterfaceParameters, ucDriverMode); // open serial port for I/O, or modify its baud rate
    return (ESP32_S2_PortID == NO_ID_ALLOCATED);
}

 

0 件の賞賛
返信

1,398件の閲覧回数
Gavin_Jia
NXP TechSupport
NXP TechSupport

Hi @Raghul_NM ,

Thanks for your interest in NXP MIMXRT series!

RT1020 provides an AN which uses uart idle interrupt & DMA for receiving indeterminate length data. Please check it out: https://www.nxp.com/products/i.MX-RT1020

Gavin_Jia_0-1736231717086.pngGavin_Jia_0-1736231717086.png

Best regards,
Gavin

0 件の賞賛
返信