---
title: 'RTOS 原理 - 建立 RTT 運行環境'
disqus: kyleAlien
---
RTOS 原理 - 建立 RTT 運行環境
===
## OverView of Content
[TOC]
## RTOS 概述
RTOS (**RealTime Operation System**) 的出現比起其他多用戶系統晚;PC 上的 CPU 出現比單晶片早
1. CPU:首先在 1987 年 Intel 的 8086 CPU 問世
2. 單晶片:之後才是 1981 年 Intel 的 8051 單晶片問世
在這之後 PC & 嵌入式的發展分道揚鑣 ~
### PC & 嵌入式 - 系統差異
* PC 系統特點:
1. 多任務
2. 多用戶
3. 使用記憶體管理單元 MMU (Memory Manager Unit),無法直接觸碰到實際記憶體位置
4. 系統龐大
* 嵌入式特點:
1. 多任務
2. 實時性
3. 資源很少 (像是記憶體就特別少)
4. 大多可以直接操作晶片中的暫存器
5. 系統較小
兩者使用雙氣泡圖來表示就會如下
> 
### RTOS 系統 - 基礎原理
* Android、Window、Linux、iOS 等等 PC 系統跟 RTOS 最大的 **差異在 ==實時性==**,但兩者仍有相同之處 (畢竟都基於某個特定硬體特性)
1. **Thread 調度**:
* **RTOS 屬於順序執行**:對於每個任務都進行排隊,在處理完一個任務後,才能開始執行下一個任務,這是屬於「非搶佔式」
> 
* **PS 屬於 CPU 輪巡機制**:對於每個任務都給予 **固定的時間,並快速切換**,由於速度快到人無法辨別,所以像是同時處理(這也就是為什麼單核心 CPU 也可以達到多工運行的特性)
> PC 系統用「`時間片` + `多工公平排程`」確保使用者體驗
>
> 
:::success
* **搶佔式調度**
在 CPU 輪尋機制之後再加上每個 **Thread 的++優先性++**,優先性越高的就越會被執行到 (**可能有一些中斷是非常緊急的任務**)
:::
:::warning
* 但這並不代表 RTOS 不能使用搶佔式調度,同長 RTOS 是使用 🔁 搶佔式調度 + 優先權制度(像是 `RT-Thread`、`FreeeRTOS`)
:::
2. **Memory 管理**:
* **RTOS 系統**:在單晶片上,很少會有記憶體管理問題 (其實仍有),記憶體通常由開發人員直接管理,通常資源也需要手動回收
> 較高效率的記憶體管理是,**動態申請內存**,在哪裡需要資源時就可以把不需要的資源釋放,改動到需要記憶體的進程
* **PC 系統**:切換到標準 PC 系統,再加上是 **Multi-Thread** 機制時,就要考慮到多個問題,其中就包括 `初始化`、`排他鎖`、`Memory 回收`... 等等問題
> PC 系統都會有記憶體管理,來自動回收記憶體,也不會讓開發者直接操作到記憶體
3. **中斷管理**:
* RTOS 最大的特色就是「即時回應中斷事件」,因為很多嵌入式應用(例如馬達控制、感測器讀取、即時反應)都無法容忍延遲,所以對中斷管理特別講究
> 會有中斷向量的規劃,詳細確定中斷來源的優先權(通常數值越小優先度約高)
```shell=
# 假設向量表長這樣:
0x00: Reset_Handler
0x04: NMI_Handler
0x08: HardFault_Handler
...
0x2C: UART0_IRQHandler
0x30: Timer0_IRQHandler
```
* **PC 系統**:在系統中由於有 **Multi-Thread** 所以也要考慮到,產生出的中斷要由哪個 Thread 負責處理,所以必須把中斷管理起來
4. **Thread (Process) 管理**:
* RTOS 裸機 (沒有系統):沒有所謂的 Thread、Process 概念,最多只有 **子函數** 的概念,但由於只有子函數,可以間單的 **用全局變量來處理**
* 操作系統:由於系統中的 Thread、Process 會將各個使用記憶體隔開,並使用 MMU 分配,需要使用系統中的進程通訊機制
### Process、Thread - 記憶體管理
* Process 進程、Thread 線程在系統中都是很重要的概念,尤其是其記憶體的分配;Thread 都在一個 **地址空間**,而 Process 則在獨立的 **地址空間**
* **地址空間**:系統的運行是 CPU 不斷的取地址、驛碼、執行
:::info
* 取地址 ?
MCU 根據 PC (`Program Count`) 的計數器 (指向要訪問的地址),去讀取資料,MCU 能訪問的儲存器範圍稱為 **地址空間**
:::
> 
* 在 PC 系統著重於多任務、多用戶,所以相當 **注重隱私**,所以 **CPU 新增一個 ==硬體 MMU== (`Memory Managerment Unit`)**,**CPU 不再直接訪問物理空間,而是讓 MMU 進行邏輯地址轉換 (也可稱為映射),再訪問 MMU 轉換後的物理地址**
> 
這樣的好處就是對於 CPU 來說他們是連續的邏輯地址 (但實際上是完全不同的物理地址)
:::danger
* 由於這個 MMU 硬體機制讓 RTOS 與其他作業系統分道揚鑣,**在 RTOS 中大部分只會有 Thread 概念**
:::
> 
### RTOS 與嵌入式系統的關係
* ✅ RTOS 是不是一定會在嵌入式系統裡?不是!
嵌入式系統是軟體與硬體的結合,但嵌入式系統並不一定要加載「整個軟體系統」,可以單純的運行簡單的軟體
:::info
這裡說的簡單軟體就無處理太多功能的軟體,而 RTOS 則可以處理複雜功能(像是任務管理、排成、中斷處… 等等)
:::
它常見有兩種常見類型:
* 裸機(`Bare-metal`)系統:直接在 MCU 上跑 C 程式,沒有作業系統。適合簡單、對資源要求小的應用(如:LED 閃爍、單一感測器讀值)
> RTOS 是軟體,解決多任務與即時性的問題
* RTOS 系統:當系統有多任務(如同時要處理 UART、BLE、觸控螢幕)或有明確即時性需求(如工業控制、車用系統)時,就會使用 RTOS
> 嵌入式系統是 「整體解決方案」,RTOS 是其中的一環(但不是必需)
## 建立 RT-Thread 環境
RT-Thread 是一款來自中國的 開源實時作業系統(Real-Time Operating System,RTOS),特別為 資源受限的嵌入式裝置 所設計,具備高度模組化、輕量化、高即時性等特性
以下我們使用
* 開發版:`AT32F407`
* 開發 OS 系統環境:`Window`
* IDE:`Keil IDE`
> 
* RT-Thread 是開源的,可以在 [**Github**](https://github.com/RT-Thread/rt-thread) 上下載到 source code,下載 or git clone
> 
:::success
這邊使用 Keil 5.36 的版本,下載請 [**參考**](https://www.jianshu.com/p/9513cb06f96c)
:::
### RT-Thread env 工具
* RTOS 有許多組件、配置項目,手動設置、下載較為麻煩,使用官方提供的 Env 工具來進行配置… 像是可以用來下載 BSP 工具、套件管理、設定 `.config` 檔案
1. 進入 [**RT-Thread 網站**](https://www.rt-thread.org/page/download.html) 下載 Env 工具,並解壓縮
> 
2. 進到解壓縮的目錄中,使用 cmd 開啟 `env.bat` (它會開啟一個新視窗)
> 
3. 在新開啟的 Window bar 上按右鍵,進入 `Setting`
> 
4. 設定點擊 Integration#Register,並按下保存
> 
5. 在任何目錄中按下右鍵,就可以看到多出的 `ConEmuHere` 選項,點擊進入後就可以開啟 Env 工具的終端機
> 
### Keil Env 配置 - 開發環境
* 進入 RT-Thread Source Code 目錄下
1. 使用 `ConEmuHere` 選項開啟該目錄
> 
2. 輸入 `menuconfig --setting` 命令進行配置 (這邊不進行任何修改,直接 Save)
> 空白鍵做選擇、Enter 進入、Esc 退出
>
> 
> 選擇 Keil MDK5
> 
* 配置 BSP 設定,以下選擇 BSP 模板 (路徑:`\rt-thread-master\bsp\at32\at32f407-start`)
:::info
* BSP 是什麼?
BSP(`Board Support Package`)是一個基於特定晶片、開發版所提供的軟體開發包,更專注於不同硬體的不同設定
:::
輸入 `menuconfig --setting` 命令進行配置 (這邊不進行任何修改,直接 Save)
> 
:::danger
* 就算不做設定仍要開啟 `menuconfig --setting` 並按下 Save,否則無法產生相對應的檔案
:::
### Keil MDK 5 開啟專案
1. 使用 Keil MDK5 開啟 `project.uvprojx` 檔案
> 
2. 設定 Debug -> Use 方式,按下 OK
> 
3. 設定 Target -> Usb 燒入,按下 OK
> 
4. 按下 Build 按鈕
> 
5. 燒入進 AT32F407 開發板
> 成功後會看到 3 個 LED 輪流亮起
:::danger
必須要有 MDK 5 的 License,否則無法燒入進去
:::
### Debug 工具 - FinSH
* RTT 有提供一個方便的 Debug 工具 FinSH,可以透過終端機進行函數測試,以下新增 `hello.c` 文件,簡單的輸出一段文字
```c=
// hello.c
#include <rtthread.h>
#include <finsh.h>
int hello_func(int argc, char** argv) {
rt_kprintf("Hello RT-Thread World~! \n");
return 0;
}
// 定義要測試的 Function
MSH_CMD_EXPORT(hello_func, hello);
```
**MSH_CMD_EXPORT** 是一個宏定義,第一個參數是 function name、第二個參數是 function nick name (別名)
> 
* 串口調適使用 Microsoft Store 中的 App (**串口調試助手**)
> 
* 測試 FinSH 功能
1. 燒入 RTT 提供的 Source Code,並確認運行
2. 開啟串口調適工具,並請指定正確的 Port 號、115200、8N1
> 
3. 輸入要測試的 Function Name 在按下發送,RTT 就會執行指定 Function (使用這個串口工具需多輸入 Enter)
> 
## Appendix & FAQ
:::info
:::
###### tags: `RTOS`