Co ja robiłem
Korzystam z mikrokontrolera STM32 i do mojego projektu muszę mieć możliwość wysyłania danych o określonych porach dnia (powiedzmy o 11 rano i 2 po południu). Mikrokontroler musi wiedzieć, która jest godzina, zanim będę mógł to osiągnąć. Niestety mam tylko komunikację jednokierunkową i dlatego nie mogę żądać aktualnego czasu z sieci.
Dlatego chcę ustawić bieżący czas, bezpośrednio po zakończeniu programowania. Wiedziałem, że jestem w stanie zapisać dane do pamięci flash za pomocą interfejsu wiersza poleceń ST-LINK Utility (ST-LINK_CLI) przy użyciu następującego polecenia:
ST-LINK_CLI.exe -w32 <Address> <data> -Rst
Napisałem prosty skrypt testowy, który zapisuje uniksowy znacznik czasu na adres, który nie jest obecnie używany przez kod.
Właśnie miałem napisać funkcję do odczytu znacznika czasu i użyć go do ustawienia czasu RTC. Dopóki nie przeczytam poniższych instrukcji w Podręczniku użytkownika narzędzia ST-LINK :
-w32 obsługuje zapis do pamięci Flash, rejestrów OTP, SRAM i R / W.
Kiedy instrukcja mówi, że obsługuje zapis do rejestrów R / W, czy oznacza to, że mogę bezpośrednio uzyskać dostęp do rejestrów RTC i je ustawić? Próbowałem, ale nie mogę pisać do tych rejestrów.
Jeśli tak, wolałbym użyć tej metody, ponieważ nie musiałbym już pisać konkretnej funkcji do obsługi mikrokontrolera. Oznacza to, że mogę ustawić czas RTC dowolnego aktualnie używanego mikrokontrolera, zamiast konieczności aktualizacji jego kodu.
Co zamierzałem zrobić
Aby ustawić rejestry RTC, próbowałem wykonać następujące kroki, jak opisano w Podręczniku referencyjnym STM :
- ustaw bit DPB w rejestrze PWR_CR
- zapisz 0xCA do rejestru RTC_WPR
- zapisz 0x53 do rejestru RTC_WPR
- zatrzymać RTC, ustawiając bit INIT w rejestrze RTC_ISR
- wybierz zegar 1Hz, pisząc do rejestru RTC_PRER
- wczytaj aktualny czas, pisząc do rejestru RTC_TR
- załaduj bieżącą datę, pisząc do rejestru RTC_DR
- uruchomić RTC, resetując bit INIT w rejestrze RTC_ISR
Aby uzyskać dostęp do rejestrów, użyłem następujących adresów:
- PWR_CR: 0x4000 7000
- RTC_WPR: 0x4000 2824
- RTC_ISR: 0x4000 280C
- RTC_PRER: 0x4000 2810
- RTC_TR: 0x4000 2800
- RTC_DR: 0x4000 2804
Co poszło nie tak
Nie mogę pisać do żadnego z tych rejestrów. Dzięki narzędziu ST-LINK pojawia się następujący komunikat:
Wystąpił błąd podczas zapisywania pamięci!
Za pomocą ST-LINK_CLI:
Zapis 0x00000100 w 0x40007000 ... Błąd!
Czytanie tych rejestrów nie stanowi problemu, ale nie mogę do nich pisać za pomocą narzędzia ST-LINK ani interfejsu wiersza poleceń.
Pytanie
Jak zapisywać do rejestrów R / W za pomocą Narzędzia ST-LINK?
Czy istnieje jakiś rodzaj ochrony przed zapisem umożliwiający zapis do rejestrów RTC, które przeoczyłem?
Odpowiedzi:
Niektóre rejestry są legalne tylko dla określonej szerokości dostępu (tj. -W32 może być niepoprawny) lub mogą nie odczytywać zapisanych wartości, co może powodować problemy z weryfikacją.
Mogą również istnieć ograniczenia sekwencji lub stanu dostępu do rzeczy.
Opcją, która powinna rozwiązać większość możliwych problemów, byłoby stworzenie małego programu do wykonania zadania, które łączyłoby się z działaniem w pamięci RAM. Możesz podstawić dane do jego pliku binarnego po ustaleniu przesunięcia, załadować zmodyfikowaną wersję i uruchomić ją. Lub możesz mieć program, który pobierze wartości z regionu pamięci RAM poza zakresem pliku, który ustawisz przed uruchomieniem. Mając bardziej szczegółową kontrolę nad łączem, możesz również przekazywać wartości do rejestrów procesora, chociaż możesz (?) Potrzebować do tego alternatywnego programu wiersza poleceń open source zamiast ST (ta mała procedura w metodzie RAM jest przypadkowo sposobem, w jaki program wykonuje zapis błysnąć)
źródło
Jednym z problemów był, jak zauważył Chris Stratton:
Oznaczało to, że weryfikacja nie powiodła się, co spowodowało wyświetlenie błędu, mimo że operacja zapisu faktycznie się powiodła.
Poniżej znajduje się odpowiedź, którą otrzymuję podczas odczytu rejestru PWR_ISR, ustawienia bitu INIT, a następnie ponownego odczytu rejestru:
Weryfikacja narzędzia ST-LINK sprawdza, czy wartość zapisana na adres i odczytana z adresu jest zgodna. W tym przypadku operacja zapisu zakończyła się powodzeniem, mimo że dwie wartości nie są zgodne, ponieważ bit INIT jest teraz ustawiony.
Innym problemem było to, że nie zauważyłem efektu operacji zapisu. Po podłączeniu do mikrokontrolera ST-LINK utrzymuje go w stanie resetowania (znanym jako „połącz w trakcie resetowania”). Musiałem użyć opcji połączenia HOTPLUG, która łączy się z mikrokontrolerem bez zatrzymywania i resetowania.
Plik wsadowy działa w pełni tak, jak chciałem! Komenda wygląda teraz tak:
źródło
Myślę, że dzieje się tak, że po zapisie wykonywany jest odczyt weryfikacyjny. Jeśli ten sam rejestr zwróci bieżący czas w odczycie, mimo że aktualizacja RTC się powiedzie, debugger nie zda sobie sprawy. Jest to mniej prawdopodobne, aby wyjaśnić problem z rejestrem mocy (chyba że debugger uzyskuje dostęp do tego rejestru również pod maską). Sprawdź odczytaną wartość ręcznie. Jeśli wystąpiłby poważniejszy problem, odczyt ten może się również nie powieść. Spróbuj także innych rejestrów na liście.
źródło