Zephyr OS на Raspberry Pi Pico в Ubuntu 22.04: від нуля до Hello World

Серія «Збираємо комп’ютер як Neotron, але по-своєму» | Частина 0: Середовище

В коментарях до статті «Це не Raspberry Pi. І саме тому це цікаво. Luckfox Pico Pro: від ATmega8 до живого відеостріму» завязалась цікава розмова немовби на форумі, хто пам’ятає часи форумів той зрозуміє. З тієї розмови я дізнався багато чого нового і цікавого за що неймовірно вдячний flyman і Олександр Литвиненко.

Отже, погуглив «pi pico zephyr» і знайшов дещо цікаве, Neotron Pico мікрокомп’ютер на базі RP2040. Видно перетнувши межу між сном і маренням, оскільки вже була глибока ніч, вирішив що теж хочу зібрати щось на кшталт того з дисплеєм, клавіатурою і, бажано, виглядом як у ретро-ЕОМ з радянських фільмів. Але замість Rust (бо я не мазохіст) — Zephyr RTOS на C.

Zephyr як виявилось це «дорослий» RTOS від Linux Foundation в якого є євангілісти і спільнота, а головне в ньому є офіційна підтримка RP2040, документація є, Stack Overflow теж є. Що ще треба людині о другій ночі?

Сьогодні зроблю тільки Hello World. Але якщо ви думаєте, що це просто, то ви ще не зустрічали west init.

Що знадобиться

  • Raspberry Pi Pico (RP2040) дешевий, задокументований, зрозумілий і в ньому Arduino поруч якщо Zephyr набридне
  • USB-кабель micro-USB
  • Ubuntu 22.04 або новіший (WSL офіційно не підтримується для прошивки)
  • Python 3.12+ — увага, Ubuntu 22.04 дає 3.10 з коробки, див. нижче
  • ~4 ГБ на диску (Zephyr любить покушать)
  • Терпіння. Багато терпіння.

💡 Windows: офіційна документація рекомендує рідний cmd.exe або PowerShell, не WSL з причин сумісності при прошивці.

Застереження: nRF Connect SDK це не те, що вам треба

Перш ніж ми почнемо важлива порада, яку я засвоїв через кілька годин болю.

Якщо ви гуглите «Zephyr Pi Pico» і натрапляєте на туторіали про nRF Connect SDK від Nordic то закрийте вкладку. Зразу. Не читайте далі.

nRF Connect SDK це форк Zephyr, заточений під чипи Nordic (nRF52, nRF53 тощо). Pi Pico там явно не люблять. Nordic навмисно не включає hal_rpi_pico у свій маніфест. Ви можете витратити кілька годин на боротьбу з помилками на кшталт:

hardware/clocks.h: No such file or directory

HAS_RPI_PICO Kconfig warning → fatal error

platform.c: No such file or directory

...і це буде нескінченний ланцюг залежностей, яких там просто немає за архітектурним рішенням Nordic. Я перевірив особисто. Не повторюйте мій шлях.

🚫 nRF Connect SDK + Pi Pico це кілька годин страждань. Використовуйте чистий Zephyr.

Крок 1: Python 3.12 (якщо Ubuntu 22.04)

Zephyr вимагає Python 3.12+. Ubuntu 22.04 з коробки дає 3.10. Ставимо через deadsnakes PPA:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12 python3.12-venv python3.12-dev

Перевіряємо: python3.12 —version # має бути Python 3.12.x

⚠️ Не замінюйте системний python3 бо він може використовуватись іншими пакетами. Ми будемо явно викликати python3.12 при створенні venv.

Крок 2: Системні залежності

Встановлюємо все необхідне одним заклинанням:

sudo apt update && sudo apt upgrade
sudo apt install --no-install-recommends \
git cmake ninja-build gperf ccache dfu-util \
device-tree-compiler wget python3-dev \
python3-venv python3-tk xz-utils file \
make gcc gcc-multilib g++-multilib \
libsdl2-dev libmagic1

Перевіряємо версії (Zephyr вимагає: cmake ≥ 3.20.5, python ≥ 3.12, dtc ≥ 1.4.6):

cmake --version
python3.12 --version
dtc --version

Крок 3: Встановлення west і завантаження Zephyr

