ESP32 як бездротовий співпроцесор для Raspberry Pi

Фото до статті

Ноутбук без бездротового зв’язку – це вже рідкість. Але коли ви шукаєте потужні одноплатні комп’ютери (SBC) з Linux, часто виявляється, що Wi-Fi в них відсутній або дуже посередній. Наявні бездротові карти часто викликають незадоволення: купа пропрієтарного програмного забезпечення, нестійкі або бінарні драйвери, дивні збої, що ніколи не виправляються, а іноді й повністю закриті драйвери з терміном придатності. Можливо, у вашому SBC немає вільного USB-порту для підключення Wi-Fi чіпа, або ви не хочете розробляти для малопоширених модулів.

А що, якби існувало унікальне рішення цієї проблеми, за умови, що у вашому SBC є вільний порт SDIO або SPI? Є бездротова карта, яка може стати вибором для багатьох. Вона не позбавлена недоліків, але надає значно більше можливостей для розвитку. Її програмне забезпечення частково з відкритим кодом, вона від відомого виробника і гарантовано легкодоступна. Йдеться про esp-hosted – використання модулів ESP32 як Wi-Fi/BT карти через SDIO або SPI.

Нещодавно я додав ESP32-C6 до свого проєкту, і налаштування esp-hosted виявилося не надто простим. Тому пропоную покрокову інструкцію та обговорення того, чому esp-hosted є таким цікавим і перспективним рішенням. Спойлер: воно працює з апаратними перемикачами живлення, його можна переробити на співпроцесор для mesh-протоколів, і воно потенційно може допомогти створити повністю відкриту SDIO Wi-Fi карту.

Дві версії, підтримка більшості чіпів

Варто роз’яснити, що під назвою esp-hosted існує два проєкти. Перший – esp-hosted-mcu (раніше esp-hosted-fg, “First Generation”). Він використовує ESP32 як мікроконтролер, підключений до Wi-Fi, і забезпечує обмежений, але самодостатній інтерфейс на стороні Linux. Мережеві з’єднання переважно керуються ESP32, тому він підключатиметься до ваших мереж Wi-Fi, навіть якщо основний комп’ютер перезавантажується або вимкнений. Таким чином, esp-hosted-mcu найкраще підходить для мікроконтролерів або коли ви хочете, щоб ESP32 був повністю автономним, так би мовити, окремою сутністю. Хочете перетворити свій ESP32 на EC для вашої плати з функціоналом Wi-Fi? Тоді обирайте версію -mcu.

esp-hosted-linux (раніше esp-hosted-ng, “New Generation”) залишає мережевий стек на стороні Linux, а ESP32 виступає як відносно проксі для Linux-мережевого стеку. Я зосереджуся на esp-hosted-linux, оскільки він поводиться максимально “нативно”, як звичайні Wi-Fi карти в Linux. Однак багато з описаного стосується й esp-hosted-mcu.

esp-hosted вимагає двох компонентів: Linux-комп’ютер з вільним портом SDIO або SPI, та чіп/модуль ESP32 з підтримуваних. Я обрав ESP32-C6. Для багатьох завдань достатньо стандартних модулів ESP32-WROOM, але підтримуються і новіші чіпи. Зокрема, ESP32-S2, -S3, -C2, -C3, -C5 та -C6/C61 можуть працювати з esp-hosted-linux. Якщо ви працюєте з чимось на кшталт -S31, перевірте трекер проблем основного проєкту.

Я використовую C6, оскільки вважав, що він має найбільший набір підтримуваних функцій, а його вартість трохи вища за інші. Це було помилкою. Якби я проєктував нову плату, я б обрав ESP32-C5. Виявляється, незважаючи на менший номер, ESP32-C5 кращий за ESP32-C6, особливо завдяки підтримці 5 ГГц.

Далі потрібно з’єднати їх через SDIO або SPI. Я рекомендую SDIO, якщо він доступний, оскільки це значно швидше. Важливо переконатися, що SDIO-інтерфейс вашого SBC підтримується операційною системою, а не перебуває в стані “апаратне забезпечення готове, але бракує драйвера”. Якщо у вас вже є готова плата розробника, ви можете тимчасово підключити SD-карту до пінів SDIO, щоб перевірити, чи працює ваш SDIO-інтерфейс!

SDIO – це повнодуплексний паралельний інтерфейс з одним керуючим сигналом (CMD), одним тактовим сигналом (CLK) і чотирма лініями даних (D0-D3), або навіть однією лінією даних (D0), якщо ви економні. Ці лінії перемикаються швидко і не є диференціальними парами, тому їх слід розташовувати як односторонні провідники. Я планую написати окрему статтю про SDIO, але поки що зверніться до чинних онлайн-посібників з розведення SDIO. Ось приклад схеми:

ESP32 як бездротовий співпроцесор для Raspberry Pi 1

Коротка рекомендація щодо розведення SDIO: забезпечте суцільний шлях повернення землі під провідниками, максимально зрівняйте довжину між сигналами (в межах 1 мм?), і загалом зробіть SDIO-з’єднання якомога коротшим. При підключенні SDIO з 40-пінового роз’єму Pi Zero або повнорозмірного Pi, деякі сигнали потребуватимуть ретельного зрівняння довжини, а деякі – ні. Це нормально, враховуючи розпіновку GPIO Raspberry Pi. Просто пам’ятайте про зрівняння. Додайте як послідовні, так і підтягуючі резистори, згідно з документацією ESP-Hosted.

Окрім сигналів SDIO, вам знадобиться керування піном EN, щоб драйвер міг скинути ESP32 у відомий робочий стан перед початком зв’язку. Для цього EN можна підключити через класичну RC-схему, яка використовується для OLED-дисплеїв, якщо у вас бракує GPIO і ви не проти. Драйверу потрібен EN, але не критично. Ви можете просто встановити resetpin=-1 у скрипті ініціалізації драйвера, якщо самостійно подбаєте про перемикання EN.

ESP32 як бездротовий співпроцесор для Raspberry Pi 2
Приклад одностороннього розведення підтягуючих та послідовних резисторів

Ви можете не турбуватися про пін BOOT. Проте, переконайтеся, що є достатнє живлення 3.3 В: 300-400 мА. Шина живлення 3.3 В на платах Raspberry Pi зазвичай достатня для живлення ESP32. Але на інших SBC, можливо, доведеться додати додатковий регулятор 3.3 В, щоб задовольнити потребу ESP32 в живленні. І останнє, але не менш важливе: забезпечте доступ до USB-порту ESP32, оскільки він знадобиться для прошивки. На щастя, прошивку потрібно робити лише один раз. Особисто я підключив його через 4-піновий JST-SH з розпіновкою, подібною до QWIIC, як видно на схемі вище.

Компіляція прошивки (або ні)

Є три речі, які потрібно зробити: переконатися, що SDIO (або SPI) інтерфейс вашого SBC вільний, скомпілювати та прошити ESP32, а потім скомпілювати та завантажити драйвер. Не обов’язково в такому порядку, але вам потрібні всі три кроки.

Звільнити SDIO-інтерфейс на Raspberry Pi відносно легко: це швидка зміна в файлі config.txt. Вам потрібно лише перепризначити SDIO-піни, а якщо є вбудована Wi-Fi карта, вимкнути її Bluetooth. Частина “вимкнення Bluetooth”, ймовірно, необхідна, тому що прошивка вбудованої Wi-Fi карти завантажується через SDIO, тому Bluetooth-частина карти в будь-якому випадку не працюватиме. Це також звільняє порт UART-консолі на Pi, що може бути надзвичайно корисно, якщо вам потрібно налагодити роботу вашого Wi-Fi інтерфейсу! До речі, я сумніваюся, що параметр poll_once=off для SDIO необхідний, і він, здається, спамить dmesg. Якщо ви коли-небудь захочете позбутися цього спаму, видалення цієї опції може бути гарним початком.

На інших SBC з SDIO можуть виникнути проблеми, але якщо це не надто екзотичні рішення, це не повинно бути великою проблемою. Якщо ви створюєте власний SBC і маєте плату розробника, сміливо підключайте слот для microSD до SDIO-пінів, додайте необхідні підтягуючі резистори та налагоджуйте роботу SDIO-інтерфейсу за допомогою запасної microSD-карти. Якщо microSD-карта працює, то, найімовірніше, ESP32 теж працюватиме.

Компіляція прошивки ESP32 також відносно проста. Можливо, ви не захочете компілювати прошивку ESP32 на своєму SBC, оскільки він може вичерпати оперативну пам’ять і зависнути під час виконання cmake. На Pi Zero зависання майже гарантоване. Просто використовуйте свій настільний комп’ютер для компіляції прошивки та уникнення проблем. Альтернативно, ви можете взагалі пропустити це і завантажити прошивку з вкладки “Releases” на Github. Вони наразі знаходяться в застарілому репозиторії, але я припускаю, що згодом нові релізи будуть розміщені в репозиторії esp-hosted-linux, тому слідкуйте.

Переконайтеся, що ваш драйвер скомпільовано з тієї ж версії репозиторію esp-hosted, що й прошивка ESP32, використовуючи git log або подібні інструменти для перевірки останнього коміту. В іншому випадку драйвер видасть попередження і відмовиться завантажуватися. Ви можете виправити це попередження, якщо вважаєте різницю незначною, але це на ваш ризик.

Драйвери, зроблені по-старому

