---
# System prepended metadata

title: TP Modul 3

---

---
title: TP Modul 3
---
# TP Modul 3

Pembuat : WN

Nama  : Muhammad Avicenna Raffaiz Adiharsa
NPM   : 2206062844
https://hackmd.io/@96kami/S15GVcFixe

**JAWABAN TANPA REFERENSI YANG SESUAI DIANGGAP MENDAPATKAN 0 POIN (UNLESS SPECIFIED OTHERWISE)**

### 1. **Jelaskan** mengenai Static Memory, Stack, dan Heap dengan menjelaskan kapan setiapnya digunakan. Serta jelaskan masalah yang berpotensi muncul dari sisi manajemen memory di setiap jenis tipe alokasi memory tersebut (20 poin).
---
**Static memory (data/bss / global)**
*   Area memori untuk variabel global dan statis yang dialokasikan saat kompilasi/link time. Contoh: `static int count;` atau `int g_var;`.
    
*   Digunakan ketika data harus bertahan sepanjang hidup program (konfigurasi, buffer global yang dipakai banyak task).
    
*   Jika penggunaan terlalu banyak static, mengurangi RAM yang tersedia untuk stack/heap. Ini menjadikan fleksibilitasnya terbatas dan suka race condition apabila banyak task mengakses global tanpa proteksi (mutex).
    
**Stack (automatic / local variables)**
*   Memori untuk frame fungsi-parameter, return address, dan variabel lokal. Di RTOS, setiap task biasanya punya stack sendiri.
    
*   Digunakan untuk variabel lokal fungsi, parameter fungsi, return address. Sangat cepat karena alokasi/dealokasi LIFO.
    
*   Ada problem _stack overflow_, jika ukuran stack per task terlalu kecil (spt recursive deep call, penggunaan buffer lokal besar), dapat korupsi memori lain dan crash. Perlu estimasi ukuran stack tiap task dan alat monitoring (stack watermark).
    
**Heap (dynamic allocation)**
*   Area untuk alokasi dinamis saat runtime (`malloc`, `pvPortMalloc`). Di FreeRTOS, pilih satu dari beberapa implementasi heap (heap_1..heap_5).
    
*   Digunakan untuk objek berdurasi variabel, buffer runtime, alokasi ketika input ukuran tidak diketahui saat kompilasi.
    
*   Ada potensi fragmentasi (mengurangi blok besar yang tersedia), kebocoran memori (tidak pernah `free`), race condition jika allocator tidak thread-safe (FreeRTOS menyediakan allocator yang cocok). Pilihan implementasi heap memengaruhi kemampuan free, penggabungan blok bebas, dan determinisme.
    
(Singkatnya: static = stabil tapi rigid, stack = cepat tapi terbatas, heap = fleksibel tapi rawan fragmentasi/leak.)

#### Referensi:
[1] Stack vs Heap Memory Allocation [Online]. Available: https://www.geeksforgeeks.org/dsa/stack-vs-heap-memory-allocation. [Diakses: 18-September-2025]

[2] Mastering stack and heap for system reliability: Part 1 – Calculating stack size [Online]. Available: https://www.embedded.com/mastering-stack-and-heap-for-system-reliability-part-1-calculating-stack-size. [Diakses: 18-September-2025]

### 2. **Jelaskan** secara singkat poin-poin manajemen heap pada FreeRTOS (heap_1 hingga heap_5). Menurut anda, faktor apa yang diperhatikan dalam pemilihan jenis manajemen? (10 poin)
---
**Ringkasan singkat tiap implementasi**
*   **heap_1**: sangat sederhana — hanya alokasi, _tidak bisa free_. Aman deterministik, kecil, cocok ketika aplikasi mengalokasi sekali saja di startup.
*   **heap_2**: alokasi + free tetapi **tidak** menggabungkan (coalesce) blok bebas, potensi fragmentasi.
*   **heap_3**: membungkus `malloc`/`free` dari runtime C library (mengandalkan libc). Berguna kalau ingin konsistensi dengan library C, tapi footprint kernel bisa lebih besar dan determinisme bergantung pada libc.
*   **heap_4**: alokasi + free + _coalescing_ (menggabungkan blok bebas) — mengurangi fragmentasi. Sering direkomendasikan sebagai pilihan umum.
*   **heap_5**: seperti heap_4 tapi mendukung beberapa blok memori non-bersebelahan (multiple non-contiguous memory regions). Berguna untuk arsitektur dengan RAM tersegmentasi.
    
**Faktor yang harus dipertimbangkan saat memilih**
*   **Apakah aplikasi butuh `free()`?** (jika tidak, heap_1 bisa sangat sederhana dan aman).
*   Risiko fragmentasi jangka panjang (jika tinggi, pilih heap_4 atau heap_5).
*   Apakah perlu menggunakan allocator C standard (heap_3) karena library pihak ketiga?
*   Determinisme dan footprint (heap_1 kecil & deterministik; heap_4 lebih kompleks).
*   Topologi RAM (apakah memori fisik non-contiguous → heap_5)

