28 czerwca 2018

Pierwszy projekt - opcja minimum

Jak poprzednio napisałem Atollic TrueSTUDIO jakoś nie wzbudziło mojego szaleńczego entuzjazmu. Nie pozostaje więc nic innego niż zakasać rękawy i przygotować projekt bez tego narzędzia. W sumie to zestaw nakładek, na eclipse, gcc, gdb, openocd, więc nie powinno być problemu z poradzeniem sobie bez niego.
Na początek kompilator. Pod linuxem jest łatwo - arm-none-eabi-gcc jest dostępny w paczce. Więc wystarczy odpalić:

apt install gcc-arm-none-eabi

I gotowe, kompilator już jest. Pod windowsem można pobrać gcc dla arm-a i zainstalować bez problemu, ale nie mam teraz tego systemu pod ręką, zostanę więc przy linuksie.
Teraz pojawia się problem - jakie opcje do kompilacji są potrzebne. gcc posiada niesamowitą liczbę opcji, na początek to nie ułatwia. Ale skoro TrueStudio sobie radzi, a używa narzędzi open-source to może warto "podpatrzeć" co ono robi. Zaglądam do loga kompilacji przykładowego kodu:

arm-atollic-eabi-gcc -c ../Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -std=gnu11 -DSTM32F42_43xxx -DUSE_STDPERIPH_DRIVER -DHSE_VALUE=8000000 -DUSE_STM32F429I_DISCO -I../src -I../Libraries/CMSIS/Include -I../Libraries/Device/ST/STM32F4xx/Include -I../Libraries/STM32F4xx_StdPeriph_Driver/inc -I../Utilities/Common -I../Utilities/STM32F429I-Discovery -O0 -ffunction-sections -fdata-sections -g -fstack-usage -Wall -specs=nano.specs -o Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.o

W pierwszej chwili wygląda, że tego sporo, ale wszystkie -I -D oraz ścieżki do plików można pominąć - wtedy zostaje:

arm-atollic-eabi-gcc -c stm32f4xx_usart.c -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -std=gnu11 -O0 -ffunction-sections -fdata-sections -g -fstack-usage -Wall -specs=nano.specs -o stm32f4xx_usart.o

Nie ma co się bać nazwy z "attolic" to i tak zwykły gcc. Zostają więc opcje:

-mthumb 
-mcpu=cortex-m4 
-mfloat-abi=hard 
-mfpu=fpv4-sp-d16 
-std=gnu11 
-O0 
-ffunction-sections 
-fdata-sections 
-g 
-fstack-usage 
-Wall 
-specs=nano.specs 

Warto byłoby dokładnie wszystkie sprawdzić, ale na razie zostawię ten problem "na później".
Jest jeszcze jeden ważny element - linkowanie aplikacji. Znowu zaglądam do logów TrueStudio - tym razem pominę pełną wersję, była bardzo długa, ale po usunięciu plików .o wygląda tak:

arm-atollic-eabi-gcc -o test01.elf -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -T../stm32f4_flash.ld -specs=nosys.specs -static -Wl,-cref,-u,Reset_Handler -Wl,-Map=test01.map -Wl,--gc-sections -Wl,--defsym=malloc_getpagesize_P=0x80 -Wl,--start-group -lc -lm -Wl,--end-group -specs=nano.specs 



Czyli użyte są następujące opcje:

-mthumb 
-mcpu=cortex-m4 
-mfloat-abi=hard 
-mfpu=fpv4-sp-d16 
-T../stm32f4_flash.ld 
-specs=nosys.specs 
-static 
-Wl,-cref,-u,Reset_Handler 
-Wl,-Map=test01.map 
-Wl,--gc-sections 
-Wl,--defsym=malloc_getpagesize_P=0x80 
-Wl,--start-group 
-lc 
-lm 
-Wl,--end-group 
-specs=nano.specs 

Warto zwrócić uwagę na opcję -T która wskazuje na skrypt linkera stm32f4_flash.ld - będzie nam potrzebny.
Poza tym -specs występuje dwa razu, jak widać autorzy TrueSTUDIO sami się gubią w swoim przerośniętym narzędziu.

Wiadomo już jak TrueSTUDIO kompiluje projekty. Można, a nawet warto najpierw przetestować działanie arm-none-eabi-gcc z linii poleceń. Jednak po chwili staje się to nudne i niewygodne.
Na szczęście dostępne są różne narzędzia wspomagające kompilację kodu. Ja wybrałem starego (nawet bardzo starego), ale dobrego make-a.
Pierwsza wersja mojego Makefile-a wygląda następująco:

