Send Data using Blocking method within FreeRTOS Fail

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

Send Data using Blocking method within FreeRTOS Fail

4,609 Views
issta
Contributor I

Hello,

 

 

I use FreeRTOS component and FlexCAN and LPUART, in order to communicated with HOST!
The MCU is S32K148 and SDK version is V3.0.3, IDE is S32 Design Studio for ARM v2.2.

I found that using XXXX_SendDataBlocking() will let the program stay where it called, and the function never get return. No matter I use CAN module Blocking method (LPUART_DRV_SendDataBlocking(....)) or LPUAR module Blocking method (FLEXCAN_DRV_SendBlocking(...)), the result is same!

It seems that within the XXXX_SendDataBlocking() function :

syncStatus = OSIF_SemaWait(&lpuartState->txComplete, timeout);

function OSIF_SemaWait() never get a return Sema-signal, so the program 'die' and wait forever there..

Below testing shows that: the character send successfully by LPUART, but the program still 'die'!

By the way ,the non-blocking method LPUART_DRV_SendDataPolling(....) and FLEXCAN_DRV_Send(.....) works fine!

Maybe the way of function calling I used under FreeRTOS is warong, or something else wrong! But I have no way...

Anyone who can Help me ?

The key function used is :

 

 

/*-----------------------------------------------------------*/

void rtos_start( void )
{
prvSetupHardware();
prvSetupSoftware();

printf("\n[2]: System Task Creating ...\n");
fflush((void*)stdout);

xTaskCreate(prvMasterRootTask, "RootStrt", configRTOS_BASIC_STACK_SIZE, NULL, mainROOT_START_TSK_PRIORITY, &RootStrtTask_TskHdl);

vTaskStartScheduler();

for (;; );
}

/*-----------------------------------------------------------*/

static void prvMasterRootTask(void* pvParameters)
{
/* Casting pvParameters to void because it is unused */
(void)pvParameters;

printf("\n[3]: Task Scheduler Is Now Running...\n");
fflush((void*)stdout);


uint8_t txBuff[40];
uint32_t nLen;

for( ;; )
{
nLen = snprintf((char*)txBuff, sizeof(txBuff), "\nh\n\r");

/* LPUART_DRV_SendDataPolling(INST_LPUART1, txBuff, nLen); */
LPUART_DRV_SendDataBlocking(INST_LPUART1, txBuff, nLen, 8000);

vTaskDelay(300 / portTICK_PERIOD_MS);

}

}

 

 


the Host can get the flowing result:

 

 

[0]: Hardware Initialize Completed...

[1]: App. Init. Finished!...

[2]: System Task Creating ...

[3]: Task Scheduler Is Now Running...
h

 

 

 

Labels (1)
Tags (1)
0 Kudos
Reply
10 Replies

4,600 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @issta,

Can you please initialize the LPUART driver within the prvMasterRootTask?

 

Thanks,

BR, Daniel

0 Kudos
Reply

4,586 Views
issta
Contributor I

Hello, here is the result : program still "die" there

Untitled.png

0 Kudos
Reply

4,538 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @issta,

I'm sorry for the delay.

I'm not sure why it does not work when the derivers is initialized after the scheduler is started.

Anyway, is there a reason to use the blocking function?

The below code does basically the same thing

LPUART_DRV_SendData(INST_LPUART1, txBuff, length);
while(LPUART_DRV_GetTransmitStatus(INST_LPUART1, &bytes) == STATUS_BUSY);

 

Regards,

Daniel

0 Kudos
Reply

4,466 Views
issta
Contributor I

hello, thanks for your replay! If have conditions, would you please create a project using the same way to find the reason ? This problem troubled some person not just me. Although I can using other method, we want to see whether it's a software-bug of SDK released by the official.

Best Regards

0 Kudos
Reply

4,387 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @issta,

I'm waiting for feedback from the SDK SW team.

It may take some additional time to resolve it.

I'm sorry for the inconvenience.

 

Regards,

Daniel

0 Kudos
Reply

4,109 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hello @issta,

I'm sorry fo the delay.

I just wanted to let you know that the issue is still being investigated by the SDK SW team.

 

Thank you for your patience and understanding,

 

Regards,

Daniel

 

 

 

0 Kudos
Reply

4,069 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi @issta,

The root cause seems to be in misconfigured interrupt priorities.

Test provided by the SDK team.

  1. Configure the maximum system call interrupt priority value is 1 and enable configASSERT() function to validate the interrupt priority.
  2. danielmartynek_0-1650626915848.jpeg

     

  • Inside the task, call the LPUART_DRV_SendDataBlocking() to transmit data, and the interrupt priority value of LPUART interrupt is zero (as the default value).
  • If the application in sun in the debug mode, we can see that at the end of transmission the OSIF_SemaPost() function is called to signal the synchronous completion object. This invoke to the funtion vPortValidateInterruptPriority() to check validity of the priority.

danielmartynek_1-1650626967791.png

 

  • Currently executing interrupt have exception number 49, it belongs to LPUART1_IRQ and the numerical priority is 0 while the numerical priority of the system call is 16 (it equals to 1 << 4).
  • Because we do not call FreeRTOS API functions from any interrupt that has a higher priority level than the system call priority level (higher logical priority is lower numerical priority), so the current configured priorities lead to false condition inside configASSERT() function and infinite loop occur.danielmartynek_2-1650627001632.png

     

 

Conclusion

The user should configure interrupt priorities correctly, following:

  • When configASSERT() function is disabled, the validity checking of priorities will be removed.
  • The maximum system call interrupt priority value must not be set to 0.
  • When configASSERT() function is enabled, please make sure that the interrupts that call to FreeRTOS API must have priority level equal or lower than the system call interrupt priority level by calling INT_SYS_SetPriority() function to set priority value before running the task.(e.g call INT_SYS_SetPriority(LPUART1_RxTx_IRQn, 1), where “1” is the priority value).
  • For more detail about interrupt priority value that are used to FreeRTOS context, please refer to here: https://www.freertos.org/RTOS-Cortex-M3-M4.html

 

Regards,

Daniel

0 Kudos
Reply

3,922 Views
issta
Contributor I

Sorry for reply so late !Actually the setting  of interrupt priority used by FreeRTOS in Project is OK!

issta_0-1651804463537.png

 But enable configASSERT() function maybe the sources of the error! I need some more times to check or prove it...

0 Kudos
Reply

4,590 Views
issta
Contributor I

hi, you means re-initialize the LPUART driver? I made the initialization of LPUART driver within the  function prvSetupHardware() by following code before  TaskStartScheduler():

 

 

/* Initialize PINS */
DrvInitRult += PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

/* Initialize LPUART */
LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0);

(void) LPUART_DRV_InstallRxCallback(INST_LPUART1, LPUART1_RxCallback_ISR, NULL);
(void) LPUART_DRV_InstallTxCallback(INST_LPUART1, LPUART1_TxCallback_ISR, NULL);

 

 

 

But I can make a test as you said!

0 Kudos
Reply

4,601 Views
issta
Contributor I
0 Kudos
Reply