#### Referensi:
[3] FreeRTOS heap memory management [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/09-Memory-management/01-Memory-management. [Diakses: 18-September-2025]

[4] 3 Heap Memory Management [Online]. Available: https://freertos.gitbook.io/mastering-the-freertos-tm-real-time-kernel/mastering.ch03. [Diakses: 18-September-2025]

[5] Manage application memory [Online]. Available: https://docs.aws.amazon.com/freertos/latest/userguide/application-memory-management.html. [Diakses: 18-September-2025]


### 3. **Jelaskan** mengenai Queue pada FreeRTOS. Masalah apa yang dapat diselesaikan dengan penggunaan queue dalam transfer data antar task? (20 poin)
---

Queue adalah struktur FIFO yang disediakan kernel untuk komunikasi antar-task (dan antara ISR ke task melalui API yang tepat). Data yang dikirim ke queue _disalin_ ke area queue (kecuali secara eksplisit mengirim pointer sehingga yang dicopy adalah isi pointer). Queue juga menyediakan mekanisme block/wait sehingga pengirim/pendengar tidak perlu busy-wait.
    
**Masalah yang dapat diselesaikan dengan queue**
1.  **Sinkronisasi data antar-task**: satu task produsen dapat mengirim data ke queue, consumer akan ter-block sampai data tersedia, ini menghilangkan polling dan menghemat CPU.
2.  **Keamanan akses data**: queue melakukan copy atomik item sehingga mengurangi kebutuhan mutex saat transfer potongan data yang ringkas.
3.  **Buffering**: jika producer menghasilkan data lebih cepat daripada consumer memproses, queue menahan data sampai consumer siap (hingga kapasitas queue).
4.  **Komunikasi ISR ke task**: ISR dapat memberi sinyal/dikirim pointer/data ke queue menggunakan API khusus dari ISR (spt `xQueueSendFromISR`) yang aman.
5.  **Menghindari race condition**: karena queue menyediakan atomic enqueue/dequeue, beberapa pengirim/penerima bisa aman digunakan tanpa proteksi tambahan.

#### Referensi:
[6] xQueueSend [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/04-API-references/06-Queues/03-xQueueSend. [Diakses: 18-September-2025]

[7] Introduction to RTOS - Solution to Part 5 (FreeRTOS Queue Example) [Online]. Available: https://www.digikey.com/en/maker/projects/introduction-to-rtos-solution-to-part-5-freertos-queue-example/72d2b361f7b94e0691d947c7c29a03c9. [Diakses: 18-September-2025]

[8] FreeRTOS Queue [Online]. Available: https://www.renesas.com/en/products/gadget-renesas/reference/gr-rose/rtos-queue. [Diakses: 18-September-2025]

[9] xQueueReceive [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/04-API-references/06-Queues/09-xQueueReceive. [Diakses: 18-September-2025]

### 4. Carilah use case lain dari Queue, lalu **jelaskan** manfaat yang diperoleh dari penggunaan queue pada kasus tersebut! (10 poin)
---
**Use case: Logging subsystem tersentralisasi**
*   Banyak embedded system membuat _logging task_ yang menulis pesan log ke flash/SD atau mengirim ke server. Task lain (sensor, comms) mengirim pesan log ke _log queue_. Log task membaca queue dan menulis ke media.
    
*   **Manfaat**: menghindari blocking panjang di task sensor (sensor hanya enqueue lalu lanjut), terjamin urutan log (FIFO), dan memusatkan akses I/O (mengurangi contention). Queue juga memungkinkan throttling: jika storage lambat dan queue penuh, bisa drop atau backpressure. 
    
**Use case lain**
*   **Pipeline data**: sensor - preprocess - classifier. Tiap tahap sebagai task, queue antar tahap menyederhanakan desain pipeline dan membuatnya modular.
    
*   **Command dispatcher**: berbagai sumber (UART, network, button ISR) mengirim perintah ke satu task dispatcher via queue, dispatcher mengeksekusi perintah terurut.
    
Manfaat umum: _decoupling_, _buffering_, _synchronization_, dan _prediktabilitas_.

#### Referensi:
[10] Logging Functionality [Online]. Available: https://www.freertos.org/Documentation/03-Libraries/06-Logging. [Diakses: 18-September-2025]

[11] FreeRTOS queues [Online]. Available: https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/02-Queues-mutexes-and-semaphores/01-Queues. [Diakses: 18-September-2025]

[12] ESP32 with FreeRTOS Queues: Inter-Task Communication (Arduino IDE) [Online]. Available: https://randomnerdtutorials.com/esp32-freertos-queues-inter-task-arduino. [Diakses: 18-September-2025]


### 5. Buatlah program yang terdiri dari 2 buah task untuk melakukan transfer data. Data yang dikirimkan adalah struct dengan 2 buah atribut, yaitu [string] pesan dan [boolean] mengandung_angka.

   Task pertama akan membaca input serial dan menyimpannya dalam atribut pesan dari struct. Task tersebut juga akan menentukan apakah string tersebut mengandung angka dan memasukkan nilai true bila string mengandung angka dan false bila string tidak mengandung angka pada atribut mengandung_angka dari struct.

   Pengiriman data dilakukan menggunakan queue dengan ukuran queue didasarkan dari angka terakhir NPM anda (bila angka terakhir adalah 0 atau 1, maka ukuran queue adalah 10). **Gunakan pass by reference dalam mengirimkan data melalui queue!**

   **BERIKAN ANALISIS KODE BERUPA PENJELASAN PENGGUNAAN FUNCTION DARI API QUEUE FREERTOS (UNTUK MEMBUAT QUEUE SERTA MENGIRIMKAN DAN MENERIMA DATA DARI QUEUE)** (40 poin)

```cpp=
#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"

#define QUEUE_LENGTH 4
#define MAX_MSG_LEN 128

typedef struct {
  char pesan[MAX_MSG_LEN];
  bool contains_number;
} Message_t;

QueueHandle_t xMsgQueue = NULL;

void producerTask(void *pvParameters) {
  (void) pvParameters;
  Serial.println("Producer ready. Type message w' serial (enter).");
  for (;;) {
    if (Serial.available()) {
      String line = Serial.readStringUntil('\n'); 
      line.trim();
      if (line.length() == 0) continue;

      Message_t *pMsg = (Message_t*) pvPortMalloc(sizeof(Message_t));
      if (pMsg == NULL) {
        Serial.println("pvPortMalloc failed!");
        vTaskDelay(pdMS_TO_TICKS(500));
        continue;
      }

      size_t copyLen = min((size_t)line.length(), (size_t)(MAX_MSG_LEN - 1));
      line.toCharArray(pMsg->pesan, copyLen + 1);
      pMsg->pesan[copyLen] = '\0';

      bool hasDigit = false;
      for (size_t i = 0; i < copyLen; ++i) {
        if (isDigit((unsigned char)pMsg->pesan[i])) {
          hasDigit = true;
          break;
        }
      }
      pMsg->contains_number = hasDigit;

      if (xQueueSend(xMsgQueue, &pMsg, portMAX_DELAY) != pdPASS) {
        Serial.println("xQueueSend failed - queue full?");
        vPortFree(pMsg); 
      } else {
        Serial.println("Pesan dikirim ke queue.");
      }
    }
    vTaskDelay(pdMS_TO_TICKS(20));
  }
}

void consumerTask(void *pvParameters) {
  (void) pvParameters;
  for (;;) {
    Message_t *received = NULL;
    if (xQueueReceive(xMsgQueue, &received, portMAX_DELAY) == pdPASS) {
      Serial.println("=== Consumer received message ===");
      Serial.print("Message: ");
      Serial.println(received->pesan);
      Serial.print("Contains number: ");
      Serial.println(received->contains_number ? "YES" : "NO");
      Serial.println("===============================");

      vPortFree(received);
      received = NULL;
    }
  }
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  xMsgQueue = xQueueCreate(QUEUE_LENGTH, sizeof(Message_t*));
  if (xMsgQueue == NULL) {
    Serial.println("Gagal membuat queue!");
    while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); }
  } else {
    Serial.printf("Queue generated: length=%d, item_size=%zu\n", QUEUE_LENGTH, sizeof(Message_t*));
  }

  xTaskCreatePinnedToCore(producerTask, "Producer", 4096, NULL, 1, NULL, 1);
  xTaskCreatePinnedToCore(consumerTask, "Consumer", 4096, NULL, 1, NULL, 1);
}

void loop() {
  vTaskDelay(pdMS_TO_TICKS(1000));
}

```

![image](https://hackmd.io/_uploads/BJcQisFolx.png)

Pada program ini, queue dibuat dengan `xQueueCreate`, di mana panjang queue ditentukan dari digit terakhir NPM (4), dan setiap slot menyimpan sebuah pointer ke struct Message_t. Dengan cara ini, kita benar-benar melakukan pass by reference karena hanya alamat struct yang dikirimkan, bukan salinan utuhnya. Task producer membaca input serial, mengalokasikan memori dengan pvPortMalloc, mengisi data pesan serta flag mengandung_angka, lalu mengirimkan alamat struct ke queue menggunakan xQueueSend, yang menyalin pointer ke buffer queue. Task consumer kemudian mengambil pointer tersebut dengan xQueueReceive, memproses isi struct, lalu membebaskan memori menggunakan vPortFree. Dengan mekanisme ini, queue berfungsi sebagai perantara aman antar task: data terjaga urutannya (FIFO), pengiriman dan penerimaan berlangsung atomik, serta tidak terjadi race condition meskipun task berjalan secara paralel.

6. Jelaskan apa passion anda, dan hal apa yang membuat anda terus kembali pada passion tersebut (0 Poin)