Lampu Kedip Dengan Model Finite State Machine dan FreeRTOS

Artikel ini adalah pengembangan dari artikel “Lampu Kedip Dengan Model Finite State Machine“. Pada artikel tersebut pewaktuan 1 detik menggunakan fungsi delay() dari Arduino. Pada artikel ini digunakan vTaskDelay pada sistem operasi real time FreeROTS untuk mendapatkan perioda 1 detik untuk eksekusi Finite State Machine (FSM).

Spesifikasi

Sistem yang dibuat adalah lampu kedip, dengan perioda 2 detik.

Perangkat Keras

Perangkat lunak dengan Arduino Nano ATmega328. Output dengan LED yang diseri dengan resistor pembatas arus. Nilai resistor tidak kritis. Pada percobaan ini dipakai nilai resistor 1000 ohm. LED disambung ke port D3 pada Arduino Nano.

Model Sistem

Model FSM untuk lampu kedip adalah sebagai berikut.

Perangkat Lunak

Pada sistem ini diperlukan pewaktuan (timing) agar lampu berkedip dengan frekuensi 0,5 Hz. Untuk itu diperlukan FSM yang dihitung/dipanggil setiap 1 detik. Untuk membuat pemanggilan periodik seperti ini dapat dilakukan dengan beberapa cara sebagai berikut:

  • delay pada Arduino atau library lain
  • interupsi timer
  • delay pada Real Time Operating System misal FreeRTOS

Pada implementasi ini yang dibuat adalah menggunakan FreeRTOS. Delay menggunakan fungsi vTaskDelay() pada FreeRTOS. Penjelasan tentang FreeRTOS di Arduino dapat dibaca di artikel https://www.arduino.cc/reference/en/libraries/freertos/

Model diagram alir (flowchart) perangkat lunak adalah sebagai berikut.

Diagram alir perangkat lunak berbasis FreeRTOS

Aplikasi memiliki 2 super loop. Super loop pertama ada di main program, tidak berisi apa-apa. Super loop kedua ada di Task FSM.

Kode lengkap dapat dilihat di repository https://github.com/waskita/embedded/blob/master/kedip/nano-fsm-freertos/nano-fsm-freertos.ino

Bagian Awal

#include "Arduino_FreeRTOS.h"

#define ON    100
#define OFF   101

#define LED_OUTPUT 3
int state = OFF;
TaskHandle_t xHandle1 = NULL;

Inisialisasi Sistem

void setup() {
  int output = 0;
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(LED_OUTPUT, OUTPUT);
  Serial.begin(115200);

  Serial.print("portTICK_PERIOD_MS: ");
  Serial.print(portTICK_PERIOD_MS);
  Serial.println();

  fsm_init(&state);
  fsm_output(output);

  xTaskCreate(
    TaskFSM
    ,  "TaskFSM"  // A name just for humans
    ,  100  // stacksize
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  &xHandle1 );
}

Implementasi Inisialisasi Finite State Machine

Implementasi ini serupa dengan di artikel “Lampu Kedip Dengan Model Finite State Machine

void fsm_init(int *state, int *out) {
  *state = OFF;
  *out = 0;
}

Implementasi Finite State Machine

Implementasi ini serupa dengan di artikel “Lampu Kedip Dengan Model Finite State Machine

void fsm(int  *state, int *out) {
  switch (*state) {
    case ON: {
        *state = OFF;
        *out = 0;
        break;
      }
    case OFF: {
        *state = ON;
        *out = 1; // nyalakan output
        break;
      }
  }
}

Implementasi Output FSM

Implementasi ini serupa dengan di artikel “Lampu Kedip Dengan Model Finite State Machine

void fsm_output(int output_value) {
  if (output_value == 1) {
    digitalWrite(LED_OUTPUT, HIGH);
  } else {
    digitalWrite(LED_OUTPUT, LOW);
  }
}

Implementasi Task / Thread

