Erlang untuk IoT

Gelombang minat pada perangkat mikroelektronika dan interaksinya satu sama lain untuk kebutuhan industri dan domestik telah mengarah pada pengembangan sejumlah besar desainer untuk pengembangan berdasarkan SoC (sistem pada chip) yang cukup kuat, agak miniatur berkenaan dengan solusi mikrokontroler, tetapi sudah mengandung sistem operasi yang lengkap. Pengembangan aplikasi untuk perancang seperti itu praktis tidak berbeda dari pengembangan server biasa, kecuali bahwa batas sumber daya harus tetap diingat.



Seiring dengan pertumbuhan produktivitas dan kemampuan, praktik menggunakan bahasa yang ditafsirkan tingkat tinggi seperti Lua, Python, JS untuk pengembangan aplikasi mendapatkan lebih banyak momentum. Namun, beberapa bahasa secara bertahap menembus ke dalam "saudara muda", mikrokontroler, dalam bentuk yang sangat terbatas.

Ada beberapa alasan untuk ini:

  • prototyping cepat - dengan segala hormat pada bahasa C, yang terutama mengembangkan mikrokontroler, sangat sulit untuk menyebutnya singkat. Bahasa tingkat tinggi memungkinkan Anda untuk menulis lebih sedikit kode dan menyederhanakan membuat perubahan pada apa yang sudah ditulis, yang sangat penting pada tahap prototipe;
  • manajemen memori otomatis dan abstrak mekanisme perhitungan yang rumit - saya pikir tidak perlu komentar, kedua proses manual dengan volume proyek yang cukup berubah menjadi sumber banyak sakit kepala;
  • penyederhanaan debugging dan pengujian - kode yang ditafsirkan lebih mudah untuk memeriksa di workstation sebelum waktu pengujian lapangan;
  • berjuang dengan kerumitan - seringkali, produktivitas yang tinggi menimbulkan keinginan pragmatis alami untuk mendorong lebih banyak pra-pemrosesan dan analisis ke perangkat, yang tidak menambah kesederhanaan untuk pengembangan.

Sayangnya, Anda harus membayar semua fasilitasnya. Dalam hal ini, harga untuk kenyamanan adalah sumber daya, kinerja, dan ukuran kode yang paling berharga (dalam banyak kasus Anda harus membawa lingkungan runtime yang agak tebal). Oleh karena itu, penerapan bidang bahasa tingkat tinggi di SoC dan SoM adalah hal yang ambigu dan, di beberapa tempat, kompromi.

Kami menggunakan bahasa Erlang untuk pengembangan, menerapkannya baik untuk tujuan yang dimaksudkan (membuat aplikasi server dan bidang kontrol), dan aplikasi web yang sangat tidak biasa. Oleh karena itu, gagasan untuk menggunakan infrastruktur bahasa ini untuk membuat solusi IoT muncul jauh sebelum tampilan papan tempat runtime Erlang dapat bekerja tanpa masalah.

Ada banyak alasan untuk menggunakan Erlang, yang paling signifikan:

  • Erlang sangat nyaman untuk parsing dan membuat urutan biner. Pencocokan pola dipasangkan dengan pemrosesan data bit memungkinkan protokol biner diimplementasikan dengan sangat cepat dan tanpa kata;
  • kurangnya variabel global dan ketidakmampuan untuk sebagian besar data - memungkinkan Anda untuk menulis dan, yang tidak kalah penting, memelihara aplikasi yang andal di mana sulit untuk secara tidak sengaja mengubah sesuatu yang salah;
  • Proses olahpesan ringan yang sangat mirip dengan apa yang harus dihadapi oleh pengembang tertanam. Intinya, mereka adalah prosedur inisialisasi dan prosedur yang memproses pesan masuk dalam loop tak terbatas, mengubah keadaan internal. Ini sangat mirip dengan Arduino, hanya ada banyak proses dan mereka bekerja secara paralel, di samping itu, dalam interval antara pesan, prosedur pemrosesan dapat diubah dengan cepat (hot code reload), yang sangat nyaman ketika Anda perlu memperbaiki kesalahan kecil atau menyesuaikan perilaku;
  • lingkungan yang terisolasi dan alokasi memori otomatis, saya pikir, tidak perlu penjelasan;
  • cross-platform - kode byte untuk runtime ERTS dapat dikompilasi pada mesin pengembang, dan kemudian ditransfer ke perangkat target tanpa masalah;
  • alat introspeksi yang sangat baik - kemampuan untuk terhubung ke aplikasi yang sedang berjalan melalui jaringan dan melihat bahwa itu melambat begitu sering sering sangat berguna.

Papan kerja pertama yang kami coba Erlang adalah Carambola 2 dari pengembang 8 perangkat Lithuania, yang dirakit pada chip AR9331 yang populer. Versi pertama dari board ini, sayangnya, tidak memiliki cukup memori flash agar sesuai dengan runtime. Tetapi versi kedua sudah cukup memungkinkan untuk mengakomodasi ERTS dan aplikasi kecil.



Instalasi dilakukan dengan metode klasik untuk perangkat jenis ini - merakit gambar OpenWRT yang mengandung Erlang, diikuti dengan mem-flash-nya ke memori flash perangkat. Peluncuran pertama lingkungan, sayangnya, menyebabkan kekecewaan - semuanya menggantung. Saya sudah menjelaskan alasannya di konferensi InoThings 2018 , tetapi, sayangnya, ternyata kemudian, saya menyesatkan rekan-rekan saya dengan secara keliru menyebutkan sumber perilaku tersebut.

Saya akan menceritakan kembali sebentar. Ketika bekerja dengan file, mesin virtual ERTS menggunakan tipe off_t , yang ukurannya dalam distribusi dihitung ketika perakitan dikonfigurasikan secara otomatis (jika berjalan pada platform target) atau diganti dari lingkungan kompilasi-silang, seperti yang terjadi dalam kasus OpenWRT. Tidak jelas mengapa, tetapi dalam pengaturan untuk prosesor MIPS dan turunannya dalam file konfigurasi rakitan dua kali lebih besar dari yang sebenarnya. Masalahnya tidak akan muncul jika kode mesin virtual tidak menggunakan arahan preprocessor seperti

#if SIZEOF_OFF_T == 4 

