不卡AV在线|网页在线观看无码高清|亚洲国产亚洲国产|国产伦精品一区二区三区免费视频

學(xué)習(xí)啦>學(xué)習(xí)電腦>操作系統(tǒng)>操作系統(tǒng)基礎(chǔ)知識>

寫一個簡易嵌入式操作系統(tǒng)

時間: 佳洲1085 分享

  在了解了操作系統(tǒng)的原理和工作后,我們可以自己寫一個簡易的嵌入式操作系統(tǒng),下面由學(xué)習(xí)啦小編為大家整理了寫一個簡易嵌入式操作系統(tǒng)的相關(guān)知識,希望對大家有幫助!

  寫一個簡易嵌入式操作系統(tǒng)概述

  1.首先確定CPU,在這里為了簡單,就選用嵌入式的CPU,比如arm系列,之所以用RISC(簡單指令集)類型的CPU,其方便之處是沒有實模式與保護(hù)模式之分,采用線性的統(tǒng)一尋址,也就是不需要進(jìn)行段頁式內(nèi)存管理,還有就是芯片內(nèi)部集成了一些常用外設(shè)控制器,比如以太網(wǎng)卡,串口等等,不需要像在PC機(jī)的主板上那么多外設(shè)芯片

  2.確定要實現(xiàn)的模塊和功能,為了簡單,只實現(xiàn)多任務(wù)調(diào)度(但有限制,比如最多不超過10),實現(xiàn)中斷處理(不支持中斷優(yōu)先級),不進(jìn)行動態(tài)SHELL交互,不實現(xiàn)動態(tài)模塊加載,不實現(xiàn)fork之類的動態(tài)進(jìn)程派生和加載(也就是說要想在你的操作系統(tǒng)上加入用戶程序,只能靜態(tài)編譯進(jìn)內(nèi)核中;不支持文件系統(tǒng),不支持網(wǎng)絡(luò),不支持PCI,磁盤等外設(shè)(除了支持串口,呵呵,串口最簡單嘛),不支持虛擬內(nèi)存管理(也就是說多任務(wù)中的每個進(jìn)程都可以訪問到任何地址,這樣做的話,一個程序死了,那么這個操作系統(tǒng)也就玩完了)

  3.確定要使用的編譯器,這里采用GCC,文件采用ELF格式,當(dāng)然,最終的文件就是BIN格式,GCC和LINUX有著緊密的聯(lián)系,自己的操作系統(tǒng),需要C庫支持和系統(tǒng)調(diào)用支持,所以需要自己去裁剪庫,自己去實現(xiàn)系統(tǒng)調(diào)用

  4.實現(xiàn)步驟:首先是CPU選型,交叉編譯環(huán)境的建立,然后就是寫B(tài)OOTLOADER,寫操作系統(tǒng)通過以上4點的學(xué)習(xí)一個簡單的嵌入式操作系統(tǒng)準(zhǔn)備工作就差不多做好了。

  寫一個簡易嵌入式操作系統(tǒng)詳解

  程序本質(zhì)的剖析

  寫操作系統(tǒng)這個高端大氣上檔次的工作肯定要有一些鋪墊了,最必須的就是對你寫的程序的了解,也許你會說,我寫的程序,我還能不理解嗎,但是這次咱么要從寄存器角度分析。

  咱們首先從類比學(xué)習(xí)開始,咱們先來理解中斷,對于中斷,學(xué)習(xí)單片機(jī)的小朋友們肯定很理解,咱么來一起回顧下,單片機(jī)是怎么用硬件實現(xiàn)中斷的(更為具體的說明在Cortex-M3權(quán)威指南-carpter9中斷的具體行為)其實中斷就是多任務(wù)的環(huán)境了,只不過這個多任務(wù)環(huán)境只能有兩個任務(wù)(在只有一個中斷的前提下),那么只要咱么能模擬出來中斷,那實現(xiàn)自己的操作系統(tǒng)也是很簡單的呢。

  CM3中斷的一個完整過程由一下幾個部分組成

  1. 入棧

  2. 取向量

  3. 更新寄存器

  4. 異常返回

  入堆棧:響應(yīng)異常的第一個行動,就是自動保存現(xiàn)場的必要部分:依次把xPSR, PC, LR, R12以及R3‐R0由硬件自動壓入適當(dāng)?shù)亩褩V?,就是保存要切換出去的任務(wù),因為下面就要開始執(zhí)行中斷這個任務(wù)了,如果不保存就無法實現(xiàn)這個任務(wù)的完全復(fù)原了。

  取向量:其實就是找到中斷任務(wù)的入口地址,這樣才能開始執(zhí)行中斷函數(shù)

  更新寄存器

  異常返回:當(dāng)異常服務(wù)例程執(zhí)行完畢后,需要很正式地做一個“異常返回”動作序列,從而恢復(fù)先前的系統(tǒng)狀態(tài),才能使被中斷的程序得以繼續(xù)執(zhí)行

  操作系統(tǒng)的任務(wù)切換也是大同小異

  1. 屏蔽所有中斷

  2. 保存正在執(zhí)行的任務(wù)的寄存器信息到任務(wù)獨立的堆棧中

  3. 從要投入運行的任務(wù)的堆棧中取出數(shù)據(jù)到寄存器中

  4. 取消中斷屏蔽

  經(jīng)過這四步,上一個任務(wù)已經(jīng)被保存起來,等待下一次的運行,要運行的任務(wù)已經(jīng)開始了運行

  上面這四步只是一個大體的概述

  在對CM3內(nèi)核的實現(xiàn)描述前有一些準(zhǔn)備知識

  1. CM3寄存器基礎(chǔ)(在Cortex-M3權(quán)威指南一書)

  2. BASEPRI寄存器,用于中斷屏蔽(在Cortex-M3權(quán)威指南一書)

  3. 線程模式和handler模式,在保存上下文時用(在Cortex-M3權(quán)威指南一書)

  4. 特權(quán)級和用戶級,明白在Systick中斷時的情況(在Cortex-M3權(quán)威指南一書)

  5. PendSV異常,在這個異常中進(jìn)行任務(wù)切換(在Cortex-M3權(quán)威指南一書)

  6. SVC異常,啟動OS,開始執(zhí)行第一個任務(wù)就是通過呼叫SVC異常(在Cortex-M3權(quán)威指南一書)

  7. MSP和PSP雙堆棧指針的使用,保存寄存器時用(在Cortex-M3權(quán)威指南一書)

  8. 中斷控制及狀態(tài)寄存器ICSR,知道如何觸發(fā)PendSV異常(在Cortex-M3權(quán)威指南一書)

  9. 向量表偏移量寄存器VTOR,第一次切入任務(wù)的(在Cortex-M3權(quán)威指南一書)

  10. 向量表結(jié)構(gòu),得到MSP的初始值(在Cortex-M3權(quán)威指南一書)

  11. 系統(tǒng)異常優(yōu)先級寄存器,用于設(shè)置PendSV異常和Systick異常的優(yōu)先級(在Cortex-M3權(quán)威指南一書)

  下面詳細(xì)說明上述幾點

  1. CM3寄存器基礎(chǔ)

  1.BASEPRI寄存器,用于中斷屏蔽(在Cortex-M3權(quán)威指南一書)

  在更精巧的設(shè)計中,需要對中斷掩蔽進(jìn)行更細(xì)膩的控制——只掩蔽優(yōu)先級低于某一閾值的中斷——它們的優(yōu)先級在數(shù)字上大于等于某個數(shù)。那么這個數(shù)存儲在哪里?就存儲在BASEPRI中。不過,如1果往BASEPRI中寫0,則另當(dāng)別論——BASEPRI將停止掩蔽任何中斷。例如,如果你需要掩蔽所有優(yōu)先級不高于0x60的中斷,則可以如下編程:

  MOV R0, #0x60

  MSR BASEPRI, R0

  如果需要取消 BASEPRI 對中斷的掩蔽,則示例代碼如下:

  MOV R0, #0

  MSR BASEPRI, R0

  2.線程模式和handler模式

  3.特權(quán)級和用戶級

  4.PendSV異常

  試想一個這個過程一個ISR正在執(zhí)行SysTick 異常會搶占其 ISR,在這時OS 不得執(zhí)行上下文切換,否則將使中斷請求被延遲,而且在真實系統(tǒng)中延遲時間還往往不可預(yù)知——任何有一丁點實時要求的系統(tǒng)都決不能容忍這種事。因此,在 CM3 中也是嚴(yán)禁沒商量——如果 OS 在某中斷活躍時嘗試切入線程模式,將觸犯用法 fault 異?!,F(xiàn)在好了,PendSV 來完美解決這個問題了。PendSV 異常會自動延遲上下文切換的請求,

  直到其它的 ISR 都完成了處理后才放行。為實現(xiàn)這個機(jī)制,需要把 PendSV 編程為最低優(yōu)先級的異常。如果 OS 檢測到某 IRQ 正在活動并且被 SysTick 搶占,它將懸起一個 PendSV 異常,

  以便緩期執(zhí)行上下文切換。

  5.SVC異常

  SVC 用于產(chǎn)生系統(tǒng)函數(shù)的調(diào)用請求。例如,操作系統(tǒng)不讓用戶

  程序直接訪問硬件,而是通過提供一些系統(tǒng)服務(wù)函數(shù),用戶程序使用 SVC 發(fā)出對系統(tǒng)服務(wù)函

  數(shù)的呼叫請求,以這種方法調(diào)用它們來間接訪問硬件。

  6.MSP和PSP雙堆棧指針的使用

  一般情況下

  在線程模式下使用PSP,在handler模式下使用MSP

  所以在進(jìn)行任務(wù)切換的時候,只需要把通用寄存器數(shù)據(jù)壓入任務(wù)的私有堆棧。

  在異常的時候,只能使用MSP堆棧指針,任務(wù)切換又是在PendSV異常中進(jìn)行的,

  所以進(jìn)入PnedSV異常的時候,

  7.先把通用寄存器的內(nèi)容保存到要切換出去的任務(wù)的私有堆棧(這是保存上文),

  8.保存通用寄存器到主堆棧,

  9.屏蔽所有中斷,進(jìn)入臨界區(qū)

  10.調(diào)用C語言函數(shù)進(jìn)行切換當(dāng)前任務(wù)的TCB指針,

  11.返回到異常匯編函數(shù)中

  12.解除中斷屏蔽

  13.從主堆棧中恢復(fù)數(shù)據(jù)到通用寄存器,

  14.從要切入任務(wù)的私有堆棧中恢復(fù)數(shù)據(jù)到通用寄存器

  15.退出異常

  16.中斷控制及狀態(tài)寄存器ICSR

  ICSR的第28位是讀寫類型,向這個位寫1就可以實現(xiàn)懸起PendSV異常

  17.向量表偏移量寄存器VTOR

  把這個作為地址從中取出的就是向量表的第一塊內(nèi)容

  18.向量表結(jié)構(gòu)

  向量表的第一塊內(nèi)容是MSP 的初始值

  19.系統(tǒng)異常優(yōu)先級寄存器

  PendSV異常和Systick異常在操作系統(tǒng)中,應(yīng)該設(shè)成最低,

  通過這兩個寄存器改變這兩個異常的優(yōu)先級

  應(yīng)該修改成0xf0

  下面對于CM3這個內(nèi)核說一下詳細(xì)的實現(xiàn)步驟

  咱們先從簡單的來,加入現(xiàn)在你寫了兩個函數(shù)

  并且有一個任務(wù)切換函數(shù)

  void TaskSwitch(void);

  void Task0(void)

  {

  while(1)

  {

  //do something task

  //實現(xiàn)任務(wù)的主動切換,就是把當(dāng)前任務(wù)切換出去把另一個任務(wù)切換進(jìn)去

  TaskSwitch();

  }

  }

  void Task1(void)

  {

  while(1)

  {

  //do something task

  //實現(xiàn)任務(wù)的主動切換,就是把當(dāng)前任務(wù)切換出去把另一個任務(wù)切換進(jìn)去

  TaskSwitch();

  }

  }

  在main函數(shù)中調(diào)用Task0函數(shù),實現(xiàn)手動啟動Task0,這就進(jìn)入了任務(wù)切換的循環(huán)了,那么TaskSwitch怎么實現(xiàn)了,下面開始進(jìn)入重點,開始一步一步說明,如何實現(xiàn)這個函數(shù)。

  這里有一個前提

  /* 當(dāng)前任務(wù)控制塊的指針 */

  OS_TCB * p_OS_TCB_Current;

  /* 高優(yōu)先級任務(wù)控制塊指針 */

  OS_TCB * p_OS_HighPriTCB_Current;

  首先先說一下TaskSwitch函數(shù)中實現(xiàn)了什么

  1. 屏蔽中斷,進(jìn)入臨界區(qū)

  2. 根據(jù)相應(yīng)的算法計算下一個應(yīng)該切入的任務(wù)是那個,咱么這里很簡單,

  如果正在執(zhí)行任務(wù)0,那么切換到任務(wù)1,

  如果正在執(zhí)行任務(wù)1,那么切換到任務(wù)0,

  這就實現(xiàn)了最簡單的任務(wù)切換。

  3. 把p_OS_HighPriTCB_Current指向要切入的函數(shù)

  4. 觸發(fā)PendSV異常

  5. 解除中斷屏蔽,退出臨界區(qū)

  這塊的任務(wù)C語言就可以實現(xiàn),但是用匯編寫效率可能會更高

  下面開始演示

  屏蔽中斷,進(jìn)入臨界區(qū)

  這里就要利用上面說的準(zhǔn)備的知識了—BASEPRI寄存器,因為用的是一個八位寄存器的高四位作為優(yōu)先級,這里只要把一個0x10的數(shù)寫入BASEPRI寄存器,就可以實現(xiàn)屏蔽所有的中斷。

  根據(jù)相應(yīng)的算法計算下一個應(yīng)該切入的任務(wù)是那個,咱么這里很簡單,

  如果正在執(zhí)行任務(wù)0,那么切換到任務(wù)1,

  如果正在執(zhí)行任務(wù)1,那么切換到任務(wù)0,

  這就實現(xiàn)了最簡單的任務(wù)切換。

  把p_OS_HighPriTCB_Current指向要切入的函數(shù)

  用C語言即可實現(xiàn)

  觸發(fā)PendSV異常

  ICSR的第28位是讀寫類型,向這個位寫1就可以實現(xiàn)懸起PendSV異常

  解除中斷屏蔽,退出臨界區(qū)

  如果往BASEPRI中寫0,則——BASEPRI將停止掩蔽任何中斷

  完成這幾步就完成了任務(wù)切換,最基本的多任務(wù)環(huán)境就實現(xiàn)了。

