590 likes | 913 Views
TinyViz Programming. Speaker : Fish (Yun-Shih Hsu). Install TinyOS. http://www.tinyos.net. Install TinyOS. Download TinyOS. Tutorial. Install TinyOS. Install TinyOS. Install TinyOS. Install TinyOS. Install TinyOS. Install TinyOS. TinyOS 1.1.0 Stable, but dated TinyOS 1.1.11
E N D
TinyViz Programming Speaker:Fish (Yun-Shih Hsu)
Install TinyOS • http://www.tinyos.net
Install TinyOS Download TinyOS Tutorial
Install TinyOS • TinyOS 1.1.0 • Stable, but dated • TinyOS 1.1.11 • TinyOS 1.1.11-3is • Less tested, but fresh
Install TinyOS • Setup Cygwin with TinyOS • Execute Cygwin
About Cygwin / Linux • $:command sign • $ls • ls:list files and directories in current directory • pwd:show the path of current directory from root • man:search information from manual • man [command / library] • man grep
About Cygwin / Linux • cd:change directory • cd [directory path] • cd ./tinyos-1.x • cd /opt/tinyos-1.x • grep: • grep [-r] “string” [filename] • grep “Fish” TestTinyViz.nc • grep “Fish” * • grep -r “Fish” *
About Cygwin / Linux • [Tab] • When typing command, [Tab] key could complete the file name or directory name • If there are many file / directory name are similar, [Tab] key will list all of files and directories which are match the non-complete name we typed
Upgrade Cygwin • $cd /opt • [/opt]$ • cvs -z3 -d:pserver:anonymous @tinyos.cvs.sourceforge.net: /cvsroot/tinyos co -P tinyos-1.x • TinyOS 1.1.15
Make TinyViz • Cygwin • $/opt/tinyos-1.x/tools/java/net/tinyos/sim • $make all • Root of Cygwin in Windows • C:\Program Files\UCB\cygwin
Using TinyViz • $export PATH=$PATH:/opt/tinyos-1.x/tools/java/net/tinyos/sim • Edit /etc/profile • at the end of file add • export PATH=$PATH:/opt/tinyos-1.x/tools/java/net/tinyos/sim • At the end line of file is empty line
Using TinyViz • $cd /opt/tinyos-1.x/apps • For example, we want to use Blink module • $cd ./blink • $make pc • $tinyviz –run ./build/pc/main.exe 10
Structure of TinyViz • All of files about TinyViz are in • /opt/tinyviz-1.x/tools/java/net/tinyos/sim • 主要程式位置都在上述之目錄 • 有關plugin的程式都在./plugin • 有關event的程式都在./event
TinyViz 主程式 • TinyViz.java • TinyViz tv; • SimDriver.java • SimDriver driver;
TinyViz mote 相關 • Layout • MoteLayoutPlugin.java • Mote的長相,以及底圖顏色等 • MoteSimObject.java • 螢幕以及地圖位置的比例轉換 • CoordinateTransformer.java
TinyViz plugin 相關 • 呼叫各個plugin • SimProtocol.java • 新增Plugin的GUI時,可以研究如何修改這部分 • 其餘相關plugin • ./plugin/ • 例如,要修改Debug Message的Plugin,就要修改DebugMsgPlugin.java • 其中部分物件與./MessageList.java有關
TinyViz • 為了確認修改的值是否正確 • 可以多利用 • System.out.println();
TinyViz & NesC • 可以參考Blink、PongMsg、TestTivyViz • 其中TestTinyViz中,包含FakeLocation以及TestTinyViz
NesC Programming • 基礎的NesC Programming • 參考Tutorial • 參考/opt/tinyos-1.x/apps/裡的程式
NesC Programming • 所有要用的變數只能宣告成全域變數 • NesC不存在區域變數 event result_t abc { uint8_t a; return SUCCESS; } command result_t cba { uint8_t b; return SUCCESS; }
NesC Programming • 變數最好給予初始值 • 以免使用時有不正常的數值存在 • 變數初始只能在 StdControl.init()
NesC Programming • 變數型態 • unsigned integer • uint8_t、uint16_t 、uint32_t • signed integer • Int8_t 、int16_t 、int32_t • 布林回傳型態 • result_t • SUCCESS • FAULT • 有無其他型態不確定
NesC Programming • 確定可用之基本功能 • 迴圈 • for • 判斷式 • if • else • else if • 其他 • break • continue
NesC Programming • NesC programming除了基本的 *.nc 以及 *M.nc以外,可以使用標頭檔 (*.h) • 需要使用其他變數型態,或是需要自定義一些結構等等
NesC Programming • *.h • 不可以使用 #define • 常在標頭檔宣告使用的東西 • enum • typedef struct typedef struct test { uint16_t a; uint8_t b; double src_x; double src_y; }test_t; enum { a = 7, b = 8, c= 9, };
NesC Programming • *.h • 標頭檔裡大致上是可以使用C的變數型態 • *.h 和 *.nc 以及 *M.nc一樣,其檔案最後一行必須是空白行,若沒有留空白行,會compile錯誤
NesC Programming • 標頭檔的引入方式 • 在*.nc中 • includes [標頭檔名]; • Ex: includes test; (假設標頭檔名為 test.h)
NesC Programming • NesC可以將已經寫好的module直接引入使用 • Ex:有另一個寫好的module Y.h、Y.nc Y.nc: includes Y; interface { command result_t test(); } Y.h: uint8_t cc;
NesC Programming • 引入方式 • Ex:X要引入module Y,必須在X.nc和XM.nc加上 module XM { provides { interface Y; } uses { } } implementation { command result_t Y.test() { return SUCCESS; } } configuration X { provides interface Y; } implementation { Y = XM; }
NesC Programming • NesC中有兩種型態的task • command • 相當於固定的命令,可以在任何時候使用 • Ex:每秒執行一次 command A() • event • 臨時觸發的事件,只有在特定事件發生時才會啟動 • Ex:有接收到封包時,執行event • event發生時,將會插斷正在執行的command
NesC Programming • 為了避免因event發生而導致command的某些運算錯誤 • atomic atomic { for(i=0; i<6; i++) a+=i; } atomic a = a * b + c;
NesC Programming • atomic使用時要注意 • 由於atomic可以保證一定做完才准許被插斷,因此有可能遺漏發生的event • Ex:程式正在執行command中某個被atomic包住的運算,此時有封包傳過來,會造成mote無法接收此封包並進行處理。 • 所以atomic使用的時機必須恰當
NesC Programming • 在command中,若有進行assign動作的程式碼,最好用atomic包起來,以免出錯 atomic a = a * b + c;
NesC Programming • 如何進行封包傳遞 • 首先,必須在*.h內,宣告要使用的「頻道」為何 • 這個動作並非必要,但若程式中有要發送多種格式的封包時,每個使用的頻道就會不同,列在標頭檔可以清楚知道使用了哪些頻道 enum { AM_InitMsg = 7, };
NesC Programming • 在*.nc內,implementation中,在components內使用GenericComm,並且將自訂的函式與GenericComm中的函示連結關係 • 發送和接收都要連結清楚 • implementation { • components GenericComm; • ………………… • XM.SendInitMsg -> GenericComm.SendMsg[AM_InitMsg]; • XM.ReceiveInitMsg -> GenericComm.ReceiveMsg[AM_InitMsg]; • }
NesC Programming • 在*M.nc中 module XM { provides { interface StdControl; ……………… } uses { interface SendMsg as SendInitMsg; interface ReceiveMsg as ReceiveInitMsg; } }
NesC Programming • 在 *M.nc的implementation中,必須要有以下三個函式 • 發送封包 • 發送完成 call SendInitMsg.send(TOS_BCAST_ADDR, sizeof(InitMsg_t), msg); event result_t SendInitMsg.sendDone( TOS_MsgPtr sMsg, result_t success ) { return SUCCESS; }
NesC Programming • 接收封包 event TOS_MsgPtr ReceiveInitMsg.receive( TOS_MsgPtr rMsg ) { ……………… return rMsg; }
NesC Programming • *.h必須自訂封包內容 typedef struct initMsg { uint16_t src; double src_x; double src_y; }initMsg_t;
NesC Programming • *M.nc宣告全域變數 • 注意:星號必須貼著struct名稱 TOS_MsgPtr msg; TOS_Msg msgBuf; initMsg_t* initMsg; initMsg_t * initMsg; initMsg_t *initMsg;
NesC Programming typedef struct TOS_Msg { // The following fields are transmitted/received on the radio. uint16_t addr; uint8_t type; uint8_t group; uint8_t length; int8_t data[TOSH_DATA_LENGTH]; uint16_t crc; uint16_t strength; uint8_t ack; uint16_t time; uint8_t sendSecurityMode; uint8_t receiveSecurityMode; } TOS_Msg;
NesC Programming • 在StdControl.init() • 在需要傳送封包的地方,將需要傳遞的值塞入封包 atomic initMsg = (initMsg _t *)msgBuf.data; initMsg->src=TOS_LOCAL_ADDRESS;