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.

stm32 - zapis zmiennych do trwałej pamięci, podczas pracy procesora.

lolonet 05 Gru 2011 13:14 5236 29
  • #1 05 Gru 2011 13:14
    lolonet
    Poziom 11  

    Witam,
    Mam problem z emulowanym eepromem. Główną przyczyną są Gaskoin oraz Freddie Chopin :) gdyż oczywiście racjonalnie namówili mnie do niekorzystania z bibliotek lecz do pracy na rejestrach. Jest to teraz również i według mnie wiele leprze rozwiązanie lecz wiążą się z tym pewne problemy. Na temat tego jak w oparciu o same rejestry zapisywać trwale pewne wartości do pamięci nie potrafił mi pomóc nawet wujek google. A z pliku RM0008 nie daję rady samemu tego rozpracować :(. Mam więc prośbę, czy mógł by ktoś napisać parę linijek kodu realizujący taki trwały zapis ?

    Dziękuję i pozdrawiam serdecznie.

    0 29
  • Computer Controls
  • Computer Controls
  • #3 05 Gru 2011 14:18
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Kiedyś muszę chyba wrzucić do netu moją wersję emulacji EEPROMu dla STM32 jak i inne biblioteki (; Może zrobię to wkrótce (;

    4\/3!!

    0
  • #4 05 Gru 2011 14:48
    lolonet
    Poziom 11  

    Och wrzuć wrzuć :) , bo ja to jeszcze dwa tygodnie będę rozpracowywał.
    tak patrzę na ten plik PM0075 i widzę mnóstwo możliwości konfiguracji pamięci, jakieś zabezpieczenia, organizacja i łapię się za głowę. dwa tygodnie z życia na pewno. Może przy najmniej ktoś opisze kolejno co muszę ustawić i jak wpisywać i odczytywać dane z pamięci ? Widzę tu jakieś rejestry:
    FLASH_ACR
    FLASH_KEYR
    FLASH_OPTKEYR
    FLASH_SR
    FLASH_CR
    FLASH_AR
    FLASH_OBR
    FLASH_WRPR
    i nawet nie potrafię wyłuskać z tego co kolejno i po co konfigurować.
    Freddie - prosił bym o krótki kod z komentarzami co się gdzie ustawia i poco bo bez komentarza to ooo łaaa. Chodzi mi o stworzenie w pamięci tablicy 4095 komórek przechowujących wartości napięć dozwolonych ... :).

    0
  • #5 05 Gru 2011 15:24
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Tyle że ja mam implementację EEPROMu podobną do tej od ST, tyle że przechowującą dowolny rozmiar w jednej "komórce". Moja implementacja jest dobra jeśli masz kilka-kilkanaście-kilkadziesiąt zmiennych do zapisywania w teorii dowolną ilość razy w dowolnej kolejności.

    Jeśli u siebie będziesz przechowywał te wartości razem i np ustawiał je tylko raz (nigdy nie będziesz ich zmieniał), to sprawa jest prostsza, jeśli chcesz je zmieniać to robi się gorzej, a jeśli chcesz zmieniać każdą z osobna, to już w ogóle [;

    Procedura zapisu:
    0. Wyczyścić cała stronę (jesli wyczyszczona, to pomijasz)
    1. Odblokować zapis (dwa wpisy do FLASH->KEYR)
    2. Upewnić się, że flash nie jest "zajęty" - rejestr SR
    3. Właczyć zapis do flasha - FLASH_CR_PG_bb = 1
    4. Dokonać zapisu - normalny zapis jak do zmiennej w RAM, tyle że rozmiar musi być 16-bit
    5. Poczekać na zakończenie - rejestr SR
    6. Wyłaczyć programowanie - FLASH_CR_PG_bb = 0
    7. Zablokować możliwość zapisu - FLASH_CR_LOCK_bb = 1

    To jest wersja najbardziej rozbudowana. Nie ma oczywiście konieczności blokowania/odblokowywania możliwości zapisu przed każdym zapisem itd.

    Postaram się w końcu udostępnić to co tam mam u siebie [;

    4\/3!!

    0
  • #6 06 Gru 2011 01:45
    lolonet
    Poziom 11  

    Oto moje wypociny:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    if((GPIOA->IDR & 0x1) == 0)
    {
    //FLASH->WRPR; //Ochrona zapisu jest standardowo nie włączona. Więc nie dotykam jej.
    FLASH->CR |= 1<<1; //PER: Page erase //Ustawiam czyszczenie strony.
    FLASH->CR |= 1<<6; //START - Wywołóje operację kasowania.
    //FLASH->ACR |= 1<<4; //Prefetch buffer enable //Załącza jakiś dozorujący bufor, ale niewiem po co.
    //FLASH->ACR |= 2<<0; //010 Two wait states, if 48 MHz < SYSCLK . 72 MHz //Załącza jakieś opóźnienie dla mojej częstotliwości 72MHz, lecz też niewiem po co miał bym tego użyć więc nie używam.
    //FLASH->KEYR |= 3<<0; //Odblokowuję zapis jednorazowy na bitach 0 i 1 dla jakiegoś FPEC - niewiem co to :(;
    //Ustawia się tu wartość klucza odblokowującego zapis do pamięci flash. //Być może że jak to ustawię to jóż nigdy nie zaprogramuję tego procka przy użyciu tylko JTAG !! :).
    //FLASH->CR |= 1<<7; //Jeśli damy tu 1, to zapis do pamięci będzie zablokowany do czasu wykrycia sekwencji bodajże zawartej w FLASH->KEYR.
    while(FLASH->SR & 1<<0); //Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR |= 1<<0; //Właczam zapis do flasha.
    d = 15; //zapisuję coś sobie do zmiennej short int d - bo to procek 32 bitowy więc d będie miało 16 bitów :).
    while(FLASH->SR & 1<<0); //Sprawdzam czy flash nie jest zajęty, czy skończył zapis ... . //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR |= 0<<0; //Wyłaczam zapis do flasha.
    //FLASH->CR |= 1<<7; //Jeśli damy tu 1, to zapis do pamięci będzie zablokowany do czasu wykrycia sekwencji bodajże zawartej w FLASH->KEYR.
    //Ja ani nie odblokowuję ani nie blokuję bo jak zablokuję i nie odblokuję to procka muszę przelutować :).
    }
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie działa mi to za bardzo. Myślę, że źle czyszczę stronę. Niewiem ale wydaje mi się że adres do wyczyszczenia ostatnio używanej strony powinienem brać z FLASH_AR. Jest tam napisane : "Updated by hardware with the currently/last used address. For Page Erase operations, this
    should be updated by software to indicate the chosen page."

    Hmm, Jak poprawnie to zrobić ?
    Pozdrawiam.

    0
  • #7 06 Gru 2011 08:59
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie wiem skąd pomysł, że po resecie flash jest odblokowany do zapisu, skoro tak nie jest...

    No i ustaw jakiś adres tej strony, a zapisu dokonaj pod konkretnym adresem np. przez wskaźnik, bo tak jak masz pokazane to coś czuję, że program przestanie Ci zaraz działać po tym kasowaniu...

    Zawsze jak coś Ci nie działa, a można odczytać jakieś flagi, to po prostu je przejrzyj - odpowiedź zwykle jest własnie tam.

    4\/3!!

    0
  • #8 06 Gru 2011 22:03
    kemot55
    Poziom 30  

    Zdecydowanie w rejestrze SR procesor zapisuje wszystko co go boli a również poprawność operacji. Zapis do flash'a jest dość mocno "strzeżony" i jeżeli pominiesz coś po drodze to się skończy odmową ( a czasem procesor może "polecieć"do wyjątku). Akurat w przypadku obsługi tej pamięci można podejrzeć biblioteki standardowe ST.
    A tak na marginesie to bez podania sekwencji

    Kod: c
    Zaloguj się, aby zobaczyć kod
    niczego z pamięcią nie zrobisz (oprócz odczytu)
    Poza tym kolega Freddie Chopin dał Ci przepis (skuteczny) punkt po punkcie i jak nie będziesz "kombinował" to wszystko będzie OK :-)

    0
  • #9 07 Gru 2011 01:40
    lolonet
    Poziom 11  

    Co oznacza to że mam czegoś szukać we flagach - co to flagi?

    Niestety nie poradziłem sobie jeszcze z zapisaniem zmiennej na stałe w pamięci.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod


    half-world - może tu powinienem pogmerać ?

    Wydaje mi się, że tym razem dobrze czyszczę stronę i dobrze odblokowuję pamięć.
    Niestety zmienna d nie ma żadnej wartości po ponownym załączeniu zasilania do procesora, i ponadto jak już jej nadam wartość to zostaje nadpisywana przez inne peryferia mikro kontrolera.

    0
  • #10 07 Gru 2011 08:25
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Przecież te zmienne są w RAMie, więc czego się spodziewasz?

    No i dalej kombinujesz i to ostro...
    1. Flash trzeba odblokować przed KAŻDĄ operacją - niby czemu miałby Ci pozwolić kasować strony bez odblokowywania?
    2. Stronę wybrałes na chybił-trafił w istocie - masz 90% szansy, że po skasowaniu jej Twój program natychmiast przestanie działać. Jeśli tak się nie stanie, to tylko przypadkiem. Nie jest chyba szczególnie mądre kasowanie strony NA POCZĄTKU flasha...
    3. No i te zmienne w RAM...

    4\/3!!

    0
  • #11 07 Gru 2011 11:33
    lolonet
    Poziom 11  

    Rzeczywiście program wychacza po skasowaniu strony - próbowałem kasować dwusetną stronę i to samo.
    Jak w takim razie wybrać odpowiednią stronę do skasowania ?
    Jak zapisać zmienną na stałe - sugerowałeś podać adres przez wskaźnik.
    Rzeczywiście program wychacza po skasowaniu strony - próbowałem kasować dwusetną stronę i to samo.

    0
  • #12 07 Gru 2011 12:01
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Rzeczywiście program wychacza po skasowaniu strony - próbowałem kasować dwusetną stronę i to samo.

    Może nie rób tego na ślepo, masz aby dwusetną stronę pamięci u siebie? Coś wątpię...

    Cytat:
    Jak zapisać zmienną na stałe - sugerowałeś podać adres przez wskaźnik.

    Ale adres we flashu, a Ty podajesz adres zmiennej d, która jest w RAM...

    4\/3!!

    0
  • #13 07 Gru 2011 19:27
    lolonet
    Poziom 11  

    Czy poprzez podanie adresu zmiennej która jest we flash'u rozumiesz podanie adresu zmiennej utworzonej w ten sposób? volatile short int d; volatile short int *c = &d;

    Jak mam się dowiedzieć jaki numer strony muszę podać do skasowania?
    Po podaniu 50 strony program nie wychacza ale to przypadek.
    FLASH->AR = 0x08028800;

    0
  • #14 07 Gru 2011 20:34
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Czy poprzez podanie adresu zmiennej która jest we flash'u rozumiesz podanie adresu zmiennej utworzonej w ten sposób? volatile short int d; volatile short int *c = &d;

    Żadna z tych zmiennych nie jest we flashu ani nie zawiera adresu znajdującego się we flashu.

    lolonet napisał:
    Jak mam się dowiedzieć jaki numer strony muszę podać do skasowania?

    Generalnie nie masz się "dowiedzieć" tylko powinieneś to "wiedzieć" [;

    4\/3!!

    0
  • #15 12 Gru 2011 12:01
    lolonet
    Poziom 11  

    Witam,
    Doszedłem do tego - w jaki sposób kasować strony. Mam 128KB pamięci flash która jest podzielona na 128 stron po 1024B każda. tak więc numer ostatnirj strony to 127. Aby skasować stronę, do rejestru FLASH->AR = 0x0801FC00; podajemy adres którego kolwiek bajtu zawierającego się w tej stronie, nie koniecznie pierwszego !!!! Bardzo ładnie mi to działa.
    Problem natomiast pojawia się gdy próbuję zapisać coś do pamięci flash.
    Robię to tak, że tworzę wskaźnik
    short int *c;
    potem karzę mu wskazywać na adres w pamięci flash do którego chcę zapisać dane
    c = 0x0801FC00; <- i tu sie pluje kompilator więc robię tak :
    c = (int16_t*)0x0801FC00;
    potem zapisuję jakąś liczbę pod wskazany adres:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    a potem każę mu wyświetlić wartość na którą wskazuje *c.
    W rezultacie wartość pamięci na którą wskazuje *c nie zostaje zmieniona.
    Wtedy robię reset systemu i jeszcze raz próbuję zapisać wartość do pamięci i się udaje. Przed każdą podobną operacją taką jak zapis czy kasowanie czegoś w pamięci flash muszę resetować procka.
    Znalazłem, że po restarcie w rejestrze FLASH_WRPR strony są poustawiane na 1 co oznacza, odblokowanie zapisu lub odczytu danej strony. Problem w tym, że po przeprowadzeniu operacji na przykład zapisu czegoś w danej stronie - bit odpowiadający tej stronie w rejestrze FLASH_WRPR zmienia się automatycznie na 0 a jedynym sposobem na jego ustawienie w stan 1 jest reset procka.
    Czy mógł by mi ktoś pomóc poprawnie zmienić wartość na którą wskazuje *c w pamięci flash bes resetowania procesora ?
    Pozdrawiam.

    0
  • #16 14 Gru 2011 00:03
    lolonet
    Poziom 11  

    O.K. Sam sobie poradziłem z problemem :).

    Sprawa z zapisem danych na pamięć flash tak aby po ponownym załączeniu zasilania dane tam wciąż były (EMULACJA PAMIĘCI EEPROM) okazuje się być bardzo skomplikowana. He pewnie dlatego nikt na forum nie wiedział ;).

    Zacznijmy od tego, że jeśli chcemy zapisać coś do pamięci flash to musimy dokładnie wiedzieć pod jakim adresem w tej pamięci chcemy daną liczbę zapisać. Opiszę całą sytuację na tym co obecnie tresuję czyli STM32F103VBT6 , Cortex M3 , 128KB MAIN FLASH , 2KB SRAM. Ten procesor ma organizację pamięci poukładaną zgodnie z tak zwanym (medium-density devices) czyli mając 128 Kilobajtów pamięci "Main memory flash" ma 128 stron (sektorów, klastrów) - każda po 1024 Bajty. PAGE 0 do PAGE 127. Cała adresacja jaką dysponują rdzenie M3 jest rozmieszczona na przestrzeni czterech gigabajtów czyli 4GB = 4294967295 Bajtów = 0xFFFF FFFF Bajtów. Tak więc adres od którego poczynają :) się strony to 0x0800 0000. Jeśli więc jedna nasza strona ma (1024B czyli 0x400B w hex'ie) to pierwsza strona PAGE 0 będzie umieszczona w pamięci w adresie pomiędzy 0x0800 0000 a 0x0800 03FF, druga PAGE 1 : 0x0800 0400 do 0x0800 07FF i tak dalej aż do końca pamięci flash czyli PAGE 127 : 0x0801 FC00 do 0x0801 FFFF.
    Jest to fajnie pokazane w dokumentacji mikro kontrolera RM0008.
    Pamięć flash jest o tyle trudna w obsłudze, że nie wolno nam skasować pojedynczego bajtu lecz musimy skasować całą stronę. Zapisywać nie wolno nam w ten sam bajt więcej jak jeden raz bez ponownego skasowania danego obszaru przed kolejnym zapisem. Nie wolno nam zapisywać jednokrotnie mniej ani więcej jak 16 Bajtów. Oprócz tego pamięć flash jest tak chroniona przed zapisem jak TROJA z mitologi. a każda próba przechytrzenia kontrolera FPEC kończy się resetem procesora.
    Aby więc skasować jakąś jedną wartość - stosujemy trick taki, że zczytujemy zawartość całej strony we flash'u, modyfikujemy odpowiednie wartości, kasujemy całą stronę i wgrywamy na nowo już zmodyfikowane dane po kolei oczywiście po 16 Bajtów. He sprawa już wydaje się byś skomplikowana - ale to dopiero początek jazdy :) . Całym tym operacjom musi towarzyszyć mnóstwo zabiegów odblokowujących dostęp do pamięci.
    Na pierwszy rzut moje kasowanie strony - podajemy do rejestru FLASH->AR adres który zawiera się w tej stronie (nie koniecznie pierwszy ze strony). Poprzedzamy tę operację zapisem pewnej ściśle określonej sekwencji klucza do rejestru FLASH->KEYR odblokowującej zapis.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    O.K. Teraz pokażę w jaki sposób zapisać wartość do wskazanego miejsca w pamięci, ale to będzie działało tylko jednokrotnie dla jednej wartości - potem pamięć się blokuje na amen i kolejną wartość będzie można dopiero zapisać po restarcie mikro kontrolera (chyba, że dodamy jeszcze trochę kodu który zamieszczę poniżej - do odblokowania zapisu stron) . Najpierw pamiętamy, że zapisać można nam tylko 16 Bajtowe wartości. Tworzymy więc wskaźnik :
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Potem każemy mu wskazywać na miejsce w pamięci - gdzie chcemy zapisać daną. Ja zapisuję do ostatniej strony na jej pierwsze bajty:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Potem przeprowadzamy całą procedurę zapisu pamiętając o wcześniejszym skasowaniu strony do której cokolwiek próbujemy zapisać :
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Jeśli spróbujemy przydzielić jeszcze jakieś wartości zaraz pod tą linią "*j = 1;" to procek się zresetuje. taką procedurę jak tu powyżej stosujemy zawsze jak coś wpychamy do flash'a.
    Teraz pokażę kawałek kodu który trzeba dokleić na początku programu poto by odblokować zapis danych do stron - by nie trzeba było resetować procesora celem odblokowania jednokrotnego zapisu:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Kod: c
    Zaloguj się, aby zobaczyć kod

    I w ten oto cudowny sposób problem zapisu danych do flash'a zażegnany.
    Jest jeszcze jeden mądry ale według mnie zubożony sposób zmiany zawartości pamięci flash - Trzeba przenieść program do pamięci SRAM żeby z tam tond się wykonywał i wtedy można swobodnie zmieniać dane na flash, tyle że SRAM ma tylko 2KB i przeszkadza nam taka operacja w działaniu innych rzeczy.

    Kurcze - kawał artykułu mi wyszedł :) ale czułem, że jest to trudny i nie okiełznany temat do teraz, na problem którego trafia wiele osób a jedyne rozwiązanie to paskudne biblioteki :). Mam nadzieję, że pomogłem nie jednemu programiście w potrzebie, i że nie narobiłem zbyt wielu błędów przy analizie tych rejestrów. Czekam jeszcze na uwagi - może ktoś coś poprawi :)

    Pozdrawiam i powodzenia. :D

    0
  • #17 14 Gru 2011 08:18
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Cytat:
    Zapisywać nie wolno nam w ten sam bajt więcej jak jeden raz bez ponownego skasowania danego obszaru przed kolejnym zapisem.

    Można zapisywać wielokrotnie, ale jedyne co może się stać to zmiana 1 na 0 - jeśli na danym bicie było już 0, to dalsze zmiany nie są możliwe.

    Rzutujesz wskaźnik na int16_t, a zmienna uparcie jest "short int" - po co?

    No i w Option Byte'ach wcale nie musisz przywracać zabezpieczenia zapisu - ono domyślnie jest wyłączone, nie jest konieczne do czegokolwiek.

    4\/3!!

    0
  • #18 14 Gru 2011 10:36
    lolonet
    Poziom 11  

    Tak wiem, że nie muszę przywracać zabezpieczenia, tylko spróbowałem ale się nie udało :).

    Freddie Chopin napisał:
    Rzutujesz wskaźnik na int16_t, a zmienna uparcie jest "short int" - po co?

    Bo tylko tak działa! Nie wiem jak inaczej mogę to zrobić ?

    0
  • #19 14 Gru 2011 11:06
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Chodzi mi o to, że zmienna też mogłaby być int16_t i nie trzeba się wtedy zastanawiać czy aby na pewno ma 16-bitów.

    A z option bytes chodzi mi o to, ze ja u siebie mogę zapisać jedną zmienną jak i sto - nie muszę robić żadnych dziwnych kroków, ponieważ nigdy nie włączałem zabezpieczeń w option bytes czy gdziekolwiek indziej - po prostu flash jest albo odblokowany, albo zablokowany.

    4\/3!!

    0
  • #20 14 Gru 2011 12:34
    lolonet
    Poziom 11  

    Ja nie tworzę żadnej zmiennej tylko wskaźnik któremu każę wskazywać na pewien adres.

    Fredie :) dziewięć dni temu prosiłem cię oto żebyś wkleił ten kawałek pierońskiego kodu na forum i się doczekałem tylko kilku krotnego chwalenia się tym, że go masz i że jest taki genialny ... . Pamięć jest odblokowana do zapisu tylko jednokrotnego i to zaraz po resecie. Potem po pierwszym zapisie się modyfikuje WRPR i trzeba wykonać procedurę odblokowania pamięci. Więc ja tę procedurę wykonuję przy starcie procka i już mogę zapisywać do pamięci setki razy tak jak ty. Nie wydaje mi się żeby dało się to osiągnąć bez tego kawałka kodu na starcie.
    Nie obraź się na mnie ale siedziałem nad tym problemem po piętnaście godzin dziennie przez 8 dni wiedząc, że jakiś koleś chwali się na forum, że to zrobił ale trzyma to dla siebie bo musi się mieć czym podbudowywać :).

    Pozdrawiam.

    0
  • #21 14 Gru 2011 13:16
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Ja nie tworzę żadnej zmiennej tylko wskaźnik któremu każę wskazywać na pewien adres.

    Ten wskaźnik może być chyba typu int16_t, czy nie?

    Cytat:
    Fredie :) dziewięć dni temu prosiłem cię oto żebyś wkleił ten kawałek pierońskiego kodu na forum i się doczekałem tylko kilku krotnego chwalenia się tym, że go masz i że jest taki genialny ... .

    Nigdzie się nie chwaliłem i nigdzie nie pisałem, że jest genialny. Nie zwykłem wrzucać kodu na forum, zwłaszcza przy takim podejściu. Napisałem do czego może się taki kod nadać, a do czego się nie nada na pewno - nie sprecyzowałeś jakie jest Twoje zastosowanie. Napisałem, że jest to rozwiązanie bardzo zbliżone do rozwiązania z ST, przedstawionego szczegółowo w odpowiedniej nocie aplikacyjnej, zacytuj może to chwalenie się kodem i genialnością, sam poczytam chętnie.

    Cytat:
    Pamięć jest odblokowana do zapisu tylko jednokrotnego i to zaraz po resecie.

    Nieprawda.

    Cytat:
    Potem po pierwszym zapisie się modyfikuje WRPR i trzeba wykonać procedurę odblokowania pamięci.

    Nieprawda.

    Cytat:
    Więc ja tę procedurę wykonuję przy starcie procka i już mogę zapisywać do pamięci setki razy tak jak ty.

    Ta procedura jest potrzebna, bo masz coś gdzieś pomieszane, np włączyłeś zabezpieczenia flasha, których włączać nie trzeba.

    Cytat:
    Nie wydaje mi się żeby dało się to osiągnąć bez tego kawałka kodu na starcie.

    No to najwidoczniej kilka moich programów nie ma prawa działać, a jednak...

    Cytat:
    Nie obraź się na mnie ale siedziałem nad tym problemem po piętnaście godzin dziennie przez 8 dni wiedząc, że jakiś koleś chwali się na forum, że to zrobił ale trzyma to dla siebie bo musi się mieć czym podbudowywać :).

    Napisałeś coś o mnie w pierwszym poście, to się odezwałem, powiedziałem, że kiedyś muszę wrzucić to co mam i tyle. Nie wiem w którym miejscu widzisz jakieś "podbudowywanie się" czy cokolwiek, ale widzę że zupełnie niepotrzebnie odpowiadałem na Twoje wątpliwości rozwiązując tym samym Twoje problemy (pięć raz pod rząd? czy źle policzyłem?), bo tego już nie zauważyłeś, a tylko jakieś "chwalenie się" i "obnoszenie się genialnością".

    A że siedziałeś nad tym 15h przez 8 dni... Może zamiast "siedzieć" wystarczyło pomyśleć i zrealizować po prostu punkty które przedstawiłem w jednym z pierwszych swoich postów? Bez kombinowania (widocznego w każdym poście), omijania pewnych kroków i innych czarodziejskich sztuczek? Może zamiast strzelać na ślepo (skasowałem pierwszą stronę flasha [gdzie jest program], skasowałem dwusetną stronę flasha [której nie ma - czemu nie od razu stutysięczną?], ...) wystarczyło przeczytać dokładnie dokumentację, zrobić tak żeby działało i dopiero potem kombinować?

    P.S. Zapomniałem dodać, że udostępnienie mojego kodu to nie jest "wklejenie kawałka kodu", tylko większy problem, bo jeden plik zależy od drugiego, drugi od trzeciego itd. Nie wszystkie nadają się do wrzucenia "od razu", nie mam teraz czasu się tym zająć. Proste.

    4\/3!!

    0
  • #22 14 Gru 2011 14:06
    lolonet
    Poziom 11  

    Poprzez chwalenie się rozumiałem to, że po prostu mówiłeś, że to masz i że potrafi to :

    Freddie Chopin napisał:
    tyle że przechowującą dowolny rozmiar w jednej "komórce". Moja implementacja jest dobra jeśli masz kilka-kilkanaście-kilkadziesiąt zmiennych do zapisywania w teorii dowolną ilość razy w dowolnej kolejności.
    Gdybyś mi to wkleił to bym to zrobił w jeden dzień no ale co racja to racja - każdy może nie mieć czasu, ja tak samo.
    Problem w tym, że nigdzie nie włączam żadnego zabezpieczenia zapisu stron. Znajomy również nie włączał i miał identyczny problem. Hmm może mamy inne procki i dlatego ty nie potrzebujesz nic kombinować ?
    Freddie Chopin napisał:
    Ten wskaźnik może być chyba typu int16_t, czy nie?

    Przecież jest typu int16_t bo to to samo co short int bo też 16 bit rezerwuje w pamięci, czy się mylę ?

    1
  • #23 14 Gru 2011 14:29
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Hmm może mamy inne procki i dlatego ty nie potrzebujesz nic kombinować ?

    Przypuszczam nawet, że masz innego procka niż inżynierowie z ST, bo u nich aby jakiekolwiek zmiany w option bytes weszły w życie potrzebny jest RESET układu (programowy), czego Ty nie robisz (a przynajmniej ani słowa o tym nie ma w Twoim poście), więc...

    Cytat:
    2.4.2 Write protection
    [...]
    Unprotection
    To disable the write protection, two application cases are provided:
    ● Case 1: Read protection disabled after the write unprotection:
    – Erase the entire option byte area by using the OPTER bit in the Flash memory
    control register (FLASH_CR)
    – Program the correct RDP code 0x00A5 to unprotect the memory. This operation
    first forces a Mass Erase of the main Flash memory.
    – Reset the device (system reset) to reload the option bytes (and the new WRP[3:0]
    bytes), and to disable the write protection

    ● Case 2: Read protection maintained active after the write unprotection, useful for inapplication
    programming with a user bootloader:
    – Erase the entire option byte area by using the OPTER bit in the Flash memory
    control register (FLASH_CR)
    – Reset the device (system reset) to reload the option bytes (and the new WRP[3:0]
    bytes), and to disable the write protection.


    Jak chcesz sprawdzić, czy masz takie zabezpieczenie, to połącz się z bootloaderem (przez UART) i w programiku od ST sobie zobaczysz czy jest takie zabezpieczenie włączone czy nie. Wyłącz je tam i problem z głowy na zawsze.

    lolonet napisał:
    Przecież jest typu int16_t bo to to samo co short int bo też 16 bit rezerwuje w pamięci, czy się mylę ?

    short int MOŻE mieć 16-bitów, ale wcale nie musi - jest to zależne od implementacji.

    4\/3!!

    0
  • #24 15 Gru 2011 01:20
    lolonet
    Poziom 11  

    Hmm, ciekawe gdzie się mijamy w toku rozumowania :).

    Freddie Chopin napisał:
    Przypuszczam nawet, że masz innego procka niż inżynierowie z ST, bo u nich aby jakiekolwiek zmiany w option bytes weszły w życie potrzebny jest RESET układu (programowy), czego Ty nie robisz (a przynajmniej ani słowa o tym nie ma w Twoim poście)
    He He procka to na pewno mam innego niż inżynierowie z ST :) ale problem trwałego zapisu danych dość często w końcu dopada programistów a ja napisałem na forum kod który ten problem rozwiązuje czyli DZIAŁA ! jeśli nie kazałem prockowi się zresetować to zapewne dlatego, że jest to zbędne a przeszkadzające. Proszę zauważyć również, że MASS ERASE także nie wykonuję :).
    Freddie Chopin napisał:
    Jak chcesz sprawdzić, czy masz takie zabezpieczenie, to połącz się z bootloaderem (przez UART) i w programiku od ST sobie zobaczysz czy jest takie zabezpieczenie włączone czy nie. Wyłącz je tam i problem z głowy na zawsze.
    pomysł ciekawy zresztą pisałeś już gdzieś na forum o tym lecz mnie nie może to rozwiązanie zadowolić gdyż jak mam jeden procesor na stole operacyjnym :) to pomoże ale jak będzie wypuszczane setki modułów na rynek to nie mogę kazać technikom 10 razy podłączać jednej płytki pod kompa. Dopuszczam tylko wpięcie kilku pinów i kliknięcie F8 celem wgrania softu i następny moduł i następny. Potem i tak trzeba przeprowadzać testy na każdym module. Tzw. masówka :).
    rzeczywiście rejestr OB->RDP ma ciągle wartość A5 lecz bez tego kawałka kodu nie zapiszę wielokrotnie nic do flasha:
    lolonet napisał:
    WRPR = FLASH->WRPR;
    useroptionbyte = FLASH->OBR >> 2;//User Option Byte ( STDBY STOP SW )
     
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->OPTKEYR = 0x45670123;//Podobno jak taką sekwencją zapiszę klucz, to się odblokuje jednorazowo zapis do flasha wartości na stałe.
    FLASH->OPTKEYR = 0xCDEF89AB;//Odblokowuję zapis do flasha tą sekwencją zapisu.
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR |= 0x00000020; //CR_OPTER_Set
    FLASH->CR |= 0x00000040; //CR_STRT_Set // kasujemy option byte
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR &= 0x00001FDF; //clear bit 'OPTER'
    FLASH->CR |= 0x00000010; //CR_OPTPG_Set //Enable the Option Bytes Programming operation
    OB->RDP = 0x00A5; //RDP is 0xA5 //Enable the readout access
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR &= 0x00001FEF; //clear bit 'OPTPG'

    +
    lolonet napisał:
    FLASH->OPTKEYR = 0x45670123;
    FLASH->OPTKEYR = 0xCDEF89AB;
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR |= 0x00000010; /* Enable the Option Bytes Programming operation */
    OB->USER = useroptionbyte | (uint16_t)0xF8; //User Option Byte Config
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty. //Jeśli jest to będzie się kręcić pętla i kręcić.
    FLASH->CR &= 0x00001FEF;/* disable the OPTPG Bit */

    i nie jestem w stanie bez tego ruszyć.

    Freddie Chopin napisał:
    short int MOŻE mieć 16-bitów, ale wcale nie musi - jest to zależne od implementacji.
    mikrokontroler stm32f103vbt6 jest 32 bitowy czyli int rezerwuje sobie 32 bity w pamięci a short int 16 bitów wedłóg kompilatorów z których ja kożystałem do tych czas :) . czyli short int a; gdzie a może przybrać wartości od -32 768 do 32767 :).

    Pozdrawiam :).

    0
  • #25 15 Gru 2011 08:45
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    napisałem na forum kod który ten problem rozwiązuje czyli DZIAŁA

    Dodajmy jednak, że jest to "problem", który sam sobie stworzyłeś mieszając coś w tych option bytes wcześniej.

    lolonet napisał:
    mnie nie może to rozwiązanie zadowolić gdyż jak mam jeden procesor na stole operacyjnym to pomoże ale jak będzie wypuszczane setki modułów na rynek to nie mogę kazać technikom 10 razy podłączać jednej płytki pod kompa

    Dziwnym trafem okoliczności w moich projektach ("setki sztuk") nie jest to konieczne, bo zabezpieczenie zapisu domyślnie jest WYŁĄCZONE, option bytes domyślnie są czyste, a u Ciebie problem jest jednostkowy bo coś tam pomieszałeś, a wyciągasz wnioski które uważasz za uniwersalne. Może się wręcz okazać, że jak zaczniesz już klepać te setki sztuk, to nie zadziałają z Twoim kodem, bo wykonujesz kroki które w ogóle nie zgadzają się z dokumentacją...

    lolonet napisał:
    nie jestem w stanie bez tego ruszyć

    Skoro uparcie nie chcesz wyczyścić option bytes i zabezpieczenia zapisu porządnie, to nie ma się co dziwić...

    Miej świadomość, że rozwiązujesz OBJAW zamiast PROBLEMU. Dodatkowo Twoje rozwiązanie nie jest zgodne z dokumentacją. No ale wybór jest Twój.

    4\/3!!

    0
  • #26 16 Gru 2011 01:26
    lolonet
    Poziom 11  

    Sprawdziłem to i zwracam honor freddie :) , po poprawnym skonfigurowaniu optionbytes - a można to zrobić w ten sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Potem po takiej funkcji należy zresetować procesor, a można tego dokonać na przykład konfigurując wathdog IWDG i walnąć po tej funkcji pętelką while(1); żeby watchdog się nie odświeżył i aby nastąpił reset.

    Zapis do flash'a śmiga potem na danym procku, a można go wykonywać w ten sposób : który zresztą już wyżej opisywałem :). Gdzie *j wskazuje na docelowy adres we flash'u.
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Che fajna batalia, zawsze to się człowiek czegoś nauczy a myślę, że ta rozmowa nie jednemu się przyda i rozjaśni problemy związane z zapisem do flash'a :).

    Wesołych świąt i szczęśliwego, mikrokontrolerowego, nowego roku :).

    0
  • #27 16 Gru 2011 07:57
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Potem po takiej funkcji należy zresetować procesor, a można tego dokonać na przykład konfigurując wathdog IWDG i walnąć po tej funkcji pętelką while(1); żeby watchdog się nie odświeżył i aby nastąpił reset.

    Na Cortexach możesz wykorzystać specjalny rejestr, który umożliwi Ci reset procka. W CMSIS jest do tego udostępniona funkcja NVIC_SystemReset() z nagłówka core_cm3.h.

    4\/3!!

    0
  • #28 16 Gru 2011 12:15
    lolonet
    Poziom 11  

    Tak tak, procka można zresetować na wiele sposobów.
    Abstrahując od bibliotek i tego się starajmy trzymać :) :
    SCB->AIRCR = 0x05FA0000 | (u32)0x04; //I system się resetuje na łeb na szyję :).

    0
  • #29 16 Gru 2011 12:20
    Freddie Chopin
    Specjalista - Mikrokontrolery

    lolonet napisał:
    Abstrahując od bibliotek i tego się starajmy trzymać

    Biblioteki od ST są lewe. Biblioteka CMSIS od ARM jest dobra. [;

    4\/3!!

    0
  • #30 16 Gru 2011 22:43
    lolonet
    Poziom 11  

    No myślę, że rozwiązaliśmy problem dostatecznie go podsumowując, także zamykamy.
    A ja dziękuję za zagorzałą :) dyskusję.
    Pozdrawiam.

    Temat okazał się być niedostatecznie rozwiązany gdzyż funkcje nie działały poprawnie.

    A oto 100% działające kody do obsługi flash:

    Wyłączenie zabezpieczenia zapisu wybranych oczywiście grup stron :

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kasowanie wybranej strony :

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zapis danych do pamięci:

    Deklaracje wcześniej :

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod


    Pozdrawiam.

    3