Upss… Coś nie tak z Twoją przeglądarką
Do poprawnego wyświetlania formularza zalecana jest przeglądarka Chrome lub Safari.
Blog

Optymalizacja pamięci w systemach wbudowanych w języku C – ROM

W poprzednich częściach omówiliśmy temat optymalizacji zużycia pamięci w systemach embedded w zakresie narzędzi developerskich, jak również sposobów optymalizacji pamięci RAM. Czas na ostatnie zagadnienie – optymalizacja pamięci ROM.

Wyzwania związane z optymalizacją pamięci ROM

W pamięci ROM znajdziemy wartości stałe, dane inicjalizacyjne sekcji .data oraz instrukcje naszej aplikacji. Pomiędzy kodem napisanym przez programistę a zawartością pamięci znajduje się kompilator, który tłumaczy kod na instrukcje zrozumiałe dla procesora. Nowoczesne kompilatory bardzo dobrze optymalizują kod pod kątem rozmiaru. Jeśli nawet uda się znaleźć jakąś sprytną sztuczkę w kodzie, która pozwoli nam zaoszczędzić kilka bajtów, może się okazać, że taka zmiana nie będzie długo funkcjonować w naszym kodzie. Zadziała bowiem tylko dla konkretnego kompilatora. Co zatem w przypadku, gdy w grę wchodzi pisanie kodu na różne platformy – z odmienną architekturą i kompilatorem? Wyzwań tylko przybywa, ponieważ tego typu działania mogą utrudnić utrzymywanie kodu.

Jeśli jesteśmy pod ścianą i brakuje dostępnych opcji, nie pozostaje nic innego jak poznawanie tajników konkretnego kompilatora. Jeśli musimy wspierać kilka platform, możemy optymalizować fragmenty kodu pod konkretną platformę i używać preprocesora do definiowania, którego kodu w danej sytuacji użyć. Takie praktyki oznaczają jednak generowanie dodatkowych ścieżek w naszej aplikacji, które wymagają kolejnych testów, a zatem stają się potencjalnym źródłem nowych błędów.

Co warto optymalizować w pamięci ROM?

To, co z pewnością należy optymalizować, to przede wszystkim algorytmy i logika działania aplikacji. Co to oznacza w praktyce?

  • Upraszczanie działania kodu. Warto podjąć próbę napisania tej samej funkcjonalności z użyciem mniejszej liczby operacji. Redukcja liczby operacji to nie tylko mniej zużytej pamięci ROM, ale również szybsza aplikacja!
  • Sprawdzenie, czy w aplikacji nie ma fragmentów kodu, które wykonują podobne czynności. Części wspólne można następnie zamknąć w funkcje, co zmniejszy zużycie pamięci ROM.
  • Jeśli mamy zapas pamięci RAM, a w pamięci ROM przechowujemy dane, które mogą być wygenerowane, warto poświęcić trochę czasu procesora i wygenerować takie dane, aby były przechowywane w pamięci RAM. Jeśli nie ma możliwości wygenerowania danych, można w pamięci ROM przechowywać dane skompresowane, a następnie dekompresować je do RAMu przy inicjalizacji. Zyskamy wówczas pamięć ROM kosztem RAMu i czasu procesora. Kod do generowanie lub dekompresji pochłonie trochę pamięci ROM, dlatego ta metoda może się sprawdzić tylko przy dużej ilości danych.

Firmware update oraz użycie bootloadera lub apploadera

Wśród funkcjonalności występujących w systemach wbudowanych warto przyjrzeć się aktualizacji oprogramowania. OTA (Over-the-air) update, czyli aktualizacja bezprzewodowa, jest powszechnie spotykana w urządzenia bezprzewodowych.

Często spotykanym sposobem aktualizacji oprogramowania jest metoda, w której w pamięci ROM zostają wydzielone dwie partycje na aplikację – APP1 i APP2. Bootloader decyduje, która partycja zawiera najnowszą wersję oprogramowania. Podczas procedury aktualizacji oprogramowania obraz aplikacji jest pobierany, a następnie zapisywany na sąsiedniej partycji.

Rozwiązanie to jest odporne na przerwanie transmisji danych, ponieważ nie nadpisuje obecnej wersji aplikacji. Po utracie zasilania lub połączenia aplikacja uruchomi się poprawnie, a proces aktualizacji można bezpiecznie powtórzyć lub z niego zrezygnować. Takie rozwiązanie nie jest jednak bezkosztowe, gdyż partycje na aplikację są tego samego rozmiaru, przez co wykorzystujemy w przybliżeniu 50% dostępnej pamięci.

Można zastosować alternatywne podejście z użyciem apploadera, który jest rozbudowaną wersją booloadera. Cechą apploadera jest stos bezprzewodowy pozwalający na pobranie nowej wersji oprogramowania i zapisanie bezpośrednio na partycję aplikacyjną (APP). Rozwiązanie to pozwala zwiększyć ilość pamięci przeznaczoną na aplikację, gdyż implementacja apploadera będzie znacznie lżejsza od docelowej aplikacji.To rozwiązanie nie pozwala na korzystanie z poprzedniej wersji aplikacji po przerwanej aktualizacji, gdyż apploader nowym obrazem aplikacji nadpisuje obecną wersję. Po utracie zasilania lub połączenia należy spodziewać się, że urządzenie będzie w trybie aktualizacji, a proces trzeba będzie przeprowadzić poprawnie, by przywrócić pełną sprawność urządzenia.

Podsumowanie

Zarządzanie zużyciem pamięci w systemach wbudowanych jest skomplikowanym zagadnieniem i może przysporzyć wielu wyzwań. Znając dobrze swój system oraz metody optymalizacji, możesz jednak rozwiązać większość tych problemów. Nasza seria artykułów powinna wskazać kierunek tym, którzy próbują stawić czoła problemom z pamięcią we własnym systemie. Poszczególne części prezentują kilka dobrych praktyk pozwalających również uniknąć komplikacji w przyszłości. Nie wszystkie miejsca, w których pamięć jest marnowana, widoczne są na pierwszy rzut oka. Dlatego warto inwestować w rozwiązania automatyczne, które wykryją problemy z pamięcią na wczesnych etapach projektu.

 

Najczęściej czytane w kategorii Technologie