FreeRTOS LPUART driver problem

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

FreeRTOS LPUART driver problem

489 Views
Oliver_R
Contributor I

Hi,

I'm using a RT1176 based board with (currently the older) mcux-sdk, but the problem looks identical in the mcuxsdk (really confusing names!):

The Freertos-LPUART driver (fsl_lpuart_freertos.c) does not call HAL_UartInit (fsl_adapter_lpuart.c) in the LPUART_RTOS_Init function. Instead it calls just LPUART_Init, which is not enough!

The problem is that the field s_UartState (line 719 in fsl_fsl_adapter_lpuart.c) is not written in LPUART_Init which then leads to an assertion if a receive interrupt from the UART occurs:

ASSERT ERROR " NULL != uartHandle ": file "D:\usr\TQM\mcuxsdk\core\components\uart\fsl_adapter_lpuart.c" Line "433" function name "HAL_UartInterruptHandle"

So I wonder, how this driver could ever worked, because the array s_UartState is read for the handle in the interrupt driver (and then it is NULL).

So, did I anything wrong or has this driver a problem? Maybe I have to rewrite the code to use a lower API driver for the LPUARTS?

Thanks and bye,
Oliver

 

Labels (1)
0 Kudos
Reply
6 Replies

457 Views
Pablo_Ramos
NXP Employee
NXP Employee

Hi @Oliver_R,

Could you help me with the following question?

Are you using VS Code or MCUXpresso?

If you test with mcuxsdk , does the problem persist?

In VS Code, there is an example project: evkbmimxrt1170_freertos_lpuart_cm7. Could you help me test whether it works with your hardware?

Best Regards,
Pablo

0 Kudos
Reply

426 Views
Oliver_R
Contributor I

Hello,

I'm using the VSCode plugin with the latest mcux-sdk. We're using a TQMa117xL based board and unfortunately the BSP is not yet ready for mcuxsdk.

This means I can't test it right now with mcuxsdk but in the future we will change to it.

The mentioned example is new, as I can't find it in mcux-sdk? I will check it out.

The assertion happens right after the Init function:

lpuart_rtos_config_t mSerConfig;
lpuart_rtos_handle_t mRtosHandle;
_lpuart_handle       mUartHandle;
mRtosHandle = {};
mUartHandle = {};
mSerConfig             = {};
mSerConfig.srcclk = CLOCK_GetRootClockFreq(kCLOCK_Root_Lpuart9);
mSerConfig.base   = LPUART9;
mSerConfig.baudrate    = aBaudrate;
mSerConfig.parity      = kLPUART_ParityDisabled;
mSerConfig.stopbits    = kLPUART_OneStopBit;
mSerConfig.buffer      = mReadBuf;
mSerConfig.buffer_size = sizeof(mReadBuf);
mSerConfig.enableRxRTS = true;
mSerConfig.enableTxCTS = true;
int status = LPUART_RTOS_Init(&mRtosHandle, &mUartHandle, &mSerConfig);

The code is in a C++ class but I will compare the init code with the example.

 

Bye,

Oliver

0 Kudos
Reply

376 Views
Oliver_R
Contributor I

Hi,

in the meantime I discovered, that this is not related only to the FreeRTOS-Uart driver, but also to the underlying lpuart driver.

Unfortunately, I found nothing in the SDK documentation or in the forums to the HAL_Uart-driver

For what reason is the HAL_Uartxxx-API (fsl_adapter_lpuart.c)? Why and when should I use it? There are only two sources in the whole SDK which are using HAL_UartInit at all: fsl_component_serial_port_uart.c and fsl_debug_console.c in the debug_console_lite folder.

The problem I have with this API is that when fsl_adapter_lpuart.c is compiled WITHOUT the define "HAL_UART_TRANSFER_MODE=1" then all lpuart interrupts are defined in this source and then I HAVE to use HAL_UartInit in order to avoid the assertion in the receive IRQ. And as the IRQs are already defined, I have no change to register my own IRQ anymore.

But all UART examples do not set HAL_UART_TRANSFER_MODE=1 and some examples are defining their own IRQs, so I wonder how this could work. I define DEBUG_CONSOLE_TRANSFER_NON_BLOCKING and I'm not using the "utility_debug_console_lite" component.