static void TaskFSM(void *pvParameters) 
{
  TickType_t xLastWakeTime;
  /* The xLastWakeTime variable needs to be initialised with the current tick
    count.  Note that this is the only time we access this variable.  From this
    point on xLastWakeTime is managed automatically by the vTaskDelayUntil()
    API function. */
  xLastWakeTime = xTaskGetTickCount();
  while (1)
  {
    int output = 0;
    fsm(&state, &output);
    if (output == 1) {
      digitalWrite(LED_OUTPUT, HIGH);
    } else {
      digitalWrite(LED_OUTPUT, LOW);
    }
    Serial.print("state: ");
    Serial.print(state);
    Serial.print(" output: ");
    Serial.print( output);
    Serial.println();
    vTaskDelayUntil( &xLastWakeTime, ( 1000 / portTICK_PERIOD_MS ) ); // perioda 1 detik
  }
}

Pengujian

Pengujian dilakukan dengan menjalankan program, kemudian mengamati kedipan lampu dan output ke port serial.

Pada output serial akan muncul tampilan seperti berikut ini:

16:23:36.204 -> state: 100 output: 1
16:23:37.280 -> state: 101 output: 0
16:23:38.302 -> state: 100 output: 1
16:23:39.324 -> state: 101 output: 0
16:23:40.390 -> state: 100 output: 1
16:23:41.415 -> state: 101 output: 0
16:23:42.427 -> state: 100 output: 1
16:23:43.466 -> state: 101 output: 0
16:23:44.534 -> state: 100 output: 1
16:23:45.557 -> state: 101 output: 0
16:23:46.581 -> state: 100 output: 1
16:23:47.652 -> state: 101 output: 0
16:23:48.674 -> state: 100 output: 1

Dari output serial tersebut nampak perubahan state dan output terjadi sesuai rancangan.

Waktu perubahan tidak tepat 1 detik, terlihat bergeser sedikit. Penyebabnya kemungkinan karena implementasi timer tick pada FreeRTOS Arduino menggunakan Watchdog Timer, bukan Timer 0, Timer 1 ataupun Timer 2. Watchdog Timer pada Arduino menggunakan osilator RC yang tidak setepat osilator kristal.

Video

Lampu Kedip di ESP32 Dengan Sistem Operasi FreeRTOS

Berikut ini contoh program sederhana untuk membuat LED onboard berkedip di pada ESP32 Lolin32 Lite. Sistem operasi yang digunakan adalah FreeRTOS. IDE menggunakan Arduino. Delay menggunakan delay dari FreeRTOS, dengan fungsi vTaskDelayUntil().

ESP32 Lolin32 Lite (atas) dan ESP32 DevkitC (bawah)

ESP32 Lolin32 Lite (atas) dan ESP32 DevkitC (bawah)

Lampu berkedip dengan frekuensi 1 Hz. Suatu angka (counter) dikirim melalui port serial setiap detik. Kecepatan port serial adalah 115200 bps

#define LED_BUILTIN 22 # Wemos Lolin32 onboard LED di pin 22

void setup() {
  Serial.begin(115200);
  Serial.println("Start");  
  pinMode(LED_BUILTIN, OUTPUT);

  if (1)
    xTaskCreate(
      TaskBlinker, /* Task function. */
      "TaskBlinker", /* String with name of task. */
      1000, /* Stack size in bytes. */
      NULL, /* Parameter passed as input of the task */
      1, /* Priority of the task. */
      NULL); /* Task handle. */
}

// the loop function runs over and over again forever

void loop() {
  delay(10000);
}

void TaskBlinker(void *parameter) {  
  int counter = 0;
  TickType_t xLastWakeTime;
  const TickType_t xPeriod = 500      ;   
  xLastWakeTime = xTaskGetTickCount();
  while (1) {
    digitalWrite(LED_BUILTIN, HIGH);
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
    digitalWrite(LED_BUILTIN, LOW);
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
    Serial.print("Counter:");
    Serial.println(counter);
    counter++;
  }
}

Real Time pada Raspberry Pi

Raspberry Pi dapat dibuat menjadi real time dengan menggunakan sistem operasi RTOS (Real Time Operating System), misalnya:

Berikut ini petunjuk instalasi RTOS pada Raspberry Pi:

Raspberry Pi umumnya menggunakan sistem operasi Raspbian , yang merupakan varian dari Debian Linux. Sistem operasi Linux ini bukan sistem operasi real time, sehingga Raspberry Pi tidak real time jika menggunakan sistem operasi Raspbian.

Fitur penting pada Raspbery PI adalah kemampuan komputasinya di prosesornya yang cepat (bisa sampai 4 core @1  GHz), memori yang besar (sampai 8 GB) dan sistem operasi Linux yang fleksibel.

