2012-10-03 16 views
9

Używam płyty LPC 1768 z mbed, (z korpusem M3 cpu) i staram się coś tutaj osiągnąć, głównie aktualizuję aplikację użytkownika z karty SD, piszę dwa programy, najpierw bootloader/nano-kernel, a użytkownik-aplikacja (helloworld zrobi na początek):Bootloader dla Cortex M3

  • bootloadera/nano-jądro przy 0x00 tras adresowych, będzie to zrobić kilka kontroli i ostatecznie pobrać plik binarny na SD karta
  • Bootloader/nano-kernel skopiuje ten plik binarny pod adres 0x9000 (który może później się zmienić, ale to miejsce nie jest używane przez bootloader/nano-kernel, więc powinno być ok)
  • Bootloader przeskakuje do aplikacji użytkownika pod 0x9000 + 4

Karta Sd jest dość łatwa do opanowania, mam problemy z częścią do skoków. Oto kod funkcji skaczącej.

void run(void) { 

    void (*user_code_entry)(void); 

    unsigned *p; 
    SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80); 

    // Load contents of second word of user flash - the reset handler address 
    // in the applications vector table 
    p = (unsigned *)(USER_FLASH_START +4); // USER_FLASH_START is 0x9000 

    user_code_entry = (void (*)(void))p; 

    // Jump to user application 
    user_code_entry(); 

}

Więc mam skompilowane (używam Keil uvision4) wniosek użytkownik zmienia adres startowy do 0x9000. Jeśli zaprogramuję moją tablicę (za pomocą flashmagictool), a następnie ręcznie przeskoczę (nadal używając flashmagictool) do 0x9004 (0x9000 + 4), aplikacja użytkownika zostanie uruchomiona, więc uważam, że kompilacja działa dobrze, więc aplikacja użytkownika może działać pod 0x9000.

Ale jeśli uruchomię bootloader/nano-kernel, ten nie przeskoczy do aplikacji użytkownika i niestety, ponieważ nie mogę debugować, nie jestem pewien co się dzieje ... Próbowałem też nie użyj części SD copy, więc programuję bootloadera najpierw z samym skokiem do 0x9004. Następnie programuję aplikację użytkownika, która będzie znajdować się pod adresem 0x9000. Jeśli zrestartuję płytę, bootloader działa, ale nie przechodzi do aplikacji użytkownika. Sprawdziłem pamięć i wygląda na to, że oba programy (bootloader + user-app) są poprawne i we właściwym miejscu.

Jestem pewien, że czegoś tu brakuje, czy jest jakiś kod niskiego poziomu, na który powinienem patrzeć? Czytałem tony dokumentów online, a z przykładów, które znalazłem, przeskakują do kodu użytkownika w taki sam sposób jak ja ... Dziękuję bardzo za pomoc.

+0

to powinno działać dość podobny w komputerze też, ale z adresami wirtualnymi, zamiast fizycznego - spróbować i zobaczyć, czy to działa, a następnie przenieś kod do Keil – Ulterior

+1

Cortex M3 nie ma MMU, więc nie ma adresów wirtualnych. –

Odpowiedz

8

Cortex M3 może działać tylko w trybie Kciuk. Dlatego zawsze musisz przeskoczyć do address +1, w przeciwnym razie wygeneruje błąd.

Spróbuj:

user_code_entry = (void (*)(void))(USER_FLASH_START +4 +1);

+0

Nie mogę uwierzyć, że to było to! Dziękuję bardzo Turbo J :) – batmat

+3

Zdaję sobie sprawę, że to prawdopodobnie zadziałało, ale nie ma sensu. Kompilator powinien generować dla ciebie instrukcje Thumb. Robię dokładnie to samo, co ty tam (bez +1) i wydaje się, że działa dla mnie. Czy masz ustawioną flagę 'thumb' dla kompilatora' arm-none-eabi-gcc'? – nonsensickle

+0

Dzięki! To również zadziałało dla mnie na M4. Wszystko skompilowane w porządku, debugger przebiegł cały kod dobrze, z jednym wyjątkiem tego ostrzeżenia debuggera IAR, które nastąpiłoby po skoku podczas przechodzenia przez kod: "T-bit XPSR wynosi 0, ale powinien być 1. Zmieniony na 1 ." – tniles09

3

Wystarczy przeczytać dokument AN10866 na NXP UNESCO. Trzeba załadować komputer i wskaźnik stosu, a następnie przejść do przerwania Reset:

__asm void boot_jump(uint32_t address){ 
    LDR SP, [R0]  ;Load new stack pointer address 
    LDR PC, [R0, #4] ;Load new program counter address 
} 

void execute_user_code(void) 
{ 
    /* Change the Vector Table to the USER_FLASH_START 
    in case the user application uses interrupts */ 
    SCB->VTOR = USER_FLASH_START & 0x1FFFFF80; 

    boot_jump(USER_FLASH_START); 
} 
+0

Chciałbym również dodać, że http://infocenter.arm.com/help/topic/com.arm.doc.dui0056d/DUI0056.pdf na stronie 4-6 i 4-7 w części" Różnice między wbudowanym asemblerem i armasm "stwierdza, że ​​nie można przechowywać wartości na PC. Stwierdza również, że instrukcja 'bx' nie jest obsługiwana, ale mam kod, który aktualnie używa go w inline asm, który działa (chociaż sprawdzam to ponownie). – nonsensickle

+0

Moja poprzednia uwaga dotyczy zespołu wbudowanego, takiego jak używany @John Sinclair. Są one bezpieczne do użycia w osobnym pliku kodu montażowego, jednak miałem wersję robiącą to samo w montażu inline i również działało dobrze, więc nie jestem pewien, co zrobić z zaleceniami ARM. – nonsensickle

Powiązane problemy