|
NOTE:This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
FreeRTOS Support Archive
The FreeRTOS support forum can be used for active support both from Amazon Web Services and the community. In return for using our software for free, we request you play fair and do your bit to help others! Sign up for an account and receive notifications of new support topics then help where you can.

This is a read only archive of threads posted to the FreeRTOS support forum. Use these archive pages to search previous posts. New forum support threads can be started at the FreeRTOS forums.
[FreeRTOS Home]
[Live FreeRTOS Forum]
[FAQ]
[Archive Top]
[February 2016 Threads]
xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3Posted by ajellisuk on February 19, 2016 Hi,
I have a block of code for handling USART interrupts on an STM32F407 discovery board:
~~~~
void USART2 IRQHandler( void )
{
portBASETYPE xHigherPriorityTaskWoken = pdFALSE;
portCHAR cChar;
if( USART_GetITStatus( USART2, USART_IT_TXE ) == 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.
USART_SendData( USART2, cChar );
}
else
{
USART_ITConfig( USART2, USART_IT_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.3Posted 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.3Posted 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.3Posted 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 __NVICPRIOBITS
/* __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) )
/* !!!! configMAX SYSCALLINTERRUPT_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:
~~~~
NVIC InitStructure.NVICIRQChannel = USART2 IRQn;
NVICInitStructure.NVIC IRQChannelPreemptionPriority = configMAXSYSCALL INTERRUPTPRIORITY + 10;
NVIC InitStructure.NVICIRQChannelSubPriority = 0; // Not used as 4 bits are used for the pre-emption priority.
NVIC InitStructure.NVICIRQChannelCmd = ENABLE;
NVIC Init( &NVICInitStructure );
USART ITConfig( 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.
xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3Posted 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.3Posted 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:
OSA TaskCreate(tasktwo,”task two”,TASKONE STACKSIZE,0,6u,NULL,false,&task twotask handler);
OSATaskCreate(vATask,”vATask”,TASK ONESTACK SIZE,0,5u,NULL,false,&vATasktask handler);
OSATaskCreate(vADifferentTask,”vADifferentTask”,TASK ONESTACK SIZE,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;
uint32_t * test_ptr;
// 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.3Posted 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.3Posted by ajellisuk on February 24, 2016 I have called NVIC PriorityGroupConfig( NVICPriorityGroup_4 ); just before calling vTaskStartScheduler();
My main() function reads:
~~~~
int main( void ) {
HwInit();
vDebugInitQueue();
vDebugPrintf( "rnEPS Test1 0.0.1 - 1/4/2012rn" );
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”, configMINIMAL_STACK_SIZE,
NULL, mainDEBUG_TASK_PRIORITY, &hDebugTask );
NVIC PriorityGroupConfig( 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 I2C1 ER. The ISR which calls xQueueReceiveFromISR() is USART2IRQHandler(), and has a value of 38.
xQueueSendFromISR() & xQueueReceiveFromISR() causing configASSERT() failure in V8.2.3Posted 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.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|
|