CROSS_COMPILE=arm-none-eabi-
AS=$(CROSS_COMPILE)as
CC=$(CROSS_COMPILE)gcc
SIZE=$(CROSS_COMPILE)size

CFLAGS=-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -std=gnu11 -O0 \
        -ffunction-sections -fdata-sections -g -fstack-usage -Wall -specs=nano.specs

LDFLAGS=$(CFLAGS) -Wl,--gc-sections -specs=nosys.specs -Wl,-cref,-u,Reset_Handler \
        -Wl,-Map=bin/test01.map -Tsrc/stm32f4_flash.ld

all: bin/test01.elf
        $(SIZE) $<

bin/test01.elf: obj/main.o obj/startup_stm32f429xx.o
        $(CC) $(LDFLAGS) -o $@ $^

obj/main.o: src/main.c
        $(CC) $(CFLAGS) -o $@ -c $<

obj/startup_stm32f429xx.o: src/startup_stm32f429xx.s
        $(CC) $(CFLAGS) -o $@ -c $<

debug: bin/test01.elf
        openocd -f board/stm32f429discovery.cfg -f interface/stlink-v2.cfg \
                -c "init; sleep 200; reset halt; wait_halt; \
                flash write_image erase bin/test01.elf; \
                reset run; sleep 10; shutdown"