dan cek dangkal dalam kode (saya menduga bahwa hasil kompilasi akhir akan sama, tetapi tidak ada cukup sekering untuk memeriksa):

 if (sizeof(off_t) == 4) { 

Akibatnya, ERTS dikumpulkan pada iterasi pertama ketika mencoba membaca file ~ / .erlang.cookie (sejenis kata sandi untuk identifikasi selama interaksi jaringan) pada awalnya berhasil menerima sampah dengan urutan tinggi dan jatuh dengan keras.

Patch patch dan paket dengan versi terakhir ERTS untuk OpenWRT dapat diunduh dari GitHub . Selain itu, masalah belum diamati, semuanya bekerja seperti yang diharapkan.

Platform perangkat keras kedua yang kami coba Erlang adalah perancang LinkIt Smart 7688 dari Mediatek dan SeeedStudio , yang dirancang khusus untuk pembuatan prototipe cepat dan mempelajari dasar-dasarnya. Papan ini hanyalah pendewaan dari pesta pora dalam hal sumber daya - frekuensi inti MIPS telah tumbuh sebesar 1,5 kali, lebih banyak RAM (untuk ERTS itu penting, GC tidak tertidur) dan lebih banyak memori flash, serta kehadiran kartu microSD dan kemungkinan menggunakan co-prosesor Atmel Atmega 32U4 dalam versi Duo untuk bekerja dengan periferal.

Secara umum, platform ini sangat cocok untuk melanjutkan perjamuan, dan kehadiran perangkat plug-in tambahan yang terhubung tanpa penyolderan memungkinkan Anda dengan cepat dan kondisional memasang bangku tes di lutut Anda.

Platform ini dilengkapi dengan perangkat lunak dengan antarmuka web sendiri, serta pustaka Python dan NodeJS untuk pengembangan. Ekosistem untuk majelis tidak berubah - itu masih OpenWRT. Jika karena alasan tertentu Anda menemukan semua keragaman ini tidak berguna, maka pada repositori di atas ada paket yang berisi sekumpulan minimal komponen yang diperlukan . Setelah perakitan, gambar flash ditulis ke perangkat dan setelah reboot, Anda dapat menggunakan REPL dengan aman.

Untuk membangun aplikasi di Erlang untuk IoT, satu masalah arsitektur perlu diselesaikan.

Bahasa dirancang dan dikembangkan dengan mata pada apa yang akan berfungsi sebagai bidang kontrol, yaitu lapisan kontrol, saat bekerja dengan besi seharusnya melalui FFI. Tiga jenis interaksi disediakan untuk ini:

  1. ports (ports) - secara terpisah memproses proses yang ditulis dalam bahasa apa pun, interaksi dengan yang terjadi melalui input / output stream. Mereka dapat dimulai kembali jika jatuh, tetapi karena metode interaksi, produktivitas mereka dalam hal komunikasi kecil (namun, itu sudah cukup bagi kita);
  2. NIF-functions - terlihat seperti fungsi standar bahasa, tetapi panggilan mereka menghasilkan eksekusi kode yang dikompilasi dalam ruang runtime. Jika terjadi kesalahan, mereka dapat menyeret seluruh mesin virtual di belakangnya.
  3. C-node - ketika seluruh pekerjaan dilakukan dalam proses terpisah, dan interaksi dilakukan seperti dengan lingkungan runtime yang berjalan secara terpisah melalui jaringan. Kami tidak akan mempertimbangkan opsi ini karena biaya overhead yang cukup besar dalam kerangka satu perangkat yang lemah.

Dilemanya adalah ini: kita hanya dapat memindahkan barang ke FFI (mis., Dukungan untuk GPIO, I2C, SPI, PWM, UART, dll.), Dan kita dapat berinteraksi langsung dengan sensor dan perangkat lain di Erlang, atau sebaliknya, untuk mentransfer driver perangkat sepenuhnya ke kode modul eksternal, meninggalkan aplikasi untuk menerima data mentah dan memprosesnya, dalam hal ini, mungkin masuk akal untuk menggunakan kode yang sudah ditulis.

Kami memutuskan untuk menggunakan opsi pertama. Ada beberapa alasan untuk ini:

  • karena kita bisa;
  • seperti yang telah saya sebutkan, Erlang dilengkapi dengan alat yang cukup kuat untuk merakit dan membongkar urutan biner, sementara itu matematika yang cukup sederhana, yang memungkinkan Anda untuk tidak khawatir tentang perlindungan terhadap luapan dan sihir lain yang digunakan untuk memproses hasilnya. Bukan karena sihir orang-orangan sawah ini, tetapi itu memengaruhi neofit secara mengejutkan;
  • secara intuitif, tampaknya driver dalam bahasa tingkat tinggi akan lebih sederhana dan lebih dapat diandalkan (proses macet akan me-restart supervisor, yang akan mengarah pada inisialisasi ulang perangkat yang dikendalikan).

Oleh karena itu, perpustakaan ErlangALE dengan cepat ditemukan, yang berisi dukungan yang sudah diterapkan untuk GPIO, I2C dan SPI melalui antarmuka kernel, dan para pengembang platform perangkat keras, pada gilirannya, telah merawat mereka. Pustaka untuk bekerja dengan UART sudah diuji, ditambah kami menambahkan erlexec , sebuah aplikasi yang memungkinkan Anda membuat dan mengelola proses OS.

Semua aplikasi ini menggunakan port (secara terpisah meluncurkan proses biner) untuk bekerja dengan peralatan dan OS, yang membutuhkan dukungan kompilasi-silang untuk bahasa C dan C ++, yang mana skrip shell yang agak rumit ditulis yang mengonfigurasi lingkungan build untuk menggunakan kompiler yang diperlukan.

Untuk menguji keputusan yang kami buat, kami mengumpulkan perangkat sederhana dari LinkIt Smart 7866, dua perangkat I2C (sensor suhu dan tekanan BMP280 dan 128 OLED display 64 piksel) dan modul GPS USB yang mengirimkan data melalui UART. GPIO diuji pada LED di papan, itu bekerja, dan menghubungkan tampilan SPI tampaknya tidak perlu pada tahap komplikasi ini.



Ternyata aplikasi itu terbilang kompak dan sederhana, kode sumbernya bisa dilihat di Github.

Saya tidak akan menggali fragmen kode, tetapi mencoba menjelaskan dalam ikhtisar cara kerja aplikasi.

Driver semua perangkat dibuat dalam bentuk proses gen_server, ini nyaman karena memungkinkan Anda untuk menambahkan parameter tambahan dan, kadang-kadang, keadaan perangkat ke negara. Yang terakhir dapat dilihat pada contoh uart_gps - data dari UART tiba secara tidak serempak, diurai oleh parser NMEA0183, dan hasilnya ditulis ke status proses, dari mana mereka diperoleh berdasarkan permintaan.

Siklus utama aplikasi dijelaskan dalam modul gps_temp_display - setiap detik proses membaca data GPS dan meminta status suhu dan tekanan dari BMP280 dan menampilkannya pada layar OLED. Untuk kepentingan, Anda dapat melihat driver display dan sensor BMP280 - semuanya ternyata cukup ringkas, 150-170 baris per modul.

Secara umum, tugas di atas (menulis kode driver, menggabungkan semuanya menjadi satu aplikasi, perakitan dan pengujian) memakan waktu sekitar empat malam, rata-rata dua jam, mis. sesungguhnya, beberapa hari kerja. Menurut saya pribadi ini adalah indikator yang baik untuk mencoba menggunakan Erlang dalam aplikasi embedded yang lebih kompleks dan serius yang tidak memerlukan batasan waktu nyata yang ketat.

Tentu saja, upaya kami untuk menggunakan Erlang untuk sistem embedded bukan satu-satunya. Ada beberapa proyek menarik dalam hal ini:

Source: https://habr.com/ru/post/id417245/


All Articles