HardFault when using Queues in Interrupt

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

HardFault when using Queues in Interrupt

Have you taken into account point 3 on the following page? www.freertos.org/FAQHelp.html Regards.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

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: %cn", ReceivedChar);
    xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR( UART2_ReceiveCntQueue, &xHigherPriorityTaskWoken );
    if( xHigherPriorityTaskWoken == pdTRUE ) {
        vPortYieldFromISR();
    } 
}
configCHECK_FOR_STACK_OVERFLOW is 0.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

> 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.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

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

HardFault when using Queues in Interrupt

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;  ?

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

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.

HardFault when using Queues in Interrupt

Gizm0r, do you find a solution? Thanks
For me the problem was an not correctly initialized queue variable.
Now everything works for me.