Już od wielu lat znam problem ale nigdy nie chciało mi się do niego przysiąść. Czyli lenistwo poziom expert.
Do obsługi FLASHa używam nieznacznie przerobionych kodów autorstwa w123456xy (nie z elektrody, tylko gdzieś w internecie znalazłem).
I problem taki: Dam optymalizację -O0, działa. Dam -Os, nie działa.
Do tej pory radziłem sobie po prostu pozostawiając optymalizację -O0.
Ale najwyższa pora coś z tym zrobić.
Kod raczej prosty:
Porównałem operacje i ich kolejność z datasheetem, i się zgadzają.
I moja funkcja:
Niedziałanie dla -Os w ogólności polega na tym że w pamięci ciągle znajdują się wartości 0xFF.
Dzisiaj porobiłem trochę testów i wnioski są takie:
1. Samo kasowanie pamięci jednak działa. Jak pamięć zawiera coś innego niż 0xFF to wywołanie funkcji Zapisz_EEPROM zmienia te wartości na 0xFF (niezależnie od tego co podam w tablicy TAB (dla -O0 zapisuje we FLASHu wartości tej tablicy)).
2. Zmienianie Timeoutów nic nie zmienia w działaniu.
3. Funkcja FLASH_WaitForLastOperation zwraca wartość 4, czyli PGERR: Programming error.
I tu ciekawostka, zwraca to nawet dla optymalizacji -O0 (mimo że zapis wtedy działa), oraz również dla kasowania pamięci. I to mnie trochę dziwi. Bo chyba powinno zwracać taką wartość tylko dla programowania? Przy kasowaniu oczywiste jest że wartość wejściowa może być inna niż 0xFF (bo dopiero kasujemy do wartości 0xFF) więc jaki sens ma zwracanie błędu w takim przypadku?
4. Widząc błąd powyżej, dodałem kasowanie flagi PGERR przed wywołaniami funkcji FLASH_WaitForLastOperation (myślałem że po prostu flaga PGERR pamięta jakiś błąd z wcześniejszych operacji). Ale nic się w działaniu nie zmieniło. Ciągle mam 4-krotnie zwracaną wartość równą 4.
4-krotnie czyli:
- przed wykasowaniem strony (po sprawdzeniu czy FLASH nie jest zajęty jakąś operacją)
- po wykasowaniu strony (po oczekiwaniu na zakończenie kasowania strony)
- przed zapisem strony (po sprawdzeniu czy FLASH nie jest zajęty jakąś operacją)
- po zapisaniu (albo i nie zapisaniu) strony (po oczekiwaniu na zakończenie zapisu ostatniej wartości na stronę)
Posprawdzałem w plikach lss czym się różnią te dwa kody. Różnice oczywiście widzę, ale nie wiem jaki wpływ na działanie może to mieć.
Np. zapis do FLASH->KEYR:
Wersja -O0:
Wersja -Os:
I nie wiem. Spodziewał bym się np. że zapis musi być w całości 32-bitowy (czyli że procek nie akceptuje dostępów 8 czy 16-bitowych do tego rejestru). Ale nic na ten temat nie znalazłem w datasheecie czy też w manualu STM32F100xx
value line Flash programming. Ale tu akurat w obu wersjach zapis samego rejestru jest taki sam (instrukcja str r2, [r3, #4]).
To może jakieś Timingi? Też nic nie piszą w datasheecie (że np. zapis musi być nieprzerywany przerwaniami, albo np. następować w gwarantowanym odstępie np. 4 cykli zegarowych tak jak to jest np. w przypadku rejestrów układu RTC). No nic nie pisze.
I tym sposobem pomysły mi się skończyły. Więc pytam na forum.
Ktoś coś wie na ten temat?
Są jakieś wymagania co do dostępów do rejestrów FLASH->KEYR i innych?
PS. Oczywiście pamięć FLASH jest w całości odblokowana.
Do obsługi FLASHa używam nieznacznie przerobionych kodów autorstwa w123456xy (nie z elektrody, tylko gdzieś w internecie znalazłem).
I problem taki: Dam optymalizację -O0, działa. Dam -Os, nie działa.
Do tej pory radziłem sobie po prostu pozostawiając optymalizację -O0.
Ale najwyższa pora coś z tym zrobić.
Kod raczej prosty:
Kod: C / C++
Porównałem operacje i ich kolejność z datasheetem, i się zgadzają.
I moja funkcja:
Kod: C / C++
Niedziałanie dla -Os w ogólności polega na tym że w pamięci ciągle znajdują się wartości 0xFF.
Dzisiaj porobiłem trochę testów i wnioski są takie:
1. Samo kasowanie pamięci jednak działa. Jak pamięć zawiera coś innego niż 0xFF to wywołanie funkcji Zapisz_EEPROM zmienia te wartości na 0xFF (niezależnie od tego co podam w tablicy TAB (dla -O0 zapisuje we FLASHu wartości tej tablicy)).
2. Zmienianie Timeoutów nic nie zmienia w działaniu.
3. Funkcja FLASH_WaitForLastOperation zwraca wartość 4, czyli PGERR: Programming error.
I tu ciekawostka, zwraca to nawet dla optymalizacji -O0 (mimo że zapis wtedy działa), oraz również dla kasowania pamięci. I to mnie trochę dziwi. Bo chyba powinno zwracać taką wartość tylko dla programowania? Przy kasowaniu oczywiste jest że wartość wejściowa może być inna niż 0xFF (bo dopiero kasujemy do wartości 0xFF) więc jaki sens ma zwracanie błędu w takim przypadku?
4. Widząc błąd powyżej, dodałem kasowanie flagi PGERR przed wywołaniami funkcji FLASH_WaitForLastOperation (myślałem że po prostu flaga PGERR pamięta jakiś błąd z wcześniejszych operacji). Ale nic się w działaniu nie zmieniło. Ciągle mam 4-krotnie zwracaną wartość równą 4.
4-krotnie czyli:
- przed wykasowaniem strony (po sprawdzeniu czy FLASH nie jest zajęty jakąś operacją)
- po wykasowaniu strony (po oczekiwaniu na zakończenie kasowania strony)
- przed zapisem strony (po sprawdzeniu czy FLASH nie jest zajęty jakąś operacją)
- po zapisaniu (albo i nie zapisaniu) strony (po oczekiwaniu na zakończenie zapisu ostatniej wartości na stronę)
Posprawdzałem w plikach lss czym się różnią te dwa kody. Różnice oczywiście widzę, ale nie wiem jaki wpływ na działanie może to mieć.
Np. zapis do FLASH->KEYR:
Wersja -O0:
Kod: C / C++
Wersja -Os:
Kod: C / C++
I nie wiem. Spodziewał bym się np. że zapis musi być w całości 32-bitowy (czyli że procek nie akceptuje dostępów 8 czy 16-bitowych do tego rejestru). Ale nic na ten temat nie znalazłem w datasheecie czy też w manualu STM32F100xx
value line Flash programming. Ale tu akurat w obu wersjach zapis samego rejestru jest taki sam (instrukcja str r2, [r3, #4]).
To może jakieś Timingi? Też nic nie piszą w datasheecie (że np. zapis musi być nieprzerywany przerwaniami, albo np. następować w gwarantowanym odstępie np. 4 cykli zegarowych tak jak to jest np. w przypadku rejestrów układu RTC). No nic nie pisze.
I tym sposobem pomysły mi się skończyły. Więc pytam na forum.
Ktoś coś wie na ten temat?
Są jakieś wymagania co do dostępów do rejestrów FLASH->KEYR i innych?
PS. Oczywiście pamięć FLASH jest w całości odblokowana.