Statystyki mocy HAL

Moc podsystemu urządzenia jest często mierzona i rejestrowana w środowisku laboratoryjnym dla różnych warunków stanu ustalonego, na przykład gdy ekran jest włączony lub urządzenie znajduje się w stanie bezczynności. Działa to w przypadku podsystemów o stałym poborze mocy lub w warunkach, które można łatwo zmierzyć w środowiskach laboratoryjnych, ale nie w niektórych przypadkach użycia, np. gdy na ekranie wyświetlany jest obraz wideo.

IPower.hal 1.0 zapewnia interfejs do przekazywania wskazówek dotyczących zasilania i raportowania zbiorczych danych na temat metryk stanu uśpienia podsystemu. W Androidzie 10 i nowszych funkcja skumulowanego raportowania statystyk znajduje się w interfejsach API zbierania statystyk mocy IPowerStats.hal i umożliwia pobieranie danych o zużyciu energii na urządzeniu. Zastępuje to część interfejsu IPower.hal służącą do gromadzenia skumulowanych statystyk, zapewniając wyraźniejszy podział funkcjonalności.

Odczyty usługi IPowerStats nie są okresowe. Występują one w kluczowych momentach, np. przy spadku naładowania baterii o 1%. Odczyty są rzadsze, gdy poziom naładowania baterii jest niski, i częstsze, gdy jest wysokie. Dane mogą zostać przesłane z powrotem na serwery i użyte w raportach o błędach w celu analizy i selekcji. Wspiera to ciągłe wysiłki mające na celu zmniejszenie zużycia energii i wydłużenie żywotności baterii.

IPower.hal i IPowerStats.hal

Zarówno interfejsy IPower.hal , jak i IPowerStats.hal są dostępne w systemie Android 10, ale funkcja gromadzenia statystyk IPower.hal jest dostępna tylko z poziomu interfejsu IPowerStats.hal . Funkcjonalność IPowerStats.hal obejmuje interfejsy API umożliwiające pozyskiwanie i wykorzystywanie danych zebranych z pomiarów mocy na urządzeniach dla obsługiwanych urządzeń:

  • Wykonuje pomiary energii na poziomie szyny dla klientów o niskiej częstotliwości ( getRailInfo ) i wysokiej częstotliwości ( streamEnergyData ) i raportuje energię skumulowaną od momentu uruchomienia.
  • Raportuje informacje dotyczące każdej obsługiwanej PowerEntity , dla której dostępne są dane. PowerEntity to podsystem platformy, urządzenie peryferyjne lub domena mocy, która ma wpływ na całkowite zużycie energii przez urządzenie.
  • Raportuje zestaw stanów jednostek mocy ( getPowerEntityStateInfo ), dla których określone jednostki dostarczają dane o miejscu zamieszkania, a następnie raportuje skumulowane dane dla każdego określonego PowerEntity .

Z interfejsów API IPowerStats.hal korzystają następujący klienci:

  • Statsd do zbierania wskaźników zużycia energii na szynę.
  • Perfetto , aby skorelować zużycie energii z aktywnością procesora.
  • Batterystats , aby poprawić przypisanie baterii poprzez wykorzystanie zmierzonych danych zamiast szacowania zużycia baterii na podstawie predefiniowanych stałych w power_profile.xml.

W przypadku systemu Android 10 i nowszego producent urządzenia może wybierać między funkcjami IPower.hal i IPowerStats.hal , ale wszyscy klienci muszą wrócić do IPower.hal , jeśli IPowerStats.hal nie jest zaimplementowany.

Opcje implementacji IPowerStats.hal

Tylko funkcje IPower.hal są dostępne w systemach Android 7–Android 9. Urządzenia zaktualizowane do systemu Android 10 muszą mieć sprzętowy podsystem monitorowania zasilania lub inne dostępne środki umożliwiające monitorowanie i rejestrowanie statystyk zasilania. Niektóre układy SoC gromadzą dla Ciebie statystyki dotyczące zużycia energii lub możesz uzyskać informacje o stanie jednostki energetycznej za pomocą oprogramowania. Sprzęt do monitorowania zasilania jest niezbędny tylko do obsługi metod getRailInfo() , getEnergyData() i streamEnergyData() .

Jeśli zaimplementujesz IPowerStats.hal bez sprzętu do monitorowania zasilania, getRailInfo(), getEnergyData() i streamEnergyData() zwrócą NOT_SUPPORTED . Podobnie getPowerEntityInfo(), getPowerEntityStateInfo() i getPowerEntityStateResidencyData() mogą również zwrócić NOT_SUPPORTED , jeśli nie są przeznaczone do użycia.

Przykłady danych zwracanych przez interfejsy API monitorowania kolei obejmują

  • Szyna zasilająca wyświetlacza zużywała X µW.
  • Szyna zasilająca modemu zużywała Y µW.

