邏輯系統與多任務系統

裸機系統與多任務系統

說在前面(閒話)

大學一開始迷茫的我在大一下學期既然接觸到單片機這麼好且玩神奇的東西,好多人在初中(高中)的時候都已經接觸了。爲什麼我大學才能接觸(哭遼)。。。。。原因可能是高中瞭解的接觸的太少了。最開始上手51單片機點亮一個小燈泡就賊有成就感,四五行的代碼看的滿心歡喜,覺得嵌入式應該不難並決定以後要超這個方向發展。(什麼狗屁通信工程——老子喜歡嵌入式)
直到我學習了中斷學習了PWM我才知道原來和我想的不太一樣啊!給的例程可以跑得通,我自己寫的就是沒啥效果(內心罵自己100遍——爲什麼我這麼菜)實現一個功能代碼我調了近一天。不過黃天不負有心人我最終還是達到了效果。學習51單片機讓我對IO口有了基本的認識。
大一暑假接觸了STM32,學長學姐建議先學習使用寄存器版的。我內心想着應該和51差不多,上去直接看代碼。看了以後只想說(臥槽臥槽臥槽)這都是啥???然後慢慢地看正點原子給的資料和例程有了一定的認識。瞭解了GPIO時鐘等概念,後來學習了定時器、中斷、輸入捕獲對寄存器有了一定的認識。通過尋跡小車基於STM32的三路超聲波避障小車對學到的東西鞏固了一些,進一步加深理解和認識。(文章都是寄存器版本的呦,網上有的源碼很少,支持一哈博主唄!!!)後來學習了LCD、TFLCD等就看文章、看代碼、下載驗證感覺沒有學到啥(作用不大)。後來通過STM32實現一個五子棋小遊戲加深了對觸摸屏的理解,同時對C語言鞏固了不少。然後不知不覺一年就過去了,要期末考試了。成績出來我既然沒有掛科!!!(感謝信號老師讓我61分飄過,今年不掛、來年必定好好學習)
學期末沒有怎麼學,看了一點UCOS相關的知識。瞭解了一些API函數、消息隊列、信號量等內容但是沒有深究。剛好放假了可以深入學習一哈,動手寫一個實時操作系統。再看看數據結構與算法相關的內容。希望2020會有好運,能有更大的收穫。
立個flag——每個月發表博客平均在3篇以上!!

裸機系統

裸機系統通常分成輪詢系統和前後臺系統,

輪詢系統

輪詢系統即是在裸機編程的時候, 先初始化好相關的硬件設備,然後讓主程序在一個死循環裏面不斷循環, 順序地做各種事情,大概的僞代碼具體見代碼清單 4-1。通常只適用於那些只需要順序執行代碼且不需要外部事件來驅動的就能完成的事情。在代碼清單 4-1 中,如果只是實現 LED 翻轉,串口輸出,液晶顯示等這些操作,那麼使用輪詢系統將會非常完美。但是,如果加入了按鍵操作等需要檢測外部信號的事件,用來模擬緊急報警,那麼整個系統的實時響應能力就不會那麼好了。假設DoSomething3 是按鍵掃描,當外部按鍵被按下,相當於一個警報,這個時候,需要立馬響應,並做緊急處理,而這個時候程序剛好執行到 DoSomething1,要命的是DoSomething1需要執行的時間比較久,久到按鍵釋放之後都沒有執行完畢,那麼當執行到 DoSomething3的時候就會丟失掉一次事件。可見,輪詢系統只適合順序執行的功能代碼,當有外部事件驅動時,實時性就會降低。
在這裏插入圖片描述

前後臺系統

相比輪詢系統,前後臺系統是在輪詢系統的基礎上加入了中斷。外部事件的響應在中斷裏面完成, 事件的處理還是回到輪詢系統中完成,中斷在這裏我們稱爲後臺, main 函數裏面的無限循環我們稱爲後臺,大概的僞代碼見代碼如下:

