Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by ajellisuk on February 19, 2016

Hi,

I have a block of code for handling USART interrupts on an STM32F407 discovery board:

~~~~ void USART2IRQHandler( void ) { portBASETYPE xHigherPriorityTaskWoken = pdFALSE; portCHAR cChar;

if( USARTGetITStatus( USART2, USARTITTXE ) == SET ) { /* The interrupt was caused by the TX register becoming empty. Are there any more characters to transmit? */ if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE ) { // A character was retrieved from the queue so can be sent to the // USART now. USARTSendData( USART2, cChar ); } else { USARTITConfig( USART2, USARTIT_TXE, DISABLE ); } }

if( USART_GetITStatus( USART2, USART_IT_RXNE ) == SET )
{
	/* A character has been received on the USART, send it to the Rx
	handler task. */
	cChar = USART_ReceiveData( USART2 );
	xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );
}

/* If sending or receiving from a queue has caused a task to unblock, and
the unblocked task has a priority equal to or higher than the currently
running task (the task this ISR interrupted), then xHigherPriorityTaskWoken
will have automatically been set to pdTRUE within the queue send or receive
function.  portEND_SWITCHING_ISR() will then ensure that this ISR returns
directly to the higher priority unblocked task. */
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

} ~~~~

Previously I was using V7.1.0, which is available through CooCox. The code worked fine with this version of FreeRTOS, but I needed to upgrade to V8.2.3 so that I could access some of the new features, such as xTaskNotify. When I try and run my firmware, whenever either of the aforementioned functions are used, my firmware ends up hitting configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); in the following block of code:

~~~~

if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;

	/* Obtain the number of the currently executing interrupt. */
	__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );

	/* Is the interrupt number a user defined interrupt? */
	if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
	{
		/* Look up the interrupt's priority. */
		ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

		/* The following assertion will fail if a service routine (ISR) for
		an interrupt that has been assigned a priority above
		configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
		function.  ISR safe FreeRTOS API functions must *only* be called
		from interrupts that have been assigned a priority at or below
		configMAX_SYSCALL_INTERRUPT_PRIORITY.

		Numerically low interrupt priority numbers represent logically high
		interrupt priorities, therefore the priority of the interrupt must
		be set to a value equal to or numerically *higher* than
		configMAX_SYSCALL_INTERRUPT_PRIORITY.

		Interrupts that	use the FreeRTOS API must not be left at their
		default priority of	zero as that is the highest possible priority,
		which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
		and	therefore also guaranteed to be invalid.

		FreeRTOS maintains separate thread and ISR API functions to ensure
		interrupt entry is as fast and simple as possible.

		The following links provide detailed information:
		http://www.freertos.org/RTOS-Cortex-M3-M4.html
		http://www.freertos.org/FAQHelp.html */
		configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
	}

	/* Priority grouping:  The interrupt controller (NVIC) allows the bits
	that define each interrupt's priority to be split between bits that
	define the interrupt's pre-emption priority bits and bits that define
	the interrupt's sub-priority.  For simplicity all bits must be defined
	to be pre-emption priority bits.  The following assertion will fail if
	this is not the case (if some bits represent a sub-priority).

	If the application only uses CMSIS libraries for interrupt
	configuration then the correct setting can be achieved on all Cortex-M
	devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
	scheduler.  Note however that some vendor specific peripheral libraries
	assume a non-zero priority group setting, in which cases using a value
	of zero will result in unpredicable behaviour. */
	configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
endif /* configASSERT_DEFINED */

~~~~

Can anyone suggest what the issue is here please? As I say the code worked fine with an older version of FreeRTOS, so is there something extra I need to use xQueueSendFromISR() & xQueueReceiveFromISR() in later versions of FreeRTOS.

Thanks

Andrew


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by rtel on February 20, 2016

I'm not sure what more I can say over and above the information provided in the comments of the code you have already posted.......you have an incorrect interrupt priority.

You didn't hit this assert before because the assert was added to the code after the older FreeRTOS version you were using, and it seems your code will always have had this bug but you were just lucky enough not to hit it - yet.

More information is provided on the following link: http://www.freertos.org/RTOS-Cortex-M3-M4.html

Regards.


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by ajellisuk on February 22, 2016

Thank you for getting back to me.

I'll take a look at the link you sent me, and I'll let you know how I get on.

Regards

Andrew


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by ajellisuk on February 23, 2016

Hi,

I have read through the link you have provided, and I'm still unclear what I'm doing wrong. I have attached my project. I have placed a couple of snippets of code which I beleive to be where my problem lies.

In FreeRTOSConfig.h the relevent interrupt priority macros are defined as:

~~~~ /* Cortex-M specific definitions. */

ifdef _NVICPRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS       		__NVIC_PRIO_BITS
else
#define configPRIO_BITS       		4        /* 15 priority levels */
endif

/* The lowest interrupt priority that can be used in a call to a "set priority" function. */

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0xf

/* The highest interrupt priority that can be used by any interrupt service routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values. */

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

