Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

HardFault when using Queues in Interrupt

Posted by Gizmor on December 31, 2010
Hi,

I'm running the recent version of FreeRTOS on my Cortex M3 (LPC1768).

It runs fine, but if I want to send anything to a queue from an interrupt it crashed (jumps to HardFault).
I tried "xSemaphoreGiveFromISR" and "xQueueSendToBackFromISR", but both of them will crash at the memcpy command.

I used the functions the same way as in the samples, so I don't see what's wrong there? Is there anything I need to setup in the config for it to run?
The usage of the queues from normal tasks works without any problems.

I hope anyone can help me with this problem.


Bye
Gizmor

RE: HardFault when using Queues in Interrupt

Posted by Richard on December 31, 2010
Have you taken into account point 3 on the following page?

www.freertos.org/FAQHelp.html

Regards.

RE: HardFault when using Queues in Interrupt

Posted by Gizmor on December 31, 2010
Thanks for your response!
Yes, I already found this, but I'm not fully understandig how to use it :)


In FreeRTOSConfig.h there are the following settings (from the included lpc1768 demo):
#define configPRIO_BITS       5        /* 32 priority levels */

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY ( 31 << (8 - configPRIO_BITS) ) //248

/* Priority 5, or 160 as only the top three bits are implemented. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - configPRIO_BITS) ) //40



I tried to set different priorities to my Interrupt (UART2). But it doesn't change anything if I set it to 0 (highest), to 31(lowest) or to anything between.

RE: HardFault when using Queues in Interrupt

Posted by Richard on December 31, 2010
How are you setting the interrupt priority? Directly, or using a function.

Do you have the stack overflow checking switched on?

Can you post your entire ISR code?

Is the UART enabled? --- does it work ok without the call to the queue function?

Regards.

RE: HardFault when using Queues in Interrupt

Posted by Gizmor on December 31, 2010
I use the CMSIS Macro => NVIC_SetPriority(UART2_IRQn, 10);

static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}

So, this should be correct.

The folloging code is the part of my interrupt function where a char is received. The received char is printed out (debug_printf) correctly in the debug terminal (over jtag). So yes, without the Queue, everything works as expected.


/*** UART2 Receive Data Available interrupt (RDA) ***/
void UART2_ISR_ReceiveChar(void) {
static portBASE_TYPE xHigherPriorityTaskWoken;
unsigned char ReceivedChar = LPC_UART2->RBR; //Read received Char from register

UART2_ReceiveBuffer[UART2_ReceiveBufferPosW] = ReceivedChar;

if(UART2_ReceiveBufferPosW == UART2_BUFSIZE-1) {
UART2_ReceiveBufferPosW = 0;
} else {
UART2_ReceiveBufferPosW++;
}

debug_printf("ISRRec: %c\n", ReceivedChar);

xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR( UART2_ReceiveCntQueue, &xHigherPriorityTaskWoken );

if( xHigherPriorityTaskWoken == pdTRUE ) {
vPortYieldFromISR();
}
}


configCHECK_FOR_STACK_OVERFLOW is 0.

RE: HardFault when using Queues in Interrupt

Posted by Richard on December 31, 2010
A couple of things that stick out:

1) Definitely don't call debug_printf() from an ISR! Does the queue work when that line is removed?

2) Set configCHECK_FOR_STACK_OVERFLOW to 2, and define a stack overflow hook function. Just something like the following will be ok for a start.

void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
{
( void ) pxTask;
( void ) pcTaskName;

for( ;; );
}


Regards.

RE: HardFault when using Queues in Interrupt

Posted by Gizmor on December 31, 2010
> 1) Definitely don't call debug_printf() from an ISR! Does the queue work when that line is removed?

No, doesn't change anything. Even if I put only the xSemaphoreGiveFromISR in the ISR and remove everything else it doesn't work.

> 2) Set configCHECK_FOR_STACK_OVERFLOW to 2, and define a stack overflow hook function. Just something like the following will be ok for a start.

Ok, put this in, but it keeps jumping to the hardfault. vApplicationStackOverflowHook isn't executed.



RE: HardFault when using Queues in Interrupt

Posted by Richard on December 31, 2010
Running out of ideas here...

Is the queue valid? Was it created, and when it was created did you check that the xQueueCreate() return value was a valid handle (not null)?

Regards.

RE: HardFault when using Queues in Interrupt

Posted by FBU on January 19, 2011
Hi
I have the same problem with a PIC32 target, and it occurs when I raise the item number of the Queue.
When I have 4 Items, the general_exception become after a little time
when I have 8 items, the general_exception become in 1 second.
I test the configCHECK_FOR_STACK_OVERFLOW to 2 and i don't go in the vApplicationStackOverflowHook function.

