STM32F103RE + FreeRT OS V9.0.0 code is crashing at list.c line 179 pxIterator = pxList->xListEnd.pxPrevious

luogf wrote on Wednesday, July 31, 2019:

Hi,I have some problems when developing on FreeRT OS.
Contidition:
MCU:STM32F103RE
OS:FreeRT OS V9.0.0(STM32CubeMX generate)
IDE: MDK5.26.2.0

Code condition:
1.All tasks are block task, should be actived by message(singal).
2.#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 means all IT can be controlled by OS Kernel.
3.TIM4 interrupt priority is 5,and will send message(singal) in TIM4 ISR function.The TIM4 interrupt frequency is 1Hz.It means that send message(singal) in ISR frequency is 1Hz.

Q1:I do not know the reason code is crashing at list.c line 179 pxIterator = pxList->xListEnd.pxPrevious.
I have tested no stack overflow, a queue or semaphore has been initialised,
API function called by ISR end in “FromISR” (STM32CubeMX generate code,singal send function has been repackaged in case of sending singal in ISR error).
I am not sure that the interrupt priority settings is correct or not.
The bug that code is crashing at list.c line 179 pxIterator = pxList->xListEnd.pxPrevious is accidental.

Q2:If the message send twice with the same value(call send_msg_userLcdMsgId(LCD_MSG_ID_S3) once in ISR,call send_msg_userLcdMsgId(LCD_MSG_ID_S3) again before the task actived ),what the FreeRT OS kernel will do?

Best regards.

Task below:

/* UserLcdDisplayTask function */
void UserLcdDisplayTask(void const * argument)
{
  /* USER CODE BEGIN UserLcdDisplayTask */
 	#ifdef DEBUG_BY_LUOGF
	uint32_t recv;
	osEvent evt;
  	#endif
	DEBUG_BY_LUOGF_PRINTF(0,">>>>[%4d][%s] is called.\r\n",__LINE__,__FUNCTION__); 
  /* Infinite loop */
  for(;;)
  {
 	#ifdef DEBUG_BY_LUOGF
	evt = osMessageGet(userLcdMsgId,osWaitForever);
	if(evt.status == osEventMessage)
	{
		recv = (evt.value.v);
		DEBUG_BY_LUOGF_PRINTF(0,">>[%d][%s][recv = %d] \r\n",__LINE__,__FUNCTION__,recv);
		switch(recv)
		{
			case LCD_MSG_ID_S1:
					user_lcd_display();
			break;
			case LCD_MSG_ID_S2:
					user_lcd_display();	
			break;
			case LCD_MSG_ID_S3:
					user_lcd_display();
			case LCD_MSG_ID_S4:
					user_lcd_display_rtc();		
			break;				
			default:
			break;
		}
        set_user_lcd_display_flag(false);
	}
	#else
    osDelay(1);
	#endif
  }
  /* USER CODE END UserLcdDisplayTask */
}

Waiting for message to active task

evt = osMessageGet(userLcdMsgId,osWaitForever);//Waiting for Message
if(evt.status == osEventMessage)
{
        recv = (evt.value.v);
		DEBUG_BY_LUOGF_PRINTF(0,">>[%d][%s][recv = %d] \r\n",__LINE__,__FUNCTION__,recv);
		switch(recv)
        {
             case LCD_MSG_ID_S1:
			break;
			case LCD_MSG_ID_S2:
					user_lcd_display();	
			break;
			case LCD_MSG_ID_S3:
					user_lcd_display();
			case LCD_MSG_ID_S4:
					user_lcd_display_rtc();		
			break;				
			default:
			break;
        }
 }

sending massage in ISR

void HAL_TIM_PeriodElapsedCallback_TIM4(TIM_HandleTypeDef *htim)
{
	DEBUG_BY_LUOGF_PRINTF(0,">>[%4d][%s]\r\n",__LINE__,__FUNCTION__);
	send_msg_userLcdMsgId(LCD_MSG_ID_S3);
	DEBUG_BY_LUOGF_PRINTF(0,"<<[%4d][%s]\r\n",__LINE__,__FUNCTION__);
}

send message function

void send_msg_userLcdMsgId(uint32_t id)
{
	
	if(userLcdMsgId == NULL)
	{
			return;
	}
	else
	{
		if(get_user_lcd_display_flag() == false)
		{
			set_user_lcd_display_flag(true);
			osStatus ret = osMessagePut(userLcdMsgId,(uint32_t)id,0);
			DEBUG_BY_LUOGF_PRINTF(0,">>>>[%d][%s][id = 0x%x]\r\n",__LINE__,__FUNCTION__,id);
			if(ret != osOK)
			{
				DEBUG_BY_LUOGF_PRINTF(0,">>>>[%d][%s][ret = 0x%x]\r\n",__LINE__,__FUNCTION__,ret);
			}
		}
	}	
}

rtel wrote on Wednesday, July 31, 2019:

I agree it is most likely an interrupt priority problem. If you update
your FreeRTOS code to the latest 10.2.1 then you will have many more
configASSERT() statements in the code that will detect most, but not
all, such priority problems for you. More information is provided on
this link: RTOS for ARM Cortex-M - take care
to note the special requirements for STM32 users with regards to setting
the interrupt priority bits are set to preemption priority.

