cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 HardFault_Handle

rthorstensson
Associate II
Posted on August 07, 2014 at 16:13

I have a problem in STMF103C8T7 and I can't find the solution.

The STM32 reads corrupt data in array and when reaching a certain memory adress it crashes.

The array look like this:

typedef struct

{

int32_t v1;

int32_t v2;

uint32_t v3;

short v4;

}V_Data;

&sharpdefine DATA_LENGTH 850

V_Data data[DATA_LENGTH];

Reading index 670 to 696 results in corrupt data. When writing to index 697 HardFault Exception occures. Variables after the array can be read witthout problems

The .map file looks like:

0x20001268 other variable

0x2000126c data array

0x2000478c other variable, can be ead and written

0x20004790 other variable, can be ead and written

0x20004858 other variable, can be ead and written

0x2000485c other variable, can be ead and written

The corrupt data starts at

0x2000126c + 670 * 16 = 15436 => 0x20003C4C

The crash address is at

0x2000126c + 697 * 16 = 15868 => 0x20003DFC

The STM32 has 20 kB SRAM and SRAM starts at adress 0x20000000 with size 0x00005000.

I have put protection around pointeras and arrays which could access the data array.Since Hardfault exception occurs I suspects that there is something wrong in the memory mapping.

Heap and stack are located on:

.heap 0x20004a04 0x0

0x20004a04 __end__ = .

0x20004a04 _end = __end__

0x20004a04 end = __end__

*(.heap*)

0x20004a04 __HeapLimit = .

.co_stack 0x20004a04 0x404 load address 0x0801377c

0x20004a08 . = ALIGN (0x8)

*fill* 0x20004a04 0x4 

*(.co_stack .co_stack.*)

.co_stack 0x20004a08 0x400 ..\obj\startup_stm32f10x_md.o

0x20004a08 pulStack

0x20005000 __StackTop = (ORIGIN (ram) + 0x5000)

0x20004bfc __StackLimit = (__StackTop - SIZEOF (.co_stack))

0x20005000 PROVIDE (__stack, __StackTop)

0x00000001 ASSERT ((__StackLimit >= __HeapLimit), region ram overflowed with stack)

I am using GCC 4.8.2 and CooCox 1.7.6

#stm32
16 REPLIES 16
chen
Associate II
Posted on August 08, 2014 at 17:34

''if i try to #include core_cmFunc.h

I get the following errors:''

Try including core_cm4.h or the one that is correct for your processor

(I think core_cm4.h is for STM32F4 parts)

It contains the #include for core_cmFunc.h plus the other includes it needs

rthorstensson
Associate II
Posted on August 08, 2014 at 18:40

Thank again.

I have modifirying the Default handler to

#include ''stackdebug.h''

void Default_Reset_Handler(void)

{

  /* Initialize data and bss */

  unsigned long *pulSrc, *pulDest;

  /* Copy the data segment initializers from flash to SRAM */

  pulSrc = &_sidata;

  for(pulDest = &_sdata; pulDest < &_edata; )

  {

    *(pulDest++) = *(pulSrc++);

  }

  

  /* Zero fill the bss segment.  This is done with inline assembly since this

     will clear the value of pulDest if it is not kept in a register. */

  __asm(''  ldr     r0, =_sbss\n''

        ''  ldr     r1, =_ebss\n''

        ''  mov     r2, #0\n''

        ''  .thumb_func\n''

        ''zero_loop:\n''

        ''    cmp     r0, r1\n''

        ''    it      lt\n''

        ''    strlt   r2, [r0], #4\n''

        ''    blt     zero_loop'');

  

  ClearStackArray();

  SaveStack();

  /* Setup the microcontroller system. */

  SystemInit();

  SaveStack();

  /* Call the application's entry point.*/

  main();

}

And when I print the stack array I get

sp[0] = 20003F50

sp[1] = 20003F50

sp[2] = 20003EC8

sp[3] = 20003EC8

Thus the flash seems correct and the stack is wrong before even System_Init which brings mw to the question:

could the copy from flash to ram mess up my stackpointer?

pulSrc = &_sidata;

  for(pulDest = &_sdata; pulDest < &_edata; )

  {

    *(pulDest++) = *(pulSrc++);

  }

  

  /* Zero fill the bss segment.  This is done with inline assembly since this

     will clear the value of pulDest if it is not kept in a register. */

  __asm(''  ldr     r0, =_sbss\n''

        ''  ldr     r1, =_ebss\n''

        ''  mov     r2, #0\n''

        ''  .thumb_func\n''

        ''zero_loop:\n''

        ''    cmp     r0, r1\n''

        ''    it      lt\n''

        ''    strlt   r2, [r0], #4\n''

        ''    blt     zero_loop'');

rthorstensson
Associate II
Posted on August 08, 2014 at 18:46

I tried without bootloader and it gives the same result...

rthorstensson
Associate II
Posted on August 08, 2014 at 18:55

My mistake.

If I run without bootloader the stack pointer is correct

Posted on August 08, 2014 at 20:32

Using an RTOS in the loader?

As I recall the alignment is actually 512 bytes, you could probably confirm by writing 0xFFFFFFFF to SCB->VTOR

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rthorstensson
Associate II
Posted on August 09, 2014 at 14:19

There is no RTOS in bootloader, it and all hardware functions are written by me.

Regarding the alignment it is aligned to 512 byte:

0x3400/512 = 26

I will test what value bootloader sets SP to and then what SP is when it is accessed in application. Feels like I am getting close...

rthorstensson
Associate II
Posted on August 11, 2014 at 12:23

I finally found it.

Changed 

__set_MSP(*(uint32_t*) FLASH_START);

to

__set_MSP(*(uint32_t*) (FLASH_START));

Which will result in:

#define BL_FLASH_START  0x08000000

#define BL_FLASH_SIZE    0x3400 // 13 kB

#define FLASH_START (BL_FLASH_START + BL_FLASH_SIZE)

__set_MSP(*(uint32_t*) 0x08000000 + 0x3400);

__set_MSP(*(uint32_t*) (0x08000000 + 0x3400));

Thus the MSP is set to valu at 0x08000000 and then add 0x3400, instead of reading data at address 0x08003400