ozsmit wrote on Thursday, November 15, 2012:
Richard,
I tried what you suggest both making ISR Naked or not and still have the same problem that the PC never gets to the end of the IRQ_Handler and return to the previous code that the processor was executing.
Here is my latest IRQ_Handler:
void IRQ_Handler(void) __attribute__((interrupt (“IRQ”)));
void IRQ_Handler(void)
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. */
__asm volatile( “bl vTaskIncrementTick” );
#if configUSE_PREEMPTION == 1
__asm volatile( “bl vTaskSwitchContext” );
#endif
/* clear timer interrupt. */
OSTIMER1_CTRL |= 0x00000008;
//OSTIMER1_CTRL = 0x00000000A;
/* Restore the context of the new task. */
portRESTORE_CONTEXT();
}
The bottom line is when the Context is restored, The PC is not pointing back to the end of the IRQ_Handler Routine.
Here is the ASM of the Handler:
void IRQ\_Handler\(void\)
\{
E92D080C push \{r2-r3, r11\}
E28DB008 add r11, sp, \#8
-- mainISR.c - 129 --------------------------
/\* Save the context of the interrupted task. \*/
portSAVE\_CONTEXT\(\);
E92D0001 push \{r0\}
E94D2000 stmdb sp, \{sp\}^
E1A00000 mov r0, r0
E24DD004 sub sp, sp, \#4
E8BD0001 pop \{r0\}
E9204000 stmdb r0\!, \{lr\}
E1A0E000 mov lr, r0
E8BD0001 pop \{r0\}
E94E7FFF stmdb lr, \{r0-lr\}^
E1A00000 mov r0, r0
E24EE03C sub lr, lr, \#0x3C
E14F0000 mrs r0, spsr
E92E0001 stmdb lr\!, \{r0\}
E59F0094 ldr r0, 0x00002A90 <IRQ\_Handler+0xD8>
E5900000 ldr r0,
E92E0001 stmdb lr\!, \{r0\}
E59F008C ldr r0, 0x00002A94 <IRQ\_Handler+0xDC>
E5900000 ldr r0,
E580E000 str lr,
E59F3070 ldr r3, 0x00002A84 <IRQ\_Handler+0xCC>
E5933000 ldr r3,
E59F306C ldr r3, 0x00002A88 <IRQ\_Handler+0xD0>
E5933000 ldr r3,
-- mainISR.c - 133 --------------------------
/\* Increment the RTOS tick count, then look for the highest priority
task that is ready to run. \*/
\_\_asm volatile\( "bl vTaskIncrementTick" \);
EB0010B7 bl 0x00006D00 <vTaskIncrementTick>
-- mainISR.c - 138 --------------------------
\#if configUSE\_PREEMPTION == 1
\_\_asm volatile\( "bl vTaskSwitchContext" \);
EB00113C bl 0x00006F18 <vTaskSwitchContext>
-- mainISR.c - 141 --------------------------
\#endif
/\* clear timer interrupt. \*/
OSTIMER1\_CTRL |= 0x00000008;
E59F3060 ldr r3, 0x00002A8C <IRQ\_Handler+0xD4>
E59F205C ldr r2, 0x00002A8C <IRQ\_Handler+0xD4>
E5922000 ldr r2,
E3822008 orr r2, r2, \#8
E5832000 str r2,
-- mainISR.c - 145 --------------------------
//OSTIMER1\_CTRL = 0x00000000A;
/\* Restore the context of the new task. \*/
portRESTORE\_CONTEXT\(\);
E59F0054 ldr r0, 0x00002A94 <IRQ\_Handler+0xDC>
E5900000 ldr r0,
E590E000 ldr lr,
E59F0044 ldr r0, 0x00002A90 <IRQ\_Handler+0xD8>
E8BE0002 ldm lr\!, \{r1\}
E5801000 str r1,
E8BE0001 ldm lr\!, \{r0\}
E169F000 msr spsr\_cf, r0
E8DE7FFF ldmia lr, \{r0-lr\}^
E1A00000 mov r0, r0
E59EE03C ldr lr,
E25EF004 subs pc, lr, \#4
E59F3014 ldr r3, 0x00002A84 <IRQ\_Handler+0xCC>
E5933000 ldr r3,
E59F3010 ldr r3, 0x00002A88 <IRQ\_Handler+0xD0>
E5933000 ldr r3,
-- mainISR.c - 149 --------------------------
\}
E24BD008 sub sp, r11, \#8
E8BD080C pop \{r2-r3, r11\}
E25EF004 subs pc, lr, \#4
The strange this is the compiler is placing the parethesis at the end of the Restore context Macro, when in fact the end should be the restore of resgisters and reload of PC and SPSR…
E24BD008 sub sp, r11, #8
E8BD080C pop {r2-r3, r11}
E25EF004 subs pc, lr, #4
Here is my stack configuration, just in case you see a problem with that.
.heap 0x0000f9b4 0x400
0x0000f9b4 __heap_start__ = .
*(.heap .heap.*)
0x0000fdb4 . = ALIGN (MAX ((__heap_start__ + __HEAPSIZE__), .), 0x4)
*fill* 0x0000f9b4 0x400 00
0x0000fdb4 __heap_end__ = (__heap_start__ + SIZEOF (.heap))
0x0000fdb4 __heap_load_end__ = __heap_end__
0x00000001 . = ASSERT (((__heap_end__ >= __SRAM_segment_start__) && (__heap_end__ <= __SRAM_segment_end__)), error: .heap is too large to fit in SRAM memory segment)
0x0000fdb4 __stack_load_start__ = ALIGN (__heap_end__, 0x4)
.stack 0x0000fdb4 0x400
0x0000fdb4 __stack_start__ = .
*(.stack .stack.*)
0x000101b4 . = ALIGN (MAX ((__stack_start__ + __STACKSIZE__), .), 0x4)
*fill* 0x0000fdb4 0x400 00
0x000101b4 __stack_end__ = (__stack_start__ + SIZEOF (.stack))
0x000101b4 __stack_load_end__ = __stack_end__
0x00000001 . = ASSERT (((__stack_end__ >= __SRAM_segment_start__) && (__stack_end__ <= __SRAM_segment_end__)), error: .stack is too large to fit in SRAM memory segment)
0x000101b4 __stack_irq_load_start__ = ALIGN (__stack_end__, 0x4)
.stack_irq 0x000101b4 0x100
0x000101b4 __stack_irq_start__ = .
*(.stack_irq .stack_irq.*)
0x000102b4 . = ALIGN (MAX ((__stack_irq_start__ + __STACKSIZE_IRQ__), .), 0x4)
*fill* 0x000101b4 0x100 00
0x000102b4 __stack_irq_end__ = (__stack_irq_start__ + SIZEOF (.stack_irq))
0x000102b4 __stack_irq_load_end__ = __stack_irq_end__
0x00000001 . = ASSERT (((__stack_irq_end__ >= __SRAM_segment_start__) && (__stack_irq_end__ <= __SRAM_segment_end__)), error: .stack_irq is too large to fit in SRAM memory segment)
0x000102b4 __stack_fiq_load_start__ = ALIGN (__stack_irq_end__, 0x4)
.stack_fiq 0x000102b4 0x100
0x000102b4 __stack_fiq_start__ = .
*(.stack_fiq .stack_fiq.*)
0x000103b4 . = ALIGN (MAX ((__stack_fiq_start__ + __STACKSIZE_FIQ__), .), 0x4)
*fill* 0x000102b4 0x100 00
0x000103b4 __stack_fiq_end__ = (__stack_fiq_start__ + SIZEOF (.stack_fiq))
0x000103b4 __stack_fiq_load_end__ = __stack_fiq_end__
0x00000001 . = ASSERT (((__stack_fiq_end__ >= __SRAM_segment_start__) && (__stack_fiq_end__ <= __SRAM_segment_end__)), error: .stack_fiq is too large to fit in SRAM memory segment)
0x000103b4 __stack_svc_load_start__ = ALIGN (__stack_fiq_end__, 0x4)
.stack_svc 0x000103b4 0x200
0x000103b4 __stack_svc_start__ = .
*(.stack_svc .stack_svc.*)
0x000105b4 . = ALIGN (MAX ((__stack_svc_start__ + __STACKSIZE_SVC__), .), 0x4)
*fill* 0x000103b4 0x200 00
0x000105b4 __stack_svc_end__ = (__stack_svc_start__ + SIZEOF (.stack_svc))
0x000105b4 __stack_svc_load_end__ = __stack_svc_end__
0x00000001 . = ASSERT (((__stack_svc_end__ >= __SRAM_segment_start__) && (__stack_svc_end__ <= __SRAM_segment_end__)), error: .stack_svc is too large to fit in SRAM memory segment)
0x000105b4 __stack_abt_load_start__ = ALIGN (__stack_svc_end__, 0x4)
.stack_abt 0x000105b4 0x0
0x000105b4 __stack_abt_start__ = .
*(.stack_abt .stack_abt.*)
0x000105b4 . = ALIGN (MAX ((__stack_abt_start__ + __STACKSIZE_ABT__), .), 0x4)
0x000105b4 __stack_abt_end__ = (__stack_abt_start__ + SIZEOF (.stack_abt))
0x000105b4 __stack_abt_load_end__ = __stack_abt_end__
0x00000001 . = ASSERT (((__stack_abt_end__ >= __SRAM_segment_start__) && (__stack_abt_end__ <= __SRAM_segment_end__)), error: .stack_abt is too large to fit in SRAM memory segment)
0x000105b4 __stack_und_load_start__ = ALIGN (__stack_abt_end__, 0x4)
.stack_und 0x000105b4 0x0
0x000105b4 __stack_und_start__ = .
*(.stack_und .stack_und.*)
0x000105b4 . = ALIGN (MAX ((__stack_und_start__ + __STACKSIZE_UND__), .), 0x4)
0x000105b4 __stack_und_end__ = (__stack_und_start__ + SIZEOF (.stack_und))
0x000105b4 __stack_und_load_end__ = __stack_und_end__
0x00000001 . = ASSERT (((__stack_und_end__ >= __SRAM_segment_start__) && (__stack_und_end__ <= __SRAM_segment_end__)), error: .stack_und is too large to fit in SRAM memory segment)
0x000105b4 __tbss_load_start__ = ALIGN (__stack_und_end__, 0x4)
Thanks
Ozmit