west це утиліта для керування Zephyr-проєктами. Типу npm, але для мікроконтролерів і з більшим відчуттям небезпеки.

Спочатку створюємо Python virtual environment з версією 3.12 (важливо!):

python3.12 -m venv ~/zephyrproject/.venv
source ~/zephyrproject/.venv/bin/activate
# На Windows: .venv\Scripts\activate.bat
Додаємо venv до PATH назавжди, щоб CMake завжди брав правильний Python:
echo 'export PATH=~/zephyrproject/.venv/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Тепер встановлюємо west та завантажуємо весь Zephyr (~1-2 ГБ, час на каву):

pip install west west init ~/zephyrproject cd ~/zephyrproject west update west zephyr-export pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt

⚠️ west update може тривати 10-20 хвилин залежно від інтернету. Це нормально бо Zephyr тягне кілька десятків репозиторіїв. west packages pip —install може не побачити venv — тоді використовуйте pip install -r напряму, як показано вище.

Крок 4: Zephyr SDK (компілятор для ARM)

SDK це крос-компілятори та інструменти для збірки під ARM (і ще 20+ архітектур, але нас цікавить саме ARM для RP2040).

cd ~ wget 
https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.17.0/zephyr-sdk-0.17.0_linux-x86_64.tar.xz
tar xf zephyr-sdk-0.17.0_linux-x86_64.tar.xz cd zephyr-sdk-0.17.0 ./setup.sh
github.com/...​.17.0_linux-x86_64.tar.xz
tar xf zephyr-sdk-0.17.0_linux-x86_64.tar.xz
cd zephyr-sdk-0.17.0
./setup.sh

Актуальну версію SDK завжди перевіряйте на github.com/zephyrproject-rtos/sdk-ng/releases.

Крок 5: Створюємо Hello World

Zephyr немає готового прикладу hello_world, і ми зробимо свій. Структура проєкту мінімальна:

mkdir -p ~/hello_pico/src

cd ~/hello_pico

src/main.c

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

int main(void)
{
    /* Чекаємо поки USB CDC підключиться до хосту */
   k_sleep(K_SECONDS(3));

   printk("Привіт від Zephyr на Pi Pico!\n");
   while (1) {
       printk("Живий. Тікаю далі...\n");
      k_msleep(1000);
   }
   return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hello_pico)
target_sources(app PRIVATE src/main.c)

prj.conf

Тут вмикаємо USB CDC ACM — це віртуальний серійний порт через USB. Без нього Pico буде мовчати як партизан:

CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_CDC_ACM=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y
CONFIG_UART_LINE_CTRL=y
CONFIG_USB_DEVICE_PRODUCT="Pico Zephyr"
CONFIG_USB_DEVICE_VID=0x2e8a
CONFIG_USB_DEVICE_PID=0x000a
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

app.overlay — ключовий файл!

Ось де ховається головний підводний камінь, через який Pico з’являвся як USB-пристрій але без жодних інтерфейсів. Без цього файлу CDC ACM не реєструється, хоч як налаштовуй prj.conf:

 {
   chosen {
       zephyr,console = &cdc_acm_uart0;
    };
};
&zephyr_udc0 {
     cdc_acm_uart0: cdc_acm_uart0 {
        compatible = "zephyr,cdc-acm-uart";
     };
};

💡 Device Tree Overlay (.overlay) — це механізм Zephyr для опису апаратного забезпечення. Без явного оголошення CDC ACM вузла в дереві пристроїв — USB стек просто не знає про його існування, навіть якщо Kconfig вмикає драйвер.

Крок 6: Збираємо проєкт

Активуємо venv (якщо ще не активований) і збираємо:

source ~/zephyrproject/.venv/bin/activate
cd ~/zephyrproject
west build -b rpi_pico ~/hello_pico

Якщо все добре — через 2-3 хвилини побачите:

[165/165] Linking C executable zephyr/zephyr.elf
Memory region         Used Size  Region Size  %age Used
BOOT_FLASH:         256 B        256 B    100.00%
FLASH:       19024 B    2096896 B      0.91%
RAM:        7960 B       264 KB      2.94%
Converted to uf2, output size: 38912, start address: 0x10000000
Wrote 38912 bytes to zephyr.uf2

