Visual Studio Code dan PlatformIO

Beberapa waktu lalu saya sempat membuat catatan pengenalan tentang PlatformIO. Saat itu PlatformIO dikombinasikan dengan text editor Atom. Untuk kali ini saya akan memperkenalkan kombinasi antara PlatformIO dengan Visual Studio Code. Berbeda dengan Sublime Text, VSCode benar-benar gratis, bebas pakai seperti Atom. VS Code tersedia untuk sistem Windows, GNU/Linux maupun Mac.

PlatformIO memungkinkan pengguna untuk melakukan pemrograman terhadap mikrokontroler Atmel AVR. Bahkan lebih dari itu, ada banyak sistem lain selain AVR yang semakin mudah untuk diprogram dengan bantuan PlatformIO. Berikut saya kutip dari PlatformIO IDE for VSCode:

The next generation integrated development environment for IoT

PlatformIO is an open source ecosystem for IoT development.
Cross-platform build system and unified debugger. Remote unit testing and firmware updates.

Atmel AVR & SAM, Espressif 8266 & 32, Freescale Kinetis, Intel ARC32, Lattice iCE40,
Maxim Integrated MAX32, Microchip PIC32, Nordic nRF51, Nordic nRF52, NXP LPC, Silicon Labs EFM32, ST STM32,
TI MSP430 & Tiva, Teensy, Arduino, ARM mbed, libOpenCM3, ESP8266, etc.

Features

  • Cross-platform code builder without external dependencies to a system software:
    • 400+ embedded boards
    • 20+ development platforms
    • 10+ frameworks
  • PIO Remote™
  • PIO Unified Debugger
  • Unit Testing
  • C/C++ Intelligent Code Completion
  • C/C++ Smart Code Linter for rapid professional development
  • Library Manager for the hundreds popular libraries
  • Multi-projects workflow with multiple panes
  • Themes support with dark and light colors
  • Serial Port Monitor
  • Built-in Terminal with PlatformIO Core tool (pio, platformio)

Proses instalasi PlatformIO untuk VSCode cukup mudah, ikuti saja urutan langkah pada Gambar 1.

../_images/platformio-ide-vscode-pkg-installer.pngGambar 1. Instalasi [sumber]

Gambar 2.

Untuk memulai suatu proyek dengan PlatformIO, pengguna perlu membuka suatu direktori/folder dalam file system agar semua file proyek bisa disimpan. Pengguna bisa membuat folder baru dari aplikasi file browser tersendiri di luar VSCode, atau membuka folder yang sudah ada lalu mencari tempat untuk membuat folder yang baru dari dalam VSCode dengan menggunakan Open Folder (Gambar 2).

Gambar 3.

Setelah pengguna memilih sebuah folder untuk proyek (entah folder yang sudah ada atau yang baru dibuat), selanjutnya pengguna bisa membuat file atau folder baru. Caranya  seperti tampak pada Gambar 3, pilih icon yang sesuai (silakan hoover mouse di atas icon untuk mengetahui).

Gambar 4.

Awal pembuatan proyek yang akan menempatkan file-file di dalam folder dimulai dengan menekan Crtl+Shift+P, lalu memilih menu yang sesuai seperti pada Gambar 4. Yang lebih mudah adalah dengan menggunakan shortcut keys Ctrl+Alt+I.

Gambar 5.

Di Gambar 5 terlihat bahwa pengguna bisa memilih mikrokontroler atau sistem papan yang sesuai setelah PlatformIO menyelesaikan proses inisialisasi. Di bar bagian bawah akan muncul tulisan Selecting a board – PlatformIO Project initialization….

Gambar 6.

Pengaturan tentang bagaimana PlatformIO membantu pengguna di atur di dalam file platformio.ini seperti pada Gambar 6. Pengguna dapat memilih untuk menggunakan framework seperti bootloader dari Arduino atau mengakses langsung mikrokontroler. Dengan cara itu pengguna/pemrogram dapat memilih dari banyak mikrokontroler tanpa perlu/harus menggunakan framework.