/* Interrupt priorities used by the kernel port layer itself. These are generic to all Cortex-M ports, and do not rely on any particular library functions. */

define configKERNELINTERRUPTPRIORITY ( configLIBRARYLOWESTINTERRUPTPRIORITY << (8 - configPRIOBITS) )

/* !!!! configMAXSYSCALLINTERRUPT_PRIORITY must not be set to zero !!!! See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */

define configMAXSYSCALLINTERRUPTPRIORITY ( configLIBRARYMAXSYSCALLINTERRUPTPRIORITY << (8 - configPRIOBITS) )

~~~~

In my serial.c file, the usart interrupts are set up with:

~~~~ NVICInitStructure.NVICIRQChannel = USART2IRQn; NVICInitStructure.NVICIRQChannelPreemptionPriority = configMAXSYSCALLINTERRUPTPRIORITY + 10; NVICInitStructure.NVICIRQChannelSubPriority = 0; // Not used as 4 bits are used for the pre-emption priority. NVICInitStructure.NVICIRQChannelCmd = ENABLE; NVICInit( &NVICInitStructure ); USARTITConfig( USART2, USARTIT_RXNE, ENABLE ); ~~~~

If I have understood the documentation correctly, then the usart interrupt priority should be well within the range of the interrupt priority limts. If I comment out xQueueSendFromISR() & xQueueReceiveFromISR() in my usart isr, the firmware does not hit configASSERT.

Attachments

STMDiscoveryTest.zip (843684 bytes)

xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by rtel on February 23, 2016

Those priorities look ok. As you are using an STM32, have you also called NVICPriorityGroupConfig( NVICPriorityGroup_4 ); ?


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by koor1200 on February 23, 2016

Hi, Thank you for your response. My target is not STM32. It is the KINETIS K64 series as stated in the original post. There are 4 tasks:

OSATaskCreate(tasktwo,"tasktwo",TASKONESTACKSIZE,0,6u,NULL,false,&tasktwotaskhandler); OSATaskCreate(vATask,"vATask",TASKONESTACKSIZE,0,5u,NULL,false,&vATasktaskhandler); OSATaskCreate(vADifferentTask,"vADifferentTask",TASKONESTACKSIZE,0,5u,NULL,false,&vADifferentTasktask_handler);

//create task
result = OSA_TaskCreate(task_one,
		(uint8_t *)"task_one",
		TASK_ONE_STACK_SIZE,
		0,
		6u,
		(task_param_t)0,
		false,
		&task_one_task_handler);

        and here:

        void vATask( void *pvParameters )

{ struct AMessage *pxMessage; uint32t * testptr;

// Create a queue capable of containing 10 pointers to AMessage structures.
// These should be passed by pointer as they contain a lot of data.
xQueue = xQueueCreate( 16, sizeof( unsigned int*  ) );
if( xQueue == 0 )
{
    // Failed to create the queue.
}



// ...



// Send a pointer to a struct AMessage object.  Don't block if the
// queue is already full.
pxMessage = & xMessage;
test_ptr= &test_var;
xQueueSend( xQueue, ( void * )/* &pxMessage*/&test_ptr, ( TickType_t ) 0 );



// ... Rest of task code.

}


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by koor1200 on February 23, 2016

Sorry my mistake. My reply doe not belong to the this original post.


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by ajellisuk on February 24, 2016

I have called NVICPriorityGroupConfig( NVICPriorityGroup_4 ); just before calling vTaskStartScheduler();

My main() function reads:

~~~~ int main( void ) {

HwInit();

vDebugInitQueue();
vDebugPrintf( "\r\nEPS Test1 0.0.1 - 1/4/2012\r\n" );
vDebugPrintResetType();

// Tasks get started here...
xTaskCreate( vTimeTask, (signed char *) "TIME", configMINIMAL_STACK_SIZE,
        NULL, mainTIME_TASK_PRIORITY, &hTimeTask );
xTaskCreate( vMemsTask, (signed char *) "MEMS", configMINIMAL_STACK_SIZE,
        NULL, mainMEMS_TASK_PRIORITY, &hMemsTask );

xTaskCreate( vDebugTask, (signed char *) "DEBUG", configMINIMALSTACKSIZE, NULL, mainDEBUGTASKPRIORITY, &hDebugTask );

NVICPriorityGroupConfig( NVICPriorityGroup_4 );

vTaskStartScheduler(); // This should never return.

// Will only get here if there was insufficient memory to create
// the idle task.
for( ;; );  

}

~~~~

When I step into xQueueReceiveFromISR(), the code reaches vPortValidateInterruptPriority() as I would expect, then I get some results which I'm perplexed by.

When asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); is called ulCurrentInterrupt is 32 which according to the stm32 reference manual is I2C1ER. The ISR which calls xQueueReceiveFromISR() is USART2IRQHandler(), and has a value of 38.


xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3

Posted by edwards3 on February 24, 2016

Looks like it is not the interrupt you think, but be careful with the numbering in case the numbers are an index into the vector table or from the first non system interrupt.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists