六月丁香五月婷婷,丁香五月婷婷网,欧美激情网站,日本护士xxxx,禁止18岁天天操夜夜操,18岁禁止1000免费,国产福利无码一区色费

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

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

時(shí)間: 佳洲1085 分享

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

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

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

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

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

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

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

  程序本質(zhì)的剖析

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

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

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

  1. 入棧

  2. 取向量

  3. 更新寄存器

  4. 異常返回

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

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

  更新寄存器

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

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

  1. 屏蔽所有中斷

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

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

  4. 取消中斷屏蔽

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

  上面這四步只是一個(gè)大體的概述

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

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

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

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

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

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

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

  7. MSP和PSP雙堆棧指針的使用,保存寄存器時(shí)用(在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)先級(jí)寄存器,用于設(shè)置PendSV異常和Systick異常的優(yōu)先級(jí)(在Cortex-M3權(quán)威指南一書)

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

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

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

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

  MOV R0, #0x60

  MSR BASEPRI, R0

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

  MOV R0, #0

  MSR BASEPRI, R0

  2.線程模式和handler模式

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

  4.PendSV異常

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

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

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

  5.SVC異常

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

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

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

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

  一般情況下

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

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

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

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

  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位是讀寫類型,向這個(gè)位寫1就可以實(shí)現(xiàn)懸起PendSV異常

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

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

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

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

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

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

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

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

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

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

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

  void TaskSwitch(void);

  void Task0(void)

  {

  while(1)

  {

  //do something task

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

  TaskSwitch();

  }

  }

  void Task1(void)

  {

  while(1)

  {

  //do something task

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

  TaskSwitch();

  }

  }

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

  這里有一個(gè)前提

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

  OS_TCB * p_OS_TCB_Current;

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

  OS_TCB * p_OS_HighPriTCB_Current;

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

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

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

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

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

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

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

  4. 觸發(fā)PendSV異常

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

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

  下面開始演示

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

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

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

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

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

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

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

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

  觸發(fā)PendSV異常

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

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

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

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

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

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

精選文章

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

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

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

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

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

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

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

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

3634356