Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[LPC1754]Upgrade programu z pamięci USB.

markosik20 27 Lis 2011 16:19 2304 19
  • #1 27 Lis 2011 16:19
    markosik20
    Poziom 33  

    Mam takie w sumie teoretyczne pytanie jaką drogę wybrać.
    W oprogramowaniu mam zawarty FatFs oraz obsługę USB Host'a. Mogę zapisywać, odczytywać pliki z popularnych "pendrive'ów" na kartę SD i z powrotem.
    Posiadając takie możliwości aż prosi się o dopisanie obsługi aktualizacji oprogramowania....tylko którą metodę wybrać.
    Umieszczenie funkcji obsługi FatFs i IAP w RAM'ie odpada (~20kB).
    1. Czy skopiować w odpowiednim czasie funkcje obsługi do RAM'u i je stamtąd odpalić (FatFs + IAP)?
    2. Czy przeznaczyć ostatnie 32kB flash'a i załadować tam wszystkie niezmienne elementy?

    Jeżeli chodzi o pkt. 1 to obawiam się że będzie to dosyć skomplikowane, natomiast w pkt. 2 jak przypilnować zgrabnie i szybko aby wszystkie funkcje w tym niezmiennym flash'u (+ funkcje biblioteczne które są wykorzystywane) były dostępne cały czas pod tym samym adresem?

    0 19
  • #2 27 Lis 2011 16:53
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Ja bym zrobił wersję nr1 (; Po przeflashowaniu softu i tak (raczej) musisz zrobić reset, więc nie musisz odtwarzać zawartości pamięci RAM, możesz więc sobie generalnie pokasować wszystkie inne zmienne [; Tak naprawdę na karcie możesz mieć dwa obrazy - nowy wsad i "bootloader". Kopiujesz sobie do RAMu "wprost" ten bootloader (kompletny działający z RAMu program ze wszystkimi funkcjami), a potem przechodzisz ze starego programu (we flashu), do tego bootloadera - on dopiero kopiuje sobie po kawałku nowy wsad do flasha.

    Jeśli masz nadmiar flasha, to wersja nr2 też oczywiście jest dobra (; Trochę mniej kombinowania z nią jest [;

    Co do wersji nr2 i pytania, to najprostszą opcją jest zrobienie sobie tablicy tych funkcji pod stałym adresem, podobnie jak jest zrobiona tablica wektorów (; Ograniczasz rozmiar pamięci flash w skrypcie linkera, dopisujesz niejako "drugą" pamięć flash z jakimś adresem startu i rozmiarem, następnie umieszczasz tam swoje funkcje, a na początku tablicę wskaźników na funkcje - tak jak to jest zrobione z wektorami przerwań.

    Pamiętaj o zostawieniu w RAM pewnego bufora na operacje IAP - on korzysta z końcowej czy tam początkowej części RAM no i ze stosu.

    4\/3!!

    0
  • #3 27 Lis 2011 17:13
    markosik20
    Poziom 33  

    A co zrobić z funkcjami bibliotecznymi jeżeli chodzi o pkt.2 ?
    Takie zabawy robiłem swego czasu na prockach 8051 z Silab'a i wszystkie funkcje biblioteczne musiałem też umieścić pod stałymi adresami...sęk w tym że w kompilatorze dla 8051 było ich znacznie mniej :)

    0
  • #4 27 Lis 2011 17:55
    Freddie Chopin
    Specjalista - Mikrokontrolery

    A będziesz z takowych korzystał? <:

    Jest inna opcja - tworzysz dwa osobne projekty. Jedyna zależność między nimi jest taka, że ten pierwszy ("zwyczajny") może uruchomić ten drugi ("bootloader") poprzez skok pod adres początku tamtego (lub jakiś inny znany i stały adres). Projekt bootloadera będzie miał po prostu skrypt linkera w którym pamięć flash będzie się zaczynała zupełnie gdzie indziej, a ponieważ jest to niezależny projekt, to będzie miał komplet potrzebnych mu funkcji. Specjalną kwestią w tym projekcie będzie startup i tablica wektorów. Startup musi ustawić stosy ręcznie (bo główny stos Cortex-a nie ustawi się sam - w końcu nie było resetu), musi też przestawić NVIC tak aby korzystał z tablicy wektorów położonej pod innym adresem (lub w RAM) jeśli oczywiście będziesz korzystał tam z przerwań, bo jeśli nie, to można olać. Adres pod który należy skoczyć, żeby rozpocząć wykonywanie takowego bootloadera, to będzie jego "reset handler", czyli drugi wpis w tablicy wektorów.

    4\/3!!

    0
  • Pomocny post
    #5 27 Lis 2011 18:00
    michalko12
    Specjalista - Mikrokontrolery

    Też skłaniałbym się do wersji 1. Z tym, że dla oszczędności flash z pendriva ładowałbym do ramu plik z kodem, który aktualizowałby flash z innego pliku.

    0
  • #6 27 Lis 2011 18:03
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Jeśli jednak będziesz korzystał z jakichś funkcji "standardowych" to faktycznie lepsza jest opcja druga - mniej problemów, lub opcja pierwsza, tyle że na karcie masz (i ładujesz do RAM) cały projekt bootloadera ze wszystkimi potrzebnymi funkcjami.

    4\/3!!

    0
  • #7 27 Lis 2011 18:50
    markosik20
    Poziom 33  

    Reasumując, czy taka droga będzie poprawna?

    1. Kopiuję plik .bin z nowym wsadem na kartę SD.
    2. Kopiuję cały FatFs do RAM'u (po odchudzeniu zmieści się w 14kB).
    3. Kopiuję funkcję IAP do RAM.
    4. Odpalam IAP z RAM'u.

    I teraz w jaki sposób "zmusić" bibliotekę FatFs aby korzystała ze swoich funkcji/kopii w RAM'ie.
    Jeszcze muszę sprawdzić czy FatFs korzysta z jakiś funkcji bibliotecznych...ale na pierwszy rzut oka takowych nie ma.

    choć

    Freddie Chopin napisał:
    ... lub opcja pierwsza, tyle że na karcie masz (i ładujesz do RAM) cały projekt bootloadera ze wszystkimi potrzebnymi funkcjami.


    jest w sumie niezła choć trzeba zrobić całkowicie nowy projekt który "działał by" z RAM'u.

    0
  • #8 27 Lis 2011 20:07
    michalko12
    Specjalista - Mikrokontrolery

    Co rozumiesz przez pojęcie IAP?
    Żeby cokolwiek uruchomić z RAMu musisz to mieć skompilowane pod ten obszar.

    0
  • #9 27 Lis 2011 21:03
    markosik20
    Poziom 33  

    michalko12 napisał:
    Co rozumiesz przez pojęcie IAP?


    IAP to generalnie funkcja która będzie zapisywać flasha danymi pobranymi z karty SD.

    0
  • #10 27 Lis 2011 21:15
    michalko12
    Specjalista - Mikrokontrolery

    IAP to funkcja w ROM i trzymajmy się tego, żeby nie było potem nieporozumień. Ty chcesz zrealizować funkcję FlashLoadera, który będzie korzystał z IAP.

    0
  • #11 28 Lis 2011 23:38
    markosik20
    Poziom 33  

    Pomysł z skopiowaniem osobnego programu z karty SD do RAM'u i odpalenie go stamtąd udało mi się zaimplementować. Projekt bootloadera grzecznie się uruchomił :D.
    Zastanawia mnie tylko dlaczego assembler rzucał mi się o to:

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    Cytat:
    C:\DOCUME~1\marek\USTAWI~1\Temp\cc3GlMGP.s:6648: Error: invalid constant (2007c000) after fixup
    cs-make: *** [file.o] Error 1


    i musiałem poprawić na:

    Kod: asm
    Zaloguj się, aby zobaczyć kod

    0
  • #12 29 Lis 2011 08:44
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie ma takiej instrukcji (składni):
    MOV R0,0x2007C000
    Można tak załadować stałą która ma max 8bitów + (chyba) opcjonalne przesunięcie. Pozatym brakuje Ci tam znaczka "#" (w "poprawionej wersji tak samo). Generalnie jak chcesz ładować tak duże wartości, to robi się to albo tak jak zrobiłeś w wersji drugiej, albo tak:
    LDR rejestr, =wartosc
    taka konstrukcja "wartosc" umieści gdzież za funkcją i załaduje ją pośrednio ([PC, #offset]).

    Hint: instrukcje wewnątrz "asm" można łączyć mniej więcej tak:
    asm(" \
    instrukcja \n \
    instrukcja \n \
    instrukcja \n \
    ");

    P.S. instrukcjami powyżej przestawiasz AKTUALNY stack-pointer, a pamiętaj, że używane są dwa lub jeden, zależnie od Twojej konfiguracji. Do przestawiania konkretnego SP używać musisz instrukcji "MSR PSP, rX" lub "MSR MSP, rX".

    4\/3!!

    0
  • #13 29 Lis 2011 22:05
    markosik20
    Poziom 33  

    Freddie Chopin napisał:

    P.S. instrukcjami powyżej przestawiasz AKTUALNY stack-pointer, a pamiętaj, że używane są dwa lub jeden, zależnie od Twojej konfiguracji.


    Dzięki za info , jeszcze sobie to sprawdzę i odpowiednio poustawiam.
    Zastanawiam się jeszcze nad jednym problemem jaki może wystąpić tzn. błędem podczas wykonywania aktualizacji flash'a. W takim przypadku pozostaje wgrawanie softu tylko przez fabrycznego bootloadera lub JTAG'a/SWD.
    Gdzieś znalazłem w sieci opis softu który siedzi sobie gdzieś we flash'u, po czym kopiuje się sam do RAM'u i stamtąd wykonuje wgrywanie pliku do flash'a. Tylko tutaj także jest ryzyko że nastąpi błąd podczas aktualizacji akurat tego obszaru w której znajduje się ten nasz "bootloader" .
    Wychodzi na to że żeby nasz bootloader "nie został skasowany" najlepiej umieścić go na stałe we Flash'u i stamtąd odpalać...tylko z drugiej strony skoro nastąpi błąd aktualizacji to i tak nam nici z tego bootloadera....no bo co go uruchomi? :D ...chyba że bootloader będzie zaraz na początku i sprawdzi poprawność flash'a (lub ewentualnie zrobi upgrade jak wykryje plik na SD).
    Sorki za te dziwne wywody.....może trochę na wyrost obawiam się błędów podczas aktualizacji (ale klienci są różni...wystarczy wyłączyć zasilanie podczas upgrade'u..) :D

    0
  • #14 29 Lis 2011 22:22
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Najbezpieczniej jest właśnie tak jak wymyśliłeś - bootloader jest pierwszą rzeczą która uruchamia się zawsze, sprawdza czy jest nowy program do wgrania, sprawdza czy aktualny program jest dobry (jakaś suma kontrolna np.) i następnie go uruchamia. Wtedy jednak Twój "normalny" kod musi być przewidziany do działania z wektorami przerwań pod innym adresem lub w RAM.

    4\/3!!

    0
  • #15 29 Lis 2011 22:42
    markosik20
    Poziom 33  

    Freddie Chopin napisał:
    Najbezpieczniej jest właśnie tak jak wymyśliłeś - bootloader jest pierwszą rzeczą która uruchamia się zawsze, sprawdza czy jest nowy program do wgrania, sprawdza czy aktualny program jest dobry (jakaś suma kontrolna np.) i następnie go uruchamia.


    I też tak na szybko zrobiłem... i całkiem ładnie to funkcjonuje.
    Dopiszę jeszcze w ResetHadler zerowanie całego RAM'u...profilaktycznie :D.
    Czy oprócz przypilnowania tych dwóch Stack Pointer'ów trzeba jeszcze o czymś ważnym pamiętać?

    0
  • Pomocny post
    #16 29 Lis 2011 22:54
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Zakładam, że pytasz o sytuację uruchomienia jednego programu (normalnego) przez drugi (bootloader)? Generalnie dobrze by było, gdyby ten bootloader po sobie sprzątał, tzn np. wyłączał wszystkie układy peryferyjne których używał, doprowadzając całość do stanu jak najbardziej zbliżonego do prawdziwego resetu. Po stronie "normalnego" programu generalnie trzeba tylko pamiętać o tym, że jeden ze SP nie ustawi się "sam", a do tego może być jeszcze zablokowany dostęp do instrukcji MSR z poziomu zwykłego kodu - o NIE-włączanie takiego zabezpieczenia musi zadbać bootloader.

    Swoją drogą to sprawdź czy wymuszenie programowego resetu (jest do tego funkcja w CMSIS) przy przestawionej tablicy wektorów nie spowoduje przypadkiem grzecznego uruchomienia tego "normalnego" kodu - bo istnieje taka szansa (;

    A na koniec małe "IMHO" - IMHO zerowanie RAMu nie ma żadnego sensu, bo co to za różnica co w nim jest? Po resecie zawsze masz w nim jakieś śmieci i niczemu to nie przeszkadza przecież, o ile startup robi to co powinien.

    4\/3!!

    0
  • #17 29 Lis 2011 23:12
    markosik20
    Poziom 33  

    Freddie Chopin napisał:
    Swoją drogą to sprawdź czy wymuszenie programowego resetu (jest do tego funkcja w CMSIS) przy przestawionej tablicy wektorów nie spowoduje przypadkiem grzecznego uruchomienia tego "normalnego" kodu - bo istnieje taka szansa (;


    Niestety wykonanie
    Kod: c
    Zaloguj się, aby zobaczyć kod


    odpala kod od zera.
    Ale i tak jest pełny sukces. Szkoda tylko że nie mogę debugować kodu jednocześnie z projektu bootloadera i właściwego programu.....bo to już by była "Ameryka" :D

    0
  • #18 01 Sty 2012 18:12
    Byron
    Poziom 10  

    Cytat:

    Ale i tak jest pełny sukces. Szkoda tylko że nie mogę debugować kodu jednocześnie z projektu bootloadera i właściwego programu.....bo to już by była "Ameryka" :D


    witam.

    oczywiscie ze mozna debugowac. niech kolega napisze w czym problem, postaram sie pomoc.

    pozdrawiam
    marcin

    0
  • #19 01 Sty 2012 19:04
    markosik20
    Poziom 33  

    Byron napisał:

    oczywiscie ze mozna debugowac. niech kolega napisze w czym problem, postaram sie pomoc.



    No ciekawe jakie masz rozwiązanie na to żeby JTAG (LPCLink) debugował kod jednocześnie z dwóch plików .axf ? Chodzi o to żeby najpierw debugować jeden plik *.axf po czym automatycznie rozpocząć debugowanie drugiego.

    0
  • #20 01 Sty 2012 20:14
    Byron
    Poziom 10  

    markosik20 napisał:
    Byron napisał:

    oczywiscie ze mozna debugowac. niech kolega napisze w czym problem, postaram sie pomoc.



    No ciekawe jakie masz rozwiązanie na to żeby JTAG (LPCLink) debugował kod jednocześnie z dwóch plików .axf ? Chodzi o to żeby najpierw debugować jeden plik *.axf po czym automatycznie rozpocząć debugowanie drugiego.


    witam.

    nie uzywam lpclink i nie znam formatu axf (podejrzewam ze jest to obudowany elf).
    opisze przypadek gdb (front-end moze byc dowolny np. ddd lub eclipse) + openocd.

    odpalasz projekt bootloadera, ladujesz elfa, debugujesz, na koniec ustawiasz breaka na entry point wlasciwej aplikacji.
    odpalasz nowy projekt juz wlasciwej aplikacji i debugujesz spokojnie dalej.
    jesli masz do czynienia z kodem relokowalnym. ladujesz odpowiednie sekcje pod konkretne adresy poleceniem add-symbol-file i jedziesz z koksem dalej.


    pozdrawiam
    marcin

    0
TME logo Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
TME Logo