這里都是linux什么的,很高端的,可是我們玩8位機的,沒有資源玩那么高端的東西哦,最近閑逛,看到一個小東西,轉過來給大家看看,這是我轉過來的 博大家一樂 Protothreads極輕量級系統用于資源緊張的單片機。 080101-KV2004 @daxia.com Ptotothreads的作者是Adam Dunkels <[email protected]>,很感謝作者給我們提供這樣一個好的系統,我認為合適的才是最好的。 作者描述Protothreads的特性是: 1 沒有專用的機器代碼,純C實現; 2 不使用容易犯錯的跳轉指令; 3 極小的內存占用; 4 當不當做操作系統來用都行; 5 所提供的阻斷等待不需要堆棧或者full multi-threading(誰能翻譯一下,剛剛接觸操作系統)。 作者提供了幾個例子,以幫助我們理解。 先看一下作者提供的5個頭文件,這5個頭文件就是Protothreads的全部文件。 lc-addrlabels.h :以字符串方式實現Protothreads系統,占用的ram可能會多些。 lc-switch.h :以標準C的switch結構實現Protothreads系統(默認) lc.h :選擇lc-addrlabels.h或lc-switch.h兩種實現Protothreads系統 pt.h :在實際應用中一般只包含此文件就行了 pt-sem.h :附加的信號量操作的支持,不需要的話則不必包含他 雖然我不熟悉其他的操作系統,但是,單看一眼其他系統的源代碼,就能看到有不少壓棧和出棧的指令。我認為,對于小小單 片機來說 ,不太合適,壓棧和出棧的指令明顯占用了時間,更占用了大量的本來不寬裕的ram。并且,似乎用于ram緊張的單片機,還會 留有隱患 。 對于我來說,使用“系統”只是為了讓我的程序思路更清晰,不然一堆變量,信號量和信號量之間互相制約,有沒有層次感,時 間一長 ,思路斷了,只能重新編寫。 Protothreads提供給我們另外一種思路:我們的程序經過了Protothreads的包裝,而實際上Protothreads的“線程”就是普通的 函數。 所有的“線程”都是(也允許不是)一個死循環,不多占用堆棧,不能被搶占,所以中途必須“退出”,不然怎么會有其他“線程”被 調度的機會?退出有兩種結果:下一次被調度后從頭運行或從退出的位置繼續向后運行。Protothreads使用C語言中的 “switch”結構 或goto語句來實現。既然能夠從上一次退出的位置繼續向后運行,那么就需要一個變量來記錄這個“位置”信息,這個變量就是 線程唯 一占用的ram變量。作者提供的數據類型是短整型或字符串類型。我認為這就是Protothreads的精髓,也就是說Protothreads 線程不是 被其他程序“中斷”的,而是自己主動退出(有點雷鋒精神),但退出之前記錄當前位置,以便下次從此位置繼續運行(真是矛盾 的統一 體)。 Protothreads為我們提供方便的同時也有一些需要我們改變編程習慣的地方,比如,我們不能在正常線程里面放一個類似 “while(1); ”的程序,除非我們確實需要這樣做--期待看門狗復位。但是,Protothreads提供給我們一個理解Protothreads的機會,源代碼 完全開 放,實現“多任務”的方式方式又是如此的簡單明了。我們完全可以根據自己的需要修改庫文件。并且以我們對Protothreads的 理解, 作出我們“心中有數”的程序。 上面描述過作者提供的5個頭文件,而我只想把Protothreads用在ram和速度都緊張的單片機(如avr的m16)上,所以,我去掉 了兩個頭 文件,只留下了三個: lc.h :以標準C的switch結構實現Protothreads系統 pt.h :Protothreads的接口,必須包含此頭文件 pt-sem.h :附加的信號量操作的支持,不需要的話則不必包含他 在pt.h中包含所有實現Protothreads的宏和變量結構的定義: 可以閱讀一下作者提供的幫助文檔,已經非常詳細了,結合作者提供的例子,很快就能理解了,幾乎都是字面意思,我保證在 你真正了 解C語言的前提下,不用半天就能夠理解Ptotothreads。 我只說一下我對PT_YIELD(pt)的理解:放棄當前執行后續代碼的機會,退出,但是下一次調度到本線程,將從此處繼續運行。 有了這個 宏就給了其他線程被調度的機會,如果一個線程中包含PT_WAIT_UNTIL(pt)或PT_WAIT_WHERE(pt)之類的宏,則沒有必要再調用 PT_YIELD(pt)了。另外,作者為了實現PT_YIELD(pt),而定義了一個局部變量PT_YIELD_FLAG,我認為沒有必要,所以我對pt.h 相關地方 做了修改,已經把局部變量PT_YIELD_FLAG去掉了。 作者提供的庫沒有提供線程的自掛起和恢復掛起功能,這個動作可以使用作者提供的PT_YIELD_UNTIL(pt,cond)宏,來實現, 或利用一 下信號量的操作,使用pt-sen.h頭文件所包含的宏來實現。但以我對Protothreads的理解,把pt.h做了一點修改,提供了與 PT_YIELD(pt)相似的方法,實現了線程的“自己”掛起和“他人”恢復。 既然看懂了系統的源程序,那么我們的思路還可以再擴展一下,函數當中什么地方只運行一次(PT_BEGIN(pt)后面),什么地 方每次調 度都能運行(PT_BEGIN(pt)前面),為什么作者說局部變量不能亂用等等。我們都能從系統的源程序里面找到答案。 AVR GCC對C支持的很好。Protothreads可以很好的用在avrgcc上。實際效果也很好,程序看起來更清晰了,多個線程配合的也 很好。 我對操作系統了解不多,對其他的操作系統也沒有深入接觸過,有些名詞會有錯誤。但我認為,Ptotothreads極容易掌握,對 于像avr 的m16之類的單片機,Protothreads是很好的選擇。 這篇文章是基于作者的Protothreads-1.4版寫的,作者還在不斷的更新中,作者網站是:http://www.sics.se/~adam/pt/ 我修改過的三個頭文件請見后面的跟貼,我想也應該能適合51單片機,正如作者所說,庫文件里面沒有任何特殊的代碼,只要 求編譯環 境對標準C語言支持的好一點。 ![]() |
23.94 KB, 下載積分: 積分 -1