Pemrograman Dasar TinyOS Komponen dan Antarmuka Komponen • Setiap komponen memiliki ciri-ciri/tanda yang mendeskripsikan fungsi yang dipanggil dan fungsi yang dapat dipanggil oleh komponen lain • Ciri/tanda tersebut dinyatakan dalam bentuk antarmuka • Antarmuka adalah kumpulan fungsi dari suatu layanan atau abstraksi • Komponen dapat berupa modul (module), yaitu implementasi logika aplikasi, atau konfigurasi (configuration) yang menghubungkan komponenkomponen pada abstraksi yang lebih besar Komponen • Program dalam nesC adalah kumpulan dari komponen-komponen • Setiap komponen berkorespondensi satu-ke-satu dengan nama file-nya • Contoh, LedsC.nc berisi kode implementasi komponen LedsC dan PowerupC.nc berisi implementasi komponen PowerupC • Nama komponen berada pada lingkup global, artinya hanya ada satu definisi komponen PowerupC, yaitu file PowerupC.nc Komponen • Modul dan konfigurasi dapat digunakan secara bersama-sama untuk membentuk suatu layanan atau abstraksi yang lebih kompleks • Keduanya berbeda pada bagian implementasi • Bagian implementasi pada modul berisi kode nesC: deklarasi variable, deklarasi fungsi, pemanggilan fungsi • Bagian implementasi pada konfigurasi berisi kode wiring nesC yang menghubungkan komponenkomponen Sintaksis Komponen Modul Konfigurasi Visualisasi Komponen Ciri/Tanda Komponen • Sintaksis pada blok ciri/tanda komponen baik untuk modul maupun konfigurasi adalah sama, yaitu berupa nol atau lebih antarmuka (interface) • Ciri/tanda komponen mendeklarasikan apakah komponen tersebut menyediakan (provide) atau menggunakan (uses) antarmuka • Atau keduanya: menyediakan dan menggunakan • Contoh, komponen yang menginginkan untuk menyalakan atau mematikan LED menggunakan antarmuka Leds, sementara komponen yang mengimplementasikan fungsi untuk menyalakan atau mematikan LED menyediakan antarmuka Leds Ciri/Tanda Komponen Pengguna Penyedia Ciri/Tanda Komponen • Kata kunci “as” dapat digunakan untuk memberikan alias pada suatu antarmuka • Digunakan jika suatu modul menggunakan 2 antarmuka yang sama agar dapat dibedakan • Contoh, pada saat booting ada 2 tahap inisialisasi, yaitu PlatformInit dan SoftwareInit. Keduanya sama-sama antarmuka Init tetapi untuk membedakan 2 tahap maka diberikan alias yang berbeda • Antarmuka dapat dikelompokkan (clustered) • Contoh, pada komponen LedsP Penamaan Komponen (dan File) • Akhiran C dan P pada nama komponen bukan suatu keharusan, melainkan hanya kesepakatan • Komponen dengan nama yang berakhiran dengan C berarti dapat digunakan secara bebas, yaitu dapat digunakan oleh komponen lain yang berbeda fungsi • Komponen dengan nama yang berakhiran dengan P menandakan komponen tersebut bagian dari sistem yang lebih kompleks (suatu abstraksi atau layanan yang lebih besar) • C berarti Component • P berarti Private Implementasi Komponen: Modul • Perbedaan antara nesC dan C utamanya pada bagaimana pemanggilan fungsi dilakukan dan lingkup variabel • Komponen harus menyediakan implementasi perintah (command) untuk antarmuka yang disediakan dan implementasi kejadian (event) untuk antarmuka yang digunakan: kode modul harus mendefinisikan fungsi-fungsi tersebut • Modul memanggil perintah dengan kata kunci “call” dan memanggil kejadian dengan kata kunci “signal” Implementasi Komponen: Modul • Modul menyediakan state dan mengimplementasikan logika aplikasi • Fungsi dan variabel di dalam modul diekspor melalui antarmuka • Deklarasi variabel sama seperti pada C • Contoh, antarmuka Get Implementasi Komponen: Konfigurasi • Agar suatu komponen (dalam hal ini modul) dapat melakukan pekerjaannya, maka harus ditentukan komponen yang menyediakan antarmuka yang digunakan • Menghubungkan komponen satu dengan lainnya yang menyediakan antarmuka dilakukan di dalam konfigurasi • Menghubungkan 2 komponen disebut dengan wiring • Konfigurasi digunakan untuk membangun abstraksi yang lebih besar dengan cara menghubungkan komponen-komponen terkait Implementasi Komponen: Konfigurasi • Konfigurasi harus menyebutkan komponen mana saja yang akan dihubungkan dengan kata kunci “components” yang dapat dituliskan pada baris manapun di dalam implementasi konfigurasi • Komponen harus disebutkan terlebih dahulu sebelum dihubungkan Implementasi Komponen: Konfigurasi • Operator konfigurasi: =, ->, dan <• Operator “=“ digunakan untuk menghubungkan spesifikasi konfigurasi (akan dijelaskan lebih lanjut) • Operator “->” dan “<-” memiliki arti yang sama, yaitu menghubungkan pengguna dan penyedia antarmuka • Tanda panah menunjuk dari pengguna ke penyedia, tetapi hubungan bersifat dua arah • Konfigurasi utama pada suatu aplikasi tidak menggunakan ataupun menyediakan antarmuka Komponen Generik • Pada dasarnya komponen pada TinyOS adalah singleton: hanya ada 1 buah instance komponen • Artinya, jika ada 2 komponen di dalam konfigurasi yang terhubung pada komponen yang sama, maka kedua komponen tersebut mengakses kode yang sama (state dan fungsi) • Komponen generik memungkinkan untuk membuat banyak instance untuk sebuah komponen Komponen Generik • Komponen generik umumnya digunakan pada struktur data: struktur perangkat keras umumnya singleton, tetapi struktur data pada tingkat perangkat lunak tidak • Komponen generik memungkinkan pemanfaatan ulang kode yang sudah ada (code reuse) • Contoh, struktur data antrian, struktur data vektor bit, dll Komponen Generik Definisi Menggunakan Antarmuka • Antarmuka mendeskripsikan hubungan fungsional antarkomponen • Peran sebuah komponen dalam suatu relasi ditentukan apakah komponen tersebut menyediakan atau menggunakan antarmuka • Antarmuka juga memiliki hubungan satu-kesatu dengan nama file-nya (tentu saja tanpa akhiran C atau P untuk membedakan dengan komponen) Antarmuka • Sama halnya dengan komponen, nama antarmuka juga memiliki lingkup global • Sintaksis penulisan antarmuka: Antarmuka Antarmuka • Antarmuka mendefinisikan fungsi dengan tipe perintah (command) atau kejadian (event) • Ingat: pada modul digunakan kata kunci “call” dan “signal” • Antarmuka yang mendefinisikan command dan event disebut dengan bi-directional interface, contoh: Timer • Tidak ada perbedaan dalam perintah atau kejadian: semua diterjemahkan sebagai function call pada C • Tipe dari suatu fungsi menentukan peran dari suatu antarmuka, apakah sebagai penyedia atau pengguna • Pada komponen: menyediakan antarmuka berarti memberikan layanan, menggunakan antarmuka berarti menggunakan layanan yang disediakan Antarmuka Kata kunci apa yang digunakan pada hubungan ini? Kearah mana function call dilakukan? Antarmuka Generik • Antarmuka generik menyediakan satu atau lebih tipe sebagai parameter • Jika ada lebih dari satu parameter maka dipisah dengan tanda koma: <a, b> Antarmuka Dua Arah • Antarmuka dua arah mendefinisikan 2 jenis fungsi: command dan event • Contoh, antarmuka Notify • Antarmuka dua arah memungkinkan mekanisme callback pada nesC tanpa harus menggunakan function pointer Antarmuka Split-Phase • Termasuk pada jenis antarmuka dua arah • Terdapat 2 jenis – Antarmuka generik, contoh Read, digunakan untuk akuisisi data: type checking saat kompilasi – Antarmuka non-generik, contoh Send, digunakan dalam pengiriman paket: tidak menggunakan variable passing tetapi menggunakan pointer passing untuk mengirimkan data yang lebih besar Alokasi Memori • nesC tidak menganjurkan penggunaan dynamic allocation mengingat tidak adanya proteksi memori pada perangkat keras (Programming hint 3) • Alokasi memori dilakukan dengan mendefinisikan variabel di dalam modul: static allocation • Atau menggunakan shared pool, contoh pada antarmuka Send • Rekursi dan array sangat tidak dianjurkan (Programming hint 2) Alokasi Memori • Setiap saat hanya boleh ada satu modul yang memiliki suatu objek memori (variabel atau elemen dalam array) • Dalam hal suatu objek memori harus dipakai bersama-sama, harus ada serah terima yang jelas mengenai kepemilikan objek memori • Pada akhirnya, kepemilikan objek memori harus dikembalikan kepada pemiliknya, contoh antarmuka Receive • Programming hint 4: menegaskan mekanisme kepemilikan objek memori Alokasi Memori • Deklarasikan konstanta sebagai enumerasi: kompiler akan menempatkan konstanta pada memori program alih-alih pada RAM (Programming hint 5) • Tetapi hanya berlaku untuk konstanta bertipe integer, selain integer maka deklarasikan dengan #define • Jangan menggunakan enumerasi untuk mendeklarasikan variabel: alokasi memori akan lebih besar sesuai enumerasinya (Programming hint 5) Deklarasi Tipe Data/Konstanta • Dilarang menggunakan atribut “packed” pada deklarasi struktur untuk menjaga portabilitas kode (Programming hint 6) • Mengenalkan adanya prefiks “nx_” (big endian) atau “nxle_” (little endian) pada tipe data sejak nesC 1.2 • Deklarasi struktur atau union dengan “nx_struct” dan “nx_union” pada nesC 1.2 untuk menjaga portabilitas (Programming hint 7) • Programming hint 6 dan 7 terkait dengan pertukaran data antarplatform • Platform independent type harus diubah menjadi native type jika digunakan pada komputasi yang intensif untuk menjaga kecepatan (Programming hint 8) Deklarasi Tipe Data/Konstanta • Untuk tipe data yang digunakan antarmuka, antarmuka harus menyertakan deklarasi tipe datanya (Programming hint 9) sehingga komponen yang menggunakan antarmuka tersebut tidak perlu menyertakan deklarasi tipe data • Untuk menyertakan suatu file deklarasi (header file, .h) menggunakan sintaks yang sama dengan C, yaitu #include Deklarasi Tipe Data/Konstanta • Untuk konstanta yang dideklarasikan dengan #define, selalu deklarasikan di dalam sebuah file .h dan sertakan disetiap komponen yang menggunakannya (Programming hint 10) • Penggunaan pustaka C dapat langsung dilakukan dengan menyertakan pustaka yang sesuai