寫一個簡易嵌入式操作系統(tǒng)

在了解了操作系統(tǒng)的原理和工作后,我們可以自己寫一個簡易的嵌入式操作系統(tǒng),下面由學(xué)習(xí)啦小編為大家整理了寫一個簡易嵌入式操作系統(tǒng)的相關(guān)知識,希望對大家有幫助! 寫一個簡易嵌入式操作系統(tǒng)概述 1.首先確定CPU,在這里為了簡單,就選
推薦度:
點擊下載文檔文檔為doc格式

精選文章

  • 講解操作系統(tǒng)的有關(guān)書籍推薦
    講解操作系統(tǒng)的有關(guān)書籍推薦

    學(xué)習(xí)操作系統(tǒng)最重要的是選擇一本好書,下面由學(xué)習(xí)啦小編為大家整理了講解操作系統(tǒng)的有關(guān)書籍推薦的相關(guān)知識,希望對大家有幫助! 講解操作系統(tǒng)的有

  • 簡述幾種計算機(jī)網(wǎng)絡(luò)操作系統(tǒng)
    簡述幾種計算機(jī)網(wǎng)絡(luò)操作系統(tǒng)

    計算機(jī)網(wǎng)絡(luò)操作系統(tǒng)種類繁多,下面由學(xué)習(xí)啦小編為大家整理了簡述幾種計算機(jī)網(wǎng)絡(luò)操作系統(tǒng)的相關(guān)知識,希望對大家有幫助! 簡述幾種計算機(jī)網(wǎng)絡(luò)操作系

  • 簡述如何加固計算機(jī)操作系統(tǒng)
    簡述如何加固計算機(jī)操作系統(tǒng)

    出于安全,我們可以對計算機(jī)操作系統(tǒng)進(jìn)行加固處理,下面由學(xué)習(xí)啦小編為大家整理了簡述如何加固計算機(jī)操作系統(tǒng)的相關(guān)知識,希望對大家有幫助! 簡述

  • 簡述什么是計算機(jī)操作系統(tǒng)
    簡述什么是計算機(jī)操作系統(tǒng)

    計算機(jī)操作系統(tǒng)是什么?它又有哪些分類呢?下面由學(xué)習(xí)啦小編為大家整理了簡述什么是計算機(jī)操作系統(tǒng)的相關(guān)知識,希望對大家有幫助! 簡述什么是計算機(jī)操

3634356