2.#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1

This will only work if you have the number of priroity bits set
correctly, which I think on an STM32 is 4 (priorities 0 to 15).

3.TIM4 interrupt priority is 5,

Whether 5 is the right setting or not depends on the function used to
set the priority. Some expect the priority setting to be shifted into
the most significant bits before being passed as a parameter, whereas
others will do the shifting inside the function. That is explained on
the link above - but first thing is to use a newer FreeRTOS version to
see if the asserts() will highlight your problem right away.

luogf wrote on Thursday, August 01, 2019:

Thanks for your reply,Richard Barry.
I noticed the link above before and followed the suggestions to set the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,interrupt priority on STM32F103RE,Cortex-M3 MCU.STM32F103RE has 4 priroity bits(priorities 0 to 15).
Maybe interrupt priority is not the reason for my problems.

Maybe the the xItemValue is the same as the back marker the iteration loop is the reason for my problem.I have send message repeatedly in TIM4 ISR function.The notation says I should check first and modifie the algorithm slightly if necessary.

I will try to debug the FreeRT OS code to figure out.
Thanks,again!

If the list already contains a list item with the same item value then the
	new list item should be placed after it.  This ensures that TCB's which are
	stored in ready lists (all of which have the same xItemValue value) get a
	share of the CPU.  However, if the xItemValue is the same as the back marker
	the iteration loop below will not end.  Therefore the value is checked
	first, and the algorithm slightly modified if necessary. */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		/* *** NOTE ***********************************************************
		If you find your application is crashing here then likely causes are
		listed below.  In addition see http://www.freertos.org/FAQHelp.html for
		more tips, and ensure configASSERT() is defined!
		http://www.freertos.org/a00110.html#configASSERT

			1) Stack overflow -
			   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
			2) Incorrect interrupt priority assignment, especially on Cortex-M
			   parts where numerically high priority values denote low actual
			   interrupt priorities, which can seem counter intuitive.  See
			   http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
			   http://www.freertos.org/a00110.html
			3) Calling an API function from within a critical section or when
			   the scheduler is suspended, or calling an API function that does
			   not end in "FromISR" from an interrupt.
			4) Using a queue or semaphore before it has been initialised or
			   before the scheduler has been started (are interrupts firing
			   before vTaskStartScheduler() has been called?).
		**********************************************************************/

		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
		{
			/* There is nothing to do here, just iterating to the wanted
			insertion position. */
			#if 1//DEBUG_BY_LUOGF
			//DEBUG_BY_LUOGF_PRINTF(0,">>>>[%d][%s]\r\n",__LINE__,__FUNCTION__); 
			#endif
		}

luogf wrote on Friday, August 02, 2019:

Thanks for your reply,Richard Barry.
I noticed the link above before and followed the suggestions to set the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY,interrupt priority on STM32F103RE,Cortex-M3 MCU.STM32F103RE has 4 priroity bits(priorities 0 to 15).
Maybe interrupt priority is not the reason for my problems.

Maybe the the xItemValue is the same as the back marker the iteration loop is the reason for my problem.I have send message repeatedly in TIM4 ISR function.The notation says I should check first and modifie the algorithm slightly if necessary.

I will try to debug the FreeRT OS code to figure out.
Thanks,again!

If the list already contains a list item with the same item value then the
	new list item should be placed after it.  This ensures that TCB's which are
	stored in ready lists (all of which have the same xItemValue value) get a
	share of the CPU.  However, if the xItemValue is the same as the back marker
	the iteration loop below will not end.  Therefore the value is checked
	first, and the algorithm slightly modified if necessary. */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		/* *** NOTE ***********************************************************
		If you find your application is crashing here then likely causes are
		listed below.  In addition see http://www.freertos.org/FAQHelp.html for
		more tips, and ensure configASSERT() is defined!
		http://www.freertos.org/a00110.html#configASSERT

			1) Stack overflow -
			   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
			2) Incorrect interrupt priority assignment, especially on Cortex-M
			   parts where numerically high priority values denote low actual
			   interrupt priorities, which can seem counter intuitive.  See
			   http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
			   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
			   http://www.freertos.org/a00110.html
			3) Calling an API function from within a critical section or when
			   the scheduler is suspended, or calling an API function that does
			   not end in "FromISR" from an interrupt.
			4) Using a queue or semaphore before it has been initialised or
			   before the scheduler has been started (are interrupts firing
			   before vTaskStartScheduler() has been called?).
		**********************************************************************/

		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */
		{
			/* There is nothing to do here, just iterating to the wanted
			insertion position. */
			#if 1//DEBUG_BY_LUOGF
			//DEBUG_BY_LUOGF_PRINTF(0,">>>>[%d][%s]\r\n",__LINE__,__FUNCTION__); 
			#endif
		}

aggarg-aws wrote on Friday, August 02, 2019:

Can you share your project so that we can take a closer look and help you better?

Thanks.

luogf wrote on Tuesday, August 06, 2019:

Hi,Gaurav Aggarwal.
I have already solved the problem.The xItemValue is the same as the back marker the iteration loop is the reason for my problem.Do not send message(singal) with the same value in user application.
Thanks for your concern.