Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

AVR32 UART to Ethernet Performance

Posted by Sven Schmidt on October 11, 2012
Hi,

i have an EVK1100 from Atmel and have tried to build a serial to ethernet bridge, starting from the ASF sample project (lwip + FreeRTOS Example from the Atmel Studio 6). I have made some changes to support up to 4 serial interfaces (running at 921.600 baud) which lead to 4 separate TCP/IP ports.

Everything is running quite well if there is only less traffic. After that i have connected some measurement systems to the serial ports (each systems has a sample rate of 4 kHz. and each data packet consist of 16 Bytes resulting in a data throughput of 64 kBytes / second). But the AVR seems to be overloaded by those measurement systems. So i have made some test but the best result i can get where 2 channels running without data loss. If i connect more channels, there will be a massive data loss on the serial side.

Can Someone give me some hints, what i could change to improve the performance.

RE: AVR32 UART to Ethernet Performance

Posted by Richard on October 11, 2012
Well, I don't know your code, or how you have implemented your serial drivers, so I can only give generic hints. The most efficient way of implementing the drivers will be to use a DMA. That way the Rx can be left running all the time with little CPU overhead, and the Tx can be zero copy (again with little overhead) and the CPU can get on and do other processing while both the Rx and Tx are in process.

Don't try doing anything slow, like using message queues to pass characters into and out of the UART interrupts.

Regards.

RE: AVR32 UART to Ethernet Performance