Kekurangan Raspberry Pi jika menggunakan RTOS adalah contoh programnya tidak sebanyak Raspberry Pi dengan sistem operasi Raspbian. Jika kita perlu Raspberry Pi dengan sistem operasi Raspbian tapi perlu juga fitur real time, maka salah satu solusinya adalah fitur real time ditangani oleh prosesor lain, misal ATmega328 (Arduino Nano) atau ESP32. Untuk menghubungkan Raspberry Pi ke ArduinoNano / ESP32 dapat menggunakan protokol serial, seperti serial asinkron maupun I2C (Inter Integrated Circuit).

Referensi

 

 

Percobaan Penjadwal Periodik Dengan FreeRTOS pada Arduino Nano

Pada percobaan ini dilakukan penjadwalan untuk sebuah task periodik pada sistem operasi FreeRTOS. Mikroprosesor yang dipakai adalah Arduino Nano (ATmega328).

Pengukuran akan dilakukan dengan video dengan kecepatan 25 frame per detik, sehingga pemilihan waktu eksekusi dan periode tidak boleh terlalu kecil. Untuk percobaan dipilih waktu eksekusi 4 detik, dengan perioda task adalah 10 detik.

Task 4 detik dibuat menggunakan TaskDummy yang sudah dibuat di percobaan sebelumnya. Pemilihan waktu 4 detik dapat dilakukan dengan menggunakan parameter fungsi yang sesuai.

Perangkat Keras

Perangkat keras yang digunakan adalah Arduino Nano dengan 2 buah LED terhubung ke pin 2 dan pin 3.

Implementasi Program

Berikut ini source code percobaan tersebut.

// 1 task periodik dengan FreeRTOS Arduino Nano (ATmega328)
// template umum FreeRTOS di Arduino Nano  https://github.com/feilipu/Arduino_FreeRTOS_Library/blob/master/examples/AnalogRead_DigitalRead/AnalogRead_DigitalRead.ino
// contoh pemakaian vTaskDelayUntil dan xTaskGetTickCount dari https://github.com/feilipu/avrfreertos/blob/master/MegaBlink/main.c

#include "Arduino_FreeRTOS.h"
#include <semphr.h>

#define LED1  2
#define LED2  3

static void TaskBlinkLED1(void *pvParameters);

// task handle diperlukan jika ingin mengakses parameter suatu task. optional
TaskHandle_t xHandle1 = NULL;

void TaskDummy(int LED_A, int LED_B, long int counter) {
  long int i;
  for (i = 0; i < counter; i++) {
    cli();
    digitalWrite(LED_A, LOW);
    digitalWrite(LED_B, HIGH);
    sei();
    asm("nop");
    cli();
    digitalWrite(LED_A, HIGH);
    digitalWrite(LED_B, LOW);
    sei();
    asm("nop");
  }
  digitalWrite(LED_A, LOW);  // matikan semua LED
  digitalWrite(LED_B, LOW);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);

  xTaskCreate(
    TaskBlinkLED1
    ,  "TaskBlinkLED1"  // A name just for humans
    ,  100  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  &xHandle1 );
}

void loop() {
}

static void TaskBlinkLED1(void *pvParameters) // Main Red LED Flash
{
  TickType_t xLastWakeTime;
  /* The xLastWakeTime variable needs to be initialised with the current tick
    count.  Note that this is the only time we access this variable.  From this
    point on xLastWakeTime is managed automatically by the vTaskDelayUntil()
    API function. */
  xLastWakeTime = xTaskGetTickCount();
  while (1)
  {
    Serial.println(millis());
    Serial.println(xLastWakeTime); // cetak last wake time, untuk debugging. hanya untuk slow system

    TaskDummy(LED1, LED2, 10000L / 0.172 * 4 ); // 4 detik waktu eksekusi
    vTaskDelayUntil( &xLastWakeTime, ( 10000L / portTICK_PERIOD_MS ) ); // 10 detik perioda

  }
}

Pengukuran Dengan Video

Pengukuran dilakukan dengan merekam kedipan LED selama kurang lebih 30 detik. Kecepatan frame video yang dihasilkan adalah 25 frame per detik.

Berikut ini rekaman video lampu kedip yang dihasilkan.

Analisis frame per frame dilakukan dengan menggunakan aplikasi DaVinci Resolve 16.

