Cortex M3 - Hard fault

puppenspiel wrote on Thursday, March 25, 2010:

Dear all,
I use FreeRTOS V6.0.1 running on a Cortex M3 with the delivered default configuration.

When I try to set NVIC priority groups to:
SCB->AIRCR = 5FA0700

Which should be equal to:
0 Preempting Priorities
16 Sub Priorities

The controller crashes with a hard fault after calling the SVC statement within the FreeRTOS function vPortStartFirstTask( ).

void vPortStartFirstTask( void )
{
__asm volatile(
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0,  \n"
" ldr r0,  \n"
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
" svc 0 \n" /* System call to start first task. */
);
}

When a I do NOT modify the AIRCR register and leave the default reset value ( 0x0 ) everything works fine. It seems that there is priority conflict with vPortSVCHandler( ) handler ?

Has anyone an idea what could be the failure ?!

woops_ wrote on Thursday, March 25, 2010:

Never understood the sub priorities but if you call svc while it is masked or while the mcu is already at a higher priority then it will fault for sure.

puppenspiel wrote on Thursday, March 25, 2010:

But how can I mask the svc when just changing the priority group. What do you mean with: “…while the mcu is already at a higher priority…” ? I think the MCU does currently not handle an interrupt.

vijaypst wrote on Friday, April 09, 2010:

If I understand correctly FreeRTOS needs ‘Exception Pre-emption’ (interrupt nesting) for it to work properly. Having 0x07 for PRIGROUP disables exception preemption and so a valid range is 0x02 to 0x04 for NXP LPC176x(priority field uses 5 bits). A value of 0x0 is not a valid value for CM3 based chips from STM or NXP(it may work though). Iam also not sure who checks the PRIGROUP  value and hits a Hard-Fault if the value is out of range.

anonymous wrote on Monday, April 26, 2010:

I have same problem on stm32. During interrupt (priority 12) I’m rading data from queue and send it to USART  And processor is having hard fault :(.

Configuration for interrupt priorities is taken from example to stm32 primer2:
#define configKERNEL_INTERRUPT_PRIORITY 255
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */

If the priority is above or equal 11 (0…11) it will work fine but below…. it’s a problem.

void handleInterruptUSART(enum COMPort com){
    xQueueHandle queue;
    USART_TypeDef* usart = GET_USART_TYPE(com); 
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    char data = '?';
    portBASE_TYPE queueRes;
    if(USART_GetITStatus(usart,USART_IT_TXE) != RESET ){
        queue = USART_WRITE_QUEUE[com];
    
        if(uxQueueMessagesWaiting(queue)<=1){
            USART_ITConfig(usart, USART_IT_RXNE, DISABLE);
        }
            
        queueRes = xQueueReceiveFromISR(queue, &data, &xHigherPriorityTaskWoken);
        if(queueRes == pdTRUE){
            USART_SendData(usart, data);
        } else {
            ;
        }
    }
    if(USART_GetITStatus(usart,USART_IT_RXNE) != RESET){
       //Samething
    }    
    if( xHigherPriorityTaskWoken )
    {
        taskYIELD();
    }
}

Thx in advence

stf12 wrote on Monday, April 26, 2010:

Hi,

Regards to your configuration, if you assign a priority level below 11 you can’t use any FreeRTOS API in your IRQ Handler. This should be the root of your hard fault. For more information look at the following web page of FreeRTOS.org:
http://www.freertos.org/a00110.html#kernel_priority

Regards,
Stefano