Posted by Sven Schmidt on October 11, 2012
I have used the original serial drivers, which had come with the project ( http://support.atmel.no/knowledgebase/avr32studiohelp/AT32UC3B_Software_Framework/SERVICES/FREERTOS/Demo/AVR32_UC3/DOC/html/serial_8c-source.html ). And as far as i can see, they are using queues from FreeRTOS.

I think i have to write my own serial driver, but i can't use DMA, because the measurement systems can be configured at run time, so there is not allways a fixed data packet legth.

RE: AVR32 UART to Ethernet Performance

Posted by Sven Schmidt on October 11, 2012
Sorry, was the wrong link. I can't find the correct one.

Only the init sequence seems to be different, so i will post he correct one here. I have made some extension to the code to handle those 4 serial interfaces.
/*!
* \brief Init the serial port.
* \param UsartId The identifier of the Usart to init.
* \param ulWantedBaud The required baudrate.
* \param uxRxQueueLength The length of the Rx buffer (if 0, rx is not supported).
* \param uxTxQueueLength The length of the Tx buffer (if 0, tx is not supported).
* \return xComPortHandle Handler on the COM port.
*/
xComPortHandle xUsartInit( eCOMPort UsartId, unsigned portLONG ulWantedBaud,
unsigned portBASE_TYPE uxRxQueueLength,
unsigned portBASE_TYPE uxTxQueueLength)
{
xComPortHandle xReturn;
xUsartPrivateData *pxUsart;
int UsartRxEnMask = ((uxRxQueueLength==0) ? 0 : AVR32_USART_CR_RXEN_MASK);
int UsartTxEnMask = ((uxTxQueueLength==0) ? 0 : AVR32_USART_CR_TXEN_MASK);
int iTempoStatus;
// USART options.
usart_options_t USART_OPTIONS =
{
.baudrate = 57600,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE
};

USART_OPTIONS.baudrate = ulWantedBaud;

// xReturn = pxUsart = (UsartId == serCOM1 ? &xUsart0 : &xUsart1);
if (UsartId == serCOM1)
{
pxUsart = &xUsart0;
xReturn = pxUsart;
}
if (UsartId == serCOM2)
{
pxUsart = &xUsart1;
xReturn = pxUsart;
}
if (UsartId == serCOM3)
{
pxUsart = &xUsart2;
xReturn = pxUsart;
}
if (UsartId == serCOM4)
{
pxUsart = &xUsart3;
xReturn = pxUsart;
}


/* Create the rx and tx queues. */
iTempoStatus = iprvSerialCreateQueues( uxRxQueueLength, &(pxUsart->xRxedChars),
uxTxQueueLength, &(pxUsart->xCharsForTx) );

/* Configure USART. */
if( ( iTempoStatus != pdFAIL ) &&
( ulWantedBaud != ( unsigned portLONG ) 0 ) )
{
portENTER_CRITICAL();
{
/**
** Configure USART.
**/
/* Enable USART RXD & TXD pins. */
if(UsartId == serCOM1)
{
if(uxRxQueueLength)
{
gpio_enable_module_pin(AVR32_USART0_RXD_0_1_PIN, AVR32_USART0_RXD_0_1_FUNCTION);
//gpio_enable_module_pin(AVR32_USART0_RXD_0_0_PIN, AVR32_USART0_RXD_0_0_FUNCTION);
}
if(uxTxQueueLength)
{
gpio_enable_module_pin(AVR32_USART0_TXD_0_1_PIN, AVR32_USART0_TXD_0_1_FUNCTION);
//gpio_enable_module_pin(AVR32_USART0_TXD_0_0_PIN, AVR32_USART0_TXD_0_0_FUNCTION);
}
}
if(UsartId == serCOM2)
{
if(uxRxQueueLength)
{
gpio_enable_module_pin(AVR32_USART1_RXD_0_1_PIN, AVR32_USART1_RXD_0_1_FUNCTION);
// gpio_enable_module_pin(AVR32_USART1_RXD_0_0_PIN, AVR32_USART1_RXD_0_0_FUNCTION);
}
if(uxTxQueueLength)
{
gpio_enable_module_pin(AVR32_USART1_TXD_0_1_PIN, AVR32_USART1_TXD_0_1_FUNCTION);
// gpio_enable_module_pin(AVR32_USART1_TXD_0_0_PIN, AVR32_USART1_TXD_0_0_FUNCTION);
}
}
if(UsartId == serCOM3)
{
if(uxRxQueueLength)
gpio_enable_module_pin(AVR32_USART2_RXD_0_1_PIN, AVR32_USART2_RXD_0_1_FUNCTION);
if(uxTxQueueLength)
gpio_enable_module_pin(AVR32_USART2_TXD_0_1_PIN, AVR32_USART2_TXD_0_1_FUNCTION);
}
if(UsartId == serCOM4)
{
if(uxRxQueueLength)
gpio_enable_module_pin(AVR32_USART3_RXD_0_1_PIN, AVR32_USART3_RXD_0_1_FUNCTION);
if(uxTxQueueLength)
gpio_enable_module_pin(AVR32_USART3_TXD_0_1_PIN, AVR32_USART3_TXD_0_1_FUNCTION);
}

// Initialize USART in RS232 mode.
usart_init_rs232(pxUsart->usart, &USART_OPTIONS, CP_PBA_SPEED);

/* We're not fully done yet: disable receiver and transmitter. */
pxUsart->usart->cr |= AVR32_USART_CR_RXDIS_MASK | AVR32_USART_CR_TXDIS_MASK;

// Register the USART interrupt handler to the interrupt controller and
// enable the USART interrupt.
if(UsartId == serCOM1)
INTC_register_interrupt((__int_handler)&vUSART0_ISR, AVR32_USART0_IRQ, AVR32_INTC_INT2);
if(UsartId == serCOM2)
INTC_register_interrupt((__int_handler)&vUSART1_ISR, AVR32_USART1_IRQ, AVR32_INTC_INT3);
if(UsartId == serCOM3)
INTC_register_interrupt((__int_handler)&vUSART2_ISR, AVR32_USART2_IRQ, AVR32_INTC_INT1);
if(UsartId == serCOM4)
INTC_register_interrupt((__int_handler)&vUSART3_ISR, AVR32_USART3_IRQ, AVR32_INTC_INT1);

/* Enable USART interrupt sources (but not Tx for now)... */
if(uxRxQueueLength)
pxUsart->usart->ier = AVR32_USART_IER_RXRDY_MASK;

/* Enable receiver and transmitter... */
pxUsart->usart->cr |= UsartTxEnMask | UsartRxEnMask;
}
portEXIT_CRITICAL();
}
else
{
xReturn = serINVALID_COMPORT_HANDLER;
}

return xReturn;
}


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner