Architektura ARM Cortex-Mx („mikrokontrolerowa”), obecnie w wersjach v6, v7 i v8, jest dojrzałym, wypróbowanym rozwiązaniem do ekonomicznych aplikacji systemów wbudowanych. Jej zaletami są: ogromna popularność wiążąca się z dostępnością narzędzi i doświadczeniem inżynierskim, skalowalność umożliwiająca wytwarzanie zarówno prostych mikrokontrolerów o cenie detalicznej na poziomie 0,10 USD, jak i rozbudowanych układów o dużej mocy obliczeniowej, a także – co ważne w systemach wbudowanych – zaprojektowany od nowa 15 lat temu dla ARMv6-M, nowatorski system obsługi wyjątków, w tym wielopoziomowy system przerwań z wywłaszczaniem, eliminujący wady spotykane w starszych architekturach.
ARM-M ma również pewne wady, z których główną jest to, że architektura stanowi własność firmy ARM, co pociąga za sobą konieczność ponoszenia przez producentów opłat licencyjnych i uniemożliwia dokonywanie modyfikacji, w tym rozszerzeń procesorów przez producentów poszczególnych układów.
Architektura RISC-V powstała jako rezultat prac doświadczalnych, prowadzonych około roku 2010 na uniwersytecie Berkeley. Jest ona uwspółcześnioną wersją architektury MIPS, wywodzącej się jeszcze z lat 80. XX wieku. W przeciwieństwie do ARM i MIPS, RISC-V jest architekturą otwartą – każdy może zaprojektować własny procesor zgodny z RISC-V, jest również możliwe rozszerzanie własności architektury, w tym listy instrukcji procesora. Projektant i producent procesora ma pełną kontrolę nad jego implementacją, nie musi on więc polegać na zaufaniu do dostawcy produktu zamkniętego, jak ma to miejsce w przypadku architektur ARM. Ma to również wpływ na model bezpieczeństwa, bazujący na otwartości i możliwości wskazywania błędów w znanym projekcie implementacji procesora (o ile sam projekt procesora pozostaje otwarty, co pozostaje w gestii jego właściciela).
Mikrokontroler RP2040
Chcąc rozszerzyć swoją aktywność na obszar niskokosztowych rozwiązań mikrokontrolerowych, Fundacja Raspberry Pi w styczniu 2021 wprowadziła na rynek swój pierwszy mikrokontroler – RP2040 – wraz z gotowymi modułami/płytkami uruchomieniowymi. W porównaniu z mikrokontrolerami innych producentów miał on dość nietypową charakterystykę, wynikającą z zastosowanej technologii półprzewodnikowej – zawierał dwa rdzenie ARM Cortex-M0+ o wysokiej maksymalnej częstotliwości pracy (133 MHz) i pamięć RAM o pojemności 264 kB oraz niemodyfikowalną pamięć ROM o pojemności 16 kB. Układ RP2040 jest zasilany napięciem z przedziału 1,8..3,3 V, a sam rdzeń pracuje z napięciem 1,1 V, wytwarzanym przez wbudowany stabilizator liniowy.
Ponieważ mikrokontroler nie zawiera programowalnej pamięci nieulotnej, oprogramowanie użytkowe może być albo ładowane przez jeden z dostępnych interfejsów do pamięci RAM i z niej wykonywane, albo uruchamiane bezpośrednio z pamięci Flash dołączonej do interfejsu QSPI mikrokontrolera. Pierwsza możliwość ma zastosowanie wyłącznie wtedy, gdy mikrokontroler jest używany jako inteligentny sterownik wejścia-wyjścia współpracujący z systemem nadrzędnym. Do zastosowań „wolno stojących” niezbędne jest użycie zewnętrznej pamięci Flash z serii 25Q.
Przepustowość interfejsu QSPI jest znacznie mniejsza od wymaganej przez rdzenie nowoczesnych procesorów szybkości pobierania instrukcji. Interfejs pamięci został w związku z tym wyposażony w bufor przyspieszający powtarzające się sekwencje odwołań (np. podczas wykonywania pętli programowych). Taki sposób pobierania i wykonywania programu jest określany jako XIP (Execute In Place – wykonanie bezpośrednio z pamięci QSPI). Ponieważ osiągana w ten sposób wydajność nie zawsze okazuje się wystarczająca, alternatywnym sposobem jest skopiowanie wybranych części lub całości oprogramowania z zewnętrznej pamięci Flash do wewnętrznej pamięci RAM, co gwarantuje pobieranie instrukcji bez opóźnień. Z podobnej techniki korzystają popularne mikrokontrolery firmy Espressif Systems (np. ESP8266, ESP32), a także niektóre modele STM32. Wewnętrzna pamięć RAM ma organizację wielobankową, co w połączeniu z wieloszynową strukturą wewnętrzną układu ogranicza konflikty przy równoczesnym dostępie do pamięci przez wiele modułów mikrokontrolera, w tym przy równoczesnej pracy obu rdzeni procesorowych.
Oprócz standardowego zestawu modułów peryferyjnych, podobnego do spotykanego w większości współczesnych mikrokontrolerów, RP2040 jest wyposażony w mikroprogramowany blok wejścia-wyjścia PIO, który może być użyty do realizacji nietypowych modułów peryferyjnych, w tym timerów lub niestandardowych interfejsów szeregowych.
Mikrokontroler RP235x
W upublicznionym we wrześniu 2024, nowym układzie RP235x zostały zrealizowane dodatkowe funkcje, takie jak: wbudowana pamięć masowa, stany bezczynności o niskim poborze mocy, szybsze rdzenie, więcej pamięci RAM i funkcje ochrony kodu.
RP235x występuje w czterech wersjach, które są identyfikowane w nazwie przez: liczbę rdzeni (2), cyfrę luźno powiązaną z typem rdzenia (3), log2 liczby bloków RAM po 16 kB (5), log2 liczby bloków pamięci Flash po 128 kB (0 lub 4) oraz literę oznaczającą typ obudowy (A lub B):
- RP2350A – 30 GPIO w obudowie QFN-60 o wymiarach 7×7 mm,
- RP2350B – 48 GPIO w obudowie QFN-80 o wymiarach 10×10 mm,
- RP2354A – jak RP2350A + 2 MB pamięci QSPI NOR Flash podłączonej do pierwszej linii chip select,
- RP2354B – jak RP2350B + 2 MB pamięci QSPI NOR Flash podłączonej do pierwszej linii chip select.
Układ RP2354x ma obudowę typu stack-in-one, w której pamięć Flash jest dołączona do struktury mikrokontrolera jako osobny chip.
Wyprowadzenia GPIO 30 do 47, obecne w większej obudowie, zapewniają dodatkowe piny analogowe (GPIO 40 do 47) i kilka dodatkowych IO ogólnego przeznaczenia z obsługą PWM.
Ogólna architektura układu RP235x została pokazana na rysunku 1 [6]. Procesory Cortex-M33 lub RISC-V Hazard3 uzyskują dostęp do pamięci i bloków peryferyjnych RP235x poprzez magistrale AHB i APB.
Podstawowe różnice RP235x w stosunku do RP2040 to:
- zmieniony kompleks procesorowy, zawierający dwie pary rdzeni procesorowych, o różnej architekturze – Cortex-M33 i RISC-V Hazard3.
- obsługa różnego rodzaju zabezpieczeń, w tym strefy zaufanej ARM-v8M i szyfrowania SHA-256,
- zwiększona pojemność pamięci RAM – 520 kB i ROM – 32 kB oraz dodatkowa pamięć nieulotna OTP 8 kB,
- możliwość użycia zewnętrznej pamięci Flash lub PSRAM z interfejsem QSPI,
- rozbudowany i ulepszony moduł PiO,
- impulsowy stabilizator napięcia zasilania rdzenia 1,1 V,
- szybki interfejs wejścia-wyjścia HSTX (High-Speed Serial Trasnsmit), umożliwiający realizację bardzo wydajnych interfejsów szeregowych z kodowaniem TMDS.
Wewnętrzny regulator wytwarza napięcie zasilania rdzenia, więc zazwyczaj trzeba dostarczać tylko napięcie IO. Działa on jako przetwornica typu buck w trybie przełączanym, gdy system jest aktywny, zapewniając do 200 mA przy zmiennym napięciu wyjściowym i może przełączyć się na tryb LDO o niskim prądzie spoczynkowym, gdy system jest uśpiony, zapewniając do 1 mA na potrzeby podtrzymania pamięci.
Układ RP235x ma pięć domen zasilania. Z pewnymi ograniczeniami domeny te mogą być selektywnie wyłączane, aby zmniejszyć zużycie energii przez układ. System wspiera stany niskiego poboru mocy, w których nieużywana logika jest wyłączana, zaś wybudzenie jest możliwe przy użyciu sygnałów z timera lub zdarzeń IO.
Podstawowe cechy RP235x [1, 6]:
- dwa rdzenie Arm Cortex-M33, 150 MHz z obsługą obliczeń zmiennoprzecinkowych i DSP,
- dwa rdzenie RISC-V Hazard 3, 150 MHz,
- 520 kB wbudowanej pamięci SRAM w dziesięciu bankach,
- RP2350 – brak wewnętrznej pamięci Flash, RP2354 – 2 MB wewnętrznej pamięci QSPI NOR Flash,
- dwa wbudowane układy PLL do generowania zegarów USB i rdzenia,
- obsługa do 16 MB zewnętrznej pamięci Flash za pośrednictwem dedykowanej magistrali QSPI,
- kontroler DMA,
- kompleksowa architektura bezpieczeństwa oparta na Arm TrustZone (rdzenie Cortex-M), obejmująca:
- wsparcie bezpiecznego rozruchu,
- 8 kB wbudowanej pamięci typu antifuse, programowalnej jednorazowo (OTP),
- akcelerator kryptograficzny SHA-256,
- sprzętowy generator liczb losowych (TRNG),
- zasilacz impulsowy na chipie i stabilizator LDO o niskim prądzie spoczynkowym,
- dwanaście ulepszonych maszyn stanu PIO,
- nowy blok peryferyjny HSTX do szybkiej transmisji danych,
- obsługa zewnętrznej pamięci QSPI PSRAM,
- 30/48 pinów GPIO, z czego 4/8 można wykorzystać jako wejścia analogowe
- bloki peryferyjne:
- 2× UART,
- 2× SPi,
- 2× I²C,
- 24 kanały PWM,
- kontroler USB 1.1 i PHY z obsługą hosta i urządzenia,
- 3× programowalne bloki IO (PIO), łącznie 12 maszyn stanu.
Układ RP235x, oprócz typowych układów peryferyjnych, zawiera także moduły umożliwiające programowo-sprzętową realizację szybkiej transmisji danych, w tym TMDS. Moduły te pozwalają m.in. na sterowanie wyświetlaczami w standardach DVI i VGA.
Każdy blok PIO zawiera 4 niezależne automaty o takim samym mikroprogramie. Mikroprogram może mieć długość do 32 instrukcji, przy czym dostępnych jest 9 różnych poleceń. Każdy automat zawiera: 2 rejestry przesuwne do współpracy z wejściami/wyjściami, 2 rejestry robocze, 2 kolejki FIFO do wymiany danych z procesorem, rejestr stanu/przerwań i interfejs DMA.
Interfejs debugowania SWD układu RP235x współpracuje z trzema blokami – dwoma dla rdzeni Cortex-M33 i jednym wspólnym dla dwóch rdzeni RISC-V.
Interfejs QSPI zawarty w strukturze RP235x umożliwia:
- odczyt bloków danych o dowolnej długości po jednokrotnym przesłaniu polecenia odczytu z adresem początkowym,
- obsługę XIP, czyli funkcji modułu QSPI mikrokontrolera umożliwiającej odwzorowanie zawartości pamięci QSPI w przestrzeni adresowej mikrokontrolera,
- automatyczne generowanie poleceń odczytu pamięci,
- buforowanie odczytanej zawartości pamięci w dedykowanym buforze (lokalnej pamięci RAM).
Koprocesor nadmiarowości implementuje asercje sprawdzane sprzętowo, aby pomóc w kontroli integralności przepływu sterowania i danych. Blok ten, określany skrótem RCP, jest używany w obszarze bootrom RP235x w celu zapewnienia wspomaganej sprzętowo ochrony przed atakami (wstrzykiwaniem błędów i programowaniem zorientowanym na powrót). Każdy procesor Cortex-M33 jest wyposażony w pojedynczą instancję RCP, mapowaną jako koprocesor [6].
Architekturę podsystemu procesora układu RP235x pokazano na rysunku 2 [6]. Układ RP235x zawiera dwa gniazda (sockets) dla rdzeni procesorowych, określane jako Core 0 i Core 1. Każde gniazdo zawiera rdzenie ARM Cortex-M33 oraz RISC-V Hazard3. W parze działać może tylko jeden rdzeń, drugi pozostaje w uśpieniu.
Aktywacja jednego z rdzeni pary następuje po zainicjowaniu sprzętowym mikrokontrolera (reset), na podstawie ustawionych opcji konfiguracji. Cortex-M33 jest opcją domyślną. Każdy nieużywany procesor jest utrzymywany w stanie resetu, a jego zegar jest bramkowany na najwyższym poziomie. Nieużywane procesory nie zużywają żadnej dynamicznej mocy.
Sekwencja rozruchu działa głównie na rdzeniu gniazda Core0. Jeśli bootrom napotka prawidłowy i poprawnie podpisany IMAGE_DEF dla architektury innej niż bieżąca (tj. RISC-V podczas rozruchu w trybie Arm lub Arm podczas rozruchu w trybie RISC-V), wykonuje automatyczne przełączenie architektury. Bootrom inicjuje ponowne uruchomienie do prawidłowej architektury dla wykrytego pliku binarnego, który następnie uruchamia się pomyślnie przy drugiej próbie.
Na fotografii 1 zaprezentowano płytkę krzemową procesora po usunięciu obudowy i górnej warstwy metalowej. W produkcji układu została zastosowana ta sama technologia 40 nm, co w poprzednim RP2040. Matryca krzemowa RP2350 ma teraz powierzchnię 5,3 mm² w porównaniu do 2,7 mm² (w przypadku modelu RP2040). Lewy dolny róg matrycy został pokryty siecią dystrybucji zasilania projektu. Różowe obszary to fragmenty struktury nabytego przez producenta IP, takie jak interfejs USB, przetworniki ADC itp. [2].
Rdzeń RISC-V Hazard3
RISC-V Hazard3 został opracowany przez Luke’a Wrena, obecnie głównego inżyniera w zespole Raspberry Pi, w jego wolnym czasie [1]. Rezultat solowego projektu to: wysoce zoptymalizowany, 3-fazowy procesor potokowy, implementujący zestaw instrukcji RV32I i duży zbiór standardowych rozszerzeń ukierunkowanych na wydajność i gęstość kodu. W układzie została zrealizowana architektura RV32IMAC z dodatkowymi rozszerzeniami: Zba – instrukcje generowania adresów (indeksowania), Zbb, Zbs, Zbkb – operacje bitowe, Zcb – rozszerzony zestaw instrukcji 16-bitowych, Zcmp – push/pop i podwójne przesłania, Zicsr – dostęp do rejestrów sterujących oraz Hh3power, Xh3bextm – własne instrukcje rdzenia Hazard3. Sterownik przerwań jest podobny do ARM NVIC.
Przełączanie architektury
Pamięć rozruchowa RP235x to obraz binarny w pamięci ROM, który zawiera pierwsze instrukcje wykonywane podczas resetowania. Wszystkie funkcje układu, poza kilkoma funkcjami bezpieczeństwa i akceleratorem zmiennoprzecinkowym podwójnej precyzji, są dostępne w trybie RISC-V.
Podstawą modelu zabezpieczeń RP235x jest bezpieczny rozruch. Jeśli zabezpieczenia są włączone, uruchomienie pliku binarnego jest możliwe tylko wtedy, gdy został on podpisany przy użyciu klucza prywatnego, a skrót odpowiadającego mu klucza publicznego jest przechowywany w OTP. Zapobieganie uruchamianiu dowolnego kodu przez atakującego znacznie komplikuje zadanie wyodrębniania zawartości OTP, w tym kluczy kryptograficznych używanych do ochrony kodu.
Sposoby inicjowania sprzętu i aktywacja rdzeni:
- „twarde” – włączenie zasilania, sygnał reset: aktywne rdzenie są wybierane przez opcje konfiguracji w pamięci OTP, wpływające na wstępną zawartość rejestru ARCHSEL. O ile nie ustawiono inaczej – startuje rdzeń Cortex-M33 w Core0.
- „miękkie” – programowe (CM – SysResetRq, watchdog); aktywne rdzenie wybrane są przez zawartość rejestru ARCHSEL, który może być wcześniej zapisany przez oprogramowanie. Jest możliwy wybór różnych rdzeni z obu par.
Program zapisany w zewnętrznej pamięci QSPI Flash może być wykonywany bezpośrednio z pamięci Flash – XIP lub skopiowany przy starcie mikrokontrolera do pamięci RAM i wykonywany z tejże pamięci (szybciej niż przy użyciu XIP).
W praktyce: małe programy są ładowane do RAM, a duże programy są wykonywane z XIP. Krytyczne procedury oraz stałe (np. tablica adresów procedur obsługi wyjątków) są kopiowane do RAM. Sposób wykonania programu jest określony przez skrypt konsolidatora i kod startowy projektu.
Bezpieczeństwo
Wszystkie układy mają luki w zabezpieczeniach, a strategia większości dostawców polega na tym, aby o nich nie mówić. Firma Raspberry Pi jest pod tym względem niezwykła, ponieważ o nich mówi i stara się je naprawić, zamiast zamiatać problem pod przysłowiowy dywan. Firma ogłosiła konkurs na przełamanie zabezpieczeń układu RP2350. Po 6 miesiącach prac znalazło się czterech zwycięzców. Ze szczegółami można się zapoznać tutaj [9] i nie są to banalne przypadki. To otwarte podejście do inżynierii bezpieczeństwa o nazwie „bezpieczeństwo poprzez przejrzystość” zostało dobrze przyjęte przez odbiorców.
Płytki uruchomieniowe z procesorem RP235x
Projekt minimalnej płytki z układem RP235x pokazano w dokumencie „Hardware design with RP2350” [7]. Jest tam również dokładny opis wymagań sprzętowych. Wielu producentów opracowało własne płytki z tym układem i udostępniło je równocześnie z oficjalną premierą układu RP2350.
Fundacja Raspberry Pi opracowała dwie płytki z procesorem RP2350A: Pico 2 i Pico 2W. Na swoim portalu firma pokazuje także 34 płytki innych producentów z układami RP2350A i RP2350B [3].
Przykładem może być marka Pimoroni [4] oferująca kilka modułów z nowymi mikrokontrolerami RPi.
- Pico Plus 2 z układem RP2350B, gniazdem USB-C, 16 MB zewnętrznej pamięci QSPI i z takimi samymi wyprowadzeniami jak Pico 2 może być jej bezpośrednim zamiennikiem,
- Pico Plus 2W – dodatkowy moduł Wi-Fi/Bluetooth,
- Explorer – wszystko w jednym,
- Tiny2350 – miniaturowa płytka rozwojowa z RP2350A,
- Plasma 2350 – kontroler typu wszystko w jednym zasilany przez USB-C,
- PGA 2350 – minimalna płytka typu breakout z RP2350B, zapewniająca dostęp do wszystkich 48 pinów GPIO.
Na razie nie widać na rynku płytek z układem RP2354A/B.
Płytka Pico 2/Pico 2W firmy Raspberry Pi
W styczniu 2021 roku miała miejsce premiera oryginalnej płytki Pico z mikrokontrolerem RP2040. W ciągu trzech i pół roku od tego czasu sprzedano prawie cztery miliony sztuk Pico i jego bezprzewodowej odmiany Pico W.
Wrzesień 2024 przyniósł premierę płytki Pico 2 firmy Raspberry Pi (fotografia tytułowa), a grudzień – płytki Pico 2W (fotografia 2) [1]. Obie wersje, oparte na procesorze RP2350A, są zgodne elektrycznie z płytkami Pico z pierwszej serii (Pico/Pico W). Zmieniony został tylko procesor, a reszta jest dokładnie ta sama: rozkład sygnałów na pinach płytki, zastosowane elementy i ich układ elektryczny oraz lokalizacja gniazda microUSB i przycisku BOOTSEL. Podstawowe informacje o płytkach, dokumentacji i środowisku programowym dostarcza strona firmowa „Pico 2 family, Raspberry Pi Pico 2” [10].
Płytka wymaga wlutowania dwóch złączy 2,54 mm (20-pinowych). Najlepiej zastosować listwy z wydłużonymi pinami 5,84 + 7,62 mm – wtedy po wmontowaniu na płyce (dłuższym końcem) pozostaje po obu stronach PCB dostęp do dołączenia standardowych kabelków BLS. Szczególnie przydatne okazuje się to, gdy płytka jest włożona do podstawki w ekspanderze.
Układy zasilania płytek Pico 2 i Pico 2W są prawie takie same. Różnią się jedynie modelem przetwornicy DC/DC, który został dokładnie opisany w artykule „Optymalizacja poboru mocy urządzenia IoT z płytką Raspberry Pi Pico W” [11]. Pico 2 korzysta z wbudowanej przetwornicy buck-boost, która dostarcza napięcie 3,3 V (do zasilania RP2350 i obwodów zewnętrznych) na podstawie szerokiego zakresu napięć wejściowych (1,8 do 5,5 V), co daje znaczną elastyczność w zasilaniu urządzenia z różnych źródeł – takich jak pojedyncze ogniwo litowo-jonowe lub 3 ogniwa AA połączone szeregowo. Ładowarki akumulatorów można również bardzo łatwo zintegrować z łańcuchem zasilania Pico 2. Najprostszym sposobem zasilania Pico 2 jest podłączenie kabla do gniazda micro-USB. W nocie katalogowej Pico 2/2W pokazano, jak poprzez dodanie tranzystora MOS można zrealizować potrzymanie bateryjne zasilania płytki [8].
W modułach zostały zastosowane układy pamięci NOR Flash z serii W25Q (Winbond), pracujące z częstotliwością do 133 MHz (przepustowość do 66 MB/s).
Oprogramowanie
Płytka Raspberry Pi Pico 2/2W może być programowana w dwóch językach: C/C++ [14] oraz Python w wersji na mikroprocesory [13]. Obecnie dostępne są interpretery CircuitPython dla 28 różnych płytek, w tym Pico 2, Pico 2W, Pico Plus 2, Pico Plus 2W oraz interpretery języka MicroPython dostosowane do Pico 2 i Pico 2W [15]. Można także znaleźć wersje dostarczane przez inne firmy, np. interpreter MicroPython firmy Pimoroni (Pico 2 i Pico 2W) zawiera sterowniki do wielu czujników [16, 17]. Prowadzone są też prace nad implementacją języka Rust [1].
Raspberry Pi Pico 2/2W może być programowane przez interfejs USB na dwa sposoby:
- Tryb pamięci masowej USB – aby zaprogramować w ten sposób płytkę, należy nacisnąć i przytrzymać przycisk BOOTSEL, a następnie podłączyć moduł przewodem USB do komputera. Urządzenie zostanie rozpoznane jako pamięć masowa, do której można skopiować program w sposób analogiczny do kopiowania plików na pendrive’a. Po przesłaniu pliku programu (i zapisaniu go do pamięci Flash) mikrokontroler automatycznie się zresetuje i uruchomi kod. Sposób ten nadaje się do wpisywania programów napisanych w C/C++ lub interpretera MicroPythona.
- Tryb interpretera MicroPython – drugi sposób działa tylko z programami napisanymi w języku MicroPython i wymaga wcześniejszego wpisania interpretera za pomocą pierwszej metody. Polega on na zapisaniu w pamięci układu programu przesłanego za pomocą REPL lub przy zastosowaniu środowiska programowania Thonny [5, 13].
Programowanie jest jednak możliwe także przez SWD. Trzeba wtedy podłączyć programator do płytki za pomocą złącza SWD (3 piny) i zasilanie, np. za pomocą USB. Dodatkowo można w ten sposób debugować program. Jest też możliwość zaprogramowania drugiej płytki Pico jako sprzętowego programatora/debuggera [10, 12].
Fundacja Raspberry Pi wspiera zastosowanie języka MicroPython na procesorze RP2350/2354. Obecnie dostępne są obrazy interpreterów do obsługi rdzenia ARM Cortex-M33 oraz RISC-V na Pico 2 [15] oraz próbna wersja obrazu obsługi rdzenia ARM Cortex-M33 w module Pico 2W [16]. MicroPython w wersji na Pico 2 ma pozostać zgodny ze źródłem oryginalnego MicroPythona RPi Pico [1].
Środowiska programowania
Fundacja Raspberry Pi zaleca stosowanie środowiska Thonny oraz Microsoft Visual Studio Code (VS Code), co zostało opisane w dokumencie „Raspberry Pi Pico Python SDK” [13]. Pokazane są tam przykłady obsługi różnych modułów układu RP23xx oraz użycie środowiska Thonny i VS Code. Dokładny opis pracy z VS Code znalazł się w dokumencie „Getting Started with Pico-series Microcontrollers” [12]. Pełny opis SDK C/C++ jest w dokumencie „Raspberry Pi Pico C/C++ SDK” [14]. Poniżej zostanie opisana tylko praca z językiem MicroPython.
Praca Visual Studio Code z rdzeniem ARM oraz RISC-V
Visual Studio Code to popularny edytor open source opracowany przez Microsoft. Rozszerzenie Raspberry Pi Pico VS Code ułatwia instalowanie zależności i tworzenie oprogramowania na urządzenia z serii Pico.
Rozszerzenie Raspberry Pi Pico VS Code pomaga tworzyć, rozwijać, uruchamiać i debugować projekty w Visual Studio Code. Zawiera generator projektów z wieloma opcjami szablonów, automatyczne zarządzanie łańcuchem narzędzi, kompilację projektu jednym kliknięciem i dokumentację offline Pico SDK. Rozszerzenie Raspberry Pi Pico VS Code obsługuje wszystkie urządzenia Raspberry Pi z serii Pico oraz języki Python i C/C++.
Płytka Pico 2 musi mieć wpisany interpreter MicroPythona z obsługą rdzenia ARM lub RISC-V [15]. W przypadku rdzenia ARM może to być wersja firmy od Pimoroni [17].
1. Na systemie Windows pobierz i zainstaluj aplikację VS Code z https://code.visualstudio.com/Download.
2. Po uruchomieniu VSC kliknij ikonkę Extensions i wyszukaj rozszerzenie Raspberry Pi Pico dostarczane przez Raspberry Pi. Kliknij przycisk Install.
3. Po zakończeniu instalacji sprawdź pasek boczny Activity (domyślnie po lewej stronie VS Code). Jeśli instalacja się powiedzie, to pojawi się nowa sekcja paska bocznego z ikoną Raspberry Pi Pico, oznaczona jako Raspberry Pi Pico Project. Rozszerzenie Raspberry Pi Pico VS Code może tworzyć projekty na podstawie przykładów dostarczonych przez Pico Examples. Można na przykład utworzyć projekt, który miga diodą LED na urządzeniu z serii Pico:
4. Dołącz płytkę Pico 2 kablem microUSB do komputera.
5. Uruchom VS Code.
6. Na lewym pasku bocznym VS Code wybierz ikonę Raspberry Pi Pico oznaczoną jako Projekt Raspberry Pi Pico.
7. Wybierz New MicroPython Project.
8. W polu Nazwa wpisz blink.
9. Wybierz typ płytki odpowiadający posiadanemu urządzeniu.
10. W polu Location określ folder, w którym rozszerzenie może generować pliki. VS Code utworzy nowy projekt w podfolderze wybranego folderu.
11. Kliknij Create, aby utworzyć projekt. Rozszerzenie pobierze teraz SDK i zestaw narzędzi, zainstaluje je lokalnie i wygeneruje nowy projekt. Instalacja zestawu narzędzi w pierwszym projekcie może potrwać 5…10 minut. VS Code zapyta Cię, czy ufasz autorom, ponieważ automatycznie wygenerowany został katalog .vscode. Wybierz Yes. VS Code automatycznie znajdzie port COM, na którym jest widoczna płytka i połączy się z nią. Na pasku stanu będzie widoczna informacja Pico Connected. W oknie Explorer wyświetlone zostaną pliki folderu projektu.
12. Otwórz plik blik.py w edytorze.
13. Kliknij prawym klawiszem myszki na plik blink.py i wybierz Upload file to Pico.
14. Ponownie kliknij prawym klawiszem myszki na plik blink.py i wybierz Run current file on Pico.
Po przesłaniu kodu urządzenie zostanie uruchomione – dioda LED powinna migać co sekundę. Na dole okna powinna zostać otwarta karta terminala. Wyświetli ona informacje przesłane przez kod zapisany w pamięci Pico (rysunek 3).
Praca Thonny z rdzeniem ARM
Thonny to środowisko IDE o otwartym kodzie źródłowym, które służy do tworzenia i przesyłania programów MicroPython do różnych płytek, takich jak Raspberry Pi Pico/Pico 2, ESP32 i ESP8266 [5].
W tej części artykułu zostanie opisana łatwa procedura dołączenia i uruchomienia modułu Pico 2 z czujnikiem BME680 lub BME688 firmy Bosch poprzez szynę I²C.
1. Dołącz masę modułu BME68x do GND (PIN38) oraz zasilanie do 3V3 (OUT) – PIN37, a następnie linię SDA modułu BME68x do GP4 (PIN5), a linię SCL – do GP5 (PIN6) płytki Pico 2.
2. Pobierz najnowszy interpreter MicroPythona (plik Pico2-v0.0.12-Pimoroni-micropython.uf2) ze strony firmy Pimoroni [17].
3. Trzymając wciśnięty biały przycisk BOOTSEL, podłącz Pico2 do komputera kablem micro USB. Płytka będzie widoczna jako dysk RP2350 w eksploratorze plików Windows.
4. Skopiuj plik .uf2 na Raspberry Pi Pico2.
5. Na komputerze zainstaluj najnowszą wersję programu Thonny.
6. Dołącz zaprogramowaną płytkę Pico 2 kablem USB do komputera.
7. Sprawdź w Menadżerze urządzeń, który port COM został przypisany do dołączonej płytki.
8. Uruchom program Thonny.
9. Kliknij ikonkę trzech linii w prawym dolnym rogu i wybierz „Configure interpreter”.
10. Ustaw typ interpretera na „MicroPython (Raspberry Pi Pico)”.
11. Z menu w prawym dolnym rogu wybierz MicroPython (Raspberry Pi Pico) · Board CD @COMxx.
12. Pobierz przykładowy program bme68x_demo.py odczytujący dane z czujnika BME680 z repozytorium firmy Pimoroni pod adresem [18].
13. W oknie Files kliknij prawym klawiszem myszy na plik bme68x_demo.py i wybierz Upload to.
14. Z okna Raspberry Pi Pico otwórz plik main.py (podwójne kliknięcie).
15. Kliknij przycisk Stop/Restart backend . Zobacz w oknie Shell, jakie wersje interpretera i rdzenia są wybrane (domyślny rdzeń to ARM).
16. Kliknij na przycisk Run current script .
17. W konsoli powinny być widoczne wyniki pomiarów.
18. W razie błędu dokonaj proponowanej w opisie zmiany w programie.
Praca Thonny z rdzeniem RISC-V
W Internecie można znaleźć wiele opisów pozwalających rozpocząć pracę z Pico z prostym kodem migającym diodą LED zamontowaną na płytce Pico 2/Pico 2W (dwa przykłady to: strona „Getting Started with Raspberry Pi Pico W Wireless” [19] oraz polecana przez Raspberry książka „Get Started with MicroPython on Raspberry Pi Pico” [20]). Przykładowy program pokazano na listingu 1.
import machine
import utime
led_onboard = machine.Pin(25, machine.Pin.OUT)
while True:
led_onboard.toggle()
utime.sleep(1)
Listing 1. Program testowy RPi Pico 2 [20]
19. Pobierz najnowszy interpreter MicroPythona dla rdzenia RISC-V w pliku RPi_PiCO2-RISCV-20241129-v1.24.1.uf2 ze strony firmy MicroPythona [15].
20. Zapisz plik na płytce Pico 2.
21. W programie Thonny połącz się z Pico 2 i utwórz nowy plik main.py z programem mrugania diodą LED.
22. Uruchom program. W konsoli powinny być widoczne wyniki pomiarów.
Resetowanie pamięci Flash
W przypadku modułów z serii Pico kod trybu BOOTSEL znajduje się w pamięci ROM (tylko do odczytu) wewnątrz układu RP2350 i nie można go przypadkowo nadpisać. Jeśli przycisk BOOTSEL zostanie przytrzymany podczas podłączania Pico, to płytka zawsze zgłosi się jako dysk, na który możesz przeciągnąć nowy plik UF2. Nie ma sposobu, aby uszkodzić płytkę za pomocą oprogramowania. Istnieją jednak pewne okoliczności, w których można chcieć upewnić się (lub spowodować), że pamięć Flash jest pusta. Można to zrobić przeciągając i upuszczając plik binarny flash_nuke.uf2 na dysk Pico (do pobrania na końcu strony [10]). Wtedy program kasowania całej pamięci Flash zostanie wykonany i Pico powróci do pracy w trybie pamięci masowej.
Jeśli program w pliku main.py zawiera wywołanie funkcji deepsleep, to redukuje ona pobór prądu układu RP2350, lecz jednocześnie uniemożliwia wybudzanie procesora. Nie pomaga ponowne przesłanie pliku interpretera MicroPythona w trybie pamięci masowej. Co ciekawe, dotyczy to tylko rdzenia, który był używany w pechowym programie. Wgranie interpretera MicroPythona dla innego rdzenia powoduje normalne działanie układu. Na razie dostępne interpretery MicroPythona domyślnie używają rdzenia ARM albo RISC-V z banku Core0.
Pobór mocy płytki RPi Pico 2
Do dynamicznego pomiaru prądu zasilania bardzo dobrze nadaje się zestaw Power Profiler Kit II (PPK2) firmy Nordic Semiconductor. Jest to samodzielny układ, który bez zewnętrznego sprzętu może mierzyć i dostarczać prądy od poniżej μA do 1 A. Dokładny opis PPK2 jest zamieszczony w artykule „Profilowanie mocy z zastosowaniem Power Profiler Kit II” [21].
W przykładowych pomiarach został celowo zastosowany prosty program z książki [20], pokazany na listingu 1, który używa tylko podstawowych funkcji języka MicroPython.
Pobór prądu rdzenia RISC-V płytki Pico 2 podczas wykonywania programu testowego przy zasilaniu 5 V z pinu VBUS i zastosowaniu oryginalnego interpretera MicroPythona [15] pokazano na rysunku 4. Po włączeniu zasilania występuje pik prądu 0,6 A. Potem prąd spada do wartości średniej 18,43 mA (17,17 mA przy wyłączonej diodzie LED). Analogiczny wykres dla sytuacji, w której program jest wykonywany przez rdzeń ARM pod kontrolą interpretera MicroPythona firmy Pimoroni [17], pokazano na rysunku 5 – pik natężenia wynosi 0,56 A, a prąd średni to 17,74 mA (16,39 mA przy wyłączonej diodzie LED).
Pobór mocy rdzenia RISC-V układu RP2350 w opisanych testach jest nieco mniejszy niż przy użyciu rdzenia ARM, ale ponad trzy razy mniejszy niż w przypadku płytki poprzedniej generacji (RPi Pico z układem RP2040). Warto też zwrócić uwagę, że omawiane moduły wykazują zaskakująco duży prąd startowy, jak na zastosowaną przetwornicę DC/DC z wewnętrzną kontrolą soft-start.
Podsumowanie
Nie ma wątpliwości, że architektura ARM dominuje w przestrzeni procesorów wbudowanych, jednak jest silny konkurent: RISC-V. Zamiast podejmować ryzyko zbudowania nowego produktu w oparciu tylko i wyłącznie na RISC-V, firma Raspberry Pi umieściła rdzenie z obiema architekturami w swoim kolejnym układzie scalonym RP2350/2354, umożliwiając klientowi wybór tej pary rdzeni, które uzna za lepsze w danej sytuacji. To sprytny sposób oceny popytu rynkowego bez narażania się na zbyt duże koszty. Jest to pierwszy produkt Raspberry Pi bazujący na architekturze RISC-V, ale prawdopodobnie nie ostatni.
Płytka RPi Pico 2 jest bardzo interesująca. Za niewielkie pieniądze można rozpocząć pracę ze wschodzącą gwiazdą rynku Internetu Rzeczy – rdzeniem RISC-V. Zachowanie tego samego formatu i kompatybilności elektrycznej płytki Pico 2 z poprzednią serią Pico oznacza, że można szybko uaktualnić swoje projekty do nowszego sprzętu. Tym bardziej że oprogramowanie MicroPython pozostało praktycznie bez zmian. Pozwala to ogromnej liczbie projektów opartych na RP2040 kontynuować pracę w ekosystemie Pi, przy minimalnym ryzyku wystąpienia problemów związanych z migracją. A istnieją już tysiące projektów, które dobrze działają pod kontrolą RP2040.
Zastosowanie w układzie RP235x (i w płytkach Pico 2) portu microUSB w 2024 roku jest rozczarowujące. Przy totalnym przestawieniu produkcji elektroniki konsumenckiej na złącze USB-C jest to wyraźny problem. Trochę ratuje sytuację spora oferta płytek innych producentów z obsługą USB C.
Zdecydowanie spadł pobór mocy katalogowej w warunkach uśpienia układu, ale 188 μW to nadal dość duża moc jak na najniższy poziom zasilania. Niestety próby stanów obniżonej mocy w MicroPythonie zakończyły się zablokowaniem działania rdzenia RISC-V. Obsługa uśpienia procesora w MicroPythonie po prostu nie działa. Znacznie więcej możliwości daje programowanie RP235x w języku C/C++. Podstawą optymalnej pracy urządzeń IoT jest właściwe użycie trybów obniżonego poboru mocy oraz obsługa przerwań i wybudzania z uśpienia. A z tym wszystkim w implementacji języka MicroPython na RP235x wciąż nie jest najlepiej. Miejmy nadzieję, że to dopiero pierwsze wersje oprogramowania firmowego.
Praca RP235x z językiem C/C++, używanie rdzenia RISC-V oraz tryby pracy z obniżoną mocą to zdecydowanie szersze zagadnienia i będą one tematem następnych artykułów.
Henryk A. Kowalski, Grzegorz Mazur
Instytut Informatyki
Politechnika Warszawska
Bibliografia:
- Raspberry Pi Pico 2, our new $5 microcontroller board, on sale now, 8th Aug 2024, Eben Upton, Raspberry Pi, https://www.raspberryPi.com/news/raspberry-Pi-Pico-2-our-new-5-microcontroller-board-on-sale-now/
- Pi Pico 2 Extreme Teardown, 25th August 2024, https://electronupdate.blogspot.com/2024/08/Pi-Pico-2-extreme-teardown.html
- Raspberry Pi, https://www.raspberryPi.com/
- Pimoroni, https://shop.Pimoroni.com/
- Thonny Python IDE, https://thonny.org/
- RP2350 Datasheet, 2024-10-16, Raspberry Pi, https://datasheets.raspberryPi.com/rp2350/rp2350-datasheet.pdf
- Hardware design with RP2350, 2024-10-15, Raspberry Pi, https://datasheets.raspberryPi.com/rp2350/hardware-design-with-rp2350.pdf
- Raspberry Pi Pico 2 Datasheet, 2024-10-15, Raspberry Pi, https://datasheets.raspberryPi.com/Pico/Pico-2-datasheet.pdf
- Security through transparency: RP2350 Hacking Challenge results are in, 14th Jan 2025, Eben Upton, https://www.raspberryPi.com/news/security-through-transparency-rp2350-hacking-challenge-results-are-in/
- Pico 2 family, Raspberry Pi Pico 2, https://www.raspberryPi.com/documentation/microcontrollers/Pico-series.html#Pico-2-family
- Optymalizacja poboru mocy urządzenia IoT z płytką Raspberry Pi Pico W, EP5/2024, https://ep.com.pl/projekty/moduly-w-aplikacjach/16121-internet-rzeczy-w-pomiarach-srodowiskowych-5-optymalizacja-poboru-mocy-urzadzenia-iot-z-plytka-raspberry-Pi-Pico-w
- Getting Started with Pico-series Microcontrollers. 2024-10-15, Raspberry Pi, https://datasheets.raspberryPi.com/Pico/getting-started-with-Pico.pdf
- Raspberry Pi Pico Python SDK, 2024-12-04, Raspberry Pi, https://datasheets.raspberryPi.com/Pico/raspberry-Pi-Pico-python-sdk.pdf
- Raspberry Pi Pico C/C++ SDK, 2024-12-05, Raspberry Pi, https://datasheets.raspberryPi.com/Pico/raspberry-Pi-Pico-c-sdk.pdf
- Pico 2, MicroPython, https://micropython.org/download/RPi_PiCO2/
- Pico 2 W, MicroPython, https://micropython.org/download/RPi_PiCO2_W/
- Pimoroni Pico MicroPython for RP2350 / Pico2 boards, https://github.com/Pimoroni/Pimoroni-Pico-rp2350
- BME68X, Pimoroni, https://github.com/Pimoroni/Pimoroni-Pico/tree/main/micropython/examples/breakout_bme68x
- Getting Started with Raspberry Pi Pico W Wireless, https://microcontrollerslab.com/getting-started-raspberry-Pi-Pico-w-micropython/
- Get Started with MicroPython on Raspberry Pi Pico, Gareth Halfacree, Ben Everard, Raspberry Pi, 2024, https://hackspace.raspberryPi.com/books/micropython-Pico
- Profilowanie mocy z zastosowaniem Power Profiler Kit II, EP5/2022, https://ep.com.pl/kursy/15267-systemy-dla-internetu-rzeczy-60-profilowanie-mocy-z-zastosowaniem-power-profiler-kit-ii