Pertama pengguna memilih platform yang ingin dipergunakan, misalnya untuk mikrokontroler Atmel AVR di PlatformIO platform dinamai sebagai atmelavr. Berikutnya adalah framework, sebagai contoh adalah Arduino. Jangan khawatir, pengguna tidak perlu mempergunakan (mengaktifkan)  framework jika memang tidak diinginkan. Ini hanyalah cara PlatformIO untuk mengorganisasi prosesor (mikrokontroler) dan sistem. Setelah platform dan framework berikutnya pengguna memilih board. Contoh adalah boards dari Adafruit, Arduino, EnviroDIY adan SparkFun, yang untuk masing-masing papan (board) diberi nama pengenal yang berbeda. Jika ingin membaca keterangan mengenai boards berdasar pada platform atmelavr, silakan baca halaman di link ini. Sedangkan jika ingin membaca boards yang diurutkan dalam framework yang sama (sebagai contoh Arduino) maka bisa dibaca di link ini.

Jika pengguna ingin memprogram mikrokontroler ATmega328P, maka dapat memilih board mana saja yang menggunakan mikrokontroler tersebut. Contohnya boards dari Adafruit: metro, protrinket5; dari Arduino: diecimilaatmega328, miniatmega328, nanoatmega328, pro8MHzatmega328, uno; dari SparkFun: uview. Kesemuanya bisa dipilih karena mempergunakan mikrokontroler yang sama sesuai keperluan (ATmega328P). Jika akan menggunakan pemrograman murni dengan GCC C (cara pure AVR), opsi framework di dalam file platformio.ini dapat dihapus atau dijadikan sebagai komentar.

Jadi seperti pada Gambar 5, pengguna yang ingin memprogram ATmega32 dapat memilih board mightycore32,  dari MCUdude. MightyCore adalah core atau bootloader untuk framework Arduino yang ditujukan untuk dipergunakan pada mikrokontroler seperti ATmega16, ATmega32 dan ATmega8535. Seperti terlihat pada Gambar 6, framework Arduino bisa tidak dipakai (opsinya dijadikan komentar) sehingga pengguna langsung memprogram μC dalam bahasa C (dengan compiler GCC).

Gambar 7.

Setelah selesai tahap inisialisasi, folder scr masih kosong. Pengguna perlu membuat setidaknya satu file sumber (main.c) dengan cara memilih menu New File seperti pada Gambar 7.

Gambar 8.

Pada Gambar 8 diperlihatkan jika pengguna melakukan klik untuk membuka file main.c maka kode bisa ditulis di dalam workspace.

Gambar  9.

Perhatikan bahwa proses build berhasil dilakukan walaupun frekuensi mikrokontroler dalam program pada Gambar 9 diatur sebesar 40 MHz untuk Atmega32 yang memiliki frekuensi CPU maksimum sebesar 16 MHz. Karena itu kecuali kesalahan syntax, pemrogram masih perlu sangat berhati-hati dan mengandalkan diri sendiri. Modifikasi kode untuk contoh dalam file main.c sebagai berikut.

//#ifndef F_CPU
#define F_CPU 1000000UL
//#endif

#include <avr/io.h>
#include <util/delay.h>

int main()
{
    DDRB = 0xFF;

    while(1)
    {
        // PORTB = 0x00;
        PORTB ^= (1<<PB5);
        _delay_ms(500);
    }
}

Gambar  10. Modifikasi untuk mikrokontroler ATmega16

Gambar 10 menampilkan proyek yang baru untuk ATmega16 dengan dasar kode yang sama dengan proyek untuk ATmega32 (Gambar 8). Penyesuaian dilakukan untuk frekuensi kerja mikrokontroler sehingga pengaturan untuk penundaan (delay) akan tepat.

Gambar  11. Hasil upload dengan avrdude dan usbasp

PlatformIO di VS Code juga mendukung proses upload kode ke mikrokontroler target, dengan menggunakan avrdude seperti terlihat pada Gambar 11. Uji coba dengan μC Atmel AVR ATmega16 berhasil dengan baik (Gambar 12).

Gambar  12. Uji upload dengan Atmega16 + LED

Gambar  13. Upload dengan Eclipse IDE sebagai pembanding

Gambar  14.