Tampilan DaVinci Resolve 16

Tampilan DaVinci Resolve 16

Video dapat ditampilkan dengan mode “Media”,  “Cut” maupun “Timeline”. DaVinci Resolve secara default menampilkan waktu dalam format HH:MM:SS, namun tampilan ini dapat diubah menjadi tampilan nomor frame untuk memudahkan analisis.

Berikut ini hasil analisis video LED tersebut:

Transisi Frame
OFF -> ON 161
ON -> OFF 262
OFF->ON 432
ON->OFF 534
OFF->ON 704
ON->OFF 805
OFF->ON 975

Analisis durasi waktu eksekusi

  • 262-161 = 101 frame = 4,04 detik
  • 534-432=102 frame =  4,08 detik
  • 805-704 = 101 frame = 4,04 detik.

Analisis Perioda Task

  • 432-161= 271 frame = 10.85 detik
  • 534-262= 272 frame = 10.88 detik
  • 704-432= 272 frame= 10.88 detik
  • 805-534= 271 frame = 10.85 detik
  • 975-704= 271 frame= 10.85 detik

Durasi atau waktu eksekusi adalah 4,04 detik ~ 4,08 detik

Periode Task yang terukur adalah antara 10.85 detik sampai 10.88 detik.

Pengukuran Dengan Osiloskop

Sebagai perbandingan juga dilakukan pengukuran tegangan pada LED dengan osiloskop. Berikut ini rekaman video pengukuran dengan osiloskop

Berikut ini pengukuran perioda task dengan menggunakan fitur cursor  pada osiloskop.

Pengukuran perioda task pada FreeRTOS

Pengukuran perioda task

Dari hasil pengukuran perioda didapatkan angka 10,80 detik. Hasil ini cukup  sesuai dengan analisis frame video.

Berikut ini pengukuran durasi task.

Pengukuran durasi task pada FreeRTOS

Pengukuran durasi task

Didapatkan hasil angka durasi task adalah 4,1 detik, cukup mendekati angka 4,08 detik dari hasil analisis frame.

Analisis

Dari hasil perhitungan di atas, dapat didapatkan bahwa

  • durasi eksekusi dari TaskDummy sudah cukup mendekati hasil yang diinginkan
  • durasi perioda task berbeda cukup jauh , sekitar 8%

Dari hasil studi literatur didapatkan bahwa Timer Tick pada library FreeRTOS di Arduino Nano yang dipakai menggunakan osilator pada WDT (Watch Dog Timer). Osilator WDT ini menurut literatur datasheet tidak menggunakan kristal, dan periodanya tergantung dengan temperatur ruangan. Jadi perbedaan periode dari seharusnya 10 detik menjadi 10.8 detik dapat dijelaskan.

Referensi

Task Dummy Untuk FreeRTOS

Pada percobaan FreeRTOS dengan penjadwal periodik, diperlukan suatu task (pekerjaan) dengan waktu eksekusi yang diketahui.

Berikut ini sifat-sifat yang diperlukan dari task tersebut:

  • waktu eksekusi diketahui
  • waktu eksekusi dapat diubah-ubah dengan mengubah parameternya
  • status task dapat dimonitor dari luar mikroprosesor
  • status yang perlu diketahui: RUNNING, READY, BLOCKING, STOP.

Solusi

  • Task berupa iterasi yang jumlah iterasi dapat diubah-ubah dengan parameter.
  • Pengaruh parameter terhadap waktu eksekusi diukur. Pengukuran terbaik dengan menggunakan alat ukur eksternal seperti osiloskop. Jika tidak ada osiloskop, alternatifnya menggunakan fungsi millis() pada Arduino.
  • Task Dummy melakukan aktivitas membuat 2 buah LED berkedip secara komplementer. Jika kedua lampu nampak menyala, artinya task dalam keadaan RUNNING. Jika salah satu saja yang menyala, artinya task sedang berhenti, artinya dalam keadaan READY atau BLOCKING. Jika kedua lampu mati, artinya task sedang tidak aktif.

Berikut ini kode fungsi Task Dummy pada Arduino.

 