Тепер про драйвер. Вам потрібно буде скомпілювати драйвер на самому SBC, якщо ви не використовуєте крос-компіляцію. Скрипт rpi_init.sh компілює та завантажує драйвер, а також містить деякі примітки, які можуть бути корисними. Якщо ваш SBC має 512 МБ оперативної пам’яті або менше – відкрийте rpi_init.sh у редакторі, знайдіть команду make -j8 і замініть її на make -j2 (або навіть -j1). Інакше процес компіляції вичерпає оперативну пам’ять і призведе до зависання вашого SBC.

Чи все підключено? Якщо SDIO правильно налаштовано і прошивку завантажено, драйвер завантажиться успішно, і з’явиться інтерфейс wlan. Виникли проблеми? Перевірте dmesg, щоб побачити вивід налагодження модуля драйвера. Я люблю запускати dmesg -Hw у вільному терміналі або просто у фоновому режимі.

Скрипт rpi_init.sh – чудовий інструмент для налагодження, але його варто позбутися для довготривалої роботи модуля, значною мірою тому, що він компілює модуль щоразу при запуску. У тій самій директорії ви знайдете esp_sdio.ko – це Linux-модуль, який ви щойно скомпілювали. Зробіть так:

sudo cp esp_sdio.ko /lib/modules/$(uname -r)/kernel/drivers/
sudo depmod -a

Це може бути хак, але тепер ви можете використовувати modprobe esp_sdio замість insmod з директорії скрипта. Потім ви можете додати назву модуля (esp_sdio) до файлу /etc/modules, щоб він автоматично завантажувався при кожному запуску, що набагато краще, ніж повторно запускати скрипт і пов’язану з ним перекомпіляцію.

Працездатне і дуже перспективне рішення

ESP32 як бездротовий співпроцесор для Raspberry Pi 3
Забув про підтягуючі резистори та довелося імпровізувати

Звичайно, є моменти, які потребують доопрацювання. Модуль повинен бути належним чином інтегрований в інтерфейси Device Tree, щоб його не потрібно було додавати вручну до /etc/modules, а він міг автоматично завантажуватися через overlay. Також потрібна інтеграція через DKMS, так само, як був розповсюджений драйвер esp8089. Наразі вам доводиться перекомпілювати його та повторно додавати модуль до каталогу модулів ядра після кожного оновлення ядра, а DKMS міг би це усунути. Пропускна здатність прийнятна, можна отримати 40-50 Мбіт/с при стандартній частоті SDIO. Якщо ви вважаєте, що ваше обладнання достатньо потужне і може розширити межі SDIO, є деякі налаштування, які можна змінити!

Крутий трюк, але навіщо?

Тож чому варто про це говорити? Є чотири причини, які я вважаю важливими. По-перше, це єдина Wi-Fi карта, яка, наскільки мені відомо, може передавати Bluetooth через SDIO замість використання UART-порту, що особливо корисно для плат форм-фактору Pi Zero. Це вже саме по собі вражає.

По-друге, хоча код і не ідеальний, і є купа запитів на злиття (pull requests), які варто розглянути, esp-hosted коректно обробляє апаратні перемикачі живлення в моєму проєкті! Немає збоїв чи помилок ядра, коли ESP32 втрачає живлення, він плавно відключається і підключається, апаратний перемикач просто працює, і мені це подобається.

Наступні дві причини пов’язані з тим, що це, по суті, Wi-Fi карта з відкритим програмним забезпеченням. Прошивка ESP32 не є повністю відкритою, оскільки RF-компоненти традиційно є закритими і компілюються як бінарні блоби. Однак існує кілька чудових проєктів, що намагаються звільнити пропрієтарні частини Wi-Fi стеку ESP32. Зі зростанням кількості людей, які долучаються до цієї роботи, цілком можливо, що ми зможемо перетворити всюдисущі модулі ESP32 на повністю відкриті Linux Wi-Fi карти, надзвичайно дешеві та доступні будь-де. Справді дружні до хакерів Wi-Fi карти, які довго служать – хіба це не чудово?

Остання причина – найцікавіша, і для неї навіть не потрібне видалення пропрієтарних компонентів. Після підключення SDIO у ESP32 залишається багато вільних пінів, включаючи піни з високошвидкісним SPI. Хто може сказати, що ми не можемо підключити до нього LoRa-модем і запустити Meshtastic/Meshcore/тощо? Оскільки прошивка переважно відкрита, теоретично, будь-який код може бути доданий у проміжках між Wi-Fi/BT, будь-які значущі дані потім можуть бути передані на Linux-хост. Також не залишається непоміченим, що нові чіпи ESP32 нативно підтримують Zigbee та Thread, і виведення цього на Linux – це лише питання коду. Для мене це найкраща частина – думка про те, що одного дня ми зможемо перетворити ESP32 на справжній багатофункціональний комунікаційний співпроцесор для будь-якого Linux-процесора.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *