Problem sending data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem sending data

529 Views
Nadia
Contributor III

Hello everyone, I'm having a very strange problem, I don't know if anyone else has had this happen.

I am using the USART_RTOS_Send() instruction, to send data through a serial port. I have reduced the code to a task that is constantly receiving data and sending it to the serial port, but the send data function slows down the system a lot, and I am only able to send 100 data per second. I am receiving about 2000 per second, when I leave the send instruction commented out.

I am currently using the operating system and an operating system instruction, but I did it without the operating system and with other instructions like USART_WriteBloking, and the exact same thing happened.

If anyone knows where I can look or where the problem can be found I would appreciate it.
Thank you very much.

0 Kudos
2 Replies

522 Views
carstengroen
Senior Contributor II

Nadia, 

as in your previous thread, we need MUCH more information. There is NO way anyone can guess what you have done wrong based on the information you have given. What CPU are you using, what SDK, how are you measuring the time. Have you tried debugging the code to find out why the USART_RTOS_Send()   FUNCTION  is taking so long time....

Show us the code you are running etc. In short, much more info please.....

0 Kudos

506 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Martin,

I have to say that the api function of usart code based on FreeRtos is corpulent and inefficient, that is why the transfer is slower than you expected. This is the architecture of the USART plus FreeRtos example.

The example use interrupt mechanism, for usart transmitter, after the transmitter has transmitted a character(one Byte), the LPC will enter ISR, I copy the ISR here. In the ISR, it check if the predefined size of message has transmitted, if the message has transmitted, it call a call-back function, in the call-back function, an event is triggered with the code:

You can check the USART_TransferHandleIRQ() ISR code, it is too long, inefficient.

if (status == kStatus_USART_TxIdle)
{
xResult = xEventGroupSetBitsFromISR(handle->txEvent, RTOS_USART_COMPLETE, &xHigherPriorityTaskWoken);
}

If you want to transfer as fast as possible, I suggest you call USART_TransferSendNonBlocking() without using FreeRtos, USART_TransferSendNonBlocking() function uses polling mode, it is the fastest. Secondly, you can call USART_WriteBlocking(), it uses interrupt mode, the transfer speed is middle.

Hope it can help you

BR

XiangJun Rong

 

 

void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle)
{
/* Check arguments */
assert((NULL != base) && (NULL != handle));

bool receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
bool sendEnabled = (handle->txDataSize != 0U);
uint8_t rxdata;
size_t tmpsize;

/* If RX overrun. */
if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U)
{
/* Clear rx error state. */
base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
/* clear rxFIFO */
base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
/* Trigger callback. */
if (handle->callback != NULL)
{
handle->callback(base, handle, kStatus_USART_RxError, handle->userData);
}
}
while ((receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)) ||
(sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U)))
{
/* Receive data */
if (receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U))
{
/* Receive to app bufffer if app buffer is present */
if (handle->rxDataSize != 0U)
{
rxdata = (uint8_t)base->FIFORD;
*handle->rxData = rxdata;
handle->rxDataSize--;
handle->rxData++;
receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
if (0U == handle->rxDataSize)
{
if (NULL == handle->rxRingBuffer)
{
base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
}
handle->rxState = (uint8_t)kUSART_RxIdle;
if (handle->callback != NULL)
{
handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
}
}
}
/* Otherwise receive to ring buffer if ring buffer is present */
else
{
if (handle->rxRingBuffer != NULL)
{
/* If RX ring buffer is full, trigger callback to notify over run. */
if (USART_TransferIsRxRingBufferFull(handle))
{
if (handle->callback != NULL)
{
handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData);
}
}
/* If ring buffer is still full after callback function, the oldest data is overridden. */
if (USART_TransferIsRxRingBufferFull(handle))
{
/* Increase handle->rxRingBufferTail to make room for new data. */
if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
{
handle->rxRingBufferTail = 0U;
}
else
{
handle->rxRingBufferTail++;
}
}
/* Read data. */
rxdata = (uint8_t)base->FIFORD;
handle->rxRingBuffer[handle->rxRingBufferHead] = rxdata;
/* Increase handle->rxRingBufferHead. */
if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
{
handle->rxRingBufferHead = 0U;
}
else
{
handle->rxRingBufferHead++;
}
}
}
}
/* Send data */
if (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U))
{
base->FIFOWR = *handle->txData;
handle->txDataSize--;
handle->txData++;
sendEnabled = handle->txDataSize != 0U;
if (!sendEnabled)
{
base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
handle->txState = (uint8_t)kUSART_TxIdle;

base->INTENSET |= USART_INTENSET_TXIDLEEN_MASK;
}
}
}

/* Tx idle and the interrupt is enabled. */
if ((0U != (base->INTENSET & USART_INTENSET_TXIDLEEN_MASK)) &&
(0U != (base->INTSTAT & USART_INTSTAT_TXIDLE_MASK)) && (handle->txState == (uint8_t)kUSART_TxIdle))
{
/* Disable tx idle interrupt */
base->INTENCLR |= USART_INTENCLR_TXIDLECLR_MASK;
/* Trigger callback. */
if (handle->callback != NULL)
{
handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData);
}
}

/* ring buffer is not used */
if (NULL == handle->rxRingBuffer)
{
tmpsize = handle->rxDataSize;

/* restore if rx transfer ends and rxLevel is different from default value */
if ((tmpsize == 0U) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark))
{
base->FIFOTRIG =
(base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark);
}
/* decrease level if rx transfer is bellow */
if ((tmpsize != 0U) && (tmpsize < (USART_FIFOTRIG_RXLVL_GET(base) + 1U)))
{
base->FIFOTRIG = (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(tmpsize - 1U));
}
}
}

 

 

static void USART_RTOS_Callback(USART_Type *base, usart_handle_t *state, status_t status, void *param)
{
usart_rtos_handle_t *handle = (usart_rtos_handle_t *)param;
BaseType_t xHigherPriorityTaskWoken, xResult;

xHigherPriorityTaskWoken = pdFALSE;
xResult = pdFAIL;

if (status == kStatus_USART_RxIdle)
{
xResult = xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_USART_COMPLETE, &xHigherPriorityTaskWoken);
}
else if (status == kStatus_USART_TxIdle)
{
xResult = xEventGroupSetBitsFromISR(handle->txEvent, RTOS_USART_COMPLETE, &xHigherPriorityTaskWoken);
}
else if (status == kStatus_USART_RxRingBufferOverrun)
{
xResult = xEventGroupSetBitsFromISR(handle->rxEvent, RTOS_USART_RING_BUFFER_OVERRUN, &xHigherPriorityTaskWoken);
}

if (xResult != pdFAIL)
{
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}

0 Kudos