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

STM32F303 kopiowanie do RAM -

08 Wrz 2015 14:42 1254 13
  • Poziom 9  
    Witam,
    ostatnio zajmowałem się operacją zapisu i odczytu danych z pamięci flash na mojej płytce F3 discovery. Problem pojawił się w momencie próby użycia przerwania generowanego przez timer lub przy restarcie mikroprocesora. Procek wtedy się zwiesza (zapętla się w endless loop w pliku startup_stm32f303xc.s). Zapewne chodzi o to, że operacje na flashu blokują procesor przy próbie wykonania przerwania. W tym celu po skonsultowaniu się z supportem oraz własnym przeszukaniu forów, myślę, że należy skopiować ISR vector oraz funkcje przerwań do pamięci RAM. Nie wiem jak skopiować ten wektor a co do funkcji to znalazłem taką notę: Link
    i w niej jest ładnie opisane kopiowanie kodu do CCM RAM. Postępowałem krok po kroku jak w tej instrukcji (GNU_based toolchain) no i po wgraniu kodu, który się ładnie skompilował program działa, ale oczywiście bez wektora ISR także w RAMie problem pozostał ten sam. Czy ktoś może mi poradzić jak skopiować ten wektor od pamięci RAM?



    mapowanie opisane w punkcie 2.2.4 nie działa mi w takim sensie, że procek wysiada od razu na początku.
  • Poziom 9  
    No dobra, dodałem w pliku startup taki fragment kodu:

    Kod: armasm
    Zaloguj się, aby zobaczyć kod


    Przy deklaracji każdej funkcji w pliku nagłówkowym main oraz stm32f3xx_it.h
    dopisałem:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    w celu wskazania, że ta funkcja ma być zapisana w ccmram


    Na początku funkcji SystemInit() w celu skopiowania wektora przerwan do ramu dodałem 2 linijki:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    No i kompilator wyrzuca mi błędy, że mam złe wartości w funkcji memcpy, bo powinny być kolejno void const void oraz size_t.
    Czy ktoś może mi wytłumaczyć jak argumenty funkcji mogą być typu void?
    Pierwszy raz się z czymś takim spotkałem.

    Prosiłbym o pomoc jak mogę ten wektor skopiować do ramu
  • Użytkownik usunął konto  
  • Specjalista - Mikrokontrolery
    Kiedy już uporasz się z memcpy, nadziejesz się jeszcze prawdopodobnie na dwa poważniejsze błędy.

    Moim zdaniem powinieneś zacząć od zapisu do Flash przy zablokowanych przerwaniach. Jeśli upierasz się na wykonanie kodu z RAM, to naucz się namawiać kompilator i konsolidator do samoczynnego lokowania kodu w RAM - da się to łatwo zrobić uzupełniając deklarację procedury o dyrektywę wymuszenia sekcji.

    W każdym przypadku mususz jednak zadbać o to, by funkcja w RAM nie wołała funkcji z Flash, w tym tzw. "helperów" kompilatora, o których istnieniu i wywoływaniu nawet nie wiesz.
  • Poziom 9  
    Prawda nie wiem. Poradzono mi zmapować wektor przerwań i najlepiej cały kod do RAMu. A mówiąc zapis do pamięci flash ma kolega na myśli zapis dowolnych danych do stron flasha czy mapowanie wektora i funkcji do flasha? Jeśli to pierwsze to mam to już zrobione i działa poprawnie (są to w moim przypadku odczyty z enkodera). Problem jest w momencie, gdy chcę przerwaniem timera zadawać te wartości do sterownika silnika, bo wywołanie przerwania powoduje, że procek staje w default handlerze.

    Czy wykonywanie kodu wyłącznie z flasha (bez kopiowania do RAMu) spowoduje, że te błędy znikną?
    W manualu jest napisane, że jeśli chcę żeby program działał w trakcie operacji na flashu (w tym wypadku odczyt) to MUSZĘ kod skopiować do RAMu

    Asemblera niestety nie znam, więc wszystkie zmiany w linkerze robię "na czuja" i po przeszukaniu forów.
  • Specjalista - Mikrokontrolery
    Program staje wyłącznie na czas ZAPISU do Flash. Być może w ogóle nie potrzebujesz, by program działał w czasie zapisu - wtedy sprawa jest prosta.

    Dziwne rzeczy piszesz, bo wygląda to nie na problem z zapisem do Flash, a na jakiś głupi i prosty błąd, którego jednak bez kodu źródłowego na pewno nie znajdziemy.
  • Poziom 9  
    Nie wiem o co chodzi, support STM mi powiedział, żebym wgrał kod do ramu oraz wektor przerwań.
    Cały problem od początku: Zadanie programu jest następujące:
    ze sterownika sczytuję wartości enkoderów i zapisuję je do pamięci flash. (powinno to być wykonywane timerem co 10ms). Następnie odczytuję te wartości z flasha w celu odtworzenia ruchu i odpowiednie wartości zadaję do sterowania krokiem silnika.

    Kod programu poniżej. W tej chwili nie używam timerów tylko nędznie używam pętli while z odpowiednim counterem. Wszystko z powodu zawieszania procka przy przerwaniach. Same timery działają prawidłowo. Problem pojawia się po udanym zapisie na flash. Wtedy jakiekolwiek wywołanie przerwania powoduje że debugger ląduje w default handlerze (infinityloop) i nic się nie da zrobić, nawet reset nic nie poradzi. Trzeba odpiąć dopiero zasilanie i podłączyć na nowo. Zatem jeśli brak kodu i wektora przerwań w pam. RAM nie jest tego winą to musi być funkcja zapisu do pamięci FLASH, którą pisząc sugerowałem się gotowymi przykładami z oficjalnej strony STM32. Zapis do flasha wykonuję przez buffor wielkości jednej strony flasha. Najpierw wypełniam buffor, a po przepełnieniu wymazuję kolejną stronę flasha i kopiuję buffor.

    Kod: c
    Zaloguj się, aby zobaczyć kod



    Moje środowisko programowania to CubeMX oraz System Workbench for stm32(eclipse z nakładką)
  • Specjalista - Mikrokontrolery
    Pod jakie adresy w pamięci Flash chcesz zapisywać te dane?

    Wyrzuć bezsensowną tablicę "TablicaStron" - przecież każdy jej element to indeks mnożony przez stałą z dodaną stałą. Niepotrzbnie zajmujesz pół kilobajta RAM.

    Zamęczasz też procesor zbędnymi konwersjami z int do float i z powrotem. Po co?
  • Poziom 9  
    tej tablicy używam w trakcie operacji wymazywania strony pamięci flash, nie wiem czemu ale niektóre strony nie dają się zapisać. (funkcja zwiększająca stronę)
    Przy próbie ich zapisu procek się wiesza podobnie jak po użyciu przerwania. Poza tym jest czytelniej.

    Dane chce zapisywać pod kolejnymi stronami pamięci flash zaczynając od 4.
  • Pomocny post
    Specjalista - Mikrokontrolery
    No fakt, kilkadziesiąt linii deklaracji tablicy stałych zadeklarowanych jako zmiennych ajmującej pamięć RAM jest o niebo czytelniejsze niż:

    #define PAGEADDR(n) ((void *)(0x8000000 + (n) * 0x800))

    Parę innych rzeczy też jest dziwnie, np. pisanie Flash stronami zamiast słowami, przekształcenia int na adresy itd.

    Czy jesteś pewny, że nie próbujesz pisać po programie?

    Zgaduję, że błąd polega na złym wyliczeniu adresu przy którejś operacji. Zredukuj kod do < 80 linii, to da się to znaleźć.
  • Poziom 9  
    Zaraz się tym zajmę, jeszcze jedna sprawa. Czy mój TIM3 interrupt handler jest poprawnie napisany?
    Jest to mój pierwszy projekt w STM więc możliwe, że kompilator czegoś nie widzi. Aczkolwiek jeśli jest dobry to wtedy problem w 100% po stronie flasha bo to nie wyjaśnia sprawy zawieszania procesora przy wyłączeniu i włączeniu zasilania po zapisie na flash.
    Flash piszę stronami a nie słowami ponieważ wyczytałem w manualu, że jeśli chcę zapisać jeden rejestr pamięci FLASH to muszę całą stronę wymazać na której się znajduje zanim zechcę zapisać, używanie buffora uważam za lepsze niż ciągłe kopiowanie stron i dodawaniu jednej zmiennej.
  • Poziom 1  
  • Poziom 9  
    Tak, wiem o tej żywotności. Ogólnie mi też się pomysł z tym flashem nie podobał, ale dostałem takie zadanie z góry.
    Ogólnie zapis nie będzie wykonywany w stanie ciągłym, tylko załóżmy raz na tydzień wszystkie komórki zostaną zapisane. Głównym celem jest odtwarzanie ruchu, a przy odczycie rejestrów flash się nie zużywa. Już rozwiązałem problem niedziałających przerwań timera. Naprowadził mnie kolega BlueDraco. Postanowiłem nie wykonywać zapisu od 4 strony tylko o kilka stron dalszej. Już nie mam z tym problemu. Jednak pozostaje kłopot restartu procesora. Po odłączeniu i podłączeniu zasilania Procesor nie odpowiada. Ponadto zmieniłem zapis stron flasha tak jak mi kolega poradził.
  • Poziom 9  
    Problem rozwiązany i temat można zamknąć. Głupi ja nie zastanowiłem się, że mój kod jest taki długi, że zajmował dobre pierwszych 15 stron flasha i tym samym przy próbie zapisu czegoś do pamięci flash moja akcja kończyła się na nadpisaniu kodu programu. Nie trzeba nic mapować do ramu, wystarczy wiedzieć, ile zajmuje kod i do zapisu danych używać odpowiednio dalszej strony flash tak aby nie doszło do konfliktu. Tym samym wszystkie przerwania działają poprawnie.
    Pozdrawiam