Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Computer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[LPC2478] [Eclipse OpenOcd CSLite] debug

mkawalki 20 Sty 2011 12:17 1915 6
  • #1 20 Sty 2011 12:17
    mkawalki
    Poziom 9  

    Witam,

    Mam problem z debugowanie procesora LPC2478.

    Środowisko: postawione zgodnie z tutorialem ze strony Freddiego Chopinna czyli
    Eclipse (helios edition with HDT hardware debugging) + OpenOcd + Code Sourcery Lite edition

    Procesor: ARM NXP LPC2478 z kwarcem 12MHz

    Aplikacja: Na tym etapie mrugająca diodka na timeocie opartym o przerwanie timer0, PLL ustawiony na 72 MHz po starcie aplikacji, port szeregowy bez przerwań, printf z new libc (czyli nic zaawansowanego)

    Problem:
    aplikacja kompiluje się bez problemów i wrzucona przez NXP FalshUtility działa zgodnie z oczekiwaniami
    niestety próby wgrania jej poprzez Jtag (Jtag-lockpick by Freddie Chopin) kończy się stanem ABORT procesora (sprawdzone poprzez telnet z poleceniem halt)
    podczas debugowania aplikacja przechodzi cstartup.s ale przy pierwszym poleceniu z main (próbie załadowania wartości do rejestru FIO01DIR = 0;) przechodzi natychmiast do default_handler poprzez abort_handler. Nie jestem pewien gdzie znajduje się problem więc załączam pliki linkera, cstartup,vectors oraz kod do GDB-OpenOcd

    Kod ładowania obrazu przez jtag:

    Code:

    target remote localhost:3333
    monitor arm7_9 fast_memory_access enable
    monitor arm7_9 dcc_downloads enable
    monitor reset halt
    monitor flash erase_sector 0 0 26
    monitor flash write_image erase out/Plasma_640x480.elf
    monitor reset

    cstartup.s code:
    Code:

    .text
    .balign 2
    .syntax unified
    .arm
    .func   Reset_Handler
    .global Reset_Handler

    Reset_Handler:

    /*
    +-----------------------------------------------------------------------------+
    | Stack setup
    +-----------------------------------------------------------------------------+
    */

       // after reset the core is in Supervisor mode with IRQ & FIQ disabled
       ldr   sp, =__supervisor_stack_end;            // set the stack for Supervisor mode
       msr   CPSR_c, #FIQ_MODE | CPSR_I | CPSR_F      // switch to FIQ mode, IRQ & FIQ disabled
       ldr   sp, =__fiq_stack_end;                  // set the stack for FIQ mode
       msr   CPSR_c, #IRQ_MODE | CPSR_I | CPSR_F       // switch to IRQ mode, IRQ & FIQ disabled
       ldr   sp, =__irq_stack_end;                  // set the stack for IRQ mode
       msr   CPSR_c, #ABORT_MODE | CPSR_I | CPSR_F      // switch to Abort mode, IRQ & FIQ disabled
       ldr   sp, =__abort_stack_end;               // set the stack for Abort mode
       msr   CPSR_c, #UNDEFINED_MODE | CPSR_I | CPSR_F   // switch to Undefined mode, IRQ & FIQ disabled
       ldr   sp, =__undefined_stack_end;            // set the stack for Undefined mode
       msr   CPSR_c, #SYSTEM_MODE                   // switch to System mode, IRQ & FIQ enabled
       ldr   sp, =__system_stack_end;            // set the stack for User and System mode

    /*
    +-----------------------------------------------------------------------------+
    | Branch to low_level_init_0() function (.data and .bss are not initialized!)
    +-----------------------------------------------------------------------------+
    */

       ldr      r0, =low_level_init_0
       mov      lr, pc
       bx      r0

    /*
    +-----------------------------------------------------------------------------+
    | Initialize .data section
    +-----------------------------------------------------------------------------+
    */

       ldr     r1, =__data_init_start
       ldr     r2, =__data_start
       ldr     r3, =__data_end
    1:   cmp     r2, r3
       ldrlo   r0, [r1], #4
       strlo   r0, [r2], #4
       blo     1b

    /*
    +-----------------------------------------------------------------------------+
    | Zero-init .bss section
    +-----------------------------------------------------------------------------+
    */

       mov     r0, #0
       ldr     r1, =__bss_start
       ldr     r2, =__bss_end
    1:   cmp     r1, r2
       strlo   r0, [r1], #4
       blo     1b

    /*
    +-----------------------------------------------------------------------------+
    | Call C++ constructors for global and static objects
    +-----------------------------------------------------------------------------+
    */
    #ifdef __USES_CXX
       ldr      r0, =__libc_init_array
       mov      lr, pc
       bx      r0
    #endif

    /*
    +-----------------------------------------------------------------------------+
    | Branch to low_level_init_1() function
    +-----------------------------------------------------------------------------+
    */

       ldr      r0, =low_level_init_1
       mov      lr, pc
       bx      r0

    /*
    +-----------------------------------------------------------------------------+
    | Branch to main() with link
    +-----------------------------------------------------------------------------+
    */

       ldr      r0, =main
       mov      lr, pc
       bx      r0

    /*
    +-----------------------------------------------------------------------------+
    | Call C++ destructors for global and static objects
    +-----------------------------------------------------------------------------+
    */
    #ifdef __USES_CXX
       ldr      r0, =__libc_fini_array
       mov      lr, pc
       bx      r0
    #endif

    /*
    +-----------------------------------------------------------------------------+
    | On return - loop till the end of the world
    +-----------------------------------------------------------------------------+
    */

       b      .

    .endfunc

    /*
    +=============================================================================+
    | __default_low_level_init() - replacement for undefined low_level_init_0()
    | and/or low_level_init_1(). This function just returns.
    +=============================================================================+
    */

    .text
    .balign 2
    .syntax unified
    .arm
    .func   __default_low_level_init
    .global __default_low_level_init

    __default_low_level_init:
       bx      lr

    .endfunc

    /*
    +=============================================================================+
    | assign undefined low_level_init_0() and/or low_level_init_1() to
    | __default_low_level_init()
    +=============================================================================+
    */

    .weak   low_level_init_0
    .global   low_level_init_0
    .set   low_level_init_0, __default_low_level_init

    .weak   low_level_init_1
    .global   low_level_init_1
    .set   low_level_init_1, __default_low_level_init


    vectors.c code:
    Code:

    .text
    .balign 2
    .syntax unified
    .arm
    .func __Default_Handler
    .global __Default_Handler

    __Default_Handler:
       b .

    .endfunc

    /*
    +=============================================================================+
    | assign all unhandled interrupts to the default handler
    +=============================================================================+
    */

    // Undefined instruction
    .weak   Undefined_Handler
    .global   Undefined_Handler
    .set   Undefined_Handler, __Default_Handler

    // Software interrupt (SWI)
    .weak   SWI_Handler
    .global   SWI_Handler
    .set   SWI_Handler, __Default_Handler

    // Prefetch Abort (instruction fetch memory abort)
    .weak   Prefetch_Abort_Handler
    .global   Prefetch_Abort_Handler
    .set   Prefetch_Abort_Handler, __Default_Handler

    // Data Abort (data access memory abort)
    .weak   Data_Abort_Handler
    .global   Data_Abort_Handler
    .set   Data_Abort_Handler, __Default_Handler

    // FIQ (fast interrupt)
    .weak   FIQ_Handler
    .global   FIQ_Handler
    .set   FIQ_Handler, __Default_Handler

    /*
    +=============================================================================+
    | Vector table
    +=============================================================================+
    */

    // VIC IRQ vector for older LPCs (where &VICVectAddr = 0xFFFFF030, e.g. LPC2103):
    //      ldr      pc, [pc, #-0xFF0]
    // VIC IRQ vector for newer LPCs (where &VICAddress = 0xFFFFFF00, e.g. LPC2478):
    //      ldr      pc, [pc, #-0x120]

    .section .vectors
    .balign 2
    .syntax unified
    .arm
    __vectors:

       ldr      pc, =Reset_Handler            // Reset exception
       ldr      pc, =Undefined_Handler         // Undefined Instruction exception
       ldr      pc, =SWI_Handler            // Software Interrupt exception
       ldr      pc, =Prefetch_Abort_Handler      // Prefetch Abort exception
       ldr      pc, =Data_Abort_Handler         // Data Abort exception
       nop                              // reserved for code signature
       ldr      pc, [pc, #-0x120]            // Interrupt exception -> VIC
       ldr      pc, =FIQ_Handler            // Fast Interrupt exception


    linker code:
    Code:

    .text
    .balign 2
    .syntax unified
    .arm
    .func __Default_Handler
    .global __Default_Handler

    __Default_Handler:
       b .

    .endfunc

    /*
    +=============================================================================+
    | assign all unhandled interrupts to the default handler
    +=============================================================================+
    */

    // Undefined instruction
    .weak   Undefined_Handler
    .global   Undefined_Handler
    .set   Undefined_Handler, __Default_Handler

    // Software interrupt (SWI)
    .weak   SWI_Handler
    .global   SWI_Handler
    .set   SWI_Handler, __Default_Handler

    // Prefetch Abort (instruction fetch memory abort)
    .weak   Prefetch_Abort_Handler
    .global   Prefetch_Abort_Handler
    .set   Prefetch_Abort_Handler, __Default_Handler

    // Data Abort (data access memory abort)
    .weak   Data_Abort_Handler
    .global   Data_Abort_Handler
    .set   Data_Abort_Handler, __Default_Handler

    // FIQ (fast interrupt)
    .weak   FIQ_Handler
    .global   FIQ_Handler
    .set   FIQ_Handler, __Default_Handler

    /*
    +=============================================================================+
    | Vector table
    +=============================================================================+
    */

    // VIC IRQ vector for older LPCs (where &VICVectAddr = 0xFFFFF030, e.g. LPC2103):
    //      ldr      pc, [pc, #-0xFF0]
    // VIC IRQ vector for newer LPCs (where &VICAddress = 0xFFFFFF00, e.g. LPC2478):
    //      ldr      pc, [pc, #-0x120]

    .section .vectors
    .balign 2
    .syntax unified
    .arm
    __vectors:

       ldr      pc, =Reset_Handler            // Reset exception
       ldr      pc, =Undefined_Handler         // Undefined Instruction exception
       ldr      pc, =SWI_Handler            // Software Interrupt exception
       ldr      pc, =Prefetch_Abort_Handler      // Prefetch Abort exception
       ldr      pc, =Data_Abort_Handler         // Data Abort exception
       nop                              // reserved for code signature
       ldr      pc, [pc, #-0x120]            // Interrupt exception -> VIC
       ldr      pc, =FIQ_Handler            // Fast Interrupt exception



    Nie wiem czy może mieć ustawienie samego pliku lpc2478.cfg ale jeśli ktoś ma pomysł co robię nie tak będę wdzięczny za pomoc
    pozdrawiam
    s^int

    0 6
  • Computer Controls
  • Pomocny post
    #2 20 Sty 2011 12:42
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie wrzuciłeś skryptu linkera, tylko jeszcze raz wektory...

    Anyway - jest tam kilka potencjalnych problemów

    1 (mało istotny)
    W skrypcie linkera dodałeś nową sekcję:

    Code:
        .ext_mem (NOLOAD) : { *(.ext_mem .ext_mem.*) } > sdram0

    jednak według nowej składni powinno być tak:
    Code:
        .ext_mem (NOLOAD) : { *(.ext_mem .ext_mem.*) } > sdram0 AT > sdram0


    2 (może być problematyczny)
    Twój sposób ładowania kodu do układu jest conajmniej dziwny i wcale nie odpowiada temu co zalecam w artykule... Nie wiem nawet, czy aby na pewno używasz właściwej wtyczki, bo GDB Hardware Debugging nie wymaga podania "target remote localhost:3333"...

    Upewnij się, że ściągnąłeś wtyczkę dla właściwej wersji Eclipse - w tutorialu podany jest link do wtyczki dla starej wersji Eclipse'a - .../ganymede/... - dla nowych jest to .../helios/... . Gdzieś w temacie o tutorialu jest to chyba napisane.

    Następnie zastosuj się do porad z tego posta https://www.elektroda.pl/rtvforum/viewtopic.php?p=8653959#8653959 - w nowej wersji wtyczek są pewne zmiany

    Nastepnie ogranicz komendy ładujące do "monitor reset halt" - nic więcej nie jest potrzebne. Jak już będzie działać, to dorzucisz właczenie dcc, jednak reszta komend jest zbędna.

    3 (duży problem)
    Do wywołania OpenOCD dodaj następujący kawałek:
    -c "reset_config trst_and_srst separate"
    Powinno pomóc. Podstawowym problemem jest to, że przez splot pewnych błędów plików konfiguracyjnych OpenOCD i Twojego sposobu ładowania kodu w momencie gdy startujesz ze swoim kodem, to PLL, MAM i wiele innych rzeczy już jest włączone. Próby przestawiania MAM czy PLLa w takiej sytuacji mogą spowodować dosyć zagadkowe skutki - np. takie jak widzisz.

    4\/3!!

    0
  • Computer Controls
  • #3 20 Sty 2011 13:27
    mkawalki
    Poziom 9  

    Witam,

    Dzięki, zadziałało. Będę testować dalej i zobaczymy jak to pójdzie. Trochę poplątałem ten fragment z programowanie przez GDB bo miałem tam tylko

    Code:

    monitor reset halt


    Jeszcze jedną zmianę musiałem wprowadzić i zmienić częstotliwość jtag z 2000 na 500 w innym przypadku GDB/jtag wariował. Czy to normalny objaw?

    s^int

    0
  • Pomocny post
    #4 20 Sty 2011 15:50
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Tylko dlaczego miałeś prędkość JTAGa 2000, skoro w domyślnym pliku konfiguracyjnym dla LPC2478 jest ustawione właśnie 500? Prędkość JTAGa powinna być ~8x mniejsza niż prędkość rdzenia, a po resecie rdzeń w tym układzie chodzi na 4MHz.

    4\/3!!

    0
  • #5 20 Sty 2011 23:16
    mkawalki
    Poziom 9  

    Hmm pewnie dlatego że sam ją ustawiłem. Trochę kombinowałem i widocznie z SVN złego up'a sobie wziąłem. Ale dzięki za info dlaczego tak jest.

    Podsumowując: XP plus wspomniana konfiguracja działa jak powinna, ale win7-64bit to już inna bajka. Podstawowe objawy to:
    - w oknie debug_configuration->Main Eclipse nie potrafi sam znaleźć C/C++ aplication (plik trzeba mu wskazać ręcznie). To jest powiązane z samym uruchomieniem Eclipse ponieważ muszę wejśc do debug_configuration za każdym razem po restarcie Eclipse aby mu wskazać plik (ścieżkę widać ale twierdzi że nie ma binarki)
    - sam debug ładuje sie ok (brak jakiś dziwnych wpisów na konsolach) ale po wykonaniu opcji resume nie można zrobić pause (ani step ect).
    - przy próbie terminacji konsoli twierdzi że nie potrafi (Targer request failed: failed to interrupt)

    Jako że pozwala wrzucić kod to jest nieźle ale może ktoś się spotkał z podobnymi objawami. Dodam że Eclipse pobrałem i skonfigurowałem dwa razy więc albo Eclipse ma problem albo drivery leżą albo win7 jest oporny. Ciężko cokolwiek powiedzieć.

    0
  • #6 20 Sty 2011 23:29
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Kwestię sterowników możesz moim zdaniem wykluczyć - one albo działają albo nie. Poza tym gdy pojawi się problem w Eclipse, połącz się telnetem z OpenOCD - sprawdzisz, czy można używać typowych komend (halt, resume, step, reg, mdw, ...).

    Masz ściągnięte najnowsze JRE? Ja myślę, że problem jest gdzieś w okolicach Eclipse'a lub jego wtyczek... Niemniej jednak nigdy nie słyszałem o takich objawach, więc pewnie da się to jakoś rozwiązać.

    Swoją drogą - uprawnienia administratora masz? Wszelkie głupie firewalle, antywirusy itp. wyłączone? Może przez nie jest jakiś problem?

    4\/3!!

    0
  • #7 08 Gru 2011 00:57
    mkawalki
    Poziom 9  

    Temat kontynuowany w innym wątku.

    0