void TaskDummy(int LED_A, int LED_B, long int counter) {
  long int i;
  for (i = 0; i < counter; i++) {
    cli();
    digitalWrite(LED_A, LOW);
    digitalWrite(LED_B, HIGH);
    sei();
    asm("nop");
    cli();
    digitalWrite(LED_A, HIGH);
    digitalWrite(LED_B, LOW);
    sei();
    asm("nop");
  }
  digitalWrite(LED_A, LOW);  // matikan semua LED
  digitalWrite(LED_B, LOW);
}

DigitalWrite menyalakan dan mematikan LED A dan LED B. LED yang dipakai sebagai output dapat diatur melalui parameter fungsi. cli() fungsinya untuk disable interrupt, agar perubahan LED_A dan LED_B terjadi secara serentak. sei() fungsinya untuk mengaktifkan kembali interupsi. Instruksi assembly “nop” dipakai untuk menambah waktu iterasi.

Berikut ini program lengkapnya

// Contoh TaskDummy
// dengan output ke osiloskop juga
#define LED1 2
#define LED2 3
#define LED3 4
#define LED4 5

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
}

void TaskDummy(int LED_A, int LED_B, long int counter) {
  long int i;
  for (i = 0; i < counter; i++) {
    cli();
    digitalWrite(LED_A, LOW);
    digitalWrite(LED_B, HIGH);
    sei();
    asm("nop");
    cli();
    digitalWrite(LED_A, HIGH);
    digitalWrite(LED_B, LOW);
    sei();
    asm("nop");
  }
  digitalWrite(LED_A, LOW);  // matikan semua LED
  digitalWrite(LED_B, LOW);
}

// the loop function runs over and over again forever
void loop() {
  unsigned long waktu_awal;
  unsigned long waktu_akhir;
  waktu_awal = millis();
  TaskDummy(LED1, LED2, 10000L);
  waktu_akhir = millis();
  Serial.print("waktu: ");
  Serial.println(waktu_akhir - waktu_awal);
  digitalWrite(LED_BUILTIN, HIGH);
  TaskDummy(LED1, LED2, 10000L);
  digitalWrite(LED_BUILTIN, LOW);
}

Durasi TaskDummy dalam milisekon dapat diamati di port serial. Berikut ini tampilan port serial.

Dari tampilan tersebut dapat diketahui bahwa waktu eksekusi task dummy adalah 173 ms.

Berikut ini foto pengukuran dengan osiloskop. Dari gambar nampak waktu yang diperlukan untuk task dummy adalah 172 ms

Berikut ini foto percobaan.

Osiloskop yang dipakai

Referensi

Lampu Kedip pada Arduino

Membuat LED berkedip adalah salah satu cara sederhana untuk menunjukkan kemampuan pewaktuan pada mikroprosesor.

Berikut ini beberapa teknik yang dapat dilakukan:

  • interupsi timer
  • delay arduino standar
  • delay dari FreeRTOS

Delay Standar Arduino

Delay pada Arduino dijelaskan di https://www.arduino.cc/reference/en/language/functions/time/delay/

Pada software Arduino standar seperti Arduino Nano dan UNO, delay ini diimplementasikan dengan loop software.

Contoh software yang menggunakan delay ini adalah contoh software Blink pada Arduino (https://www.arduino.cc/en/tutorial/blink)

Diagram alir program Blink ini adalah sebagai berikut

Diagram alir Blink()

Delay pada FreeRTOS

FreeRTOS memungkinkan software Arduino memiliki beberapa loop pada waktu yang bersamaan.

Porting FreeRTOS untuk Arduino UNO dan Nano dapat dilihat di https://github.com/feilipu/Arduino_FreeRTOS_Library

Library FreeRTOS ini dapat diinstall di Arduino IDE dari menu Tools -> Manage Libraries. Kemudian search dengan kata kunci FreeRTOS.

Proses instalasi library FreeRTOS

Proses instalasi library FreeRTOS

Sebagai contoh, berikut ini diagram alir (flowchart) sebuah program yang membuat LED berkedip dengan 3 buah loop. Masing-masing LED memiliki frekuensi yang berbeda.

Lampu kedip dengan FreeRTOS

Lampu kedip dengan FreeRTOS

Source code dapat dilihat di https://github.com/waskita/embedded/tree/master/atmega-blink-freertos

Fungsi FreeRTOS yang dipakai adalah

Arduino dengan LED berkedip

Arduino dengan LED berkedip

Berikut ini demo perangkat keras Arduino Nano tersebut

Interupsi Timer

under construction

ESP32 Lolin32 Lite

ESP32 Lolin32 Lite buatan WEMOS

Fitur utama dari Lolin32 Lite adalah sebagai berikut

  • WiFi
  • bluetooth
  • 4MB Flash
  • Lithium battery interface, 500mA Max charging current
Lolin32 Lite
Penampilan fisik Lolin32 Lite
Lolin32 Lite
Pin-pin pada Lolin32 Lite
Array of Lolin32 Lite

Komponen utama pada Lolin32 Lite adalah sebagai berikut:

  • ESP32-D0WDQ6  (prosesor Espressif ESP32)(https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
    “ESP32-D0WDQ6, Dual core, No embedded flash, Wi-Fi b/g/n + BT/BLE Dual Mode, QFN 6*6”
  • W25Q32FVSS (3V 32M-bit Serial Flash Memory With Dual/Quad SPI & QPI) https://www.winbond.com/resource-files/w25q32fv%20revi%2010202015.pdf
  • UMH3N (General purpose dual digital transistor) http://rohmfs.rohm.com/en/products/databook/datasheet/discrete/transistor/digital/emh3t2r-e.pdf
    https://www.mouser.com/ds/2/348/umh3ntn-e-1018108.pdf
  • CH340C (USB to serial chip) https://www.mpja.com/download/35227cpdata.pdf
  • ME6211 (High speed LDO regulators) https://datasheet.lcsc.com/szlcsc/Nanjing-Micro-One-Elec-ME6211C33M5G-N_C82942.pdf
  • TP4054 (TP4054 Standalone Linear Li-lon Battery Charger with Thermal Regulation in SOT)
    https://www.piekarz.pl/pl/pdf.php?id=30089 (English)
    https://datasheet.lcsc.com/szlcsc/Nanjing-Extension-Microelectronics-TP4054_C32574.pdf (Chinese)
  • LED onboard di pin 22 (GPIO22), active low, melalui resistor 2k

Untuk menjalankan FreeRTOS pada ESP32, ada 2 alternatif:

Resource

FreeRTOS Untuk Arduino AVR, ESP32 dan STM32F103 Blue Pill

Sistem operasi FreeRTOS dapat diaplikasikan pada berbagai mikrokontroler. Pada tulisan ini diulas SDK (IDE + compiler) yang dapat dipakai untuk menjalankan FreeRTOS pada Arduino (UNO+Nano), ESP32 dan STM32F103 (Blue Pill)

Arduino

Arduino Nano
Arduino Nano

Espressif ESP32

ESP32 Lolin Wemos
ESP32 Lolin Wemos

STM32F103C8T6 (Blue Pill)

STM32F103C8T Blue Pill
STM32F103C8T Blue Pill

Mikroprosesor untuk FreeRTOS

FreeRTOS adalah suatu sistem operasi untuk membuat sistem real time berbasis mikroprosesor. Sistem operasi ini cocok untuk sistem-sistem yang kecil dan sederhana. Untuk sistem yang lebih kompleks, diperlukan sistem operasi real-time yang lebih besar seperti eCOS, embedded Linux (or Real Time Linux) ataupun uCLinux.

Berikut ini beberapa mikroprosesor yang cocok untuk menjalankan sistem operasi FreeRTOS.

Prosesor di gambar di atas adalah sebagai berikut:

  • NXP LPCXpresso LPC1769
  • Espressif ESP8266
  • Esperssif ESP32
  • Arduino Nano (clone)
  • ST Micro STM32F103C8T dan programmernya ST-LINK-V2

Barang-barang yang ditampilkan di sini adalah prosesor yang ada di laboratorium dan sempat dicoba. Masih banyak lagi prosesor yang dapat menjalankan FreeRTOS yang belum dicoba.

Arduino Nano dapat menjalankan FreeRTOS mengingat porting FreeRTOS untuk Atmel AVR tersedia di situs FreeRTOS. Namun kemampuannya terbatas, mengingat memori di ATMega328 sangat terbatas.

Arduino Nano
Arduino Nano

Selanjutnya adalah board LPCXPresso dengan prosesor NXP LPC1769. Kemampuan prosesor ini cukup tinggi.

LPCXpresso dengan prosesor NXP LPC1769

STM32F103 kemampuannya menengah saja, tidak terlalu tinggi, namun kelebihan utama dari prosesor ini adalah tersedia dengan harga murah dari berbagai vendor. Artikel tentang modul ini banyak di Internet sehingga lumayan memudahkan bagi pemula.

Modul STM32F103C8T “Blue Pill”

STM32F103 dapat diisi proram dengan berbagai cara, namun yang paling mudah adalah menggunakan modul ST-LINK-V2 berikut ini.

ST-LINK-V2 untuk upload program ke STM32

Daya tarik utama dari ST-LINK-V2 adalah harganya yang murah, karena banyak versi clone / KW-nya.

Berikutnya adalah prosesor ESP8266 dan ESP32 dari Espressif. Porting FreeRTOS untuk prosesor ini banyak tersedia.

ESP8266
ESP8266
Modul ESP32 LOLIN32

Berikut ini tabel perbandingan kekuatan dari prosesor yang dipakai, dilihat dari clock, flash memory dan static RAM.

ModelClockFlash MemoryStatic RAM
ATMega32816 MHz32 kB2 kB
STM32F103C8T72 MHz64 kB20 kB
LPC1769100 MHz512 kB64 kB
ESP32240 MHzexternal (typical 4 MB)520 kB
ESP8266160 MHzexternal80 kB

Perbandingan clock kurang lebih mewakili kecepatan, walaupun sebenarnya perbandingan kecepatan tidak dapat hanya dibandingkan dari clock saja, namun juga mesti melihat arsitektur masing-masing mikroprosesor.

Referensi ports dan demo untuk FreeRTOS adalah sebagai berikut:

Diagram Alir Perangkat Lunak pada Mikroprosesor

Diagram alir (flow chart) adalah salah satu teknik untuk memodelkan perangkat lunak. Pada tulisan ini diuraikan secara ringkas diagram alir pada perangkat lunak desktop, mikroprosesor dengan superloop, mikroprosesor dengan interupsi dan mikroprosesor dengan multitasking.

Diagram alir adalah sebuah diagram dengan simbol-simbol grafis yang menyatakan aliran algoritma atau proses yang menampilkan langkah-langkah yang disimbolkan dalam bentuk kotak, beserta urutannya dengan menghubungkan masing masing langkah tersebut menggunakan tanda panah. Diagram ini bisa memberi solusi selangkah demi selangkah untuk penyelesaian masalah yang ada di dalam proses atau algoritma tersebut

Secara umum diagram alir dipakai untuk melakukan analisis, perancangan, dokumentasi, ataupun manajemen suatu proses atau program dalam berbagai bidang ilmu.

Dalam tulisan ini disajikan penggunaan diagram alir untuk melihat perbedaan antara 3 macam perangkat lunak:

  • Perangkat lunak desktop
  • Perangkat lunak sistem mikroprosesor tanpa sistem operasi
  • Perangkat lunak sistem mikroprosesor dengan sistem operasi

Diagram Alir Perangkat Lunak Desktop

Perangkat lunak desktop yang dibahas di sini maksudnya adalah perangkat lunak yang dijalankan pada suatu sistem operasi (misal Windows / Linux). Perangkat lunak seperti ini dijalankan pada suatu saat dan kemudian selesai pada beberapa waktu kemudian. Jadi pada perangkat lunak ini ada bagian START sebagai permulaan dan ada bagian END yang menyatakan akhir pelaksanaan perangkat lunak tersebut.

Diagram alir perangkat lunak desktop

Diagram alir perangkat lunak desktop

Pada contoh di atas, program melaksanakan 3 buah pekerjaan yaitu Inisialisasi, Proses 1 dan Proses 2, kemudian berhenti. Pekerjaan dapat bermacam-macam, namun intinya adalah ada START di awal dan END di akhirnya.

Contoh perangkat lunak seperti ini misalnya adalah web browser yang anda pakai sekarang (Firefox,Chrome, Internet Explorer, Safari, dsb). Contoh lainnya adalah perangkat lunak command line di Windows maupun Linux.

Diagram Alir Perangkat Lunak Berbasis Super Loop Tanpa Interupsi

Model berikutnya adalah model perangkat lunak yang umum dipakai pada sistem mikroprosesor/mikrokontroler. Pada sistem mikroprosesor perangkat lunak diharapkan untuk berjalan selamanya sampai perangkat tersebut dimatikan atau direset. Ciri diagram alir pada sistem ini adalah ada bagian START namun tidak END, dan ada suatu loop yang dijalankan selamanya. Karena ada loop yang dijalankan selamanya ini, maka arsitektur seperti ini sering disebut sebagai superloop.

Bagian utama software ada 2 yaitu bagian inisialisasi dan proses/pekerjaan. Bagian inisialisasi hanya dilakukan satu kali saja di awal, umumnya untuk melakukan konfigurasi pada sistem mikroprosesor yang digunakan. Contohnya adalah mengaktifkan port-port tertentu sebagai input maupun output, mengatur port serial, mengatur timer/pewaktu, dan lain-lain perangkat di dalam mikroprosesor/mikrokontroler tersebut.

Diagram alir superloop tanpa interupsi

Diagram alir superloop tanpa interupsi

Teknik pembuatan superloop dalam bahasa C umumnya menggunakan loop while(1) {} ataupun for(;;){}.

Diagram Alir Perangkat Lunak Berbasis Super Loop Dengan Interupsi

Model ini adalah perkembangan dari model sebelumnya. Perbedaannya adalah pada perangkat lunak ini ada fungsi / subroutine yang bertugas menangani adanya interupsi. Software untuk menangani interupsi ini sering disebut juga sebagai Interrupt Service Routine (ISR).

ISR ini berjalan seolah-olah tidak tergantung pada diagram alir utama, sehingga untuk memodelkan perangkat lunak ISR kita mesti membuat sebuah diagram alir terpisah. ISR dimulai dari adanya sebuah IRQ (Interrupt Request) yaitu sinyal dari hardware yang menandakan adanya suatu interupsi yang mesti dilayani. Setelah IRQ tersebut, maka ISR melaksanakan proses yang diperlukan untuk melayani IRQ tersebut sampai selesai. Setelah selesai maka ISR akan menjalankan RETI (Return from Interrupt) untuk mengakhiri ISR.

Diagram alir superloop dengan interupsi

Diagram alir superloop dengan interupsi

Suatu perangkat lunak dapat memiliki beberapa ISR, sehingga untuk masing-masing ISR ini mesti dibuatkan flowchart sendiri. Pada contoh berikut ini ada 2 buah interupsi, yaitu IRQ 1 yang menjalankan Proses 3, dan IRQ 2 yang menjalankan Proses 4.

Diagram alir superloop dengan 2 interupsi

Diagram alir superloop dengan 2 interupsi

Diagram Alir Perangkat Lunak Dengan Multithread

Berikutnya yang paling kompleks adalah diagram alir perangkat lunak dengan sistem operasi multithread. Pada perangkat lunak ini terdapat superloop dan interupsi seperti sebelumnya, namun ada lagi 1 fitur software yang tidak ada di software sebelumnya, yaitu multithreading. Pada multithreading, sistem mikroprosesor dapat menjalankan beberapa thread software sekaligus walaupun hanya memiliki 1 CPU saja. Tekniknya adalah dengan membagi waktu CPU antara beberapa thread yang aktif, sehingga meskipun hanya ada 1 CPU namun seolah-olah komputer ini memiliki beberapa CPU yang masing-masing menjalankan program tersendiri.

Perbedaan utamanya adalah pada multithread kita dapat membuat beberapa superloop, 1 di main loop, sedangkan loop lain dapat diaktifkan sebagai thread.

Diagram alir perangkat lunak dengan sistem operasi

Diagram alir perangkat lunak dengan sistem operasi

Contoh sistem operasi yang dapat dipakai pada sistem semacam ini adalah FreeRTOS (http://www.freertos.org/) dan CoOS (https://github.com/coocox/CoOS)

Daftar Istilah

  • ISR (Interrupt Service Routine)
  • IRQ (Interrupt Request)

Referensi

Produk FreeRTOS untuk NXP LPC17xx dan LPC18xx

Berikut ini adalah beberapa produk dari FreeRTOS yang free jika dipakai untuk LPC17xx dan LPC18xx:

  • FreeRTOS + FAT SL
  • FreeRTOS + CLI
  • FreeRTOS+IO

FreeRTOS_Trace_With_Zoom

FreeRTOS + Trace

Produk dari FreeRTOS yang berbayar untuk LPC17xx:

 

  • FreeRTOS+UDP
  • TCP/IP libraries
  • FreeRTOS+Trace

Referensi: