Hardfault, after adding USB stack

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hardfault, after adding USB stack

628 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jeshwanth on Thu Jan 22 22:47:13 MST 2015
Hello List,

I am working on LPC1768 board. I have integrated USB stack to our software stack, after integrating it started failing (hardfault) initial stages like initialization itself.

There are many cases where I am getting hardfaults, I would like to explain one case here.

There is a Global variable called XYZ (It's a struct). As this variable comes in .data section, while copying the .data from flash it's copying wrong value. one of the value must be zero-0 but it's copying some junk value 9502977. So my program getting failed.

Ok, now lets consider I am moving the XYZ to flash by making it const. Then the program fails in next variable which is getting used after some 30 instruction from the previous fail point.

This behaviour  I found after adding my USB stack into it, before that it works normally.

This is my size command output.
   text   data    bss    dec    hexfilename
  71936   1800  26204  99940  18664Output/App/project.axf

And I am using FreeRTOS as the RTOS and this is failing before creating FreeRTOS tasks I mean initialization itself.

As many people told, there might be problem with Linker script. So I am posting the Ld script here.
/*
 * GENERATED FILE - DO NOT EDIT
 * (C) Code Red Technologies Ltd, 2008-2014
 * Generated linker script file for LPC1768
 * Created from generic_c.ld (vLPCXpresso v5.2 (4 [Build 2122] [2013-04-29] ))
 * By LPCXpresso v5.2.4 [Build 2122] [2013-04-29]  on Thu Jun 19 10:46:14 IST 2014
 */


 GROUP(
 libcr_nohost.a
 libcr_c.a
 libcr_eabihelpers.a
 )

MEMORY
{
  /* Define each memory region */
  MFlash512 (rx) : ORIGIN = 0x0000, LENGTH = 0x80000 
  RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
  RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */

}
  /* Define a symbol for the top of each memory region */
  __top_RamLoc32 = 0x10000000 + 0x8000;
  __top_RamAHB32 = 0x2007c000 + 0x8000;


ENTRY(ResetISR)

SECTIONS
{

    .text_Flash2 : ALIGN(4)
    {
       FILL(0xff)
    *(.text_Flash2*)
    *(.text_MFlash512_246*)
    } > MFlash512_246
    
    /* MAIN TEXT SECTION */    
    .text : ALIGN(4)
    {
        FILL(0xff)
        __vectors_start__ = ABSOLUTE(.) ;
        KEEP(*(.isr_vector))
        
        /* Global Section Table */
        . = ALIGN(4) ;
        __section_table_start = .;
        __data_section_table = .;
        LONG(LOADADDR(.data));
        LONG(    ADDR(.data)) ;
        LONG(  SIZEOF(.data));
        LONG(LOADADDR(.data_RAM2));
        LONG(    ADDR(.data_RAM2)) ;
        LONG(  SIZEOF(.data_RAM2));
        __data_section_table_end = .;
        __bss_section_table = .;
        LONG(    ADDR(.bss));
        LONG(  SIZEOF(.bss));
        LONG(    ADDR(.bss_RAM2));
        LONG(  SIZEOF(.bss_RAM2));
        __bss_section_table_end = .;
        __section_table_end = . ;
        /* End of Global Section Table */
        

        *(.after_vectors*)
        
    } >MFlash512
    
    .text : ALIGN(4)    
    {
         *(.text*)
        *(.rodata .rodata.*)
        . = ALIGN(4);
        
    } > MFlash512

    /*
     * for exception handling/unwind - some Newlib functions (in common
     * with C++ and STDC++) use this. 
     */
    .ARM.extab : ALIGN(4)
    {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > MFlash512
    __exidx_start = .;
    
    .ARM.exidx : ALIGN(4)
    {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > MFlash512
    __exidx_end = .;
    
    _etext = .;
        
    
    /* DATA section for RamAHB32 */
    .data_RAM2 : ALIGN(4)
    {
       FILL(0xff)
    *(.data.$RAM2*)
    *(.data.$RamAHB32*)
       . = ALIGN(4) ;
    } > RamAHB32 AT>MFlash512
    
    /* MAIN DATA SECTION */
    

    .uninit_RESERVED : ALIGN(4)
    {
        KEEP(*(.bss.$RESERVED*))
        . = ALIGN(4) ;
        _end_uninit_RESERVED = .;
    } > RamLoc32


/* Main DATA section (RamLoc32) */
.data : ALIGN(4)
{
   FILL(0xff)
   _data = . ;
   *(vtable)
   *(.data*)
   . = ALIGN(4) ;
   _edata = . ;
} > RamLoc32 AT>MFlash512

    /* BSS section for RamAHB32 */
    .bss_RAM2 : ALIGN(4)
    {
    *(.bss.$RAM2*)
    *(.bss.$RamAHB32*)
       . = ALIGN(4) ;
    } > RamAHB32

    /* MAIN BSS SECTION */
    .bss : ALIGN(4)
    {
        _bss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4) ;
        _ebss = .;
        PROVIDE(end = .);
    } > RamLoc32
        
    /* NOINIT section for RamAHB32 */
    .noinit_RAM2 (NOLOAD) : ALIGN(4)
    {
    *(.noinit.$RAM2*)
    *(.noinit.$RamAHB32*)
       . = ALIGN(4) ;
    } > RamAHB32 
    
    /* DEFAULT NOINIT SECTION */
    .noinit (NOLOAD): ALIGN(4)
    {
        _noinit = .;
        *(.noinit*) 
         . = ALIGN(4) ;
        _end_noinit = .;
    } > RamLoc32
    
    PROVIDE(_pvHeapStart = .);
    PROVIDE(_vStackTop = __top_RamLoc32 - 0);
}


But I found everything fine in ld script.

Can anybody help me in fixing this ?

Thanks in Advance
Labels (1)
0 Kudos
6 Replies

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jeshwanth on Mon Feb 02 22:54:08 MST 2015
Hi,

I found the solution. The problem was in LD script. Orderly arranging the memory section in LD script fix the issue.

Thanks
0 Kudos

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jeshwanth on Mon Jan 26 23:51:19 MST 2015
Hello,

Not Working code (After adding USB stack):

[color=#f30]xxx1 long unsigned int9502977
xxx2 long unsigned int2
[/color]xxx3 long unsigned int0
xxx4 long unsigned int100
xxx5 long unsigned int0
xxx6 long unsigned int0
xxx7 long unsigned int268442460
xxx8 long unsigned int2
xxx9 long unsigned int11


Working code (Before USB stack):

xxx1 long unsigned int0
xxx2 long unsigned int100
xxx2 long unsigned int0
xxx4 long unsigned int0
xxx5 long unsigned int268442380
xxx6 long unsigned int2
xxx7 long unsigned int11
xxx8 long unsigned int0
xxx9 long unsigned int0


Value got from the symbol XYZ from ELF file:
00 00 00 00
64 00 00 00
00 00 00 00
00 00 00 00
5C 43 00 10
02 00 00 00
0B 00 00 00
00 00 00 00
00 00 00 00
01 00 00 00
0C 00 00 00
00 00 00 00

From above information:

I have got the data available in the struct with working code and not working code (mentioned above). If you see, in Not working code xx1 is starting from xx3. So I can say 8 bytes shifting. So my program not getting the right value to compute and it goes to Hard fault.

So I assumed that, there is a problem with my ELF only. Like the data is same in the ELF only and used the tools like objdump etc and got the value present in my ELF (Mentioned above). But my surprise the value is correct in ELF file also.

Now I can guess the problem would be in Linker, But don't know where to look for this. Can you please suggest something ?

Here is my .data symbols.

10000000 l    d  .data00000000 .data
2007c000 l    d  .data_RAM200000000 .data_RAM2
10000424 l     O .data00000048 xx1
10000478 l     O .data00000001 A
1000047c l     O .data00000004 B
10000480 l     O .data00000004 C
10000484 l     O .data00000004 D
100004dc l     O .data00000004 E
100004e0 l     O .data00000010 F
100004f0 l     O .data0000001c G
1000050c l     O .data0000013b H
1000064c l     O .data0000001c I
10000668 l     O .data000000dc J
10000744 l     O .data00000004 K
10000748 l     O .data00000004 L
100000c0 g     O .data0000035c M
10000647 g     O .data00000003 N
100004c8 g     O .data00000010 O
10000498 g     O .data00000018 P
1000041e g     O .data00000002 Q
1000046c g     O .data0000000c R
10000488 g     O .data00000004 S
100004b0 g     O .data00000018 T
10000420 g     O .data00000001 U
100004d8 g     O .data00000004 V
10000494 g     O .data00000002 W
1000041d g     O .data00000001 X
1000041c g     O .data00000001 Y
2007c000 g     O .data_RAM200000008 Z
10000000 g       .data00000000 _data
1000074c g       .data00000000 _edata
10000000 g     O .data000000c0 AA
1000048c g     O .data00000008 AB


In above .data symbols, xx1 value at 10000424 is shifted to 10000432.

Note: I have changed the symbol name here xxx1, xxx2, and A, B, C and all.

Thanks in Advance.
0 Kudos

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jeshwanth on Fri Jan 23 06:33:08 MST 2015
Hi,

I am using Red Suite 5.2.6 version, and that Linker we have created when we started with LPC Xpresso. We have created the Linker script for memory mapping of Bootloader and Application, because we use same linker file for App and Bootloader.

My Startup Code.

    ResetISR(void) {
    unsigned long *pulSrc, *pulDest;

    //
    // Copy the data segment initializers from flash to SRAM.
    //
    pulsrc=&_etext;
    for(pulDest = &_data; 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, =_bss\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");

#ifdef __USE_CMSIS
SystemInit();
#endif

#if defined (__cplusplus)
//
// Call C++ library initialisation
//
__libc_init_array();
#endif

#if defined (__REDLIB__)
// Call the Redlib library, which in turn calls main()
__main() ;
#else
main();
#endif

//
// main() shouldn't return, but if it does, we'll just enter an infinite loop 
//
while (1) {
;
}
}



I have got some more information while debugging today. Please find in below post.
0 Kudos

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Fri Jan 23 04:42:00 MST 2015

Quote:
If you read more carefully, the script he posted is the auto generated one and the comment at the top
shows that it was created by LPCXpresso 5.2.4.


Why are you making that assumption? It could quite easily have been copy and pasted - why is why I asked the question. And give that it includes the GROUP command where the auto generated one uses an INCLUDE here, strongly implies that a) it has been edited and b) it is not generated by LPCXpresso...

0 Kudos

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by MikeSimmonds on Fri Jan 23 03:50:03 MST 2015

Quote: lpcxpresso-support
Which version of LPCXpresso are you using? Why are you using your own linker script instead of the one automatically generated by LPCXpresso? What does your startup code do?



If you read more carefully, the script he posted is the auto generated one and the comment at the top
shows that it was created by LPCXpresso 5.2.4.

Although the date does look odd.

Agree we need to see the startup (copy flash to ram etc.) code.

6/10 Could do better  ;-)

Mike
0 Kudos

514 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Thu Jan 22 23:53:51 MST 2015
Which version of LPCXpresso are you using? Why are you using your own linker script instead of the one automatically generated by LPCXpresso? What does your startup code do?
0 Kudos