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

[C][AT91SAM7S256]FreeRTOS + skrypt linkera

Zaquadnik 30 Sty 2010 12:19 6281 31
  • #1 30 Sty 2010 12:19
    Zaquadnik
    Poziom 27  

    Może zacznę od komunikatu błędu kompilacji:

    Code:

    make all
    arm-none-eabi-gcc ./SRC/startup.o  ./SRC/low_level_init.o ./SRC/main.o ./SRC/RTOS/lib_AT91SAM7X256.o ./SRC/RTOS/port.o ./SRC/RTOS/portISR.o ./SRC/RTOS/croutine.o ./SRC/RTOS/heap_2.o ./SRC/RTOS/list.o ./SRC/RTOS/queue.o ./SRC/RTOS/tasks.o  -mcpu=arm7tdmi -nostartfiles -T./LNK/sam7s256_rom.ld -Wl,-Map=main_rom.map,--cref,--no-warn-mismatch    -o main_rom.elf
    d:/programy/mikrokontrolery/arm/codesourcery/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: section .stack [0010c760 -> 0010ca5f] overlaps section .bss [0010c760 -> 0010f177]
    d:/programy/mikrokontrolery/arm/codesourcery/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: main_rom.elf: warning: sh_link not set for section `.ARM.exidx'
    ./SRC/RTOS/tasks.o: In function `vTaskIncrementTick':
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1392: undefined reference to `vApplicationTickHook'
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1405: undefined reference to `vApplicationTickHook'
    d:/programy/mikrokontrolery/arm/codesourcery/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
    sbrkr.c:(.text+0x18): undefined reference to `_sbrk'
    collect2: ld returned 1 exit status
    make: *** [main_rom.elf] Error 1


    Sprawa ma się tak, że używam następującego skryptu linkera (z jakiegoś przykładu):
    Code:

    OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
    OUTPUT_ARCH(arm)
    ENTRY(_start)

    MEMORY {    /* memory map of AT91SAM7S256 */
        ROM (rx)  : ORIGIN = 0x00100000, LENGTH = 256k
        RAM (rwx) : ORIGIN = 0x00200000, LENGTH = 64k
    }

    /* The sizes of the stacks used by the application. NOTE: you need to adjust */
    C_STACK_SIZE   = 512;
    IRQ_STACK_SIZE = 128;
    FIQ_STACK_SIZE = 128;
    SVC_STACK_SIZE = 0;
    ABT_STACK_SIZE = 0;
    UND_STACK_SIZE = 0;


    SECTIONS {

        .reset : {
            *startup.o (.text)  /* startup code (ARM vectors and reset handler) */
            . = ALIGN(0x4);
         } >ROM

        .ramvect : {                        /* used for vectors remapped to RAM */
            __ram_start = .;




            . = 0x40;
        } >RAM

        .fastcode : {
            __fastcode_load = LOADADDR (.fastcode);
            __fastcode_start = .;

            *(.glue_7t) *(.glue_7)
            *isr.o (.text.*)
            *(.text.fastcode)
            *(.text.Blinky_dispatch)
            /* add other modules here ... */

            . = ALIGN (4);
            __fastcode_end = .;
        } >RAM AT>ROM

        .text : {
            CREATE_OBJECT_SYMBOLS
            *(.text .text.* .gnu.linkonce.t.*)
            *(.plt)
            *(.gnu.warning)
            *(.glue_7t) *(.glue_7)         /* NOTE: placed already in .fastcode */

            . = ALIGN (4);
            /* These are for static constructors and destructors under ELF */
            KEEP (*crtbegin.o(.ctors))
            KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
            KEEP (*(SORT(.ctors.*)))
            KEEP (*crtend.o(.ctors))
            KEEP (*crtbegin.o(.dtors))
            KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
            KEEP (*(SORT(.dtors.*)))
            KEEP (*crtend.o(.dtors))

            *(.rodata .rodata.* .gnu.linkonce.r.*)

            *(.ARM.extab* .gnu.linkonce.armextab.*)
            *(.gcc_except_table)
            *(.eh_frame_hdr)
            *(.eh_frame)

            *(.init)
            *(.fini)

            PROVIDE_HIDDEN (__preinit_array_start = .);
            KEEP (*(.preinit_array))
            PROVIDE_HIDDEN (__preinit_array_end = .);
            PROVIDE_HIDDEN (__init_array_start = .);
            KEEP (*(SORT(.init_array.*)))
            KEEP (*(.init_array))
            PROVIDE_HIDDEN (__init_array_end = .);
            PROVIDE_HIDDEN (__fini_array_start = .);
            KEEP (*(.fini_array))
            KEEP (*(SORT(.fini_array.*)))
            PROVIDE_HIDDEN (__fini_array_end = .);
        } >ROM

        /* .ARM.exidx is sorted, so has to go in its own output section.  */
        .ARM.exidx : {
            __exidx_start = .;
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            __exidx_end = .;
        } >ROM
        _etext = .;

        .data : {
            __data_load = LOADADDR (.data);
            __data_start = .;
            KEEP(*(.jcr))
            *(.got.plt) *(.got)
            *(.shdata)
            *(.data .data.* .gnu.linkonce.d.*)
            . = ALIGN (4);
            _edata = .;
        } >RAM AT>ROM

        .bss : {
            __bss_start__ = . ;
            *(.shbss)
            *(.bss .bss.* .gnu.linkonce.b.*)
            *(COMMON)
            . = ALIGN (8);
            __bss_end__ = .;
        } >RAM

        .stack : {
            __stack_start__ = . ;

            . += IRQ_STACK_SIZE;
            . = ALIGN (4);
            __irq_stack_top__ = . ;

            . += FIQ_STACK_SIZE;
            . = ALIGN (4);
            __fiq_stack_top__ = . ;

            . += SVC_STACK_SIZE;
            . = ALIGN (4);
            __svc_stack_top__ = . ;

            . += ABT_STACK_SIZE;
            . = ALIGN (4);
            __abt_stack_top__ = . ;

            . += UND_STACK_SIZE;
            . = ALIGN (4);
            __und_stack_top__ = . ;

            . += C_STACK_SIZE;
            . = ALIGN (4);
            __c_stack_top__ = . ;

            __stack_end__ = .;
        } >RAM

        _end = . ;
        __end = . ;
        PROVIDE(end = .);

        .stab 0 (NOLOAD) : {
            *(.stab)
        }

        .stabstr 0 (NOLOAD) : {
            *(.stabstr)
        }

        /* 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) }
        .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
        .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
        /DISCARD/ : { *(.note.GNU-stack)  }
    }

    /*** EOF ***/


    No i skrypt ten działa normalnie dla projektu, gdzie używam m. in. bibliotek EFSL i HELIX (wielki projekt, razem jakieś 118 kB kodu, na razie...) i śmiga. Kiedy natomiast skompilowałem sobie FreeRTOS (wykaz plików we fragmencie makefile) to wywala wspomniany wyżej błąd (że sekcje .bss i .stack zachodzą na siebie). WTF? Że tak powiem ?

    Wspomniany fragment makefile:
    Code:

    DINCDIR = INC/ \
             INC/RTOS/

    # List the default directory to look for the libraries here
    DLIBDIR =

    # List all default libraries here
    DLIBS =

    #
    # End of default section
    ##############################################################################################

    ##############################################################################################
    # Start of user section
    #

    # Define project name here
    PROJECT = main

    # Define linker script file here
    LDSCRIPT_ROM = ./LNK/sam7s256_rom.ld

    # List all user C define here, like -D_DEBUG=1
    UDEFS =

    # Define ASM defines here
    UADEFS =

    # List C source files here
    SRC  = ./SRC/low_level_init.c \
           ./SRC/main.c \
           ./SRC/RTOS/lib_AT91SAM7X256.c \
          ./SRC/RTOS/port.c \
          ./SRC/RTOS/portISR.c \
          ./SRC/RTOS/croutine.c \
          ./SRC/RTOS/heap_2.c \
          ./SRC/RTOS/list.c \
          ./SRC/RTOS/queue.c \
          ./SRC/RTOS/tasks.c \

    # List ASM source files here
    ASRC = ./SRC/startup.s

    0 29
  • SterControl
  • #2 30 Sty 2010 13:05
    Freddie Chopin
    Specjalista - Mikrokontrolery

    1. section overlaps...

    Po każdej wykorzystywanej sekcji powinno być:
    } >RAM AT > [gdziestam]
    Wymóg nowych wersji binutils. "gdziestam" jest zwykle ta sama sekcja która wymieniona jest wcześniej, czyli np "> RAM AT > RAM". Jedyną sekcją gdzie zwykle jest inaczej jest data, gdzie masz "> RAM AT > ROM".

    2. sh_link not set

    Zamiast

    Code:
        .ARM.exidx : { 
    
            __exidx_start = .;
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            __exidx_end = .;
        } >ROM

    daj:
    Code:
            __exidx_start = .;
    
        .ARM.exidx : {
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        } >ROM
            __exidx_end = .;


    3. Undefined reference...

    To już kwestia kodu. Ten pierwszy to pewnie jakaś funkcja z FreeRTOS, ten drugi to kwestia tzw. syscalls.

    4\/3!!

    0
  • #3 30 Sty 2010 21:45
    Zaquadnik
    Poziom 27  

    Wprowadziłem poprawki typu ">RAM AT>RAM" itp. oraz zrobiłem tak:

    Code:

        /* .ARM.exidx is sorted, so has to go in its own output section.  */
        __exidx_start = .;
        .ARM.exidx : {
            __exidx_start = .;
            *(.ARM.exidx* .gnu.linkonce.armexidx.*)
            __exidx_end = .;
        } >ROM AT>ROM
        __exidx_end = .;
        _etext = .;


    I teraz mam taki oto komunikat:

    Code:

    make all
    arm-none-eabi-gcc ./SRC/startup.o  ./SRC/low_level_init.o ./SRC/main.o ./SRC/RTOS/lib_AT91SAM7X256.o ./SRC/RTOS/port.o ./SRC/RTOS/portISR.o ./SRC/RTOS/croutine.o ./SRC/RTOS/heap_2.o ./SRC/RTOS/list.o ./SRC/RTOS/queue.o ./SRC/RTOS/tasks.o  -mcpu=arm7tdmi -nostartfiles -T./LNK/sam7s256_rom.ld -Wl,-Map=main_rom.map,--cref,--no-warn-mismatch    -o main_rom.elf
    d:/programy/mikrokontrolery/arm/codesourcery/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/bin/ld.exe: main_rom.elf: warning: sh_link not set for section `.ARM.exidx'
    ./SRC/RTOS/tasks.o: In function `vTaskIncrementTick':
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1392: undefined reference to `vApplicationTickHook'
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1405: undefined reference to `vApplicationTickHook'
    d:/programy/mikrokontrolery/arm/codesourcery/bin/../lib/gcc/arm-none-eabi/4.3.3/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
    sbrkr.c:(.text+0x18): undefined reference to `_sbrk'
    collect2: ld returned 1 exit status
    make: *** [main_rom.elf] Error 1


    Z tym skryptem to dziwna sprawa, bo dla innego projektu działa bez zarzutu. Podobnie z plikami źródłowymi FreeRTOS, dla LPC2148 i dla STM32F103VBT działają bez problemów (oczywiście podmieniłem pliki charakterystyczne dla każdego z procesorów). Wiesz może gdzie można poczytać nieco o skryptach linkera ?

    0
  • Pomocny post
    #4 30 Sty 2010 22:54
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Hmm... Co do sh_link, to poniżej fragment mojego skryptu, który tego problemu nie ma (przynajmniej u mnie takie "przestawienie" pomagało)

    Code:

          . = ALIGN(4);
          __exidx_start = .;
          PROVIDE(__exidx_start = __exidx_start);

       .ARM.exidx :
       {
          . = ALIGN(4);
          *(.ARM.exidx* .gnu.linkonce.armexidx.*);
       } > rom AT > rom /* index entries for section unwinding */

          . = ALIGN(4);
          __exidx_end = .;
          PROVIDE(__exidx_end = __exidx_end);


    Zasadniczo jeśli ta sekcja jest potrzebna, to znaczy, że Twój kod zaczyna używać jakichś obiektów w których używane są wyjątki - to nie jest zbyt dobra wiadomość... Do obsługi wyjątków potrzeba jeszcze kilku innych sekcji - możesz je na razie sobie dorzucić:

    Code:

    /*      . = ALIGN(4);
          *(.ARM.extab* .gnu.linkonce.armextab.*); */ /* exception unwinding information */
    /*      . = ALIGN(4);
          *(.gcc_except_table); */ /* information used for stack unwinding during exception */
    /*      . = ALIGN(4);
          *(.eh_frame_hdr); */ /* additional information about .ex_frame section */
    /*      . = ALIGN(4);
          *(.eh_frame); */ /* information used for stack unwinding during exception */


    Odkomentuj sekcje i wrzuć to tam gdzie masz .text

    Co do undefined reference, to po prostu Twój kod (bądź obiekty używane przez Twój kod) wywołują w końcu te dwie funkcje, których skompilowany kod obiektowy nie może być nigdzie odnaleziony - poszukaj tej funkcji vApplicationTickHook, bo wygląda na to, że nie jest ona kompilowana, albo nie jest linkowana - masz skompilowany plik tasks.c (który ją wywołuje), ale nie masz już samej tej funkcji, która pewnie jest w innym pliku. Co do _sbrk(), to jest to funkcja wywoływana przez malloc(), której zadaniem jest przydzielenie jej kolejnej porcji pamięci. Przykładowa implementacja tej funkcji wygląda tak (pasuje do moich skryptów, więc do swojego musisz lekko przerobić):

    Code:

    caddr_t _sbrk_r(struct _reent *r, int size)
    {
       extern char __heap_start;
       extern char __heap_end;
       static char *current_heap_end = &__heap_start;
       char *previous_heap_end;

       r = r;

       previous_heap_end = current_heap_end;

       if (current_heap_end + size > &__heap_end)
       {
          errno = ENOMEM;
          return (caddr_t) -1;
       }

       current_heap_end += size;

       return (caddr_t)previous_heap_end;
    }


    Jest też wersja która kontroluje, czy nie nastąpiła kolizja heap ze stack (w przypadku gdy stack jest nad heap, co moim zdaniem jest proszeniem się o kłopoty).

    Do tej funkcji będą Ci też potrzebne niektóre nagłówki - wklejam wszystkie które mam w swoim syscalls, niektóre na pewno nie są potrzebne.

    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <sys/types.h>

    BTW pisząc sbrk_r(), a nie sbrk() skracasz lekko ciąg wywołań, bo newlib najpierw wywołuje sbrk_r(), które po prostu wywułuje sbrk(), więc można po prostu zastąpić od razu sbrk_r().

    O skryptach linkera można czytać w manualu do ld, ale w ARMach raczej problemem jest to, że niektóre elementy skryptu po prostu MUSZĄ być obecne "bo tak", a informacji o tym trzeba by chyba szukać analizując kod gcc, więc prościej mieć skrypt, który zawsze działa - Twój widać nie jest zbyt dobry. Polecam swój - jeszcze mnie nie zawiódł <:

    4\/3!!

    0
  • #5 30 Sty 2010 23:05
    Zaquadnik
    Poziom 27  

    Jeszcze posprawdzam proponowane przez Ciebie zmiany. A masz skrypt do Atmeli ?
    Co do _sbrk to dziwne jest, bo ten sam kod (implementacja malloc() jest w pliku heap_2.c) działa na LPC2148 i na STM32, więc nie wiem dlaczego tu nie wstaje. RTOS na pewno używa wyjątku SWI.

    0
  • #6 30 Sty 2010 23:51
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Zaquadnik napisał:
    Jeszcze posprawdzam proponowane przez Ciebie zmiany. A masz skrypt do Atmeli ?

    Jeśli weźmiesz ten z przykładu dla LPC2103 to będzie się różnił tylko adresami i rozmiarami pamięci ROM/RAM - każdy skrypt linkera dla ARM7 jest taki sam. Max 4 liczby do zmiany:

    Code:
    MEMORY
    
    {
       rom (rx)   : org = 0x00000000, len = 32k
       ram (rwx)   : org = 0x40000000, len = 8k
    }


    Cytat:
    Co do _sbrk to dziwne jest, bo ten sam kod (implementacja malloc() jest w pliku heap_2.c) działa na LPC2148 i na STM32, więc nie wiem dlaczego tu nie wstaje.

    Nie wiem jak to tam jest zrealizowane, ale z tego co pamiętam, to w FreeRTOS też są syscalls, tylko trzeba je dokompilować pewnie. Plik nazywa się stf_syscalls_minimal.c Potrzeba posiadania sbrk() wskazywałaby raczej na to, że używany jest malloc() i/lub sbrk() z biblioteki standardowej newlib.

    Cytat:
    RTOS na pewno używa wyjątku SWI.

    Nie chodzi mi o te wyjątki, tylko o "try { ... } catch() { ... }" z C++ - ta przyjemność kosztuje dobre kilkadziesiąt kB pamięci Flash - niestety.

    4\/3!!

    0
  • #7 31 Sty 2010 00:06
    Zaquadnik
    Poziom 27  

    Co do takich wyjątków to FreeRTOS chyba tego nie używa, nie widziałem w kodzie. Skompilowałem całość YAGARTO i mam taki komunikat:

    Code:

    make all
    arm-elf-gcc ./SRC/startup.o  ./SRC/low_level_init.o ./SRC/main.o ./SRC/RTOS/lib_AT91SAM7X256.o ./SRC/RTOS/port.o ./SRC/RTOS/portISR.o ./SRC/RTOS/croutine.o ./SRC/RTOS/heap_2.o ./SRC/RTOS/list.o ./SRC/RTOS/queue.o ./SRC/RTOS/tasks.o  -mcpu=arm7tdmi -nostartfiles -T./LNK/sam7s256_rom.ld -Wl,-Map=main_rom.map,--cref,--no-warn-mismatch    -o main_rom.elf
    ./SRC/RTOS/tasks.o: In function `vTaskIncrementTick':
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1392: undefined reference to `vApplicationTickHook'
    E:\Projekty\ARM\Eclipse\AT91SAM7Sxxx_RTOS/SRC/RTOS/tasks.c:1405: undefined reference to `vApplicationTickHook'
    collect2: ld returned 1 exit status
    make: *** [main_rom.elf] Error 1


    co do vApplicationTickHook to sprawdzę czy nie mam czegoś w configu RTOSa niepotrzebnie włączonego.

    EDIT: Wyłączyłem opcję "configUSE_TICK_HOOK " w configu FreeRTOSa i się kompiluje w YAGARTO. Zaraz spróbuję jeszcze w CodeSourcery.

    EDIT 2: Ale jaja, pod YAGARTO chodzi, pod CodeSourcery nie. WTF ?

    I jeszcze coś dziwnego, zajmuje to wszystko jakby za dużo pamięci:
    Code:

       text      data       bss       dec       hex   filename
        368         0         0       368       170   ./SRC/startup.o
        712         0         0       712       2c8   ./SRC/low_level_init.o
         12         0         0        12         c   ./SRC/main.o
          0         0         0         0         0   ./SRC/RTOS/lib_AT91SAM7X256.o
        732         0         0       732       2dc   ./SRC/RTOS/port.o
        636         4         0       640       280   ./SRC/RTOS/portISR.o
       1956         0       128      2084       824   ./SRC/RTOS/croutine.o
        866         0     10264     11130      2b7a   ./SRC/RTOS/heap_2.o
        600         0         0       600       258   ./SRC/RTOS/list.o
       3132         0         0      3132       c3c   ./SRC/RTOS/queue.o
       7868         4       304      8176      1ff0   ./SRC/RTOS/tasks.o
      16882         8     10696     27586      6bc2   (TOTALS)
     
    Size of target .elf file:
    arm-elf-size -B main_rom.elf
       text      data       bss       dec       hex   filename
      48900      2128     11776     62804      f554   main_rom.elf


    W LPC2148 sekcja text ma jakieś 18700 B. WTF?

    0
  • SterControl
  • #8 31 Sty 2010 02:01
    Freddie Chopin
    Specjalista - Mikrokontrolery

    W yagarto się kompiluje pewnie przez to, że ma on "wbudowane" sbrk() (inna konfiguracja newlib), a do CodeSourcery musisz dodać je samodzielnie.

    Rozmiar jest na 99% spowodowany funkcjami do obsługi wyjątków - niestety jednak się dodały. Tak czy siak nie jest źle - dla STM32 obsługa wyjątków to około 50-60kB.

    4\/3!!

    0
  • #9 31 Sty 2010 10:25
    Zaquadnik
    Poziom 27  

    Hmmm, a jesteś w stanie wyjaśnić dlaczego dla LPC2148 nie ma żadnych problemów, a dla Atmela są ? Bo ja zgłupiałem.

    I żeby było śmieszniej, projekt skompilował się z pierwotnym skryptem linkera, który wywalał błąd zachodzenia na siebie sekcji .bss i .stack .

    0
  • #10 31 Sty 2010 11:15
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Wnioskuję, że kompilacje dla LPC i SAM różnią się tylko 2 plikami - stosownym plikiem w FreeRTOS i skryptem linkera. Gdzieś tam musi być coś zakręcone... No chyba że są też jakieś różnice w wywołaniach kompilacji lub w innych plikach. Musiałbyś wrzucić tutaj te dwa komplety plików, bo ciężko tak gdybać "na sucho".

    Jeśli na szybko chcesz sprawdzić, czy to rzeczywiście wyjątki C++ zajmują tyle miejsca, to poszukaj w końcowych plikach wynikowych (map? dump? najlepszy jest listing assemblera) funkcji która nazywa się chyba gxx_personality - jeśli jest, to Twój program jednak realizuje wyjątki...

    4\/3!!

    0
  • #12 31 Sty 2010 12:06
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Już chyba wiem w czym problem - Twoja kompilacja po prostu wciąga kupę nieużywanych w ogóle funkcji (i danych), które nie zostają usunięte na etapie linkowania. Po przejechaniu Twojego kodu moim skryptem (tego dla AT91...) przy optymalizacji 0, ale z usuwaniem niepotrzebnych elementów, całość zajmuje.... 1.7kB (; Jeśli tylko wyłączę usuwanie nieużywanego kodu, to od razu dostaję jakieś 50kB kodu wynikowego, no i muszę dostarczyć wtedy implementację sbrk().

    Wielkimi funkcjami które są wciągane jest m.in. printf() wraz z całą dodatkową armią funkcji pomocniczych.

    Dlaczego w przypadku LPC się tak nie dzieje? Nie wiem (; Faktem jest jednak, że to są dwa różne projekty - w jednym masz inne pliki niż w drugim, jest też obsługa LCD itd.

    Skrypt którym to robiłem wyślę Ci na PMa - nie chcę go na razie udostępniać, bo jest to jeszcze nieskończony plik który pojawi się wraz z kolejną wersją przykładów - obsługuje on kompilowanie plików w różnych podkatalogach - wystarczy podmienić i kompilacja przechodzi. Jeśli wyłączysz usuwanie nieużywanego kodu (REMOVE_UNUSED), to musisz wtedy dostarczyć sbrk() - żeby uciszyć kompilator wystarczy nawet coś takiego:

    Code:
    int _sbrk(void)
    
    {
    return 0;
    }


    4\/3!!

    0
  • #13 31 Sty 2010 19:50
    Zaquadnik
    Poziom 27  

    Dzięki za plik. Potestuję jeszcze. Mam teraz problem z LPC, przy włączaniu Schedulera włazi w wyjątek Data Abort :/ Myślałem, że udało mi się naprawić to, a tu zonk :/
    Wywala się przy:

    Code:

    void vPortISRStartFirstTask( void )
    {
       /* Simply start the scheduler.  This is included here as it can only be
       called from ARM mode. */

       portRESTORE_CONTEXT();  <- dokładnie tu
    }

    0
  • #14 31 Sty 2010 23:12
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Może jednak rdzeń nie pracuje w trybie ARM? Może któraś z tych funkcji jest w pamięci RAM? Może stos się przepełnił? Ciężko wyrokować - tu może pomóc tylko debugger i disassembler.

    4\/3!!

    0
  • #15 01 Lut 2010 09:57
    Zaquadnik
    Poziom 27  

    O ile FreeRTOS nie przełącza go w tryb Thumb to pracuje, bo ja nigdzie go nie przełączam w tryb Thumb. Muszę obejrzeć jeszcze stos, ale coś Ci pokażę:

    Code:

    #define portRESTORE_CONTEXT()                                 \
    {                                                      \
    extern volatile void * volatile pxCurrentTCB;                     \
    extern volatile unsigned portLONG ulCriticalNesting;               \
                                                          \
       /* Set the LR to the task stack. */                           \
       __asm volatile (                                       \
       "LDR      R0, =pxCurrentTCB                        \n\t"   \
       "LDR      R0, [R0]                              \n\t"   \
       "LDR      LR, [R0]                              \n\t"   \
                                                          \
       /* The critical nesting depth is the first item on the stack. */   \
       /* Load it into the ulCriticalNesting variable. */               \
       "LDR      R0, =ulCriticalNesting                     \n\t"   \
       "LDMFD   LR!, {R1}                                 \n\t"   \
       "STR      R1, [R0]                              \n\t"   \
                                                          \
       /* Get the SPSR from the stack. */                           \
       "LDMFD   LR!, {R0}                                 \n\t"   \
       "MSR      SPSR, R0                              \n\t"   \
                                                          \
       /* Restore all system mode registers for the task. */            \
       "LDMFD   LR, {R0-R14}^                              \n\t"   \
       "NOP                                          \n\t"   \
                                                          \
       /* Restore the return address. */                           \
       "LDR      LR, [LR, #+60]                           \n\t"   \
                                                          \
       /* And return - correcting the offset in the LR to obtain the */   \
       /* correct address. */                                    \
       "SUBS   PC, LR, #4                                 \n\t"   \
       );                                                   \
       ( void ) ulCriticalNesting;                                 \
       ( void ) pxCurrentTCB;                                    \
    }


    To jest owo makro, na którym się wykłada. "pxCurrentTCB" jest zadeklarowane jako extern, a nigdzie tego znaleźć nie mogę. Może przy instrukcji LDR R0, =pxCurrentTCB on próbuje do R0 wpisać coś z adresu zupełnie przypadkowego ?

    0
  • #16 01 Lut 2010 11:00
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jak przeszukasz wszystkie pliki w katalogu projektu (włącznie z nagłówkami, skryptami linkera itp.) to nie znajduje tej nazwy nigdzie?

    Poprzestawiaj sobie kompilację, żeby generowała listing assemblerowy (możesz zobaczyć jak jest w moim Makefile to zrobione), wtedy zobaczysz dokładnie co się dzieje w tym miejscu.

    4\/3!!

    0
  • #17 01 Lut 2010 11:06
    Zaquadnik
    Poziom 27  

    Hmm, znalazłem deklarację w pliku tasks.c :

    Code:

    PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;

    Więc sam wskaźnik jest zadeklarowany. Później spróbuję jeszcze zdeasemblować całość i zobaczyć co się tam dzieje. Bo procek wykrzacza się na samej linijce z wywołaniem makra, nie wchodzi w jego kod.

    0
  • #18 01 Lut 2010 11:28
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Debugger IMHO nie wchodzi w kod makr, taki jego urok... Może gdybyś tymczasowo zmienił makro na rzeczywistą funkcję (najlepiej jako "static" ... "__attribute__ ((always_inline));") to wtedy mógłbyś ją faktycznie zdebuggować.

    Nie sugerowałbym się więc pierwszymi linijkami...

    4\/3!!

    0
  • #19 01 Lut 2010 17:49
    Zaquadnik
    Poziom 27  

    Podmieniłem jeszcze plik startowy i skrypt linkera na te z przykładu z FreeRTOS dla LPC2106 (pozmieniałem rozmiary pamięci w skrypcie linkera) i nadal się wykłada :/ Spróbuję jeszcze Twoją metodą.

    0
  • #20 01 Lut 2010 18:04
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jeśli chcesz / miałbyś problem to wrzuć taki kod jaki kompilujesz obecnie (cały projekt), to wrzucę Ci dezassemblację całości - tam można wypatrzyć dosyć ciekawe rzeczy. Mogę też zmienić to makro na funkcję inline - wtedy można debuggować na pewno, a nie zaburzy to idei FreeRTOSa.

    4\/3!!

    0
  • #21 01 Lut 2010 18:08
    Zaquadnik
    Poziom 27  

    wrzuciłem ten projekt w poście wyżej.

    0
  • #22 01 Lut 2010 19:13
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Trochę kiepskie te pliki których używasz...

    W skrypcie linkera ustawiłem Ci wyrównanie stosu do 8, a nie do 4 - bez tego czasem dzieją się niezłe rzeczy. Dodatkowo wg tego skryptu i twojego startupa dane z sekcji .data są niezainicjalizowane nigdy - mają losowe wartości - mam nadzieję, że jesteś tego świadomy. Poprawiłem w skrypcie "AT > ...".

    Wynik kompilacji:

    Code:
    >make all
    
    Assembling file: src/rozbiegowka.s
    arm-none-eabi-gcc -x assembler-with-cpp -c -mcpu=arm7tdmi-s -g -ggdb3 -Wa,-amhls
    =./out/rozbiegowka.lst  -MD -MP -MF ./out/rozbiegowka.d -I.  -I./inc/  -I./inc/r
    tos/ src/rozbiegowka.s -o out/rozbiegowka.o

    Compiling file: src/armint.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/armint.
    lst  -MD -MP -MF ./out/armint.d -I.  -I./inc/  -I./inc/rtos/ src/armint.c -o out
    /armint.o

    Compiling file: src/LCD_HD44780.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/LCD_HD4
    4780.lst  -MD -MP -MF ./out/LCD_HD44780.d -I.  -I./inc/  -I./inc/rtos/ src/LCD_H
    D44780.c -o out/LCD_HD44780.o
    src/LCD_HD44780.c: In function 'LCD_print':
    src/LCD_HD44780.c:208: warning: array subscript has type 'char'
    src/LCD_HD44780.c:210: warning: array subscript has type 'char'
    src/LCD_HD44780.c: In function 'LCD_print_int':
    src/LCD_HD44780.c:226: warning: array subscript has type 'char'
    src/LCD_HD44780.c: In function 'LCD_print_time':
    src/LCD_HD44780.c:243: warning: array subscript has type 'char'
    src/LCD_HD44780.c: In function 'LCD_print_volt':
    src/LCD_HD44780.c:262: warning: array subscript has type 'char'
    src/LCD_HD44780.c:265: warning: array subscript has type 'char'
    src/LCD_HD44780.c:269: warning: array subscript has type 'char'

    Compiling file: src/main.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/main.ls
    t  -MD -MP -MF ./out/main.d -I.  -I./inc/  -I./inc/rtos/ src/main.c -o out/main.
    o
    src/main.c: In function 'main':
    src/main.c:30: warning: unused variable 'xHandleTaskLCD'
    src/main.c: In function 'vTaskLCD':
    src/main.c:45: warning: unused parameter 'pvParameters'
    src/main.c: In function 'vTaskLED1':
    src/main.c:64: warning: unused parameter 'pvParameters'
    src/main.c: In function 'vTaskLED2':
    src/main.c:77: warning: unused parameter 'pvParameters'

    Compiling file: src/rtos/croutine.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/croutin
    e.lst  -MD -MP -MF ./out/croutine.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/crouti
    ne.c -o out/croutine.o

    Compiling file: src/rtos/heap_2.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/heap_2.
    lst  -MD -MP -MF ./out/heap_2.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/heap_2.c -
    o out/heap_2.o

    Compiling file: src/rtos/list.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/list.ls
    t  -MD -MP -MF ./out/list.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/list.c -o out/
    list.o

    Compiling file: src/rtos/port.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/port.ls
    t  -MD -MP -MF ./out/port.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/port.c -o out/
    port.o

    Compiling file: src/rtos/portISR.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/portISR
    .lst  -MD -MP -MF ./out/portISR.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/portISR.
    c -o out/portISR.o
    src/rtos/portISR.c: In function 'vPortISRStartFirstTask':
    src/rtos/portISR.c:107: warning: #warning "Tu siŕ wyk│ada"

    Compiling file: src/rtos/queue.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/queue.l
    st  -MD -MP -MF ./out/queue.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/queue.c -o o
    ut/queue.o

    Compiling file: src/rtos/tasks.c
    arm-none-eabi-gcc -c -mcpu=arm7tdmi-s -O0 -ffunction-sections -fdata-sections -W
    all -Wstrict-prototypes -Wextra -g -ggdb3 -fverbose-asm -Wa,-ahlms=./out/tasks.l
    st  -MD -MP -MF ./out/tasks.d -I.  -I./inc/  -I./inc/rtos/ src/rtos/tasks.c -o o
    ut/tasks.o

    Linking target: ./out/lpc21xx_rtos.elf
    arm-none-eabi-g++ -mcpu=arm7tdmi-s -T./LNK/lpc2148-rom.ld -g -Wl,-Map=./out/lpc2
    1xx_rtos.map,--cref,--no-warn-mismatch -Wl,--gc-sections -nostartfiles  ./out/ro
    zbiegowka.o ./out/armint.o ./out/LCD_HD44780.o ./out/main.o ./out/croutine.o ./o
    ut/heap_2.o ./out/list.o ./out/port.o ./out/portISR.o ./out/queue.o ./out/tasks.
    o    -o out/lpc21xx_rtos.elf

    Creating extended listing: ./out/lpc21xx_rtos.lss
    arm-none-eabi-objdump -S out/lpc21xx_rtos.elf > out/lpc21xx_rtos.lss

    Creating memory dump: ./out/lpc21xx_rtos.dmp
    arm-none-eabi-objdump -x --syms out/lpc21xx_rtos.elf > out/lpc21xx_rtos.dmp

    Creating IHEX image: ./out/lpc21xx_rtos.hex
    arm-none-eabi-objcopy -O ihex out/lpc21xx_rtos.elf out/lpc21xx_rtos.hex

    Creating binary image: ./out/lpc21xx_rtos.bin
    arm-none-eabi-objcopy -O binary out/lpc21xx_rtos.elf out/lpc21xx_rtos.bin

    Size of modules:
    arm-none-eabi-size -B -t --common ./out/rozbiegowka.o ./out/armint.o ./out/LCD_H
    D44780.o ./out/main.o ./out/croutine.o ./out/heap_2.o ./out/list.o ./out/port.o
    ./out/portISR.o ./out/queue.o ./out/tasks.o
       text    data     bss     dec     hex filename
        348       0       0     348     15c ./out/rozbiegowka.o
        468       0       0     468     1d4 ./out/armint.o
       2820       0       0    2820     b04 ./out/LCD_HD44780.o
        572       0       0     572     23c ./out/main.o
       2024       0     128    2152     868 ./out/croutine.o
        902       0   24600   25502    639e ./out/heap_2.o
        660       0       0     660     294 ./out/list.o
        876       0       0     876     36c ./out/port.o
        652       4       0     656     290 ./out/portISR.o
       2920       0       0    2920     b68 ./out/queue.o
       6136       0     256    6392    18f8 ./out/tasks.o
      18378       4   24984   43366    a966 (TOTALS)

    Size of target .elf file:
    arm-none-eabi-size -B ./out/lpc21xx_rtos.elf
       text    data     bss     dec     hex filename
       7624       4   27128   34756    87c4 ./out/lpc21xx_rtos.elf


    W załączniku masz efekt tej kompilacji, w tym dezassemblację w pliku .lss

    4\/3!!

    0
  • #23 01 Lut 2010 22:08
    Zaquadnik
    Poziom 27  

    Wielkie dzięki, ja po prostu jakoś nie wnikałem nigdy w makefile czy skrypt linkera. Właśnie dlatego muszę o tym jeszcze poczytać, jak czas pozwoli. Ten projekt jest nadmiarowy, generalnie w pracy na razie zajmuję się czymś innym i to ma priorytet, niestety =] Co do plików to bazowałem na tych z książki p. L. Bryndzy =]

    0
  • Pomocny post
    #24 01 Lut 2010 22:15
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Generalnie to stawiałbym na coś z poniższej listy:
    1. Kolizje stosu z innymi danymi (obszarem dynamicznym lub normalnymi danymi) - jest dosyć nieprzejrzyście zdefiniowany, więc się w to nie wgłębiałem.
    2. Przepełnienie stosu - może dla któregoś z trybów jest zbyt mały
    3. Używanie danych, które powinny być zainicjalizowane a nie są (brak inicjalizacji sekcji .data!)

    No chyba że te pliki wynikowe które wrzuciłem u Ciebie działają - kto wie [;

    Odezwij się jak wrócisz do tematu

    4\/3!!

    0
  • #25 02 Lut 2010 14:03
    Zaquadnik
    Poziom 27  

    Hmmm, skompilowany przez Ciebie projekt też wywala Data Abort :/ Spróbuję znaleźć gdzie.

    EDIT: Wykłada się dokładnie na instrukcji:

    Code:
    c3c:   e59f004c    ldr   r0, [pc, #76]   ; c90 <vPortISRStartFirstTask+0x5c>
    , czyli tak, jak podejrzewałem. Program każe mu wykonać dostęp do pamięci, której nie ma. Poszukam dalej dlaczego tak się dzieje. Mówisz, że w dokumentacji do ld jest co nieco o skryptach linkera, a jest jakaś dokumentacja do make ? Jeśli tak, to poszukam w necie, żeby się podszkolić.

    0
  • #26 09 Lut 2010 17:20
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Hmm... Pokaż instrukcje "obok" bo na tej na pewno się nie wykłada - jest to rozkaz załadowania do r0 wartości spod adresu "76 dalej niż obecne PC", co na pewno istnieje i jest "za" funkcją (zresztą w komentarzu masz nawet adres tych danych - c90). Przypuszczam, że abort wywołuje się tutaj, bo np do procka dopiero teraz dotarło, że ma wykonać ABORT, albo zrozumiał, że zaraz będzie ABORT - kwestia pipeline'a.

    Znalazłem zresztą sam:

    Code:
    ...
    
         c3c:   e59f004c    ldr   r0, [pc, #76]   ; c90 <vPortISRStartFirstTask+0x5c>
         c40:   e5900000    ldr   r0, [r0]
         c44:   e590e000    ldr   lr, [r0]
    ...
         c90:   40006020    .word   0x40006020
    ...


    Zobacz więc sam - najpierw do r0 ładowane jest "coś" spod adresu c90, czyli 0x40006020, potem do r0 ładowane jest to, co jest przez r0 wskazywane - adres komórki do której odbywa się dostęp to ~24kB, więc wciąż jest OK - pamięci masz 32kB. Potem jednak do lr (rejestr obsługujący m.in. adresy powrotu - jakby ktoś nie wiedział) ładowane jest to co wskazywane jest przez r0, czyli to co jest wskazywane przez komórkę pamięci 0x40006020

    Pod tym adresem znajduje się "pxCurrentTCB" z pliku tasks.c :
    PRIVILEGED_DATA tskTCB * volatile pxCurrentTCB = NULL;

    Jeśli możesz, to sprawdź w debuggerze jaką wartość ma "tuż przed wywaleniem się" komórka o tym adresie.

    Możesz to zrobić na 3 sposoby:
    1. Połącz się z OpenOCD przez telnet (cmd -> telnet localhost 4444) i wpisz "mdw 0x40006020 1" (chyba)
    2. W debuggerze w Eclipse w Variables poproś grzecznie o pokazanie zmiennej pxCurrentTCB (prawym w okno i show global variables)
    3. W debuggerze w Eclipse w Expressions (jak nie widać to jakoś znajdziesz w Window) wpisz coś na styl "*((int*)0x40006020)"

    Jeśli komórka ta wskazuje na coś, co nie istnieje, to właśnie tu jest problem. Oczywiście wciaż istnieje szansa, że tak naprawdę wykłada się w innym miejscu - np przerwanie w tle akurat modyfikuje sp albo coś równie extremalnego... Zbadaj na razie jednak to.

    4\/3!!

    0
  • #27 09 Lut 2010 21:28
    Zaquadnik
    Poziom 27  

    Komórka o adresie 0x40006020 ma wartość 0x400002A8. Tuż przed wywaleniem się. Sprawdzałem na tym wsadzie, który mi podesłałeś ze zdeasemblowanym kodem. Kurde, to siedzi w RAMie, więc nie ma prawa takie coś się dziać. Sprawdzę jeszcze wskaźnik stosu.

    EDIT. Wskaźnik stosu przed wywaleniem się pokazuje na 0x400037A0, więc też prawidłowa lokalizacja.

    0
  • #28 09 Lut 2010 21:51
    Freddie Chopin
    Specjalista - Mikrokontrolery

    No to lecimy dalej [;

    Code:
    void vPortISRStartFirstTask( void )
    
    {
         c34:   e52db004    push   {fp}      ; (str fp, [sp, #-4]!)
         c38:   e28db000    add   fp, sp, #0
       /* Simply start the scheduler.  This is included here as it can only be
       called from ARM mode. */
    #warning "Tu się wykłada"
       portRESTORE_CONTEXT();
         c3c:   e59f004c    ldr   r0, [pc, #76]   ; c90 <vPortISRStartFirstTask+0x5c>
         c40:   e5900000    ldr   r0, [r0]
         c44:   e590e000    ldr   lr, [r0]
         c48:   e59f0044    ldr   r0, [pc, #68]   ; c94 <vPortISRStartFirstTask+0x60>
         c4c:   e8be0002    ldm   lr!, {r1}
         c50:   e5801000    str   r1, [r0]
         c54:   e8be0001    ldm   lr!, {r0}
         c58:   e169f000    msr   SPSR_fc, r0
         c5c:   e8de7fff    ldm   lr, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr}^
         c60:   e1a00000    nop         ; (mov r0, r0)
         c64:   e59ee03c    ldr   lr, [lr, #60]   ; 0x3c
         c68:   e25ef004    subs   pc, lr, #4
         c6c:   e59f3014    ldr   r3, [pc, #20]   ; c88 <vPortISRStartFirstTask+0x54>
         c70:   e5933000    ldr   r3, [r3]
         c74:   e59f3010    ldr   r3, [pc, #16]   ; c8c <vPortISRStartFirstTask+0x58>
         c78:   e5933000    ldr   r3, [r3]
    }
         c7c:   e28bd000    add   sp, fp, #0
         c80:   e8bd0800    pop   {fp}
         c84:   e12fff1e    bx   lr
         c88:   40000000    .word   0x40000000
         c8c:   40006020    .word   0x40006020
         c90:   40006020    .word   0x40006020
         c94:   40000000    .word   0x40000000

    Szanse wywalenia się są jeszcze na liniach:
    c4c - do r1 ładowane jest to na co wskazuje lr (to już jest chyba potrójny wskaźnik [; ), czyli to na co wskazuje zawartość komórki 0x400002A8 (jest to jakiś element heap)
    c54 - jak wyżej, ale tutaj wskaźnik jest brany z sąsiedniej komórki względem poprzedniej (nie wiem chwilowo czy "przed" czy "po" [;
    c58 - wartość w r0 musi być poprawnym wpisem do SPSR
    c5c - jak 2 wyżej
    c64 - tam odczytywany jest adres powrotu z tej funkcji
    c68 to rzeczywista instrukcja powrotu z tej funkcji - wszystko co jest "poniżej" nie zostanie wykonane. Do tego należy zauważyć, że zastosowana tam specyficzna metoda powrotu działa TYLKO dla niektórych wyjątków - powrót w ten sposób z normalnie wywołanej funkcji zakończy się niezbyt sensownie, bo procek wyląduje o 1 instrukcję za wcześnie, czyli przypuszczalnie na ponownym skoku do funkcji. Jeżeli całośc jest wywoływana przez jakieś przerwanie, to pamiętaj aby patrzeć na "właściwe" rejestry, bo ARM7 ma całkiem sporo bankowanych rejestrów dla różnych trybów.

    Trochę zakręcona jest ta funkcja - nie mam zbytnio pomysłów na temat tego "co jest źle"... Spróbuj prześledzić całość krok po kroku (w assemblerze) sprawdzając cały czas jakie są wartości rejestrów biorących udział w tych zabawach, jeśli nie uda ci się to w Eclipse, to można to łatwo zrobić w OpenOCD przez telnet ("step" oraz "reg")

    Nie znam się na FreeRTOS, ale przypuszczam, że któryś z Twoich plików po prostu nie pasuje do całości i dzieją się takie cuda...

    4\/3!!

    0
  • #29 09 Lut 2010 22:10
    Zaquadnik
    Poziom 27  

    Ale jeszcze jedna uwaga, procek wchodzi w Data Abort od razu po instrukcji

    Code:
    c3c:   e59f004c    ldr   r0, [pc, #76]   ; c90 <vPortISRStartFirstTask+0x5c> 
    Czy to nie wskazuje od razu miejsca gdzie należy szukać ?

    0
  • #30 09 Lut 2010 22:54
    Freddie Chopin
    Specjalista - Mikrokontrolery

    No właśnie jak dla mnie to jest bardzo dziwne, bo wg mnie wszystko przed tą instrukcją jest ok...

    Jeśli włączasz PLL i MAM, to może spróbuj odpalić wszystko bez PLL i MAM - na niskich prędkościach? A nuż jest to problem sprzętowy...

    Z jakiego przerwania jest wywoływana ta funkcja? Masz tam przerwania zagnieżdżone?

    Nie mam już pomysłów... /;

    4\/3!!

    0