EmbDev.net

Forum: ARM programming with GCC/GNU tools help! memcpy causes hardfault on STM32F4


von magnetron (Guest)


Attached files:

Rate this post
useful
not useful
hello dear forum ,
I am trying to run a TCP/IP demo on a Olimex STM32F4 board
with eclipse + yagarto
however I cannot connect to the board with LAN
when I stop the demo with JTAG to look where it hangs
it shows below code

I tried to set up a breakpoint before the memcpy function
as shown in the attached picture
It stops at the breakpoint just before the memcpy function
however when I rerun from this point
it ends up at hardfault_handler as shown below
please advice how can I proceed ?
1
void
2
HardFault_Handler(void) 
3
{
4
/* Go to infinite loop when Hard Fault exception occurs */ 
5
while (1)
6
{
7
}

: Locked by Moderator
von holger (Guest)


Rate this post
useful
not useful
>it ends up at hardfault_handler

You end up in a hard fault if pPacket points out of memory.
Or if RXBuff points out of memory.
Or pPacket + size points out of memory.

von magnetron (Guest)


Rate this post
useful
not useful
hello forum ,

I tried to write a simple memcpy demo to see what is wrong with my 
original code
1
int main(void)
2
{
3
    char name[40];
4
    char myname[] = "James Clerk Maxwell";
5
    memcpy ( name, myname, 10 );
6
}
when I run this code the programm hangs
when I stop the uC with JTAG I see it is in infinite loop of
hardfault handler

memcpy somehow causes hardfault
I think above memcpy is ok - how much simpler can it be ?

it must be something wrong with the gcc

please how can I proceed ?

von huegene (Guest)


Rate this post
useful
not useful
linkerscript?

von magnetron (Guest)


Rate this post
useful
not useful
>thank you here is the linker script
====================0=====================
Default linker script for STM32F4xx_1024K_192K
*/

/* include the common STM32F4xx  sub-script */

/* Common part of the linker scripts for STM32F devices*/

/* default stack sizes.

These are used by the startup in order to allocate stacks for the 
different modes.
*/

__Stack_Size = 1024 ;

PROVIDE ( _Stack_Size = __Stack_Size ) ;

__Stack_Init = _estack  - __Stack_Size ;

/*"PROVIDE" allows to easily override these values from an object file 
or the commmand line.*/
PROVIDE ( _Stack_Init = __Stack_Init ) ;

/*
There will be a link error if there is not this amount of RAM free at 
the end.
*/
_Minimum_Stack_Size = 0x100 ;

/* include the memory spaces definitions sub-script */
/*
Linker subscript for STM32F4xx definitions with 1024 Flash and 192 
Onchip SRAM */

/* Memory Spaces Definitions */

MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
  CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
  FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
  FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)  : ORIGIN = 0x20002000, LENGTH = 32
}

/* higher address of the user mode stack (end of 128K RAM on AHB bus)*/
_estack = 0x20020000;



/* include the sections management sub-script for FLASH mode */

/* Sections Definitions */

