Snadný překlad Raspberry Pico pod Windows
Populární Raspberry Pico oplývá sice propracovanou dokumentací a kvalitními příklady, ovšem jeho překladové prostředí je zaměřené spíše na Linux, či přesněji na Raspberry Pi. Ve Windows vyžaduje instalaci několika gigabajtů podpůrných softů a poměrně komplikovaný způsob použití. Dáváte-li přednost jednoduššímu použití, podobně jako já, připravil jsem zjednodušené překladové prostředí. Vše, co potřebujete, je ARM-GCC překladač a připravený balík s SDK a příklady (dále označuji jako RaspPicoSDK).
V RaspPicoSDK naleznete 73 demo příkladů. Na rozdíl od originálu je velká část příkladů přípravena jak pro UART konzolový výstup (např. přes UART-USB adapter), tak i pro USB konzoli (virtuální COM port). Celkem to je 120 překládaných složek.
1) K překladu potřebujete ARM-GCC překladač. Ten si můžete stáhnout zde:
V současnosti by se jednalo o verzi gcc-arm-none-eabi-10-2020-q4-major-win32.exe. Doporučuji překladač nainstalovat do složky C:\ARM10 a při instalaci vypnout volbu pro přidání cesty do PATH. Jednotlivé verze překladače nejsou vždy až tak úplně zaměnitelné a je proto praktické mít nainstalováno více verzí (složky C:\ARM9, C:\ARM8 atd.) a cestu do použité verze překladače přidat až uvnitř povelového souboru. Tímto způsobem jsou připravené i překladové souboru v RaspPicoSDK. Budete-li chtít změnit cestu do složky překladače, naleznete ji v překladových souborech _c1.bat a _boot2\c.bat. Nechcete-li používat více verzí překladače, ponechte instalaci do implicitní složky a ponechte zapnutou volbu pro přidání cesty do PATH, překlad bude fungovat správně také.
2) Dále potřebujete RaspPicoSDK:
download: RaspPicoSDK.zip
alternativní download: ulozto.cz
Rozbalte RaspPicoSDK do nějaké složky. Kamkoliv, kde budete chtít pracovat. A tím je instalace ukončena. :-)
S RaspPicoSDK se pracuje v příkazovém řádku, bez IDE prostředí. Proč - protože správný programátor pracuje v příkazovém řádku. :-) Vřele k tomu doporučuji souborový manažer FAR Manager (lze stáhnout zde https://www.farmanager.com ). Obsahuje souborový manažer typu Norton Commander a editor (přes F4), který dobře vyhovuje psaní programů pro MCU (včetně barevného zvýraznění syntaxe). Oproti jiným podobným manažerům má jednu velkou přednost - konzolové okno (zobrazení Ctrl+O nebo Ctrl+P). Vidíte výstup hlášení z překladače a můžete tak snadno upravovat programy. Vše potřebné je ihned po ruce. Dobře funguje i vyhledávání souborů podle textu (Alt+F7) a porovnání obsahu souborů (F11, Advanced compare).
Na opravdu kvalitní porovnání rozdílů obsahu souborů a synchronizaci složek doporučuji program Beyond Compare (download https://www.scootersoftware.com/download.php ). Když chci porovnat složky nebo soubory, nastavím na ně v protějších oknech FARu kurzor ('..' označuje "tuto složku"), zadám příkaz bcomp a jako parametry uvedu cesty do složek pomocí Ctrl+F. bcomp.cmd je povelový soubor nacházející se ve složce C:\Windows, s tímto obsahem:
@"C:\Program Files (x86)\Beyond Compare 3\BCompare.exe" %1 %2 %3 %4
Případně na synchronizaci složek při archivaci doporučuji program SyncBackFree (link https://www.2brightsparks.com/freeware/index.html ), používám ho při zálohování na externí disky.
Velmi užitečnou nutností při práci s Raspberry Pico je konzolový program pro komunikaci přes sériový port. Používám k tomu program begPuTTY, download begPutty.zip . Domovská stránka http://qww.cz/Ctrl-Home-and-Shift-Arrows-in-Putty-Linux.html , jedná se o modifikaci programu PuTTY https://www.chiark.greenend.org.uk/~sgtatham/putty/ . (poznámka: Ke kopii textu z konzolového okna do clipboardu stačí označit text myší)
K prvnímu osahání Raspberry Pico nepotřebujete nic jiného, než USB kabel, kterým Pico připojíte k PC. Chcete-li do Pico nahrát nový program, odpojte USB kabel, stiskněte a držte na Pico tlačítko BOOTSEL, připojte USB kabel a tlačítko uvolněte. V seznamu disků se objeví nový disk, o velikosti 127 MB, označený RPI-RP2.
Nyní můžete nový program jen přetáhnout myší do tohoto nového disku. Samozřejmě konzolový programátor se myší nezdržuje :-) a používá jednodušší způsob - odeslání programu na disk povelákem e.bat. Pro ten účel je užitečné disk pojmenovat jednotně např. R: (=Raspberry). Přejmenování se provede ve správě počítače - přes Tento počítač / Spravovat. Nebo upravit jméno disku v souboru _e1.bat.
Při zkoušení většiny demo příkladů potřebujete konzolový výstup. V nejjednodušším případě můžete využít virtuální COM port, dostupný přes USB port, sloužící k programování Pico. Velká část demo programů je pro tento účel připravena - poznáte je tak, že název složky končí na *_usb. Po nahrátí programu se ve správci zařízení objeví nový COM port, označený "Sériové zařízení USB". Správce zařízení otevřete přes Tento počítač / Vlastnosti / Správce zařízení.
Zjištěné číslo COM portu zadejte do nastavení begPuTTY. Přenosovou rychlost zvolte 115200, typ spojení Serial. V nastavení Connection / Serial nastavte 8 bitů, 1 stop bit, bez parity, řízení toku XON/XOFF. V nastavení Terminal zapněte volbu "Implicit CR in every LF".
Původní demo příklady možnost konzolového výstupu přes USB sice umožňují, ale ne tak úplně. Po nahrátí demo programu se virtuální port ze systému odpojí a poté zas připojí, což jednak trvá nějakou dobu a jednak i připojení konzolového programu nějakou dobu trvá. U begPuTTY po odpojení vyskočí chybové okno, které je potřeba odmáčknout, a nové připojení provést pravým tlačítkem na okně s volbou "Restart Session".
To vše znamená, že text hlášení po startu uteče. V takových případech je na začátek programu doplněna smyčka, která čeká na stisk mezerníku. V konzolovém okně se objeví výzva "Press spacebar to start...". Po prvním spuštění tato výzva samozřejmě uteče, ale můžete ji znovu zobrazit stiskem jiné klávesy než mezerník, např. Enter. Demo program se spustí teprve až v konzolovém okně stisknete klávesu mezerníku.
Jinou možností je připojení Pico k PC přes UART port. Standardně se k tomu používá UART0, který má výstup TX na pinu 1 (GP0) a vstup RX na pinu 2 (GP1).
UART0 nemůžete přímo připojit na RS232 počítače, protože používá napěťové úrovně 3.3V. Musíte použít buď převodník na RS232, nebo převodník na USB. Dobrou volbou je USB-UART převodník PL2303TA, který lze připojit jak k +5V TTL pinům, tak k +3.3V pinům.
Výstup TX adaptéru (zelený) připojte na pin 2 GP1 UART0_RX, vstup RX adaptéru (bílý) na pin 1 GP0 UART0_TX. GND (černý) připojte na pin 3 GND nebo 38 GND. Budete-li Pico napájet z převodníku, a ne z USB kabelu, připojte +5V (červený) na pin 39 VSYS. Podle dokumentace by se připojení mělo provést přes diodu, ale v tomto případě to není nutné.
Po připojení adaptéru se ve správci zařízení objeví nový COM port, "Prolific USB-to-Serial Comm Port". K begPuTTY ho připojte podobně jako USB virtuální COM port s tím rozdílem, že v nastavení Serial zvolte Flow control = None.
Dobrou kombinací je současné zapojení jak USB-UART převodníku, tak USB kabelu. V tom případě nezapojujte pin +5V (červený). Takto můžete Pico programovat a současně vidět konzolový výstup, aniž vám uteče začátek textu.
Všechny demo příklady v RaspPicoSDK jsou již připravené přeložené (přeložený soubor má vždy jméno program.uf2). Stačí je jen nahrát do Pico spuštěním e.bat (="Export"). Budete-li chtít v kódu něco měnit, nový překlad zajistíte spuštěním c.bat (="Compile"). Ve FAR jen stiskněte c<Enter>. Vyčištění překladu provedete spuštěním d.bat (="Delete"). Smažou se všechny přechodné soubory a ponechá se jen výsledný přeložený soubor program.uf2.
V RaspPicoSDK je použita strategie zjednodušení psaní programů, i za cenu nižší rychlosti překladu. Během překladu jsou překládány všechny knihovní soubory *.c a *.cpp a linkovány k výslednému programu. Linker zajistí, že nepoužité části kódu se do výsledného programu nezahrnou, nárůst velikosti programu to nezpůsobí. Podobně jsou do hlavičkových souborů zahrnuty všechny soubory *.h. Tento přístup zajistí snadné použití knihoven - nemusíte se starat, které knihovní soubory přidat a jak je navzájem propojit. Prostě v kódu použijete potřebnou funkci a o víc se nestaráte.
A ano, samozřejmě - originální překlad v Linuxu je jistě mnohem rychlejší. Avšak, nevím jak vy, ale já trávím mnohem více času vymýšlením a psaním programu než kompilacemi, proto mě pomalejší kompilace netíží (v dnešní době rychlých PC?) a dávám přednost tomu, že se nemusím starat o nic víc, než jen o samostný kód.
Samozřejmě je během překladu zajištěno, že při úpravách souborů *.c a *.cpp se překládají jen změněné soubory, ne celý projekt. Není tedy nutný kompletní překlad po každé změně kódu. Ovšem, na rozdíl od originálu, zde není zajištěn překlad v závislosti na hlavičkových souborech *.h. Správně fungující závislost na *.h je poměrně komplikovaný proces a ne vždy funguje spolehlivě. Nejedenkrát jsem se při psaní programů vypekl hledáním chyb způsobených nepřesnou automatickou aktualizací překladů (např. při proměnlivém podmíněném překladu). Editací *.h souborů se tráví podstatně méně času než editací *.c a *.cpp souborů, komplikace s nespolehlivým řešením závislostí se nevyplatí. Stačí na to pamatovat, běžně překládat zrychleně pomocí c.bat a jen po podstatnějších změnách v *.h nebo při podezřelém chování před kompilací nejdříve vymazat starý překlad pomocí d.bat a provést pak plný překlad.
V základní složce RaspPicoSDK naleznete ještě soubory c_all.bat a d_all.bat - slouží k hromadnému přeložení nebo smazání všech demo programů. Kompletní překlad trvá asi 1 hodinu.
V souboru Makefile, nacházejícím se u každého projektu, naleznete nastavení projektu. Zpravidla si vystačíte s tím, že budete přidávat další zdrojové soubory *.c k proměnné CSRC a soubory *.cpp k proměnné SRC. Vyjdete-li z demo projektu, který je nejblíž vašemu účelu, ostatní nastavení nebudete muset měnit. Budete-li do projektu přidávat hlavičkové soubory *.h, přidávejte je do souboru src\include.h. Odkaz na include.h uvedete na začátku každého souboru *.c a *.cpp.
V RaspPicoSDK naleznete následující složky:
_boot2 - Zavaděče 2. stupně. Program je do Raspberry Pico zaváděn tak, že interní zavaděč procesoru (nacházející se v interní BOOTROM 16 KB) nejdříve načte prvních 256 bajtů ze začátku programu do RAM na adresu 0x20041f00 a předá sem řízení. Tato část je zavaděč 2. stupně a slouží k nastavení rychlejšího přístupu k Flash paměti. První stupeň zavaděče nastaví pomalý, ale bezpečný přístup.
Zavaděč druhého stupně obsahuje v posledních 4 bajtech kontrolní součet, který slouží k jeho identifikaci. K výpočtu kontrolního součtu slouží program boot2crc (překlad pomocí MS Visual Studio 2005), který vypočte kontrolní součet a vygeneruje zdrojový kód, který se začlení do výsledného programu. Metoda výpočtu kontrolního součtu zhruba odpovídá výpočtu CRC32, ale díky chybě v originálním kódu se liší. Proto v programu není použit skutečný výpočet CRC32, ale simulace originálního kódu ze zavaděče.
_exe - program elf2uf2 pro export přeloženého programu z formátu elf2 do formátu uf2, a pioasm, překladač programů pro PIO. Programy jsou připraveny pro 64-bitový systém Windows. Pro 32-bitový systém použijte knihovny ze složky 32bit.
_sdk - knihovní soubory SDK. Struktura je zjednodušená oproti originálnímu SDK. Všechny *.c soubory se nacházejí v jedné složce a všechny *.h soubory ve složce include.
_tinyusb - knihovna TinyUSB pro obsluhu USB portu.
_tools - utility pro obsluhu překladu z knihovny MinGW, jako je program "make.exe" atd.
_www - obsah této www stránky s popisem.
Ostatní složky obsahují demo příklady.
Složky končící textem *_usb používají konzolový výstup na USB port. Složky končící textem *_uart používají konzolový výstup UART0.
Ze všeho nejdříve doporučuji vyzkoušet tyto 2 základní demo příklady:
blink ... simple blinking LED on the Pico board
hello_world_usb, hello_world_serial ... repeated printing text "USB: Hello, world!"
Další demo příklady:
adc_console_uart, adc_console_usb ... ADC input to console
Menu selected from keyboard:
c0, ... : Select ADC channel n
s : Sample once
S : Sample many
w : Wiggle pins
h : print help
adc_dma_uart, adc_dma_usb ... Capture ADC input using DMA transfer. Capture channel is 0, port GPIO26. If you have VGA board, demo sample (triangle) can be generated using PIO and core 1.
adc_hello_uart, adc_hello_usb ... Repeated measure ADC voltage on pin GPIO26.
adc_joystick_uart, adc_joystick_usb ... Repeated measure joystick position using ADC, X axis on GPIO26, Y axis on GPIO27.
clocks_48MHz_uart ... Measure frequency of on-board clocks with pll and without pll.
clocks_gpout_uart, clocks_gpout_usb ... Output clock signal to GPIO21. Takes different clock sources, divide them by 100 and sends them to GPIO21 as clock signal.
clocks_resus_uart ... Resurection interrupt on system clock fail. Switch pll off. That raises emergency interrupt, which will restore lost system clock.
divider_hello_uart, divider_hello_usb ... Hello hardware divider
dma_control_uart ... Send data to UART using 2 DMAs control blocks.
dma_hello_uart, dma_hello_usb ... Copy data between 2 buffers using DMA.
dma_irq ... Control LED using PWM with PIO and DMA.
flash_cache_uart, flash_cache_usb ... Example of using flash cache hit/access counters
flash_nuke ... clear content of flash. Program will load into SRAM, clear content of Flash, shortly blink LED to indicate all ok and restart USB loader. From now, Pico board will appear empty, as from factory setting.
flash_program_uart ... Program 256-byte page of Flash memory.
flash_ssi_dma_uart, flash_ssi_dma_usb ... Measure transfer speed from Flash to RAM using DMA.
flash_xip_stream_uart, flash_xip_stream_usb ... stream DMAable FIFO
gpio_7segment_uart, gpio_7segment_usb ... Counting 7-segment display. Press button to count down.
gpio_dht_uart, gpio_dht_usb ... Measure temperature and humidity using DHT sensor.
gpio_irq_uart, gpio_irq_usb ... Print events on GPIO 2 (edge fall, edge rise).
i2c_bus_scan_uart, i2c_bus_scan_usb ... Print out a table of I2C slave adresses.
i2c_lcd1602 ... Example code to drive a 16x2 LCD panel via a I2C (3.3V).
i2c_mpu6050_uart, i2c_mpu6050_usb ... Reading MPU6050 MEMS accelerometer and gyroscope
interp_uart, interp_usb ... Texture interpolation
multicore_fifo_uart, multicore_fifo_usb ... Multicore fifo iqrs
multicore_hello_uart, multicore_hello_usb ... Multicore hello
multicore_runner_uart, multicore_runner_usb ... Multicore run functions.
picoboard_blinky ... Blinking Morse text on LED on board.
picoboard_button ... Blink LED if BOOTSEL button is pressed.
pio_addition_uart, pio_addition_usb ... Do some PIO additions
pio_apa102 ... Control RGB LEDs using APA102
pio_blink_uart ... blink LEDs at different frequencies
pio_differ_uart, pio_differ_usb ... Differential serial transmit/receive example
pio_hello ... Blinking LED using PIO
pio_hub75 ... Display an image on a 128x64 HUB75 RGB LED matrix.
pio_i2c_uart, pio_i2c_usb ... Scan an I2C bus.
pio_logic_uart, pio_logic_usb ... PIO logic analyser example
pio_manchester_uart, pio_manchester_usb ... Send and receive Manchester-encoded serial.
pio_pwm_uart, pio_pwm_usb ... Pulse width modulation to fade LED.
pio_spiflash_uart, pio_spiflash_usb ... erase, program and read back SPI serial flash memory
pio_spiloopback_uart, pio_spiloopback_usb ... loopback test with all four CPHA/CPOL combinations.
pio_squarewave ... fast square wave onto a GPIO
pio_st7789 ... display spinning image on ST7789 serial LCD.
pio_uartrx_uart, pio_uartrx_usb ... implement UART receiver
pio_uarttx_uart ... print text on debug UART
pio_ws2812_uart, pio_ws2812_usb ... Example of driving WS2812 addressable RGB LEDs.
pio_ws2812par_uart, pio_ws2812par_usb ... Example of driving WS2812 addressable RGB LEDs.
pwm_duty_uart, pwm_duty_usb ... output PWM and measure duty cycle using another PWM
pwm_hello ... Output PWM signals on pins 0 and 1
pwm_led ... fade LED using PWM
reset_hello_uart, reset_hello_usb ... Perform a hard reset on some peripherals, then bring them back up.
rtc_alarm_uart, rtc_alarm_usb ... Trigger alarm after 5 seconds
rtc_alarmrep_uart, rtc_alarmrep_usb ... Trigger an RTC interrupt once per minute.
rtc_hello_uart, rtc_hello_usb ... set and display RTC clock
spi_bme280_uart, spi_bme280_usb ... Attach a BME280 temperature/humidity/pressure sensor via SPI.
spi_dma_uart, spi_dma_usb ... Use DMA to transfer data both to and from the SPI simultaneously.
spi_flash_uart, spi_flash_usb ... Erase, program and read a serial flash via SPI.
spi_mpu9250_uart, spi_mpu9250_usb ... Attach a MPU9250 accelerometer/gyoscope via SPI.
system_board_uart, system_board_usb ... Read the 64 bit unique ID from external flash, which serves as a unique identifier for the board.
system_dbltap ... Pressing reset quickly twice will reset into USB bootloader
system_write_uart, system_write_usb ... Demonstrate the effects of 8-bit and 16-bit writes on a 32-bit IO register.
timer_hello_uart, timer_hello_usb ... Set callbacks on the system timer, which repeat at regular intervals. Cancel the timer when we're done.
timer_lowlevel_uart, timer_lowlevel_usb ... Example of direct access to the timer hardware.
timer_sampler_uart, timer_sampler_usb ... Sample GPIOs in a timer callback
uart_advanced_uart ... Use some other UART features like RX interrupts, hardware control flow, and data formats other than 8n1.
uart_hello_uart ... Print some text from one of the UART serial ports, without going through stdio.
usb_audio ... Audio headset example from TinyUSB
usb_composite ... Composite HID (mouse + keyboard) example from TinyUSB
usb_generic ... Generic HID device example from TinyUSB
usb_host_uart ... Use USB in host mode to poll an attached HID keyboard (TinyUSB example)
usb_lowlevel_uart ... A USB Bulk loopback implemented with direct access to the USB hardware (no TinyUSB)
watchdog_hello_uart, watchdog_hello_usb ... Set the watchdog timer, and let it expire. Detect the reboot, and halt.
Miroslav Němeček