logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak odblokować pamięć Flash w STM32 Cortex M3 po jednej operacji?

lolonet 14 Mar 2012 16:53 3713 16
REKLAMA
  • #1 10676725
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Witam,
    Mam problem z odblokowaniem pamięci Flash do zapisu.
    sekwencja:
    FLASH->KEYR = 0x45670123;
    FLASH->KEYR = 0xCDEF89AB;
    Działa na pewno dobrze, na co wskazuje Lock (FLASH->CR & 0x80).
    Pozwala mi to na przeprowadzenie tylko jednej operacji na flash'u, na przykład mogę skasować jakąś stronę czy zapisać jakąś daną. Problem pojawia się gdy chcę wykonać kolejną operację, aby tego dokonać muszę zresetować procesor !

    Rejestr FLASH->WRPR wciąż zawiera same jedynki, czyli utrzymuje blokade dla wszystkich stron.

    Programem ST-Link Utility - Target>Option Bytes wyłączam zabezpieczenie wszystkich stron lecz rejestr FLASH->WRPR pozostaja bez zmian 111111...

    Kombinowałem również z Option byte gdzie prubowałem zapisać wartość klucza 0xA5 lecz to również nie odblokowuje pamięci.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Proszę o pomoc bo naprawdę rozgryzam ten temat od dłóższego czasu i skończyły mi się pomysły.
    Pozdrawiam.
  • REKLAMA
  • #2 10676792
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Zamiast go rozgryzać po prostu przeczytaj dokumentację.

    Cytat:
    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.


    4\/3!!
  • REKLAMA
  • #3 10677016
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Tak,
    próbowałem na wiele sposobów.
    Według tego tekstu z dokumentacji wynikało by, że mój przypadek to ten drugi,
    czyli po odblokowaniu zapisu pamięć nadal jest chroniona.

    Robię więc tak jak sugerują po kolei :

    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty.
    FLASH->CR |= 1<<5; //CR_OPTER_Set
    FLASH->CR |= 1<<6; //CR_STRT_Set Wywołuję kasowanie option byte.
    i resetuję procesor klawiszem rst.
    niczego to nie zmienia.

    Próbowałem również dostosować się do przypadku pierwszego:

    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty.
    FLASH->CR |= 1<<5; //CR_OPTER_Set
    FLASH->CR |= 1<<6; //CR_STRT_Set //kasuję option byte
    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty.
    FLASH->CR |= 0<<5; //clear bit 'OPTER'
    FLASH->CR |= 1<<4; //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.
    FLASH->CR |= 0<<4; //clear bit 'OPTPG'

    i reset systemu - także w różny sposób próbowałem zresetować procesor.

    I nic się nie zmienia - tak jak mogłem bez resetowania dokonać tylko jednej operacji na pamięci flash tak jest dalej.
  • #4 10677454
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    lolonet napisał:
    Robię więc tak jak sugerują po kolei :

    while(FLASH->SR & 1<<0); //BSY: Sprawdzam czy flash nie jest zajęty.
    FLASH->CR |= 1<<5; //CR_OPTER_Set
    FLASH->CR |= 1<<6; //CR_STRT_Set Wywołuję kasowanie option byte.
    i resetuję procesor klawiszem rst.
    niczego to nie zmienia.

    A w dokumentacji reszta pominiętych kroków:

    Cytat:
    Erase procedure
    The option byte erase sequence (OPTERASE) is as follows:
    ● Check that no Flash memory operation is ongoing by reading the BSY bit in the
    FLASH_SR register
    ● Unlock the OPTWRE bit in the FLASH_CR register
    ● Set the OPTER bit in the FLASH_CR register
    ● Set the STRT bit in the FLASH_CR register
    ● Wait for BSY to reset
    ● Read the erased option bytes and verify


    lolonet napisał:
    FLASH->CR |= 0<<5; //clear bit 'OPTER'

    lolonet napisał:
    FLASH->CR |= 0<<4; //clear bit 'OPTPG'

    Operacje te na pewno nie robią tego co masz w komentarzach. W ogólnym przypadku linijka taka nic nie robi.

    4\/3!!
  • #5 10677889
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Nadal nie odblokowuje WRPR :(.
  • #6 10678152
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    No to ja już nie wiem... Zwykle i tak najprościej jest to zrobić przez aplikację ST Loader...

    Masz pewność, że ten kod się wykonuje, że wgrywasz go prawidłowo itd.?

    4\/3!!
  • #7 10678258
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Tak, jestem 100% pewien bo sobie porobiłem debugger na wyświetlaczu LCD.

    To jest kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wkleję jeszcze funkcję flash_write aby było ładnie widać wszystko :

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Mam nadzieję że się nie ośmieszyłem ujawniając kod mojego autorstwa - zbyt doświadczony to nie jestem więc proszę się nie śmiać :).

    Ostatnia linia LCD_WriteNumberXY(FLASH->WRPR/2 , 0, 2); wyświetla mi liczbę która świadczy o tym że strony są poblokowane.

    Po wciśnięciu guzika 2 "if((GPIOA->IDR & 0x2) == 0)" zostaje wysłana sekwencja klucza :
    FLASH->OPTKEYR = 0x45670123;
    FLASH->OPTKEYR = 0xCDEF89AB;
    która na pewno działa poprawnie bo linia:
    LCD_WriteNumberXY((FLASH->CR & 0x200) / 512 , 8 , 3);
    wyświetla mi jedynkę na wyświetlaczu LCD czyli zapis do option byte zostaje odblokowany.
  • #8 10678376
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Jeśli jedynie chcesz doprowadzić ukłąd do stanu "oryginalnego", to ja walczyłbym jednak przez aplikację do bootloadera od ST - tak jest prościej.

    4\/3!!
  • REKLAMA
  • #9 10678474
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Tak masz tację.
    tylko nie bij mnie za to co teraz napiszę ale odblokowywanie pamięci flash działa.
    Zorientowałem się dopiero kiedy jeszcze raz czytając dokumentację Write protection register (FLASH_WRPR), zauważyłem, że jedynka oznacza 1: Write protection not active, a ja myślałem, że analogicznie 0-not active, 1-active.

    Mój problem jednak nie znikną. Pomimo, że cały rejestr : Write protection register (FLASH_WRPR) - mam zapełniony jedynkami, nadal nie mogę zapisywać danych ani kasować stron bez poprzedzenia operacji resetem :(.

    Nie mam zielonego pojęcia o co może chodzić. Jeśli pamięć w option byte'ach jest odblokowana i każdą operację poprzedzam sekwencją klucza :
    FLASH->KEYR = 0x45670123;
    FLASH->KEYR = 0xCDEF89AB;
    To powinienem mieć możliwość swobodnej pracy na flash'u.
  • #10 10678491
    Bambzo
    Poziom 13  
    Posty: 43
    Pomógł: 3
    Ocena: 37
    Wprawdzie program mojego bootloadera napisałem korzystając z bibliotek ST, ale odblokowanie dowolnych stron FLASH'a do zapisu bardzo ładnie działa i nie mam z nim najmniejszych problemów. Zrobiłem to w następujący sposób (kolejność jest ważna):

    1. Odblokowanie FLASH'a:
    FLASH_Unlock();

    2. Skopiowanie ustawień bitów rejestru USER OPTION BYTES:
    KopiaOBR = FLASH_GetUserOptionByte();

    3. Skasowanie OptionBytes tzn: WriteOptionByte oraz UserOptionByte bez kasowania ReadOptionByte:
    FLASH_EraseOptionBytes();

    4. Włączenie protekcji wybranych stron (tutaj dla STM32F103RCT6 sa to strony 0-7 w których znajduje się mój program bootloadera)
    FLASH_EnableWriteProtection(0x0000000f);

    5. Przywrócenie ustawien bitów rejestru USER OPTION BYTES:
    if ((KopiaOBR & 0x07) != 0x07)
    {
    if ((KopiaOBR & 0x01) == 0x0)
    var1 = OB_IWDG_HW;
    if ((KopiaOBR & 0x02) == 0x0)
    var2 = OB_STOP_RST;
    if ((KopiaOBR & 0x04) == 0x0)
    var3 = OB_STDBY_RST;
    FLASH_UserOptionByteConfig(var1, var2, var3);
    }

    6. Wywołanie programowego resetu:
    NVIC_SystemReset();

    Po resecie wybrane strony są odbezpieczone do zapisu. Wszystkie powyższe funkcje działają przy włączonej protekcji odczytu pamięci FLASH. Oczywiście po zapisie odbezpieczone strony zostają ponownie zabezpieczone tak by po aktualizacji oprogramowania procesor był zabezpieczony przed zapisem i odczytem.
  • REKLAMA
  • #11 10678841
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Wedłóg bombzo dodałem linię : OB->WRP3 = (uint16_t)0xFF000000;

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    lecz nie pomaga.
    Niewiem - może mam przez te moje testy - tak uszkodzony procesor (nasrane w rejestrach), że wymiana procka by pomogła i nic innego ?.

    Nie rozumiem tego dostępu do FLASH'a. Przecież jak mam w rejestrze FLASH_WRPR wszystkie strony zaznaczone na 1 (czyli odblokowany zapis), to dlaczego nie mogę nic zapisywać czy kasować więcej niż jeden raz ?
  • #12 10681185
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    Napisałem piękną funkcję do usuwania zabezpieczeń zapisu w Option bytes.
    Działa bardzo ładnie. W rejestrze FLASH_WRPR widać jak odpowiednie strony zmieniają się na 1 lub 0;
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Lecz pomimo tego, że wszystkie strony mam odblokowane do zapisu i odczytu, nie mogę nic zapisać do pamięci bez poprzedzenia opreacji resetem.
    Czego to może być wina ?
    Proszę pomóżcie.
  • #14 10681700
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    No tak - dokładnie tak robię.
    Zobacz - ostatnia linia kodu : SCB->AIRCR = 0x05FA0000 | (u32)0x04; //RESET.
  • #16 10681856
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    w caałym kodzie nigdzie nie jest ponownie uruchamiane zabezpieczenie stron.
    Jak usuwam zabezpieczenie - tak go niema i sprawdzając programem ulink zgadza się - zabezpieczenie zapisu stron jest cały czas wyłączone .
  • #17 10684329
    lolonet
    Poziom 11  
    Posty: 76
    Ocena: 4
    OK. Udało się wreszcie.
    Problem tkwił w funkcji do zapisu danych.
    Wydawało mi się że zapis był realizowany poprawnie. Zapisywałem zmienną 16 bitową naraz a wolno tylko po pół słowa, jednak po zapisie zbyt dużej ilości danych sprawdzałem tylko jedną komórkę i wyświetlałem na wyświetlaczu i się zmieniała - więc myślałem, że jest wszystko z zapisem porządku , a tym czasem druga połowa słowa się nie wgrywała o czym ja nie wiedziałem - co gorsza przy takiej operacji fpec wywalał errora o którym także nie wiedziałem i blokował swoją dalszą pracę. dlatego po resecie mogłem dokonać kolejnej operacji na flash ...

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

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

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kasowanie wybranej strony :

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zapis danych do pamięci:

    Deklaracje wcześniej :

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Uff. To była długa droga.
    Dziękuję za pomoc i mam nadzieję, że komuś się przyda moja praca - jak to mówią - dla potomnych :).
    Pozdrawiam.

Podsumowanie tematu

✨ Użytkownik ma problem z odblokowaniem pamięci Flash w mikrokontrolerze STM32 Cortex M3, co pozwala na wykonanie tylko jednej operacji zapisu lub kasowania. Po odblokowaniu pamięci za pomocą sekwencji klucza, rejestr FLASH->WRPR pozostaje zapełniony jedynkami, co sugeruje, że blokada nie jest aktywna. Użytkownik próbował różnych metod, w tym resetowania procesora oraz używania aplikacji ST-Link Utility, ale nadal napotyka problemy z kolejnymi operacjami na pamięci Flash. Ostatecznie odkrył, że problem leży w funkcji zapisu danych, gdzie niepoprawne zapisywanie zmiennych 16-bitowych prowadziło do błędów, które blokowały dalsze operacje.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA