|
|
^ Blog index    << KONIK gra logiczna   
Problem z wybudzaniem BlueNRG-2
2018-08-01   Piotr Romaniuk, Ph.D.
Spis treści
Konfiguracja
Objawy problemu
Struktura oprogramowania
Protokół SPI
Pierwszy test
Obserwacja usypiania i wybudzania BlueNRG
Badanie statystyczne problemu
Dalsze badanie problemu
Jak odzyskać działanie układu?
Uwagi
Linki
Konfiguracja
Urządzenie składa się z głównego procesora STM32L4xx oraz układu BlueNRG-2. Komunikują się one po SPI.
Procesor STM32L4xx realizuje główne funkcje urządzenia, podczas gdy BlueNRG-2 zapewnia komunikację przez Bluetooth Low Energy. Układ BlueNRG-2 pracuje w konfiguracji Network Coprocessor. Jest w nim wgrane oprogramowanie dostarczone przez producenta (ST Microelecronics) z niewielką modyfikacją. Wykorzystano
projekt DTM (z pakietu BlueNRG-1_2 DK 2.6.0_2, projekt: Project/BLE_Examples/DTM), a z oryginalnego kodu, w celu uproszczenia, usunięto funkcjonalność
aktualizacji. Kompilacja wykonana została pod Atollic TrueSTUDIO for STM32 9.0.0.
Procesor główny posiada własny kod napisany na podstawie przykładu z Development Kit dla takiej konfiguracji (tzn. komunikacji po SPI z BlueNRG2).
Objawy problemu
Podczas komunikacji z BlueNRG-2 po SPI pojawia się timeout - brak odpowiedzi układu na wysłane polecenie (różne funkcje biblioteki zwracają BLE_STATUS_TIMEOUT = 0xFF).
Problem pojawia się statystycznie co około godzinę prawidłowej komunikacji, może wystąpić po 15 minutach lub 2 godzinach. Moment wystąpienia nie jest deterministyczny, wydaje się być przypadkowy. Timeout jest zgłaszany jako błąd funkcji, która poprzednio działała. Po wystąpieniu błędu dalsza komunikacja z BlueNRG-2
nie jest możliwa, wszelkie funkcje biblioteki wywoływane po stronie procesora głównego (STM32L4xx), zwracają timeout.
Struktura oprogramowania
Struktura oprogramowanie jest przestawiona na poniższym rysunku:
Rys. 1. Struktura oprogramowania z podziałem na procesory.
Biblioteka Bluetooth LE, część dla procesora głównego, jest pewnego rodzaju adapterem, który pośredniczy
pomiędzy API biblioteki (funkcje udostępniane aplikacji) a komunikacją po SPI. Ukrywa w ten sposób komunikację
po tym sprzętowym interfejsie. Funkcjonalnie ta część biblioteki nie jest zbyt złozona, zajmuje się głównie
przepakowywaniem argumentów funkcji do/z wiadomości przesyłanych/odbieranych na interfejsie szeregowym.
Komunikacja odbywa się na zasadzie dialogu REQ-ACK, oraz przesyłanych asynchronicznie zdarzeń EVENT.
Na procesorze BlueNRG-2 (Cortex-M0) umieszczona jest warstwa Transport Layer, która jest analogicznym adapterem
po drugiej stronie SPI. Nie jest ona zbyt złożona. Główna funkcjonalność stosu Bluetooth znajduje się w
dostarczanej w postaci binarnej bibliotece - Bluetooth LE ST Library (controller part).
W tym układzie znajduje się też niewielki kod odpowiadzialny za usypianie gdy nic nie jest transmitowane
oraz wybudzanie gdy wymaga tego hardware albo procesor główny żąda wymiany wiadomości.
Protokół na SPI
Dokładny opis protokołu znajduje się w Development Kicie (Docs/SPI_protocol_specification/SPI_protocol_specification.html).
Najwazniejsze cechy protokołu:
- 5 linii sprzętowych (CS, SCK, MISO, MOSI, IRQ)
- główny procesor steruje magistralą SPI (master)
- BlueNRG jest podrzędny (slave)
- linia IRQ służy do potwierdzania oraz zgłoszenia żądania transmisji
- jeśli procesor główny chce coś wysłać, zmienia CS na stan aktywny (poziom niski) i czeka na potwierdzenie na linii IRQ poziomem wysokim - co oznacza, że BlueNRG wybudził się i jest gotowy do wymiany danych,
- jeśli BlueNRG chce coś wysłać, zgłasza żądanie stanem aktywnym linii IRQ i czeka na transmisję
- na początku transmisji przesyłany jest nagłówek, gdzie zawarty jest kierunek transmisji,
ilość oczekujących danych i miejsce w buforze po stronie BlueNRG,
Pierwszy test
Timeout jest obserwowany na API - pomiędzy kodem aplikacji i biblioteli BLE, części hosta. Jest to jednak
manifestacja problemu na samej górze. Gdzie faktycznie powstaje problem i co jest jego źródłem?
Wstępna analiza kodu źródłowego wskazywała na brak reakcji BlueNGR na wystawienie sygnału CS.
W celu potwierdzenia tej obserwacji, zebrana została rejestracja sygnałów cyfrowych na SPI.
Rys. 2. Wyłapany przypadek, kiedy występuje timeout.
Faktycznie, mimo wystawienia stanu niskiego na CS, BlueNRG nie reaguje. Nie ma potwierdzenia sygnalizowanego
stanem wysokim na linii IRQ. Można wnioskować, że jakiś problem wystepuje po stronie BlueNRG.
Obserwacja usypiania i wybudzania BlueNRG
Analiza schematu pozwala stwierdzić, że sygnał CS jest podłączony do końcówki IO11 (WAKE_UP) układu BlueNRG
i wybudza go stanem niskim.
Ogólna struktura połączeń linii jest przedstawiona w dokumentacji układu BlueNRG-2 - rozdział 3.5.1 Reser management.
Przejrzenie kodu prowadzi do wniosku, że układ jest usypiany (deep sleep)
a stan procesora (rejestry procesora itp.) jest zachowywany w pamięci RAM.
Wybudzenie układu jest prawie identyczne ze sprzętowym resetem - procesor rozpoczyna wykonywanie instrukcji od początku (HandlerReset), a przyczynę
restartu można odczytać z odpowiednich dwóch rejestrów (patrz funkcja SysCtrl_GetWakeupResetReason()). Na tej podstawie można odróżnić wybudzenie od
resetu sprzętowego. To jest wykorzystane w kodzie DTM, który w momencie wykrycia wybudzenia odtwarza stan procesora,
powodując kontynuację wykonywania programu od miejsca uśpienia.
Ponieważ działanie sprzętowego bloku procesora przeznaczonego do debugowania jest wyłączone w tym trybie uśpienia,
nie można było użyć JTAGa do sprawdzenia stanu procesora gdy występuje problem.
Dalsza analiza była prowadzona innymi metodami, głównie sygnalizacją na końcówce procesora zdarzenia.
Ponadto ze względu na rezystory pull-down wewnątrz układu można pośrednio wnioskować kiedy układ wchodzi w stan uśpienia. Na rys. 3. przedstawione jest porównanie analogicznych przypadków (te same polecenia na SPI):
prawidłowej i błędnej reakcji. Kanał 0 rejestracji odpowiada uśpieniu - właśnie ze względu na wspomniane wcześniej
rezystory pull-down. Stan niski oznacza na tej linii, że BlueNRG jest w trybie uśpienia.
Rys. 3. Porównanie przypadku prawidłowej i błędnej reakcji.
Badanie statystyczne problemu
Skoro problem ma jakiś związek ze stanem uśpienia i wybudzeniem z niego, to rodzi się pytanie: dlaczego czasem właściwie się wybudza a czasem nie? Jaki jest czynnik, który różni te dwa zachowania? Celem tego rozważania było zrozumienie problemu i ewentualne zaproponowanie obejścia problemu jeśli nie da się go rowiązać.
Pomiary kilku przypadków doprowadziły do wniosku, że różnią się one wartością czasu pomiędzy wejściem w uśpienie, a pojawieniem się sygnału wybudzenia. Przeprowadzony został wielokrotny pomiar tego czasu, dla normalnej pracy,
oraz dla przypadków kiedy występował problem.
Okazało się, że we wszystkich przypadkach błędu czas ten wynosił 30us.
Dla poprawnej pracy czas przyjmował różne wartości: mniejsze albo większe (udało się też zarejestrować jeden przypadek z 30us) - patrz wykres na rys. 4.
WNIOSEK z tych obserwacji:     do problemu z wybudzaniem dochodzi gdy sygnał wybudzania jest 30us po wejściu w uśpienie układu BlueNRG-2.
Rys. 4. Czas odstępu sygnału wybudzenia od momentu uśpienia (czerwona kropka=bład, niebieskie=prawidłowe działanie.
Dalsze badanie problemu
W celu lepszego zbadania problemu przeprowadzono śledzenie wykonania programu za pomocą markerów - sygnalizacji na
zewnętrznej końcówce przejścia przez dane miejsce w programie.
Ze względu na małą liczbę dostępnych końcówek, które mogą być użyte do tego celu, użyto
wyjścia szeregowego. Przy przejściu wykonania programu przez kluczowe miejsca wysyłane były znaki odpowiednie znaki,
taki ślad był zbierany analizatorem logicznym, razem z sygnałami na SPI. Dodatkowo na końcówce sygnalizowane były
przerwania - wykonywanie kodu w ISR.
Nie zaobserwowano żadnych różnic w wykonaniu programu na BlueNRG dla przypadku prawidłowego i błędnego.
Rys. 5. Badanie wykonania programu w okolicy występowania problemu
(3=rozpoczęcie procedury zachowania stanu przed uśpieniem, 4=uśpienie układu, 10=żądanie wybudzenia, 5=odtworzenie stanu po wybudzeniu, ale przed właczeniem przerwań)
Jak odzyskać działanie układu?
Najprostszym działaniem jest zresetowanie układu. Końcówka RESET jest i tak sterowalna przez główny procesor,
wiec kiedy wykryje on timeout nalezy przeprowadzić reset i konfigurację (serwisy, charakterystyki itp.).
Można skrócić ten proces do kilkudziesięciu ms. Może to być wystarczającym rozwiazaniem gdy rozważy się specyfikę
Bluetooth LE.
Bardziej zaawansowane rozwiązanie może opierać się na wykrywaniu problematycznego odstępu czasu i omijania go (przekakiwanie).
Do wskazywania kiedy procesor BlueNGR wchodzi w uśpienie można użyć metody zastosowanej do badania problemu i opisanej powyżej.
W procesorze głównym można użyć timer sprzętowy, który będzie mierzył ile upłynęło od uspienia. Wartość tego czasu byłaby sprawdzania
tuz przed wystawieniem CS. Jeśli czas byłby w pobliżu krytycznego 30us, można byłoby dodać krótkie opóźnienie (rzędu 10us),
zanim ustawi się CS w stan aktywny.
Uwagi
Należy zwrócić uwagę, że nie jest znany mechanizm blokowania się w stanie uśpienia układu BlueNRG.
Można jednak przypuszczać, że być może ma to związek z jakimś błędem sprzętowym w synchronizacji w procesorze,
przez który dochodzi do wyścigu (hazard) właśnie dla tych 30us. Co ciekawe 30us jest dość blisko wartości
jednego okresu wolnego zegara (SXTAL) układu BlueNRG.
Opisywany tu problem zgłaszałem na liście dyskusyjnej community.st.com, próbowałem też zgłaszać w ST Microelektronics,
niestety nie udało mi się wywołać zainteresowania ani uzyskać pomocy. A szkoda, bo BlueNRG to bardzo ciekawy układ, który
daje duże możliwości.
Linki
[1] Strona producenta układu BlueNRG-2
- zawiera dokumentację układu
[2] Pakiet Development Kit - biblioteki i przykłady do BlueNRG od ST Microelectronics
[3] Tu jest dyskusja na community.com.st, opisy, zgłaszane chronologicznie w miarę
badania problemu
|
|