1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

irq_stack: provide a proper IRQ stack for FreeRTOS

The MSP (IRQ stack) was trampling across the data segment.  This was
especially disastrous in the USB interrupts since they allocate and
fill buffers on the stack.

The root of this trampling was that no RAM was being reserved for the
MSP and a hard-coded value of (0x20000400) was used as the initial MSP
base address.  This resulted in the first 1K bytes of the .data segment
overlapping with the IRQ stack.  As can be expected, all sorts of badness
resulted when interrupts were firing and trampling over variables.

This change reserves the first _isr_stack_size bytes at the beginning of
RAM for the MSP.  If an ISR call chain runs off of the end of the MSP,
a Hard Fault will be generated as the (now invalid) sp is accessed.

There are two stack pointers in the Cortex-M3 CPU.  These are MSP (Main
Stack Pointer) and PSP (Process Stack Pointer).

Which stack is in use at any given time is determined by the following table:

   Mode      CONTROL[ASPSEL]    Stack
   ----      ---------------    -----
   Thread    0                  MSP
   Thread    1                  PSP
   Handler   x                  MSP

Out of reset, the CPU is in Thread mode using the MSP.  The initial value
of the MSP is automatically loaded from address 0 (lowest word in boot
region -- typically FLASH) immediately prior to jumping to the reset vector.

When running at interrupt level, the Cortex-M3 always uses the MSP and the
ASPSEL bit is forced to zero.

FreeRTOS allocates a separate stack for each task upon task creation.  These
task stacks are allocated from the heap.  FreeRTOS sets the active stack to
the PSP whenever running in a task context (both in privileged mode and user
mode).

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@652 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
stac 2010-05-24 16:33:26 +00:00 committed by stac
parent dea006523f
commit 41da33c920
2 changed files with 21 additions and 3 deletions

View File

@ -39,6 +39,9 @@ MEMORY
/* higher address of the user mode stack */
_estack = 0x20010000;
/* This is the size of the stack for early init and for all FreeRTOS IRQs */
_irq_stack_size = 0x400;
/* default stack sizes.
These are used by the startup in order to allocate stacks for the different modes.
@ -259,6 +262,22 @@ SECTIONS
} >FLASH
/*
* This stack is used both as the initial sp during early init as well as ultimately
* being used as the STM32's MSP (Main Stack Pointer) which is the same stack that
* is used for _all_ interrupt handlers. The end of this stack should be placed
* against the lowest address in RAM so that a stack overrun results in a hard fault
* at the first access beyond the end of the stack.
*/
.irq_stack :
{
. = ALIGN(4);
_irq_stack_end = . ;
. = . + _irq_stack_size ;
. = ALIGN(4);
_irq_stack_top = . ;
} >RAM
/* This is the initialized data section
The program executes knowing that the data is in the RAM

View File

@ -50,7 +50,6 @@ defined in linker script */
.word _ebss
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
.equ Initial_spTop, 0x20000400
.equ BootRAM, 0xF1E0F85F
/**
* @brief This is the code that gets called when the processor first
@ -140,7 +139,7 @@ Infinite_Loop:
g_pfnVectors:
.word Initial_spTop
.word _irq_stack_top
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler