Author Topic: Getting Started Issues  (Read 19711 times)

Offline cstrahm

  • Newbie
  • *
  • Posts: 9
    • View Profile
Getting Started Issues
« on: February 16, 2009, 12:22:41 PM »
I'm using an LPC2468 with GNUARM.  I got the PHY code mod'd for my PHY, and the PIN setup configured for my app PCB.  Took out the LCD define. Trying to get this started up now.

(1)  I would like to suggest that the Watchdog have a default OFF when supplied.  The first thing I had to do was track down all the places that activate the watchdog to disable it.  Does not appear to have a global define in config.h to do this.

(2) The trace starts off at 0x11C fnValidatedInit, then fnStartDefaultNetwork, then fnScan, then fnFlushSerialRx, tries to access 7FFFE2BB, then jumps to Pabt error.

0x7FFF.... is the IAP area I believe.  I have no idea why it is going there.

Any suggestions?

Chris.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: Getting Started Issues
« Reply #1 on: February 16, 2009, 02:34:06 PM »
Hi Chris

I don't think that the LPC23XX project has been used with the LPC24xx before - I haven't used this so maybe there are some incompatibilities(?)

Watchdog: yes this is a bit tricky on the LPC. The debugger doesn't stop it and so it times out, causing strange things to happen.
When debugging from RAM there is a pre-processor define setting _DEBUG_CODE_, which completely removes the watchdog. When debugging from FLASH it is on - but can be disabled by either defining WATCHDOG_DISABLE() 1 or else by pulling the defined input to '0'.

Furthermore it is necessary to remember that the watchdog is not disabled by a reset. It is necessary to power down the board and start again to ensure that it is disable. I tend to keep it enable (rather than forget that it is not running in a project) and use a link on the board to pull the tested input to '0' when debugging.

I agree that this can cause some difficulties and it should be explained in detail in the tutorial (the same is true for other processor but their tutorials do explain it, whereas the LPC tutorial seems to be missing this point).

The trace is not making any sense so I don't think that the it is helping much at the moment.

Assuming the LPC24xx to boot up the same as the LPC23xx, it depends on the development tools quite a lot. See the following for details about the internal boot loader and its use of the vector table to verify application validity:
http://www.utasker.com/forum/index.php?topic=109.0 (pay special attention to the MEMMAP).

I usually load using Flash Magic. This adds the necessary check sum when it loads the project, which allows the LPC bootloader to recognize the valid application and start executing its code rather than its own. However I often use IAR 4.2 to debug and this doesn't work very well with the LPC23xx from FLASH. I have to write the MEMMAP to 0x01 manually each time it starts. Then it debugs well enough.

Check carefully that you see the same vector values at 0x00000000 as in your own code - then it is set correctly. You should then be able to single step the initialization, which calls _LowLevelInit() and configures PLL etc. (is this compatible with the LPC24XX??).

Regards

Mark






Offline cstrahm

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Getting Started Issues
« Reply #2 on: February 16, 2009, 08:10:56 PM »
Yeah something is wrong with the LD file and/or the Startup asm.  This is what the map looks like:

.vectors        0x00000000       0x30
                0x00000000                __vectors_start__ = .
 *(.vectors .vectors.*)
 .vectors       0x00000000       0x30 Build\startup_gnu.o
                0x00000000                _vectors
                0x00000030                __vectors_end__ = (__vectors_start__ + SIZEOF (.vectors))
                0x00000001                . = ASSERT (((__vectors_end__ >= __FLASH_segment_start__) && (__vectors_end__ <= (__FLASH_segment_start__ + 0x40000))), error: .vectors is too large to fit in FLASH memory segment)
                0x00000030                __init_load_start__ = (__vectors_end__ ALIGN 0x4)

.init           0x00000030       0xec
                0x00000030                __init_start__ = .
 *(.init .init.*)
 .init          0x00000030       0xec Build\startup_gnu.o
                0x00000094                __irq_dis
                0x000000f8                end
                0x00000030                Reset
                0x000000b0                __irq_en
                0x000000c0                irq_handler
                0x00000030                reset_code

The init section should be before the vector section, I think.  Your LD file seems strange.  I don't think GCC can figure it out.  reset_code should be at 0x0.  It kind of seems to me like both the 'init' and 'vector' sections both have to be at 0x0, or vector needs to be at 0x30.  It's coming out backwards.  I'm not sure why you have these broken apart.  The code can never be run in RAM since it won't fit.

I tried putting in an .org 0x0 in the startup.s in the init section, but the linker is still forcing it up into 0x30.  The problem seems to be in the LD file.  Something's not right here.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3243
    • View Profile
    • uTasker
Re: Getting Started Issues
« Reply #3 on: February 16, 2009, 08:40:29 PM »
Hi Chris

This looks correct to me and is very similar to my reference.

This is in fact the content of startup_gnu.s

Code: [Select]
/* The vector table is fixed in FLASH so that the processor can boot to the reset startup code */
    .section .vectors, "ax"
    .code 32
    .align 0
    .global _vectors
    .global reset_code
    .global end
    .extern _LowLevelInit
    .extern main

/* reset vector followed by exception vectors */
_vectors:
    ldr pc, [pc, #_reset_handler - . - 8]                                /* reset vector             */
    ldr pc, [pc, #_undef_handler - . - 8]                                /* undefined instruction    */
    ldr pc, [pc, #_swi_handler - . - 8]                                  /* swi handler              */
    ldr pc, [pc, #_pabort_handler - . - 8]                               /* abort prefetch           */
    ldr pc, [pc, #_dabort_handler - . - 8]                               /* abort data               */
#ifndef _DEBUG_CODE_
    .word 0xB8A06F88                                                     /* LPC boot loader checksum */
#else
    nop                                                                  /* reserved                 */
#endif
    ldr pc, [pc, #_irq_handler - . - 8]                                  /* irq                      */
    ldr pc, [pc, #_fiq_handler - . - 8]                                  /* fiq                      */


_reset_handler:
    .word reset_code
 
_irq_handler:
    .word irq_handler

_undef_handler:
_swi_handler:
_pabort_handler:
_dabort_handler:
_fiq_handler:
    .word default_code



/* defines
ARM_MODE_FIQ            EQU     0x11
ARM_MODE_IRQ            EQU     0x12
ARM_MODE_SVC            EQU     0x13

I_BIT                   EQU     0x80
F_BIT                   EQU     0x40                                     */



    .section .init, "ax"
    .code 32
    .align 0
/* Reset code - this is started as first code after a reset */
reset_code:
    mrs r0, cpsr                                                         /* Read the status register */
    bic r0, r0, #0x1f                                                    /* Mask out the mode bits */
    orr r1, r0, #0x1b                                                    /* prepare undefined mode */
    msr     cpsr_cxsf, r1                                                /* set mode */
...

It is correct that _vectors is at 0x00000000 since it contains the reset and interrupt vector code. The chip boots from 0x00000000 only when the check sum of the vectors is correct. As you see, this is manually set so that it can be downloaded even by tools that don't calculate and add it themselves.
The code at 0x00000000 is simply jumping to reset_code, which is at .init - 0x00000030. You can also see that reset_code is at the address 0x00000030.

The difference that I do see it
                0x00000030                Reset

I wonder where that is coming from, and why it is at the same address as the reset_code???
It may be 'overloading' the code. See whether you have a library linked with additional reset code that may be incompatible.
In my project there are only very few functions that get linked in from GCC libraries:

Archive member included because of file (symbol)

c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.2.3/thumb\libgcc.a(_udivsi3.o)
                              Build/debug.o (__aeabi_uidiv)
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.2.3/thumb\libgcc.a(_divsi3.o)
                              Build/webInterface.o (__aeabi_idiv)
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.2.3/thumb\libgcc.a(_dvmd_tls.o)
                              c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.2.3/thumb\libgcc.a(_udivsi3.o) (__aeabi_idiv0)



Regards

Mark