SECTIONS
{
    /* for Cortex devices, the beginning of the startup code is stored 
in the .isr_vector section, which goes to FLASH */
    .isr_vector :
    {
 . = ALIGN(4);
        KEEP(*(.isr_vector))            /* Startup code */
 . = ALIGN(4);
    } >FLASH

    /* for some STRx devices, the beginning of the startup code is 
stored in the .flashtext section, which goes to FLASH */
    .flashtext :
    {
 . = ALIGN(4);
        *(.flashtext)            /* Startup code */
 . = ALIGN(4);
    } >FLASH


    /* the program code is stored in the .text section, which goes to 
Flash */
    .text :
    {
     . = ALIGN(4);

        *(.text)                   /* remaining code */
        *(.text.*)                 /* remaining code */
        *(.rodata)                 /* read-only data (constants) */
        *(.rodata*)
        *(.glue_7)
        *(.glue_7t)

     . = ALIGN(4);
     _etext = .;
     /* This is used by the startup in order to initialize the .data 
secion */
     _sidata = _etext;
    } >FLASH

    /* MEMORY_ARRAY */
    .ROarraySection :
    {
            *(.ROarraySection)
    } >MEMORY_ARRAY


    /* This is the initialized data section
    The program executes knowing that the data is in the RAM
    but the loader puts the initial values in the FLASH (inidata).
    It is one task of the startup to copy the initial values from FLASH 
to RAM. */
    .data  : AT ( _sidata )
    {
     . = ALIGN(4);
        /* This is used by the startup in order to initialize the .data 
secion */
        _sdata = . ;

        *(.data)
        *(.data.*)

     . = ALIGN(4);
     /* This is used by the startup in order to initialize the .data 
secion */
     _edata = . ;
    } >RAM



    /* This is the uninitialized data section */
    .bss :
    {
     . = ALIGN(4);
        /* This is used by the startup in order to initialize the .bss 
secion */
        _sbss = .;

        *(.bss)
        *(COMMON)

     . = ALIGN(4);
     /* This is used by the startup in order to initialize the .bss 
secion */
     _ebss = . ;
    } >RAM

    PROVIDE ( end = _ebss );
    PROVIDE ( _end = _ebss );

    /* This is the user stack section
    This is just to check that there is enough RAM left for the User 
mode stack
    It should generate an error if it's full.
     */
    ._usrstack :
    {
     . = ALIGN(4);
        _susrstack = . ;

        . = . + _Minimum_Stack_Size ;

     . = ALIGN(4);
        _eusrstack = . ;
    } >RAM



    /* this is the FLASH Bank1 */
    /* the C or assembly source must explicitly place the code or data 
there
    using the "section" attribute */
    .b1text :
    {
        *(.b1text)                   /* remaining code */
        *(.b1rodata)                 /* read-only data (constants) */
        *(.b1rodata*)
    } >FLASHB1

    /* this is the EXTMEM */
    /* the C or assembly source must explicitly place the code or data 
there
    using the "section" attribute */

    /* EXTMEM Bank0 */
    .eb0text :
    {
        *(.eb0text)                   /* remaining code */
        *(.eb0rodata)                 /* read-only data (constants) */
        *(.eb0rodata*)
    } >EXTMEMB0

    /* EXTMEM Bank1 */
    .eb1text :
    {
        *(.eb1text)                   /* remaining code */
        *(.eb1rodata)                 /* read-only data (constants) */
        *(.eb1rodata*)
    } >EXTMEMB1

    /* EXTMEM Bank2 */
    .eb2text :
    {
        *(.eb2text)                   /* remaining code */
        *(.eb2rodata)                 /* read-only data (constants) */
        *(.eb2rodata*)
    } >EXTMEMB2

    /* EXTMEM Bank0 */
    .eb3text :
    {
        *(.eb3text)                   /* remaining code */
        *(.eb3rodata)                 /* read-only data (constants) */
        *(.eb3rodata*)
    } >EXTMEMB3



    /* after that it's only debugging information. */

    /* remove the debugging information from the standard libraries */
    DISCARD :
    {
     /* libc.a ( * ) */
     /* libm.a ( * ) */
     libgcc.a ( * )
     }


    /* Stabs debugging sections.  */
    .stab          0 : { *(.stab) }
    .stabstr       0 : { *(.stabstr) }
    .stab.excl     0 : { *(.stab.excl) }
    .stab.exclstr  0 : { *(.stab.exclstr) }
    .stab.index    0 : { *(.stab.index) }
    .stab.indexstr 0 : { *(.stab.indexstr) }
    .comment       0 : { *(.comment) }
    /* DWARF debug sections.
       Symbols in the DWARF debugging sections are relative to the 
beginning
       of the section so we begin them at 0.  */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }

}
>*******************************************************************
>=============== and this is the stm32f407xG.icf file ==============
>*******************************************************************
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol _ICFEDIT_intvec_start_ = 0x08000000;
/*-Memory Regions-*/
define symbol _ICFEDIT_region_ROM_start_ = 0x08000000;
define symbol _ICFEDIT_region_ROM_end_   = 0x080FFFFF;
define symbol _ICFEDIT_region_RAM_start_ = 0x20000000;
define symbol _ICFEDIT_region_RAM_end_   = 0x2002FFFF;
/*-Sizes-*/
define symbol _ICFEDIT_size_cstack_ = 0x2000;
define symbol _ICFEDIT_size_heap_   = 0x2000;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region   = mem:[from _ICFEDIT_region_ROM_start_   to 
__ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from _ICFEDIT_region_RAM_start_   to 
__ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8, size = 
_ICFEDIT_size_cstack_   { };
define block HEAP      with alignment = 8, size = _ICFEDIT_size_heap_ 
{ };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec 
};

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

