Czym jest PlatformIO?
W zasadzie trudno to jednoznacznie określić, bo jest to pewien pakiet narzędziowy skupiający kilka frameworków – np. Arduino, Mbed, itd. – dla z góry określonych platform i płytek docelowych. Twórcy zalecają by stosować go jako wtyczka do zdobywającego coraz większą popularność edytora Visual Studio Code. To razem z nim tworzy swoiste środowisko projektowe.
Instalacja PlatformIO
Aby używać środowiska PlatformIO należy zainstalować najpierw Visual Studio Code. Tam należy przejść do sekcji Extensions i w polu wyszukiwania po prostu wpisać 'platformio'. Pojawi się krótka lista i na pierwszym miejscu powinno znaleźć się Platformio IDE. Jeśli go wybierzemy pojawi się strona informacyjna i najistotniejszy dla Nas przycisk Install.
Jeśli go klikniemy rozszerzenie automatycznie doda się do listy aktywnych rozszerzeń. Ale to nie koniec instalacji. Samo PlatformIO potrzebuje jeszcze paru swoich pakietów startowych, które zainstalują się same po krótkiej chwili. W tym czasie nie należy zamykać okna edytora do czasu aż w oknie terminala nie zostaniemy poproszeni by go zrestartować.
Po restarcie na dolnym pasku statusu pojawi się dodatkowa ikona Platformio Home. Jeśli ją klikniemy otworzy się główne okno zarządzające. Dzięki niemu można będzie tworzyć nowe lub importować projekty, otwierać już istniejące czy zarządzać dostępnymi platformami i frameworkami dla nich.
Pierwszy program
Napiszmy więc jakiś banalny program by przetestować, czy nasze środowisko PlatformIO w ogóle działa. Utworzymy projekt 'Test' który docelowo będzie przeznaczony dla płytki z układem STM8S105K4T6 – popularna płytka w kolorze czarnym z tym układem dostępna w sieci – i jako framework wybierzemy Standard Pheripheral Library.
Ponieważ jeszcze nie ma odpowiednich narzędzi i plików dla wybranego zestawu to PlatformIO teraz je sobie pobierze, co zajmie niestety dłuższą chwilę. Po zakończeniu pobierania i rozpakowywania z lewej strony w oknie Workspace powinien się pojawić nasz nowy projekt.
W sekcji 'src' możemy teraz stworzyć nowy plik 'main.c':
Code: Select all
int i;
int main(void){
while(1){
if(++i > 9) i = 0;
}
}
Jeśli teraz skorzystamy z paska statusowego i umieszczonego tam polecenia Build to w oknie terminala powinniśmy otrzymać log z kompilacji zakończonej sukcesem.
Projekt dla STM8S z wykorzystaniem Standard Peripheral Library
Czas na coś większego kalibru z wykorzystaniem już biblioteki SPL. Napiszmy zatem małą aplikację która będzie nam migała diodą na pinie PE5. Tym razem wykorzystamy też pewne możliwości jakie daje nam układ i biblioteka. Przestawimy układ zegarowy w RCC by CPU pracowało taktowaniem za pomocą dołączonego kwarcu oraz skonfigurujemy odpowiednio GPIO.
Code: Select all
#include "stm8s.h"
/**
* @brief Konfiguracja zegara taktującego w module RCC
* @param Brak
* @retval Brak
*/
static void STM8_Clock_Setup(void)
{
/* Resetujemy parametry */
CLK_DeInit();
/* Włączamy poszczególne źródła */
CLK_LSICmd(ENABLE);
CLK_HSICmd(ENABLE);
CLK_HSECmd(ENABLE);
/* Włączamy możliwość zmiany stanu multiplekserów */
CLK_ClockSwitchCmd(ENABLE);
/* Wyłączamy podstawowy dzielnik HSI */
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
/* Wyłączamy dzielnik CPU */
CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
/* Przełączamy się na taktowanie zewnętrzne
* nie blokując pozostałych
*/
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO,
CLK_SOURCE_HSE,
DISABLE,
CLK_CURRENTCLOCKSTATE_ENABLE);
}
/**
* @brief Główna funkcja programu
* @param Brak
* @retval Kod wyjścia - Brak
*/
int main(void)
{
/* Ustawiamy pracę taktowania w module RCC */
STM8_Clock_Setup();
/* Ustalamy pracę portu PE5 jako wyjście */
GPIO_DeInit(GPIOE);
GPIO_Init (GPIOE, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
for(;;) {
/* Będziemy w pętli zmieniać stan LED */
for(uint16_t i = 0; i < 65535; i++) {};
GPIO_WriteReverse(GPIOE, GPIO_PIN_5);
}
}
Próba kompilacji tego przykładu w tej chwili na pewno się nie powiedzie. Mimo, że dołączyliśmy nadrzędny plik nagłówkowy stm8s.h to nadal brakuje nam pliku z konfiguracją modułów wchodzących w skład SPL. Trzeba w przykładach odnaleźć jeszcze plik stm8s_conf.h i też umieścić go w sekcji 'src'. Dzięki niemu biblioteka wie co w danym układzie jest aktywne, a co nie.
Szkoda, że PlatformIO samo tego nie robi lub nie proponuje by to zrobić, tym bardziej, że trzeba ten plik wydobywać gdzieś z przykładów.
Teraz kompilacja powinna zakończyć się pełnym sukcesem. Ale czy na pewno?
Przykra niespodzianka
I tu spotyka nas nieco przykra niespodzianka wynikająca z działania samego linkera SDCC. Otóż taki prosty program gdzie wykorzystaliśmy tylko kilka funkcji bibliotecznych z modułów CLK i GPIO zajął nam, aż 72% pamięci Flash!
Code: Select all
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [ ] 0.0% (used 0 bytes from 2048 bytes)
Flash: [======= ] 72.5% (used 11879 bytes from 16384 bytes)
Jak się okazuje, to linker dołączył nam całą skompilowaną ze źródeł bibliotekę SPL do programu. Nawet jeśli nie używamy pozostałych modułów i funkcji w nich umieszczonych. W Moim pseudo środowisku nie ma tego problemu. Wszystko przez to, że tam najpierw skompilowałem sobie cały SPL i całość umieściłem w osobnej bibliotece obiektowej. Linker wtedy pobiera sobie z biblioteki tylko te funkcje, które były niezbędne, a nie całość.
Tutaj by obejść problem należy tak zmodyfikować plik stm8s_conf.h by kompilacji poddane były tylko wyłącznie te moduły, które używamy. Drastycznie zmniejszy to rozmiar kodu wynikowego do kilku procent. Oczywiście przy zmianach w programie, gdzie wykorzystamy kolejne moduły trzeba będzie uaktualnić plik stm8s_conf.h inaczej otrzymamy całą masę błędów.
Zakomentujmy zatem wszystkie dyrektywy #include poza tymi dotyczącymi RCC (CLK) oraz GPIO. Ponowna kompilacja powinna nam dać plik wynikowy w okolicach 1300 bajtów.
To może spróbujmy teraz skompilowany program wgrać do procesora? PlatformIO też nam może to umożliwić. Jeśli mamy programator ST-LINK V2 to wystarczy, że w pliku platformio.ini dopiszemy jedną linię konfiguracyjną:
Code: Select all
upload_protocol = stlinkv2
Teraz na pasku statusu można kliknąć polecenie Upload. PlatformIO najpierw sprawdzi czy ma zainstalowane narzędzia do obsługi programatora, jeśli nie to sobie pobierze z sieci. Następnie przystąpi do ponownego przebudowania projektu i korzystając z wygenerowanego pliku test1.ihx załaduje jego zawartość do procesora.
Zakończenie
Czy warto? Dla osób, które szybko chcą zacząć z mikrokontrolerami i mieć jedno środowisko projektowe dla kilku platform i nie przeszkadza im to, że najczęściej używanym frameworkiem będzie Arduino to tak.
Dla osób, które by chciały korzystać ze zunifikowanego środowiska dla STM8S – tu sprawa jest IMO nieco dyskusyjna. Trzeba sobie umieć poradzić z pewnymi niedoskonałościami PlatformIO oraz backendu w postaci ukrytego pod PlatformIO kompilatora SDCC. Dodatkowo PlatformIO korzysta już z historycznej wersji kompilatora SDCC 3.8.4, a parę dni temu wydana została wersja 4.1.0. Mimo, iż sprawa została już zgłoszona dość dawno na GitHub-ie to dalej nikt nie dokonał aktualizacji paczki.
Dzisiejsza aktualizacja podniosła wersję SDCC do 4.1.0, zatem "modły zostały wysłuchane".