RT-Thread源碼學習第二篇,從裸機程序到多任務(線程)系統

以一個簡單的例子來講明,好比按鍵檢測:異步

1. 最簡單的方法,就是輪詢。經過定時檢測按鍵的狀態,更新計數器,從而消除抖動。線程

int main(void)
{
    int cnt = 0;
    GPIO_Init();
    unsigned KeyStatus = KEY_RELEASED;
    unsigned KeyStatus_r = KEY_RELEASED;
    while(1)
    {
        Key = GPIO_Read();
        if ( Key == 0 && cnt >= 20 )
        {
            cnt = 20;
            KeyStatus = KEY_PRESSED;
        }
        else if ( Key == 0 )
        {
            cnt++;
        }
        else
        {
            cnt = 0;
            KeyStatus = KEY_RELEASED;
        }
        if ( KeyStatus_r == KEY_PRESSED && KeyStatus == KEY_RELEASED )
        KeyStatus_r = KeyStatus;
        delay_us(500);
    }
}

輪詢將cpu的大部分資源消耗在延時器裏,浪費了計算能力。因此當系統複雜度增長時,事件可能得不到及時的響應,所以產生了先後臺系統。code

2. 先後臺系統在硬件中加入了中斷控制器,將一部分異步或者不須要cpu長時間處理的事件放給中斷去響應。主程序做爲後臺,輪詢各中斷的狀態,進行相應處理。仍是這個例子。事件

unsigned char flag = 0;

int main(void)
{
    int cnt = 0;
    Timer_Init(US_500);
    GPIO_Init();
    while(1)
    {
        if ( flag == 1 )
        {
            Key = GPIO_Read();
            if ( Key == 0 && cnt >= 20 )
            {
                cnt = 20;
                KeyStatus = KEY_PRESSED;
            }
            else if ( Key == 0 )
            {
                cnt++;
            }
            else
            {
                cnt = 0;
                KeyStatus = KEY_RELEASED;
            }
            if ( KeyStatus_r == KEY_PRESSED && KeyStatus == KEY_RELEASED )
            KeyStatus_r = KeyStatus;
        }
    }
}

void Timer_ISR(void)
{
    Reload_Timer(US_500);
    flag = 1;
}

先後臺系統解放了cpu,將延時交給專用的硬件定時器來進行。但若是系統的複雜度提高,後臺可能會被低優先級但更頻繁的中斷所佔據,或者由於某個硬件沒有正確的響應而致使整個系統崩潰。在硬件上引入中斷嵌套能夠在必定程度上解決這個問題,但更好的辦法是使用任務(在rtt中稱爲線程)調度器。資源

3. 在多任務(之後都稱爲線程)系統裏,全部線程都是死循環且不能返回,線程的切換由線程調度器完成。線程調度器扮演了先後臺系統裏的「後臺」的功能,但與先後臺系統不一樣,線程調度器不須要等到「前臺」程序運行完畢並返回才進行下一步,當高優先級線程準備好,線程調度器能夠馬上切換到高優先級的線程去執行。it

相關文章
相關標籤/搜索