BTW: What is the difference between "utility_debug_console" and "utility_debug_console_lite"? The SDK documentation is the same for both components?

All of this driver code is very very hard to understand as there is so much preprocessor magic and so few documentation for it.

So I have the impression, that the source "fsl_adapter_lpuart.c" should not be compiled in at all as it defines the lpuart IRQs in an unwanted way which lead to assertions when using other lpuarts than the debug console lpuart.

Bye,
Oliver

0 Kudos
Reply

160 Views
Pablo_Ramos
NXP Employee
NXP Employee

Hi

You mention that the issue appears to be directly on the lpuart drivers and not the implementation of freertos.

If you test an LPUART example in bare‑metal, does it work?

Could you also test this using MCUXpresso?

You can find a full description of utility_debug_console and utility_debug_console_lite in the SDK API Reference Manual.

MCUXpresso SDK API Reference Manual: Debug Console

MCUXpresso SDK API Reference Manual: Debug Console Lite

Best Regards,
Pablo

0 Kudos
Reply

128 Views
Oliver_R
Contributor I

So after hours of debugging the driver code and trying to understand all the preprocessor magic in the UART code I finally found the reason for this behaviour. And it is indeed not related to the FreeRTOS API!

The problem begins if you set a flag which is mentioned in the hello world example of the SDK: 

"just define DEBUG_CONSOLE_TRANSFER_NON_BLOCKING in your project to use the advanced debug console utility."

I thought it is a good idea to do so, as a non-blocking console doesn't disturb the code timing so much. But this option has a catastrophic side effect which is not mentioned or documented anywhere:

The startup-code (startup_mimxrt1176_cm7.c) defines the LPUART IRQs as follows:

WEAK void LPUART10_IRQHandler(void) { LPUART10_DriverIRQHandler(); }

So the IRQs are routed to the LPUART driver which is fine.

But if you define DEBUG_CONSOLE_TRANSFER_NON_BLOCKING then the IRQs of ALL LPUARTS (and not only the IRQ of the console LPUART1) are overwritten in fsl_adapter_lpuart.c then:

void LPUART10_IRQHandler(void); 
void LPUART10_IRQHandler(void) 
#endif /* LP_FLEXCOMM10 */ 
{ 
HAL_UartInterruptHandle(10); 
SDK_ISR_EXIT_BARRIER; 
} 
#endif 
#endif /* LPUART10 */

 and in HAL_UartInterruptHandle there's the line

hal_uart_state_t *uartHandle = s_UartState[instance];

which leads to an assertion afterwards if you're not using HAL_UartInit.

Or in other words: All your existing (non HAL_xxx) UART-Code will blow up, if you set DEBUG_CONSOLE_TRANSFER_NON_BLOCKING.

Please have a look in the driver code, this is really a bad, intrusive and malicious option which should have a BIG FAT WARNING if you're really using it.

In my opinion this definition should be killed from the SDK as it has so bad side effects. No wonder that none of the SDK exapmles is setting this option.

Unfortunately nobody answered some of my questions, so here once again:

1. For what reason is the HAL_Uartxxx-API (fsl_adapter_lpuart.c)? Why and when should I use it?

2. What is the difference between "utility_debug_console" and "utility_debug_console_lite"? The SDK documentation is the same for both components?

 

So please, do not point me again to the SDK documentation, I already read it and the "full description" doesn't mention any differences.

 

Bye,

Oliver

0 Kudos
Reply

43 Views
Pablo_Ramos
NXP Employee
NXP Employee

Hi,

Regarding the HAL, it is normally used if you want portability between different MCU platforms.

You can find more details about this in Why Expanding the Potential of MCUs Needs a New Way of Thinking | NXP Semiconductors

The supported debug console hardware device type varies between them, one supporting only UART (lite), and the other one UART, USB and SWO.

Something that is mentioned in the web pages of the documentation are for example that the serial interfaces supported , which are the parameters needed to use the APIs, for example for the advance there a full table showing how the information will be printed depending on the interface and the lite does not support the same amount of interfaces so it will show limited information .

Please let us know if there is any further question

Best Regards,
Pablo

0 Kudos
Reply