Kategoria: Programowanie

Przydatne biblioteki C++ STM32

C++ w systemach embedded otwiera całą gamę nowych możliwości. Poprawne użycie nowoczesnych konstrukcji języka i biblioteki standardowej pozwala ułatwić i przyspieszyć naszą pracę. Niestety większość popularnych bibliotek C++ nie jest tworzona z myślą o systemach embedded. Czasami taka biblioteka mimo wszystko u nas zadziała, jednak nie zawsze mamy tyle szczęścia. Nawet wykorzystanie dużej części STL może być problematyczne ze względu na dynamiczną alokację pamięci. Istnieją jednak biblioteki stworzone właśnie z myślą o mikrokontrolerach. W tym wpisie przybliżę kilka z nich, szczególnie pod kątem użycia w STM32.

Continue reading

FPU w STM32F4 – jak używać Floating Point Unit

Jedną z największych zalet procesorów STM32F4 i ogólnie Cortex-M4 jest jednostka Floating Point Unit (FPU) przyspieszająca obliczenia na liczbach zmiennoprzecinkowych. Jej wykorzystanie wymaga od użytkownika włączenia FPU podczas działania programu oraz kompilacji z odpowiednimi flagami, aby używać instrukcji FPU. W tym wpisie omawiam jak obsługiwać FPU zarówno od strony programu jak i kompilatora oraz jak pisać kod, aby mieć pewność, że wykorzystuje on dobrodziejstwa FPU.

Continue reading

Watchdog timer

Każdy, kto miał do czynienia z elektroniką wie, że jeśli urządzenie przestało działać, należy je zresetować. W niektórych systemach robienie tego ręcznie nie jest możliwe. Przyczyną może być trudny, czy wręcz niemożliwy, dostęp dla operatora np. w przypadku sondy kosmicznej. Są też przypadki, gdy czas potrzebny na zauważenie usterki i ręczny reset jest zbyt długi np. w przypadku aparatury medycznej podtrzymującej życie. W takich sytuacjach z pomocą przychodzi nam watchdog timer.

Continue reading

Exceptiony w mikrokontrolerach

Kiedy w programie na PC nastąpi exception, aplikacja zakończy się z błędem. W skrajnym przypadku dostaniemy blue screena i komputer się zresetuje. Wyjątki są obsługiwane przez system operacyjny. W mikrokontrolerach nie mamy dostępu do takich zaawansowanych funkcjonalności. Jednak w dalszym ciągu możemy wykonać dzielenie przez 0 lub odwołać się do null pointera. W tym artykule omówię w jaki sposób obsługiwać exceptiony w mikrokontrolerach. Zacznę od ogólnej procedury, następnie skupię się na detalach specyficznych dla procesorów PIC32 i Cortex-M.

Continue reading

O wskaźnikach i rzutowaniu w C

Zmienne programu są w pamięci reprezentowane jako pewien ciąg bitów. Dla komputera nie ma znaczenia, czy ten ciąg to liczba, string, struktura, czy cokolwiek innego. Pisząc programy definiujemy typy zmiennych i to na te typy rzutowane są wartości bitowe.

Języki wyższego poziomu jak np. C#, czy Python oddzielają tą implementację za pewną warstwą abstrakcji. Twórcy tych języków doszli do wniosku, że program nie powinien polegać na konkretnej reprezentacji bitowej. Możemy oczywiście za pomocą odpowiednich funkcji uzyskać dostęp do takiej bitowej reprezentacji, ale czynność ta celowo została utrudniona.

C jest jednak starszym językiem wyznającym zasadę, że programista wie co robi. Dlatego w C mamy łatwy dostęp do reprezentacji bitowej. Możemy używać wskaźników, czy rzutować typy na inne. Efektem jest większa wydajność wynikowych programów za cenę wolniejszego developmentu. Sprawdzanie błędów w C jest bardzo ubogie i nawet doświadczony programista może łatwo strzelić sobie w stopę.

W tym wpisie pokażę kilka potencjalnie niebezpiecznych fragmentów kodu oraz omówię jak radzi sobie z nimi standard MISRA C oraz jak to rozwiązano w C++.

Continue reading

Konwersja typów przy operacjach arytmetycznych w C

Aby wykonać operację arytmetyczną w  C, kompilator musi dysponować dwoma operandami tego samego typu. Jeżeli programista o to wcześniej nie zadbał, konwersja jest wykonywana niejawnie. Na przykład:

  • Zmienna o mniejszym rozmiarze jest konwertowana do większego np. uint8 na uint32, czy float na double.
  • Zmienna bez znaku jest konwertowana na zmienną ze znakiem.
  • Zmienna int jest konwertowana na float.

Konwersje typów są również wykonywane przy operacjach przypisania. Możemy na przykład do zmiennej uint przypisać liczbę ujemną. Możemy również do niej przypisać wynik operacji arytmetycznej, gdzie czasem wartość jest dodatnia, a czasem ujemna. Takie konwersje są dobrym miejscem do powstawania różnego rodzaju błędów i nieoczywistych, czy wręcz niezdefiniowanych zachowań.

Continue reading

Kiedy od softu zależy ludzkie życie – o systemach bezpieczeństwa

W internecie można spotkać głosy, że programiści nie wykonują odpowiedzialnych zadań i nie ma żadnych regulacji, których muszą przestrzegać. Bo co złego może się stać, jeśli strona nie będzie działać, albo komputer wywali bluescreena. W końcu świat się od tego nie zawali. Być może jest to prawdą w 99% projektów programistycznych. Jednak tam, gdzie na szali jest ludzkie życie, bardzo restrykcyjne regulacje obowiązują już od dawna. Wiem o czym mówię, ponieważ przez ostatnie dwa lata pracowałem przy systemie sterującym ruchem pociągów.

Continue reading

Jak optymalizować działanie programu?

Ostatnio w pracy miałem za zadanie dokonać optymalizacji pewnego fragmentu kodu. Postanowiłem, że to dobra okazja, aby zebrać trochę porad dotyczących optymalizacji i się nimi podzielić. Część porad odnosi się konkretnie do C, ale większość można uogólnić na każdy język. Entuzjaści wyciskania procesorów do granic możliwości mogą jednak poczuć się zawiedzeni, ponieważ nie będę się skupiał na trickach urywających pojedyncze takty. Bliżej mi do podejścia przedstawionego w dwóch zasadach optymalizacji:

  1. Nie rób tego.
  2. (Tylko dla ekspertów) Jeszcze tego nie rób.

Continue reading