# RAM (Random Access Memory)

## 🧠 **1\. Tổng quan về RAM trong Embedded Systems**

### ✅ RAM là gì và dùng để làm gì?

* **RAM (Random Access Memory)** là bộ nhớ dễ bay hơi (volatile), **dùng trong thời gian chương trình đang chạy** để:
    
    * Lưu trữ biến tạm thời (`local`, `global`, `static`)
        
    * Duy trì stack (cho function calls)
        
    * Quản lý heap (malloc/free)
        
    * Làm buffer, cache, vùng trao đổi dữ liệu.
        

### ✅ So sánh **RAM** và **Flash**

| Đặc điểm | RAM (SRAM) | Flash (ROM) |
| --- | --- | --- |
| **Tốc độ** | Rất nhanh (nanosecond level) | Chậm hơn (microsecond level) |
| **Dữ liệu** | Mất khi mất điện (volatile) | Lưu trữ lâu dài (non-volatile) |
| **Sử dụng** | Dùng trong runtime | Lưu trữ firmware/code/constants |
| **Viết/Đọc** | Nhanh, không giới hạn | Giới hạn số lần ghi |
| **Chi phí/Số lượng** | Đắt, giới hạn vài KB – MB | Rẻ hơn, thường có nhiều hơn |

> ⚠️ **STM32** có thể chỉ có từ **16KB đến 512KB RAM**, vì RAM tốn silicon và tiêu thụ điện nhiều hơn.

---

## 🧩 **2\. Phân tích từng vùng nhớ trong RAM**

Dưới đây là cấu trúc điển hình khi sử dụng RAM:

```c
sqlSao chépChỉnh sửa+----------------------+ ← Low Address (start of RAM)
| .data / .bss         |  → Static & global variables
|----------------------|
| Heap                 |  → malloc/free allocation
|   ↑ grows upward     |
|----------------------|
|                      |
|      Unused RAM      |
|                      |
|----------------------|
| Stack                |  → Function calls, local vars
|   ↓ grows downward   |
+----------------------+ ← High Address (end of RAM)
```

---

## 📌 **3\. Chi tiết từng vùng nhớ**

### 🟩 **STACK**

#### ✅ Hoạt động:

* Cơ chế **LIFO (Last-In First-Out)**.
    
* Tự động quản lý bởi **CPU và compiler** (developer chỉ cần viết code bình thường).
    
* Mỗi lần gọi hàm → stack frame được tạo.
    

#### ✅ Lưu gì?

* **Local variables** trong hàm
    
* Địa chỉ return
    
* Context của hàm (thanh ghi...)
    

#### ⚠️ Nguy cơ **Stack Overflow**:

* Khi stack chạm vùng heap hoặc giới hạn RAM → ghi đè dữ liệu.
    
* Nguy hiểm trong hệ thống nhúng vì dễ **crash** hoặc **hành vi không xác định**.
    

#### ✅ Cách phòng tránh:

* Hạn chế **đệ quy**.
    
* Tránh **biến cục bộ lớn**.
    
* Dùng **static** thay vì local nếu cần giữ giá trị.
    
* Trên **RTOS** (FreeRTOS): mỗi task có stack riêng → phân tích kỹ **task stack size**.
    

---

### 🟨 **HEAP**

#### ✅ Hoạt động:

* Dùng cho cấp phát động (`malloc`, `calloc`, `free`).
    
* Không có cơ chế tự động quản lý (developer phải chủ động `free()`).
    

#### ✅ Rủi ro:

* **Memory Fragmentation**: nhiều mảng nhỏ rải rác không liền kề.
    
* **Memory Leak**: không giải phóng heap → cạn kiệt RAM.
    

#### ⚠️ Một số hệ thống **cấm dùng heap**:

* Vì khó quản lý trong real-time systems.
    
* Gây chậm trễ, không xác định thời gian cấp phát.
    

---

### 🟦 **STATIC / DATA SECTION (.data, .bss)**

| Loại biến | Section | Đặc điểm |
| --- | --- | --- |
| `int global_var;` | `.bss` | Chưa khởi tạo → mặc định là 0 |
| `static int s = 10;` | `.data` | Đã khởi tạo → nạp từ Flash vào RAM |
| `const int val = 5;` | `.rodata` (Flash) | Không nằm trong RAM |

* **Tồn tại suốt đời chương trình.**
    
* Dữ liệu khởi tạo được **copy từ Flash vào RAM khi khởi động**.
    

---

## 💻 **4\. Code minh họa vùng nhớ**

```c
cSao chépChỉnh sửaint global_var;               // .bss (chưa khởi tạo)
static int static_var = 10;   // .data (đã khởi tạo)

void foo() {
    int local_var;            // Stack
    static int local_static;  // .bss (.data nếu khởi tạo)
    int *ptr = malloc(100);   // Heap
}
```

---

## 🧾 **5\. Map file – Compiler Memory Map**

Dùng **file .map** từ linker để kiểm tra:

```c
textSao chépChỉnh sửa.bss        0x20000000    0x400
.data       0x20000400    0x200
.stack      0x20000800    0x1000
```

→ Cho biết bộ nhớ sử dụng ở đâu, vùng nào chiếm bao nhiêu byte.

---

## 🔧 **6\. Tối ưu bộ nhớ trong Embedded Systems**

### ✅ Giảm stack usage:

* Dùng biến static nếu không cần reset mỗi lần gọi.
    
* Tránh đệ quy.
    
* Hạn chế truyền struct lớn theo kiểu pass-by-value.
    

### ✅ Quản lý heap:

* **Tránh dùng malloc** trong vòng lặp hoặc ISR.
    
* Cân nhắc sử dụng **memory pool** hoặc quản lý thủ công.
    

### ✅ Tool hỗ trợ:

* **FreeRTOS**: `uxTaskGetStackHighWaterMark()`
    
* **GCC**: kiểm tra `.map`, `-fstack-usage`, `-Wstack-usage`
    
* **Keil**: Runtime stack overflow detection, Symbol viewer
    

---

## 📘 **7\. Gợi ý tài liệu đọc thêm**

* 📘 *The C Programming Language* – Brian W. Kernighan & Dennis M. Ritchie
    
* 📘 *Embedded Systems in C* – Michael Barr
    
* 📘 *Definitive Guide to ARM Cortex-M* – Joseph Yiu
    
* 📘 *Linker Script & Memory Map in Embedded* – STM32 CubeIDE doc + GNU Linker Manual
    

---

## ❓ Một vài câu hỏi thực chiến thú vị

* **Làm sao để tính stack tối ưu cho task trong FreeRTOS?**  
    → Dùng `uxTaskGetStackHighWaterMark()` trong thời gian thực để đo mức thấp nhất còn trống.
    
* **Tại sao một số hệ thống cấm heap?**  
    → Vì **heap fragmentation** và **không đảm bảo thời gian thực (real-time)**.
    
* **Cách debug stack overflow trong Keil?**  
    → Sử dụng:
    
    * `__stack` trong map file
        
    * Bật `Stack Overflow Checking`
        
    * Quan sát call stack hoặc check HardFault handler.