⚠️ При повторній збірці після змін використовуйте —pristine для чистої збірки: west build -b rpi_pico ~/hello_pico —pristine

Крок 7: Прошиваємо Pico

Ось тут Pi Pico дає нам щось рідкісне у світі мікроконтролерів, повну відсутність програматорів:

  1. Затискаємо кнопку BOOTSEL на Pico
  2. Підключаємо до ПК через USB (не відпускаємо кнопку)
  3. Відпускаємо кнопку і Pico з’явиться як диск RPI-RP2
  4. Копіюємо файл прошивки:

cp ~/zephyrproject/build/zephyr/zephyr.uf2 /media/$USER/RPI-RP2/

  1. Pico автоматично перезавантажується і запускає прошивку

Крок 8: Дивимося результат

Після прошивки перевіряємо що Pico з’явився як серійний порт:

ls /dev/ttyACM*
# Має бути /dev/ttyACM0
# Також можна перевірити через dmesg:
sudo dmesg | tail -5
# Шукаємо: cdc_acm 3-7:1.0: ttyACM0: USB ACM device

Підключаємось і дивимось що говорить Pico:

minicom -D /dev/ttyACM0 -b 115200
# Вийти: CTRL-A, потім X
Результат, якого ми чекали:
*** Booting Zephyr OS build v4.3.0-8126-g81f27d13d16b ***
Привіт від Zephyr на Pi Pico!
Живий. Тікаю далі...
Живий. Тікаю далі...
Живий. Тікаю далі...

Виглядає скромно, але під капотом крутиться справжній RTOS з планувальником, пріоритетами задач і управлінням пам’яттю. k_msleep(1000) — це не просто delay, це yield для планувальника. Різниця принципова, хоч і непомітна в однозадачному Hello World.

Типові помилки та як з ними жити

«west: unknown command build»

Запускаєте west поза workspace. Треба бути всередині ~/zephyrproject або передавати шлях явно:

cd ~/zephyrproject

west build -b rpi_pico ~/hello_pico

«Could NOT find Python3: Found unsuitable version 3.10»

CMake бере системний Python замість venv. Вирішення — venv має бути на початку PATH:

export PATH=~/zephyrproject/.venv/bin:$PATH
# Або додайте це в ~/.bashrc щоб не повторювати щоразу

«config 1 has no interfaces?» в dmesg

Відсутній app.overlay з описом CDC ACM вузла. Без нього USB стек не знає про серійний порт. Перевірте що файл app.overlay є в папці проєкту і містить блок &zephyr_udc0.

Pico не з’являється як диск

  • Тримайте BOOTSEL до підключення кабелю
  • Спробуйте інший кабель (класика жанру)
  • Перевірте чи не зайнятий порт іншою програмою

«west packages pip —install» не бачить venv

Відоме обмеження в деяких конфігураціях. Замість цього:

pip install -r ~/zephyrproject/zephyr/scripts/requirements.txt

Про VS Code

Планував збирати через VS Code з відповідними розширеннями. Якщо хочете спробувати то потрібні розширення C/C++ і CMake Tools від Microsoft. nRF Connect для VS Code, не ставте, він тягне nRF SDK і плутає шляхи.

На практиці виявилось що термінал з west build більш надійніший варіант для першого знайомства. VS Code зручний для редагування файлів і має вбудований Serial Monitor для перегляду виводу замість minicom.

Що далі

Hello World це лише початок. Мета цієї серії — зібрати повноцінний мікрокомп’ютер на Pi Pico з:

  • Дисплеєм ST7789 або ILI9341 через SPI + бібліотека LVGL
  • PS/2 або USB клавіатурою
  • Командним рядком через Zephyr Shell
  • Файловою системою на SD-картці (FatFS)
  • І, може, VGA-виходом через PIO — якщо вистачить нервів

У наступній частині цієх серії підключаємо LCD-дисплей і виводимо перші пікселі. Там буде Device Tree, LVGL і відчуття, що ти вже справжній embedded-розробник.

Якщо у вас щось не запустилось чи є релевантніший досвід ніж у мене, то пишіть у коментарях. Досвід «у мене теж не завелось» теж корисний, бо я точно не один наступав на ці граблі.

