• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            tbwshc

            tbw

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              95 Posts :: 8 Stories :: 3 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(4)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            正如我早先說的。這個應用程序所做的兩件事之一是使紅色指示燈閃爍。這可以通過下面的代碼來做到。這里函數flashRed()作為一個任務來執行。然而,如果忽略這一點以及新的函數名,那么這段代碼和第七章“外圍設備”中我們研究過的LED 閃爍函數幾乎是一樣的。在這一級上的唯一差別就是新的頻率(10HZ)和指示燈的顏色(紅色)。
            #include "led.h"
            #include "timer.h"
            /*******************************************************************
            *
            * Function : flashRed()
            *
            * Description : Blink the red LED ten times a second.
            *
            * Notes : This outer loop is hardware-independent, However, it
            * calls the hardware-dependent function toggleLed().
            *
            * Returns : This routine contains an infinite loop.
            *
            *******************************************************************/
            void
            flashRed(void)
            {
            Timer timer;
            timer.start(50, Periodic); // Start a periodic 50 ms timer.
            while(1)
            {
            toggleLed(LED_RED); // Toggle the red LED.
            timer.waitfor(); // Wait for the timer to expire.
            }
            } /* flashRed() */
            LED 閃爍程序主要的改變在這段代碼中是看不見的。這些主要的變化是對toggleLed()函數和Timer 類進行了修改以兼容多任務的環境。toggleLed()函數就是我現在稱之為指示燈驅動的東西。一旦你開始這樣考慮這個問題,tb也許會考慮把驅動重寫成一個C++類,并已加入新的方法以明確地設置和清除指示燈,這個方法也是講得通的。但是,采用和第七章一樣的實現方法,并且僅使用一個互斥體來保護P2LTCH 寄存器不被一個以上的任務同時訪問,就已經足夠了(注1)。這里是修改后的代碼:
            #include "i8018xEB.h"
            #include "adeos.h"
            static Mutex gLedMutex;
            /*******************************************************************
            *
            * Function : toggleLed()
            *
            * Description : Toggle the state of one or both LEDs.
            *
            * Notes : This version is ready for multitasking.
            *
            * Returns : None defined.
            *
            *******************************************************************/
            void
            toggleLed(unsigned char ledMask)
            {
            gLedMutex.take();
            // Read P2LTCH, modify its value, and write the result.
            //
            gProcessor.pPCB->ioPort[1].latch ^= ledMask;
            gLedMutex.release();
            } /* toggleLed() */
            注 1:在早先的那個toggleLed()函數中存在競爭的情況。為了理解這一點,返回去查看這段代碼,并且假想兩個任務在共享指示燈,第一個任務恰好調用了那個切換紅色指示燈的函數,突然之間,第一個任務被第二個任務占先,此時,在toggleLed()函數中,指示燈的狀態都被讀入并存入一個處理器的寄存器。現在第二個任務導致兩個指示燈的狀態都被再次讀入并且存入另一個處理器的寄存器,然后兩個指示燈的狀態都被修改以改變綠色指示燈的狀態,并且導致結果寫出到P2LTCH 寄存器。當中斷的任務重新啟動時,它已經有一個指示燈狀態的拷貝。但是這個拷貝不再準確了。當發生這個變化后,指示燈變成紅燈,并且比新的指示燈狀態寫到P2LTCH 寄存器。這樣,第二個任務的改變將會被撤銷。加入一個互斥體可以消除這個潛在的危險。

            第七章中的時鐘驅動程序在應用于一個多任務的環境之前,tbw必須對它做類似的改動。然而這時不存在競爭的情況(注2)。我們需要利用一個互斥體來消除waitfor 方法中的輪詢。通過把一個互斥體和每一個軟件時鐘關聯,我們可以使任何一個在等待時鐘的任務休眠,因此,釋放了處理器以執行就緒的低優先級的任務。當等待的時鐘到期了,休眠的任務會被操作系統喚起。為此,一個指向互斥體的指針,叫做 pMutex,被加入到類的定義中:
            class Timer
            {
            public:
            Timer();
            ~Timer();
            int start(unsigned int nMilliseconds, TimerType = OneShot);
            int waitfor();
            void cancel();
            TimerState state;
            TimerType type;
            unsigned int length;
            Mutex * pMutex;
            unsigned int count;
            Timer * pNext;
            private:
            static void interrupt Interrupt();
            };
            每次構造函數創建軟件時鐘的時候,這個指針被初始化。此后,無論何時一個時鐘對象被啟動,它的互斥體可以像下面這樣獲得:
            ——————————————————————————————————
            注 2:記得時鐘硬件只初始化一次(在第一次構造函數請求的時候),并且此后時鐘專用寄存器只能由一個函數(即中斷服務例程)來讀寫。
            /*******************************************************************
            *
            * Function : start()
            *
            * Description : Start a software timer, based on the tick from the
            * underlying hardware timer.
            *
            * Notes : This version is ready for multitasking.
            *
            * Returns : 0 on success, -1 if the timer is already in use.
            *
            *******************************************************************/
            int
            Timer::start(unsigned int nMilliseconds, TimerType timerType)
            {
            if(state != Idle)
            {
            return(-1);
            }
            //
            // Take the mutex. It will be released when the timer expires.
            //
            pMutex->take();
            //
            // Initialize the software timer.
            //
            state = Active;
            type = timerType;
            length = nMilliseconds / MS_PER_TICK;
            //
            // Add this timer to the active timer list.
            //
            timerList.insert(this);
            return(0);
            } /* start() */
            通過在時鐘啟動的時候獲得互斥體,我們可以保證在同一個互斥體釋放之前沒有其他任務(甚至是啟動時鐘的任務)能夠再獲得它。并且這在時鐘自然到期(中斷服務程序)或是人為取消(通過取消的辦法)之前是不會發生的。所以在waitfor()中的輪詢可以由pMutex->take()來替換如下:
            /*******************************************************************
            *
            * Function : waitfor()
            *
            * Description : Wait for the software timer to finish.
            *
            * Notes : This version is ready for multitasking.
            *
            * Returns : 0 on success, -1 if the timer is not running.
            *
            *******************************************************************/
            int
            Timer::waitfor()
            {
            if(state != Active)
            {
            return(-1);
            }
            //
            // Wait for the timer to expire.
            //
            pMutex->take();
            //
            // Restart or idle the timer, depending on its type.
            //
            if(type == Periodic)
            {
            state == Active;
            timerList.insert(this);
            }
            else
            {
            pMutex->release();
            state = Idle;
            }
            return(0);
            } /* waitfor() */
            當時鐘最后到期時,中斷服務程序將會釋放互斥體,調用的任務會在waitfor()中被喚起。喚起的過程中,互斥體已經為下一個運行的時鐘獲得。互斥體只有當時鐘是OneShot 類型時才會被釋放,因此,是不會自動重啟的。

             

            posted on 2013-08-19 11:53 tbwshc 閱讀(351) 評論(0)  編輯 收藏 引用
            成人久久精品一区二区三区| 久久国产乱子伦精品免费强| 色婷婷综合久久久久中文字幕| 久久精品国产亚洲AV香蕉| 久久久久无码精品| 欧美一区二区久久精品| 久久人妻少妇嫩草AV无码蜜桃| 狠狠色伊人久久精品综合网| 国产成人精品久久免费动漫| 精品久久久久久国产牛牛app| 日韩久久久久中文字幕人妻| 久久九九兔免费精品6| 久久免费精品一区二区| 久久99这里只有精品国产| 久久久精品国产sm调教网站| 色综合久久久久| 久久久久99这里有精品10| 亚洲国产精品久久久久婷婷软件 | 久久久午夜精品| 99久久这里只有精品| 亚洲Av无码国产情品久久| 久久婷婷五月综合国产尤物app| 精品久久久久久无码免费| 亚洲欧美日韩久久精品第一区| segui久久国产精品| 一本一本久久a久久综合精品蜜桃| 久久精品国产91久久综合麻豆自制 | 久久se精品一区二区| 亚洲欧洲中文日韩久久AV乱码| 久久久久久夜精品精品免费啦| 色婷婷狠狠久久综合五月| 久久精品国产99国产电影网 | 久久er99热精品一区二区| 亚洲国产成人久久综合野外| 成人a毛片久久免费播放| 精品一区二区久久| 91精品国产色综合久久| 久久青青草原精品国产| 日韩人妻无码精品久久免费一| 久久精品国产欧美日韩99热| 久久精品国产72国产精福利|