logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Raspberry pi 3 A+ bare metal - mini uart

_lazor_ 02 Gru 2018 21:30 5127 24
  • Raspberry pi 3 A+ bare metal - mini uart

    1. Wstęp

    Raspbbery Pi jako platforma edukacyjna dla linuksa okazała się wielkim sukcesem . Dalszy rozwój platformy zaowocował zastosowaniem rdzeni cortex-A53 o architekturze 64bit oraz 4 rdzeniach. Zachęcam jak najbardziej do używania linuksa i jego nauki. Z drugiej strony czy jest możliwe programowanie maliny, niczym mikrokontrolera bez systemu operacyjnego?
    Oczywiście, że jest to możliwe, chociaż jest to trochę bardziej złożone, gdyż sercem maliny nie jest cortex-A, tylko VC (VideoCore) od którego wszystko się zaczyna.

    2. Proces bootup'u

    Na początku wstaje VC, który uruchamia pierwszy bootloader zawarty w pamięci nieulotnej samego VC. Jego zadaniem jest skonfigurować układ aby mógł odczytać kolejny bootloader: bootcode.bin. Ten kawałek kodu zostaje przekopiowany do pamięci L2 i uruchomiony przez VC. Kontynuuje konfigurację (konfiguracja SDRAM) i wczytuje trzeci już bootloader: start.elf. Zostaje zaczytany plik konfiguracyjny config.txt, który jest substytutem BIOS, zostają uruchomione rdzenie cortex-A oraz kernel linuksa zostaje skopiowany do pamięci SDRAM. Kernel linuksa zaczyna być wykonywany przez rdzenie cortex-A53. Piszę tutaj o kernelu linuksa a artykuł ma być na temat bare metal na raspberry Pi 3 A+, tak więc gdzie ten bare metal?
    Już odpowiadam. Podmienimy plik kernel7.img naszym własnym kodem.

    Więcej o pliku config.txt można przeczytać tutaj:
    https://elinux.org/RPiconfig

    Oczywiście można również zmodyfikować sam bootcode.bin aby wyświetlić informacje z procesu bootup’u na mini UART:

    https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/README.md

    Raspberry pi 3 A+ bare metal - mini uart

    3. Narzędzia

    Zanim przejdziemy do pisania kodu, musimy uzbroić się w odpowiednie narzędzia:

    - Kompilator dla architektury AArch64:
    https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
    lub
    https://www.linaro.org/downloads/

    - Emulator terminala (na przykład Termite)
    - cygwin (z make), mingw lub inny substytut make na windows (nie dotyczy linuksa)
    - Konwerter UART/USB
    - quemu

    4. Podłączenie konwertera USB/UART

    GND konwertera do pinu 6 (GND)
    RXD konwertera do pinu 8 (GPIO14 – TXD0)
    TXD konwertera do pinu 10 (GPIO15 – RXD0)

    Raspberry pi 3 A+ bare metal - mini uart

    5. startup.S

    start.S
    Kod: text
    Zaloguj się, aby zobaczyć kod


    W przeciwieństwie do cortex-M, cortex-A nie startuje z predefiniowanej sekwencji, a po inicjalizacji przez GPU od razu zaczyna wykonywać kod. Warto zwrócić uwagę na to, że wszystkie 4 rdzenie startują jednocześnie i w aktualnym przykładzie nie wszystkie nam będą potrzebne, dlatego zatrzymujemy je, wchodząc w nieskończoną pętle. Kolejną różnica między cortex-M a cortex-A jest adres stosu. W tym przypadku musimy go samodzielnie ustawić.
    Jako, że kernel linuksa zostaje skopiowany do pamięci SRAM, nie mamy potrzeby samodzielnego przenoszenia sekcji .data do RAM, gdyż robi to za nas bootloader. Nadal jednak mamy sekcję .bss, którą należy wyzerować.

    6. skrypt linkera

    link.ld
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Skrypt linkera rozpoczyna wrzucanie kodu pod adres 0x8000 wynikający z konwencji kernela linuksa. W naszym wypadku nie jest wymagane, ale jako że raspberry pi jest tworem dedykowanym dla linuksa, warto się jej trzymać:
    http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html

    Ważne by sekcja .text.boot była pierwszą sekcją pod adresem 0x8000 oraz aby nie została zoptymalizowana przez AS z powodu braku referencji do tej sekcji, aby temu zapobiec używamy KEEP().
    Sekcja .data nie wymaga przenoszenia, gdyż robi to za nas bootloader.

    7. main

    main.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W naszym main nie dzieje się za wiele. Najpierw inicjalizujemy mini uart, piszemy słowo „Hello” i wchodzimy w nieskończoną pętle, która będzie odsyłała każdy znak jaki prześlemy po mini uart.

    8. Obsługa mini uart

    uart.h
    Kod: text
    Zaloguj się, aby zobaczyć kod


    uart.c
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Bez dokumentacji tym razem się już nie obejdzie. Niestety dokumentacja jest dość skromna i zawiera bardzo wiele błędów to można z niej wygrzebać interesujące nas informacje. Jedno ostrzeżenie, broadcom nie podołał jakże trudnemu zadaniu zmiany rysunków i tyczą się one SoC BCM2835, chociaż tekście są już poprawne adresy.
    https://github.com/raspberrypi/documentation/files/1888662/

    Co nas interesuje? Adres pod którym zaczynają się rejestry peryferiów:
    „Physical addresses range from 0x3F000000 to 0x3FFFFFFF for peripherals.”

    Najstarszy bajt się nie zmienia, więc zdefiniujmy go jako:
    #define MMIO_BASE 0x3F000000

    Dzięki temu pozostałe adresy będą pozbawione ciągle powtarzającego się wspólnego początku.
    W rozdziale 2.2.1 mamy opis działania mini uart. Chociaż w dokumentacji mamy adres 0x7E21 5040, ale odnosi się do video core CPU Bus, ale poprzez VC/ARM MMU (memory menagment unit) jest zmapowany jako adres fizyczny ARM 0x3F21 5040.
    Reszta kodu jest już bardzo łatwa do analizy i pozostawiam ją Tobie, jako forma ćwiczenia.

    9. Makefile, qemu i termite

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Tak jak i w poprzednim przykładzie dla cortex-M:

    https://www.elektroda.pl/rtvforum/topic3520355.html#17597051

    Budujemy nasz kod bez użycia standardowych bibliotek. Nowym elementem jest nowa opcja run. Ta opcja uruchamia emulator qemu, dzięki któremu możemy testować nasz kod bez ciągłego uciążliwego przekładania karty SD.
    Po zainstalowaniu qemu i dodaniu go zmiennej środowiskowej PATH możemy wywołać opcję run i przetestować działanie

    Raspberry pi 3 A+ bare metal - mini uart

    Aby uruchomić nasz program na malinie musimy przygotować naszą kartę SD według polecenia raspberry pi fundation:
    https://www.raspberrypi.org/documentation/installation/sdxc_formatting.md
    Następnie kopiujemy na kartę następujące elementy:
    - bootcode.bin
    - fixup.dat
    - start.elf
    - kernel8.img

    Pierwsze trzy są dostępne tutaj:
    https://github.com/raspberrypi/firmware/tree/master/boot
    a kernel8.img jest wynikiem kompilacji naszego projektu. Uruchamiamy termite i konfigurujemy go jak na obrazku (com7 będzie mieć inną wartość):

    Raspberry pi 3 A+ bare metal - mini uart

    Wsuwamy kartę SD do maliny podpinamy konwerter USB/UART i zasilamy układ. Naszym oczom powinien się pokazać tekst wysłany z maliny:

    Raspberry pi 3 A+ bare metal - mini uart

    10. podsumowanie

    Pisanie kodu bare metal na raspberry pi jest możliwe i otwiera bardzo wiele możliwości, to niestety sama platforma nie jest przyjazna do tego typu pracy. Jednocześnie jest to stosunkowo tania i popularna platforma by zaznajomić się z rdzeniami cortex-A, które są znacznie bardziej złożone od cortex-M.
    Jeśli jednak chcemy zapoznać się w programowaniu układów 64bit, zbudować własny bardziej zaawansowany system operacyjny, potrzeba nam większej mocy obliczeniowej, zacząć zabawę z układami wielordzeniowymi, zapoznać się z cortex-A czy wszystko jednocześnie to myślę że jest to układ dla Ciebie.
    W sieci jest wiele dostępnych tutoriali, które pozwolą na lepszym zapoznaniu się z platformą niż mój dość skromny artykuł, który ma tylko zwrócić uwagę na to że tego typu programowanie jest możliwe na raspberry pi i nie jest to żaden „rocket science”.


    Linki warte uwagi:

    https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/README.md

    http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

    https://wiki.beyondlogic.org/index.php?title=Understanding_RaspberryPi_Boot_Process

    https://github.com/bztsrc/raspi3-tutorial

    https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/

    https://github.com/s-matyukevich/raspberry-pi-os
    O autorze
    _lazor_
    Moderator Projektowanie
    Offline 
    Materiały video na temat energoelektroniki:
    https://www.youtube.com/user/sambenyaakov/videos
    Specjalizuje się w: Programista embedded/ elektrotechnik
    _lazor_ napisał 3795 postów o ocenie 1123, pomógł 259 razy. Mieszka w mieście Wrocław. Jest z nami od 2016 roku.
  • #3 17604048
    _lazor_
    Moderator Projektowanie
    Myślę, że raspberry pi 3 A+ nie będzie miała gorszych osiągów niż jej poprzedniczki a znalazłem w sieci taki benchmark:
    http://codeandlife.com/2012/07/03/benchmarking-raspberry-pi-gpio-speed/

    Wynika z tego, że można osiągnąć do 22Mhz z jeszcze jako takim kształtem prostokąta.
  • #4 17611612
    Konto nie istnieje
    Poziom 1  
  • #5 17611682
    _lazor_
    Moderator Projektowanie
    W sumie dobra uwaga, jeśli można się dobrać do jtag to już można trochę poszaleć. A samo uruchomienie debugowania dla więcej niż jednego core może być cennym doświadczeniem.

    Jednak warto pamiętać, że oprócz ARMów jest tak VideoCore, na którego nie mamy i tak dużego wpływu.

    Ten artykuł ma raczej pokazać, że większe procesory również nie są czarną magią i może kogoś to zachęci do pogłębiania swojej wiedzy, chociaż nie jest to trywialne zagadnienie.
  • #6 17611746
    Konto nie istnieje
    Poziom 1  
  • #7 17611788
    _lazor_
    Moderator Projektowanie
    Płytki developerskie są stosunkowo drogie, ale są faktycznie znacznie ciekawsze od raspberry pi. Popatrzmy na takiego beaglebone-x15:

    Cytat:

    Processor: TI AM5728 2×1.5-GHz ARM® Cortex-A15
    2GB DDR3 RAM
    4GB 8-bit eMMC on-board flash storage
    2D/3D graphics and video accelerators (GPUs)
    2×700-MHz C66 digital signal processors (DSPs)
    2×ARM Cortex-M4 microcontrollers (MCUs)
    4×32-bit programmable real-time units (PRUs)


    Wypas board, ale koszt ponad 1000zł jest dość dyskusyjny jak na zabawy w pojedynkę (inna sprawa, że ciężko w pojedynkę wykorzystać pełen potencjał z tej płytki).
  • #8 17611815
    Konto nie istnieje
    Poziom 1  
  • #9 17611843
    _lazor_
    Moderator Projektowanie
    No cóż mi jest dane pracować przy systemie bare metal z wieloma rdzeniami, więc nie mówię czegoś z kapelusza tylko jak jest u mnie. Oczywiście nie jestem architektem, trochę mi jeszcze wiedzy i doświadczenia brakuje, ale praca przy takim systemie jest bezcenna.

    Inna sprawa, że mi w moim przypadku zależy na naprawdę szybkim zegarze (ponad 1Ghz) z instrukcjami DSP. A jak wiadomo ARM cortex-A ma NEON, którego jak najbardziej chce się nauczyć. To ma być srogie przetwarzanie sygnału. Dlaczego? Bo klepie to w domu i mogę :D
    Na początku chciałem użyć TI delfino, który ma również dwa rdzenie, trochę PRU, tani(board 200zł) oraz jest rdzeniem DSP, ale zegar 200Mhz to nie jest coś co mnie zadowoli.
  • #10 17612710
    Konto nie istnieje
    Poziom 1  
  • #11 17612773
    _lazor_
    Moderator Projektowanie
    Jeśli układ jest customowy (nie jest to coś nadzwyczajnego, że duże firmy dostają zabawki tylko dla siebie) to raczej nie skorzystasz z gotowych rozwiązań.
  • #12 17613167
    Konto nie istnieje
    Poziom 1  
  • #13 18443328
    Konto nie istnieje
    Poziom 1  
  • #14 18443844
    _lazor_
    Moderator Projektowanie
    Tak
    W czym chcesz pisać w c czy cpp? jeśli w cpp to musisz trochę linker zmienić oraz plik startup aby zapewnić wymagania języka.
  • #15 18444271
    Konto nie istnieje
    Poziom 1  
  • #16 18444293
    _lazor_
    Moderator Projektowanie
    Cóż to nie jest cortex-m i z debugowaniem będzie problem. Podobno jakoś można, przez jtag, ale na pewno nie przez st-link.
    Jedyne co można to podpiąć pod eclipse budowanie i projekt.
  • #17 18444325
    Konto nie istnieje
    Poziom 1  
  • #18 18444355
    _lazor_
    Moderator Projektowanie
    W eclipse możesz zaimportować projekt poprzez
    import->c/c++/existing code as makefile project/folder z projektem

    Indekser eclipse powinien się połapać co i jak.

    Co do nadpisania to nie mam pojęcia o co chodzi, ale wychodzi na to że czas by się poduczyć.
  • #19 18444835
    Konto nie istnieje
    Poziom 1  
  • #20 18444885
    _lazor_
    Moderator Projektowanie
    Wskazujesz folder z projektem czyli tak folder z plikami.
  • #21 18450825
    Konto nie istnieje
    Poziom 1  
  • #22 18451683
    _lazor_
    Moderator Projektowanie
    Niestety nie wiem jak wygląda hardware dla RPi 4. Trzeba poczekać aż ludzie zrobię reverse engineering lub fundacja da jakiś skrawek dokumentacji
  • #23 18451721
    Konto nie istnieje
    Poziom 1  
  • #24 18452058
    _lazor_
    Moderator Projektowanie
    https://github.com/LdB-ECM/Pi_AARCH64_Baremetal/tree/master/SayHello

    Ma dorzucone gotowe obrazy, to możesz przetestować je bez budowania projektu.
  • #25 18452859
    Konto nie istnieje
    Poziom 1  
REKLAMA