von chivas (Guest)


Rate this post
useful
not useful
>int main(void)
>{
>    char name[40];
>    char myname[] = "James Clerk Maxwell";
>    memcpy ( name, myname, 10 );
>}

The problem within this code is the string literal. A comment respective 
string literals can be found in the c standard 6.4.5, subitem 909:
"If the program attempts to modify such an array, the behavior is 
undefined."
(http://c0x.coding-guidelines.com/6.4.5.html)

A discussion and solutions concerning this problem is available under 
the following link:

http://stackoverflow.com/questions/7698441/c-malloc-and-memcpy-memory-management

von Helmut (Guest)


Rate this post
useful
not useful
Hello magnetron,
according to what I know about memcpy your call
1
memcpy ( name, myname, 10 );
tries to copy the 10 bytes starting from address myname to the 10 bytes 
starting from address name.

Therefore I cannot find anything wrong in your call to memcpy.
name is local on the stack and therefore in RAM.
myname is constant and could be in flash

The problem could be:
 - The call to memcpy.
   Is the code for memcpy really there where
   the processor needs it?
 - What memcpy does.
   Is your memcpy standard or do you have
   changed anything?
   Does your memcpy try to read/write from/to an odd address
   and your processor cannot to that?
 - The read from address myname.
   You can check that if you add an additional
   read before the call to memcpy.
 - The write to address name.
   You can check that if you add an
   additional write before the call to memcpy.

What happens if you try:
1
// volatile dummybyte to prevent the compiler from optimizing away the reads and writes below
2
char volatile dummy;
3
4
int main(void)
5
{
6
char name[40];
7
char myname[] = "James Clerk Maxwell";
8
9
// check if writing to name is possible
10
name[0] = dummy;
11
name[9] = dummy;
12
13
// check if reading from myname is possible
14
dummy = myname[0];
15
dummy = myname[9];
16
17
memcpy ( name, myname, 10 );

Best regards
Helmut

von magnetron (Guest)


Rate this post
useful
not useful
hello thank you all for the answers

can you please comment on my makefile ?
I suspect that compiler cannot build with correct library
1
#   Makefile for compiling the Getting Started project
2
3
#-------------------------------------------------------------------------------
4
#    User-modifiable options
5
#-------------------------------------------------------------------------------
6
7
# Trace level used for compilation
8
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
9
# TRACE_LEVEL_DEBUG      5
10
# TRACE_LEVEL_INFO       4
11
# TRACE_LEVEL_WARNING    3
12
# TRACE_LEVEL_ERROR      2
13
# TRACE_LEVEL_FATAL      1
14
# TRACE_LEVEL_NO_TRACE   0
15
TRACE_LEVEL = 4
16
17
# Optimization level
18
OPTIMIZATION = -O0
19
20
# Output file basename
21
OUTPUT = main
22
23
# Output directories
24
BIN = .
25
OBJ = obj
26
27
# library dirs
28
LIBRARYSRC = ./lib/src
29
30
STARTUPFILE = ./lib/startup_stm32f4xx.s
31
32
#-------------------------------------------------------------------------------
33
#    Tools
34
#-------------------------------------------------------------------------------
35
36
# Tool suffix when cross-compiling
37
CROSS_COMPILE = arm-none-eabi-
38
39
CC = $(CROSS_COMPILE)gcc
40
SIZE = $(CROSS_COMPILE)size
41
STRIP = $(CROSS_COMPILE)strip
42
OBJCOPY = $(CROSS_COMPILE)objcopy
43
OBJDUMP = $(CROSS_COMPILE)objdump
44
LD = $(CROSS_COMPILE)gcc
45
AS = $(CROSS_COMPILE)gcc
46
47
#-------------------------------------------------------------------------------
48
#    Files
49
#-------------------------------------------------------------------------------
50
51
# include folders
52
INCLUDES = -I./
53
INCLUDES += -I./lib/
54
INCLUDES += -I./lib/inc/
55
INCLUDES += -I./lib/inc/../../
56
57
# Objects built from C source files
58
C_OBJECTS = $(OBJ)/main.o
59
C_OBJECTS += $(OBJ)/system_stm32f4xx.o
60
C_OBJECTS += $(OBJ)/stm32f4xx_gpio.o
61
C_OBJECTS += $(OBJ)/stm32f4xx_rcc.o
62
C_OBJECTS += $(OBJ)/stm32f4xx_tim.o
63
C_OBJECTS += $(OBJ)/stm32f4xx_it.o
64
C_OBJECTS += $(OBJ)/stm32f4xx_syscfg.o
65
C_OBJECTS += $(OBJ)/stm32_eth.o
66
C_OBJECTS += $(OBJ)/ethernet.o
67
C_OBJECTS += $(OBJ)/clock-arch.o
68
C_OBJECTS += $(OBJ)/timer.o
69
C_OBJECTS += $(OBJ)/misc.o
70
C_OBJECTS += $(OBJ)/uip.o
71
C_OBJECTS += $(OBJ)/httpd.o
72
C_OBJECTS += $(OBJ)/uip_arp.o
73
C_OBJECTS += $(OBJ)/psock.o
74
C_OBJECTS += $(OBJ)/httpd-fs.o
75
C_OBJECTS += $(OBJ)/httpd-cgi.o
76
C_OBJECTS += $(OBJ)/http-strings.o
77
C_OBJECTS += $(OBJ)/syscall.o
78
79
# Objects built from Assembly source files
80
ASM_OBJECTS = $(OBJ)/startup_stm32f4xx.o
81
82
LINKER_SCRIPT = ./lib/stm32f4xx_flash.ld
83
84
# Append OBJ and BIN directories to output filename
85
OUTPUT := $(BIN)/$(OUTPUT)
86
87
#-------------------------------------------------------------------------------
88
#    Rules
89
#-------------------------------------------------------------------------------
90
91
# Flags
92
CFLAGS = -Wall -fno-common -c -g -mcpu=cortex-m3 -mthumb
93
CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -DTRACE_LEVEL=$(TRACE_LEVEL)
94
ASFLAGS = -g -mapcs-32
95
LDFLAGS = -g -v -nostartfiles -LC:/OlimexODS/yagarto/lib/gcc/arm-none-eabi/4.5.1
96
OBJCOPYFLAGS = -O binary
97
OBJDUMPFLAGS = -x --syms -S
98
99
all: $(BIN) $(OBJ) $(OUTPUT).out
100
101
$(BIN) $(OBJ):
102
  mkdir $@
103
104
$(OUTPUT).out: $(C_OBJECTS) $(ASM_OBJECTS) $(LINKER_SCRIPT)
105
  @ echo "..linking"
106
  $(LD) $(LDFLAGS) -T$(LINKER_SCRIPT) -o $(OUTPUT).out $(C_OBJECTS) $(ASM_OBJECTS) libgcc.a 
107
  $(OBJCOPY) $(OBJCOPYFLAGS) $(OUTPUT).out $(OUTPUT).bin
108
  @ echo "...completed."
109
  
110
$(C_OBJECTS): main.c system_stm32f4xx.c
111
  @ echo ".compiling"
112
  $(CC) $(CFLAGS) -o $(OBJ)/main.o main.c
113
  $(CC) $(CFLAGS) -o $(OBJ)/system_stm32f4xx.o system_stm32f4xx.c
114
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_it.o stm32f4xx_it.c
115
  $(CC) $(CFLAGS) -o $(OBJ)/stm32_eth.o stm32_eth.c
116
  $(CC) $(CFLAGS) -o $(OBJ)/ethernet.o ethernet.c
117
  $(CC) $(CFLAGS) -o $(OBJ)/clock-arch.o clock-arch.c
118
  $(CC) $(CFLAGS) -o $(OBJ)/timer.o timer.c
119
  $(CC) $(CFLAGS) -o $(OBJ)/uip.o uip.c
120
  $(CC) $(CFLAGS) -o $(OBJ)/httpd.o httpd.c
121
  $(CC) $(CFLAGS) -o $(OBJ)/uip_arp.o uip_arp.c
122
  $(CC) $(CFLAGS) -o $(OBJ)/psock.o psock.c
123
  $(CC) $(CFLAGS) -o $(OBJ)/httpd-fs.o httpd-fs.c
124
  $(CC) $(CFLAGS) -o $(OBJ)/httpd-cgi.o httpd-cgi.c
125
  $(CC) $(CFLAGS) -o $(OBJ)/http-strings.o http-strings.c
126
  $(CC) $(CFLAGS) -o $(OBJ)/syscall.o syscall.c
127
  @ echo ".compiling libraries"
128
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_tim.o $(LIBRARYSRC)/stm32f4xx_tim.c 
129
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_gpio.o $(LIBRARYSRC)/stm32f4xx_gpio.c 
130
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_rcc.o $(LIBRARYSRC)/stm32f4xx_rcc.c 
131
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_rcc.o $(LIBRARYSRC)/stm32f4xx_rcc.c 
132
  $(CC) $(CFLAGS) -o $(OBJ)/stm32f4xx_syscfg.o $(LIBRARYSRC)/stm32f4xx_syscfg.c
133
  $(CC) $(CFLAGS) -o $(OBJ)/misc.o $(LIBRARYSRC)/misc.c
134
  
135
$(ASM_OBJECTS): $(STARTUPFILE)
136
  @ echo ".assembling"
137
  $(AS) $(ASFLAGS) -o $(OBJ)/startup_stm32f4xx.o $(STARTUPFILE)
138
139
clean:
140
  -rm -f $(OBJ)/*.o $(BIN)/*.out $(BIN)/*.bin $(BIN)/*.dmp $(BIN)/*.map $(BIN)/*.lss

von Manuel (Guest)


Rate this post
useful
not useful
Did you solve the problem ? By looking your makefile I think you are 
missing some linker directives such as:
-mcpu=cortex-m3 -mthumb -mthumb-interwork

von Spencer O. (ntfreak)


Rate this post
useful
not useful
Just a couple of comments.

#Manuel - thumb-interwork is not required.

#magnetron - [RANT] please can everybody stop using ld to link, you 
are heading for a world of pain. If not now in the future but it will 
happen.[/RANT]

Use gcc as the link driver and it will sort the correct libs/paths for 
you - it is so easy.

Cheers
Spen

von Felix (Guest)


Rate this post
useful
not useful
Well i had the same problem with some functions from string.h and an 
stm32f4 and coide.

Turned out i just had to properly include the C standard library. Try 
adding libc.a to your linker (with the right fpu version). Then set 
Library dropdown to "Dont use C Library"

von magnetron (Guest)


Rate this post
useful
not useful
I changed below line
----------------------------------------------------------
from
LDFLAGS = -g -v -nostartfiles

to
LDFLAGS = -mcpu=cortex-m3 -mthumb -g -v -nostartfiles
----------------------------------------------------------
the answer came from ST's microcontroller forum
and it took me 2 weeks

shouldnot it come from this forum ?

von Karsten F. (Company: von Dänemark) (bingo600)


Rate this post
useful
not useful
magnetron wrote:
> I changed below line
> ----------------------------------------------------------
> from
> LDFLAGS = -g -v -nostartfiles
>
> to
> LDFLAGS = -mcpu=cortex-m3 -mthumb -g -v -nostartfiles
> ----------------------------------------------------------
> the answer came from ST's microcontroller forum
> and it took me 2 weeks
>
> shouldnot it come from this forum ?

As i read it it already did

Spence wrote :

> #magnetron - [RANT] please can everybody stop using ld to link, you
> are heading for a world of pain. If not now in the future but it will
> happen.[/RANT]

He tells you to stop using ld to link , and use gcc instead.

I totally agree , as gcc will use all the relevant options when linking.

/Bingo

This topic is locked and can not be replied to.