新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 建立一個屬于自己的AVR的RTOS(1)—函數(shù)的運行

        建立一個屬于自己的AVR的RTOS(1)—函數(shù)的運行

        作者: 時間:2016-12-03 來源:網絡 收藏
        自從03年以來,對單片機RTOS的學習和應用的熱潮可謂一浪高過一浪.03年,在離開校園前的,非典的那幾個月,在華師的后門那里買了本邵貝貝的《UCOSII》,通讀了幾次,沒有實驗器材,也不了了之。

        在21IC上,大家都可以看到楊屹寫的關于UCOSII在51上的移植,于是掀起了51上的RTOS的熱潮。

        本文引用地址:http://www.104case.com/article/201612/325272.htm

        再后來,陳明計先生推出的small rots,展示了一個用在51上的微內核,足以在52上進行任務調度。

        前段時間,在ouravr上面開有專門關于AVR的Rtos的專欄,并且不少的兄弟把自己的作品拿出來,著實開了不少眼界。這時,我重新回顧了使用單片機的經歷,覺得很有必要,從根本上對單片機的RTOS的知識進行整理,于是,我開始了編寫一個用在AVR單片機的RTOS。

        當時,我所有的知識和資源有:

        Proteus6.7可以用來模擬仿真avr系列的單片機

        WinAVR v2.0.5.48基于GCC AVR的編譯環(huán)境,好處在于可以在C語言中插入asm的語句

        mega8 1K的ram有8K的rom,是開發(fā)8位的RTOS的一個理想的器件,并且我對它也比較熟悉。

        寫UCOS的Jean J.Labrosse在他的書上有這樣一句話,“漸漸地,我自然會想到,寫個實時內核直有那么難嗎?不就是不斷地保存,恢復CPU的那些寄存器嘛。”

        好了,當這一切準備好后,我們就可以開始我們的Rtos for mega8的實驗之旅了。

        本文列出的例子,全部完整可用。只需要一個文件就可以編譯了。我相信,只要適當可用,最簡單的就是最好的,這樣可以排除一些不必要的干擾,讓大家專注到每一個過程的學習。

        第一篇:函數(shù)的運行

        在一般的單片機系統(tǒng)中,是以前后臺的方式(大循環(huán)+中斷)來處理數(shù)據(jù)和作出反應的。

        例子如下:

        makefile的設定:運行WinAvr中的Mfile,設定如下

        MCU Type: mega8

        Optimization level: s

        Debug format :AVR-COFF

        C/C++ source file:選譯要編譯的C文件

        #include

        void fun1(void)

        {

        unsigned char i=0;

        while(1)

        {

        PORTB=i++;

        PORTC=0x01<<(i%8);

        }

        }

        int main(void)

        {

        fun1();

        }

        首先,提出一個問題:如果要調用一個函數(shù),真是只能以上面的方式進行嗎?

        相信學習過C語言的各位會回答,No!我們還有一種方式,就是“用函數(shù)指針變量調用函數(shù)”,如果大家都和我一樣,當初的教科書是譚浩強先生的《C程序設計》的話,請找回書的第9.5節(jié)。

        例子:用函數(shù)指針變量調用函數(shù)

        #include

        void fun1(void)

        {

        unsigned char i=0;

        while(1)

        {

        PORTB=i++;

        PORTC=0x01<<(i%8);

        }

        }

        void (*pfun)(); //指向函數(shù)的指針

        int main(void)

        {

        pfun=fun1; //

        (*pfun)(); //運行指針所指向的函數(shù)

        }

        第二種,是“把指向函數(shù)的指針變量作函數(shù)參數(shù)”

        #include

        void fun1(void)

        {

        unsigned char i=0;

        while(1)

        {

        PORTB=i++;

        PORTC=0x01<<(i%8);

        }

        }

        void RunFun(void (*pfun)()) //獲得了要傳遞的函數(shù)的地址

        {

        (*pfun)(); //在RunFun中,運行指針所指向的函數(shù)

        }

        int main(void)

        {

        RunFun(fun1); //將函數(shù)的指針作為變量傳遞

        }

        看到上面的兩種方式,很多人可能會說,“這的確不錯”,但是這樣與我們想要的RTOS,有什么關系呢?各位請細心向下看。

        以下是GCC對上面的代碼的編譯的情況:

        對main()中的RunFun(fun1);的編譯如下

        ldi r24,lo8(pm(fun1))

        ldi r25,hi8(pm(fun1))

        rcall RunFun

        對void RunFun(void (*pfun)())的編譯如下

        /*void RunFun(void (*pfun)())*/

        /*(*pfun)();*/

        .LM6:

        movw r30,r24

        icall

        ret

        在調用void RunFun(void (*pfun)())的時候,的確可以把fun1的地址通過r24和r25傳遞給RunFun()。但是,RTOS如何才能有效地利用函數(shù)的地址呢?



        關鍵詞: AVRRTOS函

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 进贤县| 洛扎县| 安吉县| 丹棱县| 云安县| 文昌市| 神农架林区| 利津县| 静乐县| 宝山区| 屏山县| 潼南县| 太湖县| 黑龙江省| 威宁| 米易县| 高青县| 临沭县| 黄梅县| 吐鲁番市| 长兴县| 三原县| 贵南县| 马鞍山市| 佛教| 司法| 富平县| 华坪县| 昌宁县| 宁都县| 隆安县| 湾仔区| 新泰市| 彭水| 林州市| 会理县| 昌平区| 永修县| 黎平县| 筠连县| 莆田市|