clean:
        rm -f bin/* obj/*

Do programowania płytki stm32f429-discovery używam openocd co widać w załączonym pliku. Pod Debianem, na którym pracuję wystarczyło zainstalować gotowy pakiet. OpenOCD jest oczywiście dostępny w innych dystrybucjach oraz systemach, więc pod Windą, czy Mac OS nie powinno być z nim problemów.

Teraz pozostaje zebrać pliki źródłowe. Potrzebujemy:
  • startup_stm32f429xx.s - zawiera kod uruchamiany po resecie mikrokontrolera 
  • stm32f4_flash.ld - skrypt linkera
  • main.c - pierwsza aplikacja

Pierwsze dwa pliki możemy "podebrać" z TrueSTUDIO, albo lepiej pobrać bibliotekę Cube HAL dla stm32f4: https://www.st.com/en/embedded-software/stm32cubef4.html
Pobierając bibliotekę szybko odkryjemy, że straciliśmy kolejne 2GB przestrzeni dyskowej... Zaczynam mocno podejrzewać, że ST podukuje jakieś układy do dysków twardych i bardzo dba o generowanie zapotrzebowania na nie.
W każdym razie pliki należy skopiować i nieco zmienić pierwszy, czyli startup_stm32f429xx.s. Znajdziemy w nim wywołanie funkcji SystemInit (przed main). Nie mamy tej funkcji zdefiniowanej, więc najlepiej na razie zakomentować linijkę która ją wywołuje.
 
Przydadzą się również pliki nagłówkowe:
  • stm32f429xx.h
  • cmsis_gcc.h
  • core_cmFunc.h
  • core_cmSimd.h 
  • core_cm4.h
  • core_cmInstr.h
Pierwszy zawiera definicje rejestrów mikrokontrolera - jest bardzo ważny i wart dodania do projektu. Pozostałe to praktycznie śmieci, o przepraszam biblioteka CMSIS... Są włączane przez pierwszy, więc na razie warto je dodać - w wolnej chwili może uda się ich pozbyć.
Plik stm32f429xx.h poza włączaniem wspomnianych śmieci stara się również dodać plik system_stm32f4xx.h. Tego pliku nie potrzebujemy, najlepiej więc usunąc linię która się do niego odwołuje.

Na koniec pozostaje napisać pierwszy program i zapisać go jako main.c:

#include <stdint.h>
#include "stm32f429xx.h"

int main(int argc, char *argv[])
{
        volatile uint32_t dly;

        RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN;

        GPIOG->MODER |= GPIO_MODER_MODE13_0|GPIO_MODER_MODE14_0;

        while (1) {
                GPIOG->BSRR = GPIO_BSRR_BS13;
                GPIOG->BSRR = GPIO_BSRR_BR14;
                for (dly = 0; dly < 500000; dly++)
                        ;
                GPIOG->BSRR = GPIO_BSRR_BS14;
                GPIOG->BSRR = GPIO_BSRR_BR13;
                for (dly = 0; dly < 500000; dly++)
                        ;
        }

        return 0;
}


27 czerwca 2018

Szybki falstart, czyli Atollic TrueSTUDIO

Do niedawna dość dobrym, a co najważniejsze darmowym środowiskiem do pisania programów dla STM32 był OpenSTM32 (nazywany również AC6): http://www.openstm32.org/HomePage
Poprzednio o nim wspominałem. Sporo czasu jednak minęło i podobno jest to już mocno przestarzałe rozwiązanie. ST ponoć przestał wspierać inicjatywę, zainwestował za to w produkt firmy Atollic - albo raczej w całą firmę.
W każdym razie słyszałem, że teraz wskazane jest używanie Atollic TrueSTUDIO (https://atollic.com/truestudio/). Postanowiłem to sprawdzić.
Na początek trzeba pobrać pakiet instalacyjny. Podobnie jak OpenSTM32 również TrueStudio to nakładka na Eclipse. Jednak producent mocniej stara się to ukrywać i trzeba pobrać cały pakiet - w wersji dla Linuxa to 740MB, jakoś sporo, ale mamy XXI wiek więc trzeba się przyzwyczaić.
Po rozpakowaniu i instalacji jest jeszcze gorzej - 2.1GB dysku zajęte przez wtyczkę do Eclipse. Miejmy nadzieję, że to chociaż dobra wtyczka.
Uruchomienie programu nie ujawnia niespodzianek - zwykły Eclipse, nic specjalnego.
Tworzę pierwszy projekt i tutaj miłe zaskoczenie. Dostępne są szablony projektów dla bardzo wielu mikrokontrolerów STM32, nawet płytki ewaluacyjne są do wyboru. Super, wybieram więc moją stm32f429-discovery, cierpliwie przyciskam next, next, next i gotowe, mam pierwszy projekt!


Tutaj pierwsza myśl - przegapiłem wybór biblioteki. Co więcej projekt używa StdPeriph, do dobra biblioteka, ale nieco wiekowa jak na nowy wyrób.
Spróbowałem więc ponownie i zonk! TrueSTUDIO zawsze używa StdPeriph. Nie można sobie w Cube HAL projektu przygotować. Pewnie autorzy uznali, że od tego jest Cube MX, ale ja mam uczulenie na ten strasznie niedopracowany wyrób programo-podobny.
Jako ciekawostkę wygenerowałem projekt dla nowszego układu, który nie jest wspierany przez StdPeriph - wtedy TrueSTUDIO po cichu zmienia bibliotekę i stosuje Cube... Jednym słowem pakiet ma własne AI i wie lepiej czego chcemy.
Wniosek z eksperymentu jest taki - TrueSTUDIO nawet działa i pewnie można z niego korzystać. Ale jeśli nie chcemy żeby komputer był inteligentniejszy od nas, lepiej je chyba potraktować jako ciekawostkę która tylko marnuje miejsce na dysku. W każdym razie taki mam plan. Od następnego wpisu już z tego środowiska nie zamierzam korzystać.

Powrót do pisania bloga i zmiana platformy

Jak ten czas szybko biegnie. Na chwilę znudziło mi się pisanie bloga, a jak popatrzę na daty wpisów już ponad rok czasu minął. Dlaczego mi się znudziło? Jak zwykle powodów jest wiele, więc właściwie to ciężko powiedzieć. W sumie to chyba głównie dlatego, że obiecałem dokończyć kurs stm32f103 na HAL z Cube (https://forbot.pl/blog/kurs-stm32-f1-migracja-na-hal-wstep-spis-tresci-id23580) i w efekcie ten mikrokontroler obrzydł mi już całkiem. Nie dlatego, że to zły układ - może trochę dlatego że nie przepadam za bibliotekami, ale na pewno dlatego że to już drugi kurs (poprzedni wykorzystywał StdPeriph). Więc po dwóch kursach oraz początku bloga mogę chyba już mieć stm32f103 serdecznie dosyć.
Postanowiłem więc wrócić do pomysłu pisania programów z minimalną liczbą bibliotek, ale tym razem na trochę innym mikrokontrolerze. Mój wybór padł na stm32f429 oraz płytkę ewaluacyjną discovery: https://www.st.com/en/evaluation-tools/32f429idiscovery.html


Dlaczego akurat ta płytka? Po pierwsze zadecydowała cena - jest bardzo przyzwoita w porównaniu z nowszymi stm32f7xx. Poza tym na płytce znajdziemy peryferia, które niełatwo podłączyć samemu: ekran LCD oraz pamięć SDRAM. Dostępny jest również interfejs USB - więc zabawa płytką może dostarczyć sporo emocji w porównaniu z innymi produktami w większości oferującymi bardziej standardowe interfejsy.