RAM Corruption

jrubis wrote on Friday, March 19, 2010:

I am attempting to track down a RAM corruption issue.

Project Info:

Processor: STM32F103VE (Coretx M3)
Tools: ARM RVDS 4.0 SP3
Free RTOS V6.0.4
Using Portability Functions: RVDS->ARM_CM3

It appears that the Main Stack Pointer (MSP) is being corrupted when the RTOS is starting up. I traced it down to a function that sets the MSP. The function is called vPortStartFirstTask. On completion of this function the MSP is pointing directly in the middle of an array that I have defined to hold some data for my LCD. This is causing the LCD data to become corrupted.

davedoors wrote on Friday, March 19, 2010:

Normally cortex m3 chips will define a stack either as a simple array or by reserving space using the linker script. In either case the first position in the vector table should be set to point to the stack. Is this the case in your application?

Is the linker script reserving space for your LCD buffer, or is that just using C variables?

jrubis wrote on Friday, March 19, 2010:

I put a break point at the entry point my my main function and then looked vector table as you suggested. It apears that the SP address that is located in the vector table is not correct.

I am using a static C varaiable to hold the LCD data.

jrubis wrote on Friday, March 19, 2010:

Actually the SP matches what is defined in the startup_stm32f10x_hd.s file.

__initial_spTop EQU    0x20000400                 ; stack used for SystemInit_ExtMemCtl
                                                  ; always internal RAM used

The problem is that my static array for the LCD data is showing an adddress, in the debugger, of 0x200001D8 and has a length of 0x610 Bytes.

davedoors wrote on Friday, March 19, 2010:

So that explains the corruption, the question now is how did it get to be like that?  It sounds like a linker script error.

Is your application based on a demo from the main FreeRTOS zip file?

jrubis wrote on Friday, March 19, 2010:

I agree that it looks like a linker issue. I think I may be missing something my the linker directive file (scatter file) or in the project settings.  The project is not bassed on the demo in the Free RTOS zip file. I didn’t think there was a demo for ARM RVDS. I though that only CM3 ones were for MDK.

thomask wrote on Friday, March 19, 2010:

davedoors wrote:

> Normally cortex m3 chips will define a stack either as a simple array or by
> reserving space using the linker script. In either case the first position in
> the vector table should be set to point to the stack.

As I reported on 15.12.2009, “Potential stack problem on STM32”, there are use cases where the _actual_ stack pointer will have to differ from the _initial_ stack pointer given in the vector table.

The STM3210E Eval board features external memory, and the ST provided startup-code will move the stack pointer to that memory after initializing the FSMC (flexible static memory) controller.

jrubis wrote on Friday, March 19, 2010:

After looking at this some more , my MAP file generated by the linker is telling me that the Stack is located at: 0x20008128 with a length of 0x2000

    0x20002128   0x00006000   Zero   RW           69    HEAP                startup_stm32f10x_hd.o
    0x20008128   0x00002000   Zero   RW           68    STACK               startup_stm32f10x_hd.o

The first entry in the vector table doesn’t match this value.

This appears to be because the startup_stm32f10x_hd.s file defines the __initial_spTop EQU    0x20000400

This value is then used in the Vectors section:

__Vectors       DCD     __initial_spTop           ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler

On entry to main () the MSP register value is equal to 0x2000A110. Which looks like an okay address for the stack based on the stack starting at 0x20008128 with a length of 0x2000.

I think the problem, as tomask mentioned, is that the FreeRTOS code is initializing the MSP using what is in the vector section.

rtel wrote on Friday, March 19, 2010:

I could introduce something for all Cortex-M3 ports whereby the address of the stack to use after the scheduler is started is set using a #define.  If the define exists then the address is used, if the define does not exist then the address from the vector table is used.

Thoughts?

Regards.

jrubis wrote on Friday, March 19, 2010:

I checked the start up file from a STM32 sample in Keil MDK.

It defines the first entry in the Vector Table as:

__Vectors       DCD     __initial_sp           ; Top of Stack

While the start up file from ST (Ver 3.1.2) defines it as:

__Vectors       DCD     __initial_spTop           ; Top of Stack

It looks like ST has now change this with version 3.2.0

With this version the first entry in the Vector Table is:

__Vectors       DCD     __initial_sp               ; Top of Stack

rtel wrote on Friday, March 19, 2010:

Out of interest, what advantage would you get by placing the stack in slower external memory?  Or is there no speed difference?

Basically, what is the disadvantage of just leaving the stack in internal RAM?

Regards.

jrubis wrote on Friday, March 19, 2010:

Looks like switching to the new file solves the problem.

I am not sure why you would want to place the stack in xram as it is normally slower. Especally on this target. Maybe the were using the intrenal ram for a video buffer and wanted that buffer to have the fastest possible access.