Przykłady danych zwracanych przez interfejsy API stanu uśpienia podsystemu obejmują

  • Modem spał przez X ms.
  • SoC znajdował się w stanie zaniku zasilania przez Y ms.
  • Procesor graficzny znajdował się w stanie zawieszenia przez Z ms.

Użyj podsystemu monitorowania zasilania sprzętu

Jeśli projekt Twojego urządzenia zawiera podsystem monitorowania mocy sprzętu, zaimplementuj IPowerStats.hal , tworząc pojedynczy węzeł sysfs , z którego PowerStats.hal może analizować dane, lub wykonując zbiór wywołań systemowych typu ioctl .

Musisz zaimplementować sterownik jądra w sposób zapobiegający przepełnieniu akumulatora. Zastosowany algorytm zależy od unikalnego projektu podsystemu monitorowania mocy sprzętu, który musi zapewniać zarówno chwilowe, jak i średnie pomiary napięcia i prądu magistrali. Sterownik jądra musi przechwytywać te dane w sposób, który nie czyści akumulatorów energii, i musi od momentu rozruchu przechowywać dane dotyczące skumulowanej energii dla każdej szyny podrzędnej w postaci 64-bitowej zmiennej, która jest zwiększana wraz z odczytem energii z każde zapytanie do akumulatora.

Statystyki dla danego komponentu (lub opcjonalnie wielu komponentów) muszą znajdować się w jednym węźle. Chociaż nie jest to konwencjonalne użycie sysfs (które zwykle ogranicza każdy węzeł do jednej wartości), zapewnia to spójność wszystkich danych.

Wytyczne projektowe

  • Utrzymuj niskie opóźnienie (maksymalnie 1 ms) podczas odczytu z węzła sysfs lub wykonywania wywołań systemowych.
  • Upewnij się, że obsługa statystyk nie zwiększa w wymierny sposób zużycia energii:
    • Nie zwiększaj liczby wybudzeń punktów dostępu (AP) i/lub podsystemów w celu śledzenia parametrów, takich jak czas spędzony w trybie uśpienia.
    • Jeśli to możliwe, przesyłaj statystyki między procesorem aplikacji a oprogramowaniem sprzętowym, korzystając z innego ruchu.
  • W razie potrzeby podsystem może wykorzystywać następujące funkcje drajwera:
    • Wewnętrzne buforowanie danych, aby uniknąć opóźnień/wybudzeń kosztem nieco nieaktualnych danych.
    • Wykonywanie ekstrapolacji, gdy podsystem śpi, aby zapewnić zaktualizowany czas snu bez budzenia podsystemu.

Wybierz komponenty, podsystemy i statystyki

Wybierając komponenty lub podsystemy, z których mają być zbierane dane IPowerStats.hal , wybierz w urządzeniu wszystko, co pobiera znaczny prąd (5 mA lub więcej) lub obsługuje wiele trybów zużycia energii, na przykład:

  • Poszczególne podsystemy SoC.
  • Podsystemy częściowo lub całkowicie poza SoC, takie jak Wi-Fi, procesor obrazu lub procesor bezpieczeństwa.
  • Urządzenia peryferyjne, takie jak diody LED dużej mocy i kamery.
  • Domeny mocy korzystające z różnych trybów (takie jak domena mocy dla całego SoC).

Dostosowywanie

Tę opcjonalną funkcję można dostosować. Projektuj przypadki użycia i dostosowuj swoje użycie:

  • Zdecyduj, które szyny mierzyć i jak często je mierzyć.
  • Zdecyduj, kiedy czytać dane i jak je interpretować.
  • Zdecyduj, jakie działania podjąć i kiedy je podjąć, na podstawie swoich danych.

Walidacja

Testy VTS zapewniają spełnienie wymagań Androida. Komentarze w IPowerStats.hal służą do sprawdzenia, czy urządzenie jest zgodne.

Na przykład, jeśli wywołasz getRailInfo() i ona nic nie zwróci, test VTS zakończy się niepowodzeniem, ponieważ nie otrzymałeś informacji o monitorowanych szynach lub zwróconego statusu SUCCESS . Podobnie, jeśli otrzymałeś informację o kolei, ale towarzyszyła jej odpowiedź NON_SUPPORTED lub FILE_SYSTEM_ERROR , to również jest to błąd. VTS weryfikuje zgodność specyfikacji producenta urządzenia w pliku HAL, korzystając z wymagań zawartych w komentarzach IPower.hal i IPowerStats.hal. Poniżej przedstawiono przykład komentarzy wykorzystywanych w testach VTS:

/**
* Rail information:
* Reports information related to the rails being monitored.
*
* @return rails Information about monitored rails.
* @return status SUCCESS on success or NOT_SUPPORTED if
* feature is not enabled or FILESYSTEM_ERROR on filesystem nodes
* access error.
*/
getRailInfo()
generates(vec<e;RailInfo>e; rails, Status status);