Proses uploading dengan avrdude tidak selalu berhasil dengan lancar. Kadang-kadang terjadi kegagalan dengan beberapa pesan kesalahan. Hal ini terutama terjadi karena masalah komunikasi dengan target. Gambar 13 memperlihatkan proses uploading menggunakan avrdude yang diatur dari konfigurasi internal di Eclipse. Cara ini bisa dipakai sebagai pembanding untuk menentukan sumber kesalahan. Gambar 14 memperlihatkan cara yang lebih ringan daripada cara pada Gambar 13. Di GNU/Linux seperti Ubuntu atau Mint pengguna cukup membuka terminal dan mengetik perintah sebagai berikut:

avrdude -p m16 -P usb -c usbasp -B 10

Perintah ini akan menghasilkan keluaran seperti pada Gambar 14. Salah satu sumber kegagalan upload program adalah karena kecepatan pengiriman data. Solusinya adalah dengan mencoba mengatur kecepatan dengan opsi -B. Semakin besar nilainya, maka akan semakin rendah frekuensinya. Di Gambar 14 terlihat untuk -B 10, frekuensi SCK diatur menjadi 93750 Hz. Pengguna bisa mencoba-coba dari nilai -B yang besar kemudian secara bertahap dikurangi.

Opsi lain adalah -v, yaitu verbose yang berfungsi memberikan keterangan lebih banyak saat perintah avrdude dieksekusi.

avrdude -p m16 -P usb -c usbasp -B 10 -v

Opsi -e berguna untuk memberi perintah penghapusan chip. Ini berguna karena beberapa kali terjadi kesalahan akibat avrdude gagal melakukan pemeriksaan ulang kode program yang sudah diunggah ke mikrokontroler. Di dalam file platformio.ini opsi -e saya cantumkan untuk lebih menjamin keberhasilan proses upload kode.

avrdude -p m16 -P usb -c usbasp -B 10 -e

Perintah upload kode sebenarnya juga bisa dilakukan dengan menggunakan CLI pada terminal. Cukup gunakan opsi -U dan nama program.

avrdude -p m16 -P usb -c usbasp -B 10 -U flash:w:firmware.hex

Untuk lebih mudahnya, lakukan pemanggilan dari dalam direktori/folder yang sama dengan letak file *.hex.

Gambar  15.

Gambar  16. Build dan upload untuk Atmel ATmega328P

Gambar 16 menunjukkan PlatformIO dapat dipakai untuk memprogram mikrokontroler Atmel ATmega328P tanpa framework.  Kode program tidak jauh berbeda, hanya seperti modifikasi yang terdahulu, perlu menyesuaikan setting frekuensi kerja dari CPU (mikrokontroler). Isi file platformio.ini untuk memprogram mikrokontroler ATmega328P tanpa bootloader Arduino:

[env:metro]
platform = atmelavr
board = metro
; framework = arduino
upload_protocol = usbasp
upload_flags = -e -P usb -B 10

Gambar  17. Pemrograman mikrokontroler ATmega328P dengan memanfaatkan papan Arduino Uno

Gambar 17 menampilkan cara memprogram ATmega328P dengan menggunakan papan Arduino UNO. Perlu diingat, hanya karena menggunakan papan Arduino Uno tidak berarti pemrograman dilakukan dengan menggunakan Arduino sebagaimana normalnya (menggunakan port USB). Perhatikan bahwa di dalam file konfigurasi platformio.ini, baris framework = arduino dijadikan komentar sehingga tidak akan ikut dieksekusi. Artinya framework berupa bootloader Arduino tidak akan dipakai dalam pemrograman ini. Bahkan isi (termasuk bootloader Arduino) dari mikrokontroler ATmega328P telah dihapus semuanya sebelum diisi program yang baru.

Gambar  18. Upload untuk ATtiny2313A

Gambar  19. Papan latih dengan mikrokontroler ATtiny2313A