Корисні посилання

P.S. Так, я знаю, що коментарі на DOU скажуть «навіщо Zephyr, є ж Arduino». Відповідаю заздалегідь: бо хочу. І бо Zephyr крутіший. Все.

Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

👍ПодобаєтьсяСподобалось8
До обраногоВ обраному6
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

а я рушій джаваскрипта на пі піко залив)

Ого. А є десь опис чи огляд, як то робили?

авжеж) ось: kalumajs.org
і можна блимати ледом :)

const { NeoPixel } = require('neopixel')
const BOARD_NEOPIXEL_PIN = 23
const np = new NeoPixel(BOARD_NEOPIXEL_PIN, 1)
const Off = np.color(0, 0, 0)
const Green = np.color(20, 40, 0)

let on = false

const toggle = () => {
  np.setPixel(0, on ? Green : Off)
  np.show()
  on = !on
}

setInterval(toggle, 1000)

Дякую! JS на мікроконтролері не нова, але цікава тема. На AVR вже давно живе

Але замість Rust (бо я не мазохіст) — Zephyr RTOS на C.

ще цю давай скопіздь, поки я не роздуплився

Мені просто сподобалось таке твердження :)

як хоч, поки що тема раста на голому залізі з мікроконтролером не розкрита, упрашувать не буду

Я ж подякував за це ;) Тема на жаль до кінця не розкрита не зміг підключити старі дисплеї. Зараз чекаю поки прийде щось новіше

був би власником Амазона то засудив би

Та ладно ;) Тут тре колоборація бо поле непахане, а цікавість до теми тільки зростає

Пахай не пахай, все одно получиш ШІ.
Мілтех хоче щоб був високодосвічений і швець і жнець і на дуді гравець в офіс з ненормованим робочим днем і своєчасною виплатою «конкурентної» зепе.
А де інде ембедед як не був потрібний так і не буде в цій країні, щоб там не розказували про те як космічні кораблі боронують простори Всесвіту, а з підводної лодки ти ні куди не дінешся.
Я б називав ці вправи мікроконтполерним анонізмом.

Клас. Що не комент то перл, — "

Я б називав ці вправи мікроконтполерним анонізмом.

" Ну в мене усе простіше, я не збираюсь йти у цій галузі в найм, принаймні найближчим часом. Тому і виходить таке самозадоволення :) ахахапчха.
Трохи попробував, що правда в іншому не embedded напрямку, там тре усе на вчора і щоб одну кнопку натиснув і виграв мінімум битву, а краще війну, щоб витрат на розхідні матеріали було копійок на 5

І таке не тільке в нас, дивився відоси за поребриком те ж саме, відношення як до самого нижчого ланцюгового працівника, зарплатня нижче чем у веб, а найголовніше те що начальство не розуміє, що ти робиш і тре писати майже не щодня звіти про зроблену роботу. Але що поробиш, я наприклад ніколи не розумів рибалок, знайомий хвалився вудкою за 4к баксів і в нього такий портфелик і там усілякі папочки, а в них гачки, бльосни, поплавки і інший крам. І усі вихідні він рибачить, а в робочі дні спить і марить що рибачить. А в мене теж є такі папочки і боксики з smd і розсипухою, мікроконтролерами і мінікомпьтерами, усіди по будинку леди і датчики. Тож тут більше не про заробіток а про стиль життя. Кажуть, що в майбутньому щалишаться інтузіасти ті хто тим живе, як то і було раніше

якщо жінка дозволяє те все тримати, то чого б і ні, їсти воно не просить,
а в мене пішла навіть не з хати, а з гаража лампова Весна (а там транс якраз на інвертор для чистого синусу був би), яка ЕМІ ТЯЗ не боялась, , і ще десь феромагнітний стабілізатор напруги, теж для котла ІО би міг підійти

Чого горювати, пішла і пішла, буде як має бути. Коли то ще б руки дійшли то робити

буде черговий блекаут, і не буде чим котел завести,
а тут я такий із мультивібратором і трансом та П фільтром

Мда, засада. Але може і газа не бути, тре на дровах додатково ставити, там і насос простіше заживити

тут як в анекдоті, виникає питання: «ти за кого, за мене, чи за медведя?»

Підписатись на коментарі