IAR 5.41 getting to Hard Fault with low opt

baranov wrote on Friday, August 12, 2011:

Hello. I am not really sure that the problem is FreeRtos related. 
I have a project with one task consisting only of vTaskDelay(5000);
When I compile the project with medium and high optimization options it works fine. When I switch to low it goes to Hard Fault Interrupt. When I single step, it runs to vPortStartFirstTask() and gets into:

vPortSVCHandler;
	ldr	r3, =pxCurrentTCB
	ldr r1, [r3]
	ldr r0, [r1]
	ldmia r0!, {r4-r11}
	msr psp, r0
	mov r0, #0
	msr	basepri, r0
	orr r14, r14, #13
	bx r14

On exit from it my debugger shows:
**Usage fault: Attempt to use a coprocessor instruction! **
Of course I tried to vary stack and heap sizes but it did not clarify the situation.
Could anybody give a clue, what did the optimization option change?

rtel wrote on Sunday, August 14, 2011:

I am guessing, and it is just a guess, that you are using a Cortex-M3 device. If so, then IAR V5.x is out of date.  Other than that, how is your C start up code written?  The symptom you describe can often happen when the start up is written completely in C, and is caused by a loop variable being stored on the stack with zero optimisation (and so getting wiped out by its own initialisation code) compared to the same variable being held in a register at higher optimisation (and so being safe from being wiped out by memory clearing and initialisation code).

Regards.

baranov wrote on Monday, August 15, 2011:

Thank you very much!. Yes, it is STM32.  I will try IAR 6.10.

baranov wrote on Monday, August 15, 2011:

IAR 6.10 did not help.
I saw that in "medium" option  vPortSVCHandler  enters assembler function shown above  with
LR = 0xFFFFFFF9, which is correct and in “low” option LR has some other value. In my case it is e.g. 0x800D7FF. I guess, I simply have to use medium optimization.

davedoors wrote on Monday, August 15, 2011:

Can you post the code that initializes the C run time environment. The bit that zeros out the memory, normally in a file called crt0 or cstart or startup, etc.

baranov wrote on Monday, August 15, 2011:

I think, I solved the problem.
I had:

const intvec_elem __vector_table[] =
{
    { .__ptr = __sfe( "CSTACK" ) },
    __iar_program_start,
    NMIException,
    HardFaultException,
    MemManageException,
    BusFaultException,
    UsageFaultException,
    0, 0, 0, 0,             // Reserved
   SVCHandler,
    DebugMonitor,
    0,                      // Reserved
    PendSVC,
    SysTickHandler
};

and

void SVCHandler( void )
{
#ifdef FREERTOS
  	vPortSVCHandler();
#endif
}

I replaced it by:

const intvec_elem __vector_table[] =
{
    { .__ptr = __sfe( "CSTACK" ) },
    __iar_program_start,
    NMIException,
    HardFaultException,
    MemManageException,
    BusFaultException,
    UsageFaultException,
    0, 0, 0, 0,             // Reserved
   vPortSVCHandler,
    DebugMonitor,
    0,                      // Reserved
    PendSVC,
    SysTickHandler
};

It eliminated call from SVCHandler and now it works with low optimization too.
Any comments including scornful will be highly appreciated.