--- title: '嵌入式系統 - 基礎概念' disqus: kyleAlien --- 嵌入式系統 - 基礎概念 === ## OverView of Content [TOC] ## 嵌入式 - 定義 嵌入式系統的定義較為模糊,依照 `嵌入式系統 - 實戰指南 面向 IoT 應用` 定義: 嵌入式系統面向各類具有,**++獨立功能++**、可完成特定任務的 **++低功號++**、**++低成本++** 微型設備 ### 嵌入式 - 系統比較 :::success * 用系統的角度來看:嵌入式系統往往不需要多餘的外部設備 (或很少),就可以跟外部通訊 > e.g:串口、藍芽 ::: * 下表示大部分 `嵌入式系統` & `AP/PC 系統` 的比較 | 比較項目 | 嵌入式系統 | AP/PC 系統 | | -------- | -------- | -------- | | CPU | 8/16/32 bit | 32/64 bit | | 指令集 | RISC (精簡指令集) 為主,幾乎不使用 CISC (複雜指令集) | RISC/CISC | | 主頻 (全速) | <= 200MHz | > 1GHz | | 功耗 (全速) | < 100mA | >= 100mA | | RAM | `SRAM` 為主,為單位 KB,大部分內嵌 | `SDRAM`/`DDR` 為主,單位為 MB/G,大部分外插 | | Flash | `NOR - Flash` 為主,為單位 KB,大部分內嵌 | `NAND - Flash` 為主,單位為 MB/G,大部分外插 | | 操作系統 | 無 / RTOS | Linux、Android、iOS、Window、Mac | | 人機接口 | 簡單一般不設計 GUI | 支持 GUI | :::info 手機的架構與 PC 越來越相似,所以不列入 嵌入式系統 範疇 (功耗大、更專注在用戶使用) ::: * 嵌入式系統架構主要分為:硬體、軟體 * 硬體:決定了系統的複雜性、成本、軟體的實現邏輯 * 嵌入式系統 & 非嵌入式系統的差異,以最大的差異來說就是外置設備的要求不同,**AP 需要更多的外部設備** (綠色代表必要) > MCU (`Micro Computor`) 代表了 Soc (`System on chip`) > > AP 是應用處理器 Application Processor > > ![](https://i.imgur.com/9q0XmHV.png) ### RAM & Flash * RAM 是隨機訪問存储器的簡稱,**^1.^ ++隨機訪外++ 代表可以在 RAM 的任意存储單元讀寫**,**^2.^ 斷電後數據會遺失** > RAM 還有細分為 SRAM、SDRAM、DDR ... 等等,如果沒有特別說明的話 RAM 一般是指 SRAM (`static Random-Access Memory`) * Flash 程式存储器,**不能隨機訪問單個存储單元,只能 ^1.^ ++批量訪問++;最常見的是按照 Page、Block 來讀寫 Flash**,**^2.^ 斷電後數據不遺失** > E.g. `NOR-Flash`、`NAND-Flash` * 兩者還有一大差異為 **速度、價錢**,Flash 速度較慢但便宜,而 RAM 相反 > ![](https://i.imgur.com/KcvMmz5.png) ## 硬體架構 ### MCU 架構 - [AT32F407](https://www.arterytek.com/cn/product/AT32F407.jsp) * 單晶片機:把許多物件都集成到一個 Chip 上 (電源、時鐘、MCU) 這種簡單的最基礎集成就稱為單晶片機 :::success * **與 SoC 的差異?** SoC 可以集成更多的外部物件 ::: 單晶片機: 8051 (51 系列 8 bit 機)、MSP430 (16 bit 機)、ARM (32 bit 機) * 在這裡我們看 [**AT32F407**](https://www.arterytek.com/cn/product/AT32F407.jsp) MCU 系統框圖 (可下載 MCU Datasheet 查看),並說明幾個重點 > ![](https://i.imgur.com/7ecA2w6.png) 1. **核心 MCU**:這裡是使用 **ARM Cortex M4F** 內核,它是 MCU 的大腦,決定了 MUC 的性能 2. **總線**:ARM 系列的 CPU 最常見的總線有三種;^1.^ **AHB** (`Advanced High-performance Bus`)、^2.^ **APB** (`Advanced Peripheral Bus`)、^3.^ **AXI** (`Advanced eXtensible Interface`) AXI 這種高階總線通常出現在 AP 系統晶片中 * **AHB 總線**:AHB 是高性能、高速總線,在該總線上的元素都比較重要,AHB 總線上大部分有以下元素 (並非一定) | 元素 | 補充 | | - | - | | RAM | 隨機訪問記憶體 | | Flash | 區塊訪問記憶體,不流失數據 | | DMA | Direct Memory Access,可以在不干涉內核的狀況下訪問 RAM,在吞吐量較高的情況下性能高 | | 以太網 MAC | 有線網路的硬體接口 | | GPIO | 一般像是螢幕顯示就需要這樣的高速 | 最後可以看到 AHB 下有接上兩個 APB 橋接器 > ![](https://i.imgur.com/UASTg6Y.png) :::warning * 為何不把所有設備掛在 AHB 總線上 ? 1. AHB 總線上的裝置,可直接與內核通訊,尋址方式複雜 2. AHB 自帶的 **硬體 ==仲裁== 機制**,如果過多的設備,其複雜度又會以指數型成長 ::: * **APB 總線**:APB (240MHz) 總線上的時鐘速度 **只有 AHB (120MHz) 總線速度的一半** | 元素 | 補充 | | - | - | | SPI | `Serial Peripheral Interface`,串行外設接口,用於短距離的設備通信,例如感測器和閃存 | | UART | `Universal Asynchronous Receiver/Transmitter`,通用異步收發器,常用於串行通信 | | I^2^C | `Inter-Integrated Circuit`,集成電路之間的串行通信總線,用於連接低速設備如 EEPROM 和 ADC | | USB | `Universal Serial Bus`,通用串行總線,用於連接外部設備,例如鼠標、鍵盤或存儲設備 | * **RCC (Reset Clock Contorller) 復位與時鐘控制模塊**:該模塊的主要功能是,把時鐘源的時鐘分配到不同模塊 ! :::info 不同區塊的時鐘可以用軟體進行配置 ::: ### 內核架構 - Cortex M4 * 使用 ARM Cortex M4 系列處理器架構圖 > ![](https://i.imgur.com/Kh0RNp3.png) 1. **內核的主要工作**: ^1.^ `取地址 Fetch`、^2.^ `解碼 Decode`、^3.^ `執行 Execute`,具體來說程式的核心則是 **使用 ==馮.諾伊曼架構==**;取址就是從 Flash 中取得程式,經過翻譯後,最後執行 2. **內核 RAM**: 內核 RAM 的速度更快,內核可以直接訪問這裡的記憶體 (**但容量較小**),又將這個區塊稱為 **暫存器 (Register)** :::success ARM 最基礎的暫存器有 16 個,在這之後為了需求還有在擴展,不過這 16 個暫存器一值都在 ::: 3. **NVIC (`Nested Vevtored Interrupt Controller`)**: 嵌套向量中斷控制器,由於中斷有很多種,所以單晶片使用類似於 Key/Value 的模式,一個號碼對應一個中斷 :::info 晶片設計者把特定的號碼稱為 **中斷向量**、**中斷矢量** (因為從來源到目標有方向性) ::: ### 晶片架構 - 馮.諾伊曼架構 * 馮.諾伊曼架構用運在 CPU 中 1. `CPU`:中央處理器,進行讀取、解碼、執行 2. `Register`:儲存器 3. `I/O 總線`:輸入輸出系統 * CPU 運作順序如下 1. **PC 讀取**: 將程式 (`RAM`、`Flash`) 從記憶體中讀取到 Register;**PC (`Program Counter`, 程式計數器) 是 16 的原祖 Register 其中一個,每次上電都會從一個特定數值開始累加** > ![](https://i.imgur.com/1hwF4B8.png) * 指令是通過 PC 內的值作為地址來訪問 RAM、Flash,再由儲存器返回該地址中保存的 **指令**。地址則是程式中的指令在 RAM、Flash 中保存的位置。 :::warning * 指令 != 地址,指令組合語言,接下來會說明 ::: :::info * 這些被讀取指令,會保存在特殊 Register 中 (不屬於 16 原祖 Register) 特殊 Register 則是,**為了提高 CPU 的執行效率 (可看作 Cache)**,一般會 **預先將 PC 所指向的地址 & 後面的一段程式** 同時緩存到一個特別的储存器中,**避免每次都要使用到總線讀取** > ![](https://i.imgur.com/gEFra7o.png) ::: 2. **解碼器**: **CPU 將指令 Register 中的指令進行解碼**,所有指令都被定義為一串二進位程式;有的指令進行運算、讀寫、CPU 休眠 ... 等等 > ![](https://i.imgur.com/GLMc8BD.png) 3. **執行**: CPU 的執行指令 4. **回寫**: 最終結果寫回 Register、Flash、RAM 中 > ![](https://i.imgur.com/CCLE6GQ.png) ### 指令 - 組合語言 * 我們寫的 **程式最終會翻譯成一組一組的指令**,並存在 RAM、Flash 中,而 **CPU 要讀取的就是這些指令**;指令由 Binary 表達,不意了解,所以就誕生出了組合語言,**組合語言是指令的代號,只要看到這個代號就執行固定的事情** :::info * 指令集 ? 組合語言通常是短小精悍的一串英文單字,這些單字組合起來成為一個集合,**指令集合就稱為指令集,++每個 CPU 都會有不同的指令集++** ::: * 這些組合語言可以透過 **==匯編器==** 幫我們轉換成二進位,**是編譯器的雛型** * 假設要計算 `1 + 2 = ?` 彙編器會幫我們翻譯成以下指令 ```shell= ## 偽指令 ## 儲存器地址 ------ | 內容 ------------ | Register ----- | 0x00 0x1111 0x01 0x2222 C1 0x02 0x2222 C2 0x03 0x8888 C3 ``` 解釋如下 | 儲存器單元編號 (地址) | 內容 | 說明 | | -------- | -------- | -------- | | 0x00 | 0x1111 (`假設為加法指令`) | 準備對後面兩個位置的數值進行加法 | | 0x01 | 0x2222 (`假設為操作數移動指令`) | 將 0x01 數值移動到 C1 | | 0x02 | 0x2222 (`假設為加法指令`) | 將 0x02 數值移動到 C2 | | 0x03 | 0x8888 (`假設為移動指令`) | 將結果保存到 C3 | * CPU 的 **PC 暫存器就是控制用來訪問 `儲存器單元編號 (地址)`**,有關 PC 要注意如下 1. **PC 的大小**:為 32 bit,最多就是 2^32^ 也就是 4GB 的尋址空間,但真正的 **尋址寬度是由 `內核決定` (內核有手段可以拓展寬度),比較準的應該是看 ++總線數量++** :::info 一般來說運算器的寬度會跟尋址寬度一樣,**為了最佳效能** ::: 2. **PC 滿**:從 0 開始,但基本上不會滿,因為程式往往會進入一個 while 迴圈中,再次回到指定位置 ```c= // 偽程式 int main(int argc, char** argv) { // 地址 0x11223344 while(1) { // 地址 0x11550000 // Do something,最終還是會回到 0x11550000 } // 地址 0x22002200 } ``` ### I/O 設備 * MCU 要如何控制硬體 IO 設備呢 ? 主要有分為兩種方式 ^1.^ 存储器映射、^2.^ 端口映射;而嵌入式系統多為第一種 * 前面有說到外圍設備都會掛載在 APB 總線上,只要掛載到該總線上,就會 **映射** 到記憶體中某個區塊,MCU 只要操控該區塊的記憶體,就可以操控那個 IO 設備 :::info * 映射 ? 想成一個鍵值對即可,每個設備都對映射到記憶體中,概念如同 `Map<設備, 記憶體>` ::: > ![](https://i.imgur.com/gP55ssq.png) ### 傳輸線 - 總線 * CPU 和存储器、IO... 等等設備交換數據的通道,總線會將信號連接到多個設備上,**總線是共享的,如果出現衝突狀況,則透過仲裁器負責處理** > ![](https://i.imgur.com/d013oxm.png) * 一般總線有分為三種 1. **控制總線**:負責訪問控制,也就是控制 `讀`、`寫` 2. **數據總線**:負責數據交換 3. **地址總線**:用來指定要訪問的設備地址、設備內存储器、暫存器地址 :::info * 總線協議:由於各個設備共享總線,所以會有信號的時序、數據交換的規則,這個規則就稱為 `總線協議` ::: * 總線的傳輸分為 5 個大步驟:^1.^ 申請總線、^2.^ 許可總線、^3.^ 請求訪問、^4.^ 設備應答、^5.^ 釋放總線控制,如下圖 > ![](https://i.imgur.com/bHwLJPk.png) :::warning * **AHB 有總線仲裁機制**,APH 沒有仲裁機制 ::: ### 數字電路 - 鎖存鎖 * 數字電路主要有分為兩大類:^1.^ **組合邏輯電路**、^2.^ **時序邏輯電路**; * **時序邏輯電路**:與時間有關,電路存在於 CPU、DSP、FPGA ...等等,而 **體現時間則是透過共振電晶體 Clock** :::danger * **時間電路產生的問題**: 由於 **每個模塊、或是外部裝置使用的 Clock 共振時間不同,導致數據傳輸不同的的問題** (就像是不同的解碼器,對相同的數據會解析出不同結果) :::info 解決方法是數字電路,有兩種:**存鎖器**、**D 觸發器** (配套使用) ::: ::: * **==鎖存鎖==**:是一個 **存储單元**,簡單理解起來就是,**鎖住一個狀態 (狀態可能是 `0` or `1`)** 1. **AND 鎖存器**:以下是一個循環迴路 AND 鎖存器,如果 A 輸入 0 (低訊號),則輸出 Y 就會一值是 0 > ![](https://i.imgur.com/wdgPx8a.png) 2. **D 鎖存器**:使用 4 個 NAND (Not AND) 鎖存器,就可以達到鎖住任何訊號的功能; * 兩個輸入引腳 ^1.^ `D` 輸入數據 、^2.^ `E` 控制運作;E 腳特別的是,E on 時會保持前一個數據持續輸出 (無論 D 如何改變) * 兩個輸出引腳 ^1.^ `Q` 輸出數據 、^2.^ `^Q` 輸出 **反向** 數據 (NOT 數據);如果 E on,則 Q 會與 D 相同輸出 | E (Input) | D (Input) | Q (Output) | ^Q (Output) | | - | - | - | - | | 0 | 0 | 保持前一個數據的輸出 | 保持前一個數據的輸出 | | 0 | 1 | 保持前一個數據的輸出 | 保持前一個數據的輸出 | | 1 | 0 | 0 (與 D 相同) | 1 (D 反向) | | 1 | 1 | 1 (與 D 相同) | 0 (D 反向) | > ![](https://i.imgur.com/wg1BJCD.png) * **D 觸發器**:用來觸發 D 鎖存數據的更新!它的改變是,將 E (Input) 腳換為 C 代替 E 控制電路,並串起兩個 D 存鎖器; > ![](https://i.imgur.com/II7xzbP.png) C 引腳就是來接時鐘 Clock 用的,**用 C 引腳來 ++檢查 D 引腳的資料++,並 ++透過 C 引腳來控制數據輸出++**,其時序圖如下 * 請先回憶兩件事:^1.^ D、Q 是相同輸出、^2.^ C 代替 E 控制,只有當 C 上升時才能控制 D 輸出 * 下圖第一個 C 上升:檢查到 D 是下降的,準備將 Q 調降 * 在調整 Q 的輸出,這期間 D 必須保持一段時間的輸出數據 (`延遲`),也就是說數據建立是需要時間的 (下圖藍色區塊) > ![](https://i.imgur.com/J9h3wKz.png) ## Appendix & FAQ :::info ::: ###### tags: `嵌入式`