Gambar 18 dan Gambar 19 menunjukkan pemanfaatan PlatformIO untuk melakukan pemrograman pada mikrokontroler Atmel AVR ATtiny2313A. Cara yang sama berlaku untuk banyak mikrokontroler yang lain. Pengguna bahkan bisa langsung memprogram mikrokontroler tanpa mempergunakan framework/bootloader seperti dari Arduino, Adafruit atau SparkFun. Khusus untuk mikrokontroler keluarga Atmel AVR keterangan lebih rinci mengenai pemrogramannya dengan PlatformIO bisa dibaca di halaman ini. Untuk keluarga STM32 bisa dibaca di halaman ST STM32, demikian seterusnya untuk masing-masing keluarga prosesor.

http://foros.giltesa.com/otros/arduino/fc/docs/pinout/uno.jpgGambar  20. Arduino Uno pinout [sumber]

Dalam Gambar 20 sebagai contoh terlihat bahwa sesungguhnya papan Arduino Uno R3 terdiri dari mikrokontroler ATmega328P sebagai komponen utama. Gambar pinout seperti ini memudahkan pengguna untuk mencari padanan saat hendak langsung mengakses pin/port tanpa bantuan framework/bootloader. Misalnya, jika biasanya LED indikator di Arduino Uno diakses melalui pin 13 maka dapat dilihat bahwa sesungguhnya pin itu adalah pin PB5 dari μC ATmega328P.

Konfigurasi seperti ini dapat dicari untuk sistem yang lain sehingga akses langsung ke pin/port bisa dilakukan tanpa menggunakan bootloader/framework.

 

Mendapatkan hasil kompilasi dengan debug symbols di Atom+PlatformIO

PlatformIO pada text editor Atom dapat dipergunakan untuk menghasilkan kode program yang bisa di-debug. Tetapi tanpa pengaturan yang tepat akan muncul kesalahan sebagaimana yang terlihat di Gambar 1 (no debugging symbols found).

xpiodbg003Gambar 1.

Untuk mengatasi masalah ini solusinya adalah dengan memberikan keterangan tambahan pada file platformio.ini .

xpiodbg001Gambar 2.

Untuk lebih mempermudah bisa disalin dari bagian berikut ini:

#
# PlatformIO Project Configuration File
#
# Please make sure to read documentation with examples first
# http://docs.platformio.org/en/stable/projectconf.html
#
[env:nucleo_f103rb]
platform = ststm32
framework = mbed
#build_flags = -g
board = nucleo_f103rb
upload_protocol = stlink

Keterangan lengkap mengenai penggunaan building options  di PlatformIO bisa dibaca di link ini. Untuk opsi debugging dengan compiler GCC bisa dibaca di sini.

-g

Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.

On most systems that use stabs format, -g enables use of extra debugging information that only GDB can use; this extra information makes debugging work better in GDB but probably makes other debuggers crash or refuse to read the program. If you want to control for certain whether to generate the extra information, use -gstabs+, -gstabs, -gxcoff+, -gxcoff, or -gvms (see below).

 

xpiodbg002Gambar 3. Hasil kompilasi yang berhasil di-debug  dengan DDD dan gdb.

 

 Command  Explanation
bp <address> [<asid>]<length> [‘hw’|’hw_ctx’]

list or set hardware or software breakpoint

exit exit telnet session
halt [milliseconds]

request target to halt, then wait up to the specifiednumber of milliseconds (default 5000) for it to complete

init Initializes configured targets and servers. Changes command mode from CONFIG to EXEC.  Unless ‘noinit’ is called, this command is called automatically at the end of startup. (command valid any time)
load_image filename address [ ‘bin’ | ‘ihex’ | ‘elf’ | ‘s19’ ] [min_address] [max_length]
reg [(register_number|register_name) [(value|’force’)]]

display (reread from target with “force”) or set a register; with no arguments, displays all registers and their values

reset [ run | halt | init ]

Reset all targets into the specified mode.Default reset mode is run, if not given.

resume [address]

resume target execution from current PC or address

step  [address]

step one instruction from current PC or address

Cmd
  • openocd -f ~/openocd-0.9.0/tcl/interface/stlink-v2.cfg -f ~/openocd-0.9.0/tcl/target/stm32f1x.cfg
  • telnet localhost 4444
    • help
    • halt
  • arm-none-eabi-gdb ––eval-command=”target remote localhost:3333″ firmware.elf
  • ddd ––eval-command=”target remote localhost:3333″ ––debugger arm-none-eabi-gdb firmware.elf