1 int flag1 = 0;
2 int flag2 = 0;
3 int flag3 = 0;
4
5 int main(void)
6 {
7 /* 硬件相關初始化 */
8 HardWareInit();
9
10 /* 無限循環 */
11 for (;;) {
12 if (flag1) {
13 /* 處理事情 1 */
14 DoSomethin1();
15 }1617 if (flag2) {
18 /* 處理事情 2 */
19 DoSomething2();
20 }2122 if (flag3) {
23 /* 處理事情 3 */
24 DoSomething3();
25 }
26 }
27 }
28
29 void ISR1(void)
30 {
31 /* 置位標誌位 */
32 flag1 = 1;
33 /* 如果事件處理時間很短,則在中斷裏面處理
34 如果事件處理時間比較長,在回到前臺處理 */
35 DoSomethin1();
36 }
37
38 void ISR1(void)
39 {
40 /* 置位標誌位 */
41 flag1 = 2;
42
43 /* 如果事件處理時間很短,則在中斷裏面處理
44 如果事件處理時間比較長,在回到前臺處理 */
45 DoSomethin2();
46 }
47
48 void ISR3(void)
49 {
50 /* 置位標誌位 */
51 flag3 = 1;
52
53 /* 如果事件處理時間很短,則在中斷裏面處理
54 如果事件處理時間比較長,在回到前臺處理 */
55 DoSomethin3();
56 } 

在順序執行後臺程序的時候,如果有中斷來臨,那麼中斷會打斷後臺程序的正常執行流,轉而去執行中斷服務程序,在中斷服務程序裏面標記事件,如果事件要處理的事情很簡短,則可在中斷服務程序裏面處理,如果事件要處理的事情比較多,則返回到後臺程序裏面處理。雖然事件的響應和處理是分開了,但是事件的處理還是在後臺裏面順序執行的,但相比輪詢系統,前後臺系統確保了事件不會丟失,再加上中斷具有可嵌套的功能,這可以大大的提高程序的實時響應能力。 在大多數的中小型項目中,前後臺系統運用的好,堪稱有操作系統的效果

多任務系統

相比前後臺系統,多任務系統的事件響應也是在中斷中完成的,但是事件的處理是在任務中完成的。在多任務系統中,任務跟中斷一樣,也具有優先級,優先級高的任務會被優先執行。當一個緊急的事件在中斷被標記之後,如果事件對應的任務的優先級足夠高,就會立馬得到響應。相比前後臺系統,多任務系統的實時性又被提高了。 多任務系統大概的僞代碼具體見代碼如下。

1 int flag1 = 0;
2 int flag2 = 0;
3 int flag3 = 0;
4
5 int main(void)
6 {
7 /* 硬件相關初始化 */
8 HardWareInit();
9
10 /* OS 初始化 */
11 RTOSInit();
12
13 /* OS 啓動,開始多任務調度,不再返回 */
14 RTOSStart();
15 }
16
17 void ISR1(void)
18 {
19 /* 置位標誌位 */
20 flag1 = 1;
21 }
22
23 void ISR1(void)
24 {
25 /* 置位標誌位 */
26 flag1 = 2;
27 }
28
29 void ISR3(void)
30 {
31 /* 置位標誌位 */
32 flag3 = 1;
33 }
34
35 void DoSomethin1(void)
36 {
37 /* 無限循環,不能返回 */
38 for (;;) {
39 /* 任務實體 */
40 if (flag1) {
41
42 }
43 }
44 }
45
46 void DoSomethin2(void)
47 {
48 /* 無限循環,不能返回 */
49 for (;;) {
50 /* 任務實體 */
51 if (flag2) {
52
53 }
54 }
55 }
56
57 void DoSomethin3(void)
58 {
59 /* 無限循環,不能返回 */
60 for (;;) {
61 /* 任務實體 */
62 if (flag3) {
63
64 }
65 }
66 } 

相比前後臺系統中後臺順序執行的程序主體,在多任務系統中,根據程序的功能,我們把這個程序主體分割成一個個獨立的,無限循環且不能返回的小程序,這個小程序我們稱之爲任務。 每個任務都是獨立的,互不干擾的,且具備自身的優先級,它由操作系統調度管理。 加入操作系統後, 我們在編程的時候不需要精心地去設計程序的執行流,不用擔心每個功能模塊之間是否存在干擾。加入了操作系統,我們的編程反而變得簡單了。 現如今,單片機的 FLASH 和 RAM 是越來越大,完全足以抵擋 RTOS 那點開銷。無論是裸機系統中的輪詢系統、 前後臺系統和多任務系統,我們不能一錘子的敲定孰優孰劣,它們是不同時代的產物,在各自的領域都還有相當大的應用價值,只有合適纔是最好。有關這三者的軟件模型區別具體見表格 4-1。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章