MK22FN512 LPUART0 Rx overrun error

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

MK22FN512 LPUART0 Rx overrun error

ソリューションへジャンプ
415件の閲覧回数
davepfaltzgraff
Senior Contributor I

I have a design based on the MK22FN512. Originally I used the KSDK development suite with FreeRTOS. This has been running for years with no problems.

Now, extending the design, I migrated over to MCUXpresso with the .mex file and have allowed the development suite to generate all of the start-up and supporting routines.

In this new environment, I get random kStatus_UART_RxHardwareOverrun errors when the LPUART_RTOS_Receive() routine returns.

I have increased the priorities of both the hardware interrupt and the corresponding task, but the problem remains.

Can someone provide me with any pointers? (I am attaching the .mex file and can show pertinent sections of code if that helps.)

Thanks

ラベル(1)
0 件の賞賛
返信
1 解決策
288件の閲覧回数
davepfaltzgraff
Senior Contributor I

Thanks to Erich Styger for his suggestions. In looking over his code and reviewing the documentation on FreeRTOS and interrupts, I didn't find anything obvious. However, I did stumble on the answer while reviewing the sequence of events. It all came down to the FreeRTOS priorities and their definition.

Under the Freescale SDK, the default number of priorities was something around 10. When migrating the MCUXpresso, it appears the default is 5. Since most of my code started tasks at priority 6, I set the number in FreeRTOS to 7. That corrected the initial problem(s), but this one remained.

In an effort to bump the priority of this one task, I set it to 7 not knowing that the routine would set it to 0 if the number requested was too high! (Yes, I know that for programmers the first number is 0!) The result of this was that my task ran at priority 0, same as the idle task, and was starved. Thus the overruns.

During my investigation, I 'discovered' that the FreeRTOS timer is assigned to the highest priority. So, I increased the number of priorities and made the task of concern to be one less than the timer priority.

Needless to say, the program has been running for more than 4 days - a new record for the MCUXpresso version!

Thanks for the support.

元の投稿で解決策を見る

4 返答(返信)
289件の閲覧回数
davepfaltzgraff
Senior Contributor I

Thanks to Erich Styger for his suggestions. In looking over his code and reviewing the documentation on FreeRTOS and interrupts, I didn't find anything obvious. However, I did stumble on the answer while reviewing the sequence of events. It all came down to the FreeRTOS priorities and their definition.

Under the Freescale SDK, the default number of priorities was something around 10. When migrating the MCUXpresso, it appears the default is 5. Since most of my code started tasks at priority 6, I set the number in FreeRTOS to 7. That corrected the initial problem(s), but this one remained.

In an effort to bump the priority of this one task, I set it to 7 not knowing that the routine would set it to 0 if the number requested was too high! (Yes, I know that for programmers the first number is 0!) The result of this was that my task ran at priority 0, same as the idle task, and was starved. Thus the overruns.

During my investigation, I 'discovered' that the FreeRTOS timer is assigned to the highest priority. So, I increased the number of priorities and made the task of concern to be one less than the timer priority.

Needless to say, the program has been running for more than 4 days - a new record for the MCUXpresso version!

Thanks for the support.

392件の閲覧回数
ErichStyger
Specialist I

Hi @davepfaltzgraff,

I had faced similar issues in the past, and I solved it with a custom implementation based on the SDK, which now works without issues for me.

You can find it on Github: https://github.com/ErichStyger/McuOnEclipseLibrary/tree/master

The implementation is in the following three source files:

https://github.com/ErichStyger/McuOnEclipseLibrary/blob/master/lib/config/McuShellUartconfig.h

https://github.com/ErichStyger/McuOnEclipseLibrary/blob/master/lib/src/McuShellUart.h

https://github.com/ErichStyger/McuOnEclipseLibrary/blob/master/lib/src/McuShellUart.c

Search in the files for the following:

McuShellUart_CONFIG_UART_K22FN512_LPUART0_C3_C4

What I had to do is to properly enable the FIFO of the UART and properly check and reset the flags in the IRQ, code posted below:

void McuShellUart_CONFIG_UART_IRQ_HANDLER(void) {
  uint8_t data;
  uint32_t flags;
#if McuShellUart_CONFIG_USE_FREERTOS
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#endif
  uint8_t count;

  flags = McuShellUart_CONFIG_UART_GET_FLAGS(McuShellUart_CONFIG_UART_DEVICE);
#if McuShellUart_CONFIG_HAS_FIFO
  if (flags&kUART_RxFifoOverflowFlag) {
    count = 0; /* statement to allow debugger to set a breakpoint here */
  }
#endif
  /* If new data arrived. */
  if (flags&McuShellUart_CONFIG_UART_HW_RX_READY_FLAGS) {
  #if McuShellUart_CONFIG_HAS_FIFO
    count = McuShellUart_CONFIG_UART_DEVICE->RCFIFO;
  #else
    count = 1;
  #endif
    while(count!=0) {
      data = McuShellUart_CONFIG_UART_READ_BYTE(McuShellUart_CONFIG_UART_DEVICE);
  #if McuShellUart_CONFIG_USE_FREERTOS
      (void)xQueueSendFromISR(uartRxQueue, &data, &xHigherPriorityTaskWoken);
  #else
      McuRB_Put(rxRingBuffer, &data);
  #endif
      count--;
    }
  }
  McuShellUART_CONFIG_CLEAR_STATUS_FLAGS(McuShellUart_CONFIG_UART_DEVICE, flags|McuShellUART_CONFIG_CLEAR_EXTRA_STATUS_FLAGS);
#if McuShellUart_CONFIG_USE_FREERTOS
  if (xHigherPriorityTaskWoken != pdFALSE) {
    vPortYieldFromISR();
  }
#endif
#if McuLib_CONFIG_CPU_IS_ARM_CORTEX_M && ((McuLib_CONFIG_CORTEX_M==4) || (McuLib_CONFIG_CORTEX_M==7))
  /* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt.
  * For Cortex-M7, if core speed much faster than peripheral register write speed, the peripheral interrupt flags may be still set after exiting ISR, this results to
  * the same error similar with errata 83869. */
  __DSB();
#endif
}

I'm using a FreeRTOS Queue for the characters received, and with the above implementation using FIFO and sufficient queue buffer (depending on the receive task priority and handling), I have been able to receive data with and above 115k without issues or buffer overruns.

Notice the possibility in the above code to set a breakpoint or checkpoint in case of buffer overrun: I kept that in the code just in case, but had no need to use it for several years.

I hope this helps,

Erich

384件の閲覧回数
davepfaltzgraff
Senior Contributor I

Hi Erich,

I'll look into this approach - after I'm done tearing out my hair trying to figure out what's going on now!

You mention setting the FIFO, but in this case there is no FIFO and the Rx is single buffered. My first thought was that this might be the problem, but I don't see the problem in the older code.

I forgot to mention that the baud rate is only 9600. Since there is not much going on the system until the message is received (marked by \r), there should be plenty of time to service the interrupt.

Thanks, Dave

364件の閲覧回数
ErichStyger
Specialist I

Hi Dave,

Yes, there should be plenty of time. But it could be that you are blocking interrupts for too long, for some reasons.

I wrote an article series here: https://mcuoneclipse.com/2016/08/14/arm-cortex-m-interrupts-and-freertos-part-1/

The other thought I have: maybe you could use the SystemView trace to see what's going on?

I hope this helps,

Erich

0 件の賞賛
返信