this is my test code :
void vU3AInterruptHandler( void )
{
/* Declared static to minimise stack use. */
static portCHAR cByte;
static portBASE_TYPE Resultat;
static portBASE_TYPE xHigherPriorityTaskWoken;
static xComPortHandle pxPort=&UART3A_ComPort;

xHigherPriorityTaskWoken = pdFALSE;
Resultat = pdTRUE;


/* Are any Rx interrupts pending? */
if( INTGetFlag(INT_U3ARX) )
{
while(( UARTReceivedDataIsAvailable( pxPort -> eUARTId ))&&(Resultat == pdTRUE))
{
/* Retrieve the received character and place it in the queue of
received characters. */
cByte =UARTGetDataByte(pxPort -> eUARTId);

Resultat = xQueueSendFromISR( pxPort ->xRxCharsBuffer , &cByte, &xHigherPriorityTaskWoken ); // Here the memcpy() in the prvCopyDataToQueue() function in queue.c make a general exception ( 0x00000007 = EXCEP_DBE = bus error (load/store))
}
INTClearFlag( INT_U3ARX );
}

/* Are any Tx interrupts pending? */
if( INTGetFlag(INT_U3ATX) )
{
while( UARTTransmitterIsReady(pxPort -> eUARTId))
{
if( xQueueReceiveFromISR( pxPort -> xTxCharsBuffer, &cByte, &xHigherPriorityTaskWoken ) == pdTRUE )
{
/* Send the next character queued for Tx. */
UARTSendDataByte( pxPort -> eUARTId, cByte );
}
else
{
/* Queue empty, nothing to send. */
pxPort -> xTxHasEnded = pdTRUE;
break;
}
}
INTClearFlag(INT_U3ATX);
if (pxPort -> xTxHasEnded == pdTRUE) // si c'est fini
INTEnable(INT_U3ATX, INT_DISABLED);
}

/* If sending or receiving necessitates a context switch, then switch now. */
//portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}


Gizm0r, do you find a solution?
Thanks

RE: HardFault when using Queues in Interrupt

Posted by little_coder on January 21, 2011
hi,


i got exactley the same problem...

the core registers of the 1768 says fault CFSR 0x400 and that leads to INVPC (invalid program counter)

I think we are might not allowed to jump back into the isr ?

further hints i found :

when using the nvic set priority function ? whats the matter with negative values ?

    
**
* @brief Set the priority for an interrupt
*
* @param IRQn The number of the interrupt for set priority
* @param priority The priority to set
*
* Set the priority for the specified interrupt. The interrupt
* number can be positive to specify an external (device specific)
* interrupt, or negative to specify an internal (core) interrupt.
*
* Note: The priority cannot be set for every core interrupt.
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
else {
NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */
}


and another question : in portmacro.h of freertos I found

#define portSET_INTERRUPT_MASK_FROM_ISR()0;portSET_INTERRUPT_MASK() // test
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)portCLEAR_INTERRUPT_MASK();(void)x

whats the matter with the 0; ?

RE: HardFault when using Queues in Interrupt

Posted by Richard on January 21, 2011
“when using the nvic set priority function ? whats the matter with negative values ?


This is ARM provided code, nothing to do with FreeRTOS, but the answer to your question is "nothing is the matter with negative values". Read the Cortex-M technical reference manual and the CMSIS manual.


“and another question : in portmacro.h of freertos I found

#define portSET_INTERRUPT_MASK_FROM_ISR()0;portSET_INTERRUPT_MASK() // test
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)portCLEAR_INTERRUPT_MASK();(void)x

whats the matter with the 0; ?”


Again, the answer is "nothing is the matter with 0". If you try removing it you will find your code won't compile. It is there to tailor a generic macro to a specific chip in the most efficient manner possible while maintaining common kernel core code across all architectures.

These crashes while using queue functions in interrupts in Cortex-M3 ports are nearly always due to the mistakes made configuring the interrupt controller, due in part to the strange nature of setting interrupt priorities (priority 0 being the highest, not the lowest, and the fact that the most significant bits are used not the least). it is understandable why people get it wrong. People often say "I have read your FAQ, followed it and it still crashes", but when you drill deeper you find that is not the case. Case in point: https://sourceforge.net/projects/freertos/forums/forum/382005/topic/4059693 .

I would go as far as to say, I have never come across a case where the issue is caused by either just a standard everyday bug in the application C code, or a misconfiguration of the interrupt controller and/or the kernel configuration constants that relate to the interrupt controller.

I'm not saying there are no issues in the kernel code, nothing can ever give that guarantee, but I would say I am yet to have anybody provide evidence of a problem.

Regards.


RE: HardFault when using Queues in Interrupt

Posted by Richard on January 21, 2011
“I have never come across a case where the issue is caused”


...should say "I have never come across a case where the issue is not caused"

Regards.

RE: HardFault when using Queues in Interrupt

Posted by FBU on January 21, 2011
I resolve the problem by raising the stack size of my all my tasks (I give them 600 bytes).
Now, when I use the vTaskList() function, many tasks use about 500-550 bytes for their own stack.
It seems the vApplicationStackOverflowHook function didn't work for me with configCHECK_FOR_STACK_OVERFLOW equal to 1 or 2.
I'm not sure the stack size is the only reason because I've done many corrections of my code.
Regards
I hope my answer will be useful.

RE: HardFault when using Queues in Interrupt

Posted by Gizmor on January 22, 2011
“Gizm0r, do you find a solution? Thanks ”


For me the problem was an not correctly initialized queue variable.
Now everything works for me.


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


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

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

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner