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 TinyOS 1.1.11-3is Less tested, but fresh Install TinyOS Install TinyOS 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/tinyos1.x/tools/java/net/tinyos/sim Edit /etc/profile at the end of file add export PATH=$PATH:/opt/tinyos1.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 基礎的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 enum { }; a = 7, b = 8, c= 9, typedef struct test { uint16_t a; uint8_t b; double src_x; double src_y; }test_t; 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.h: Y.nc: uint8_t cc; includes Y; interface { command result_t test(); } NesC Programming 引入方式 Ex:X要引入module Y,必須在X.nc和XM.nc加 module XM { 上 configuration X { provides interface Y; } implementation { Y = XM; } provides { interface Y; } uses { } } implementation { command result_t Y.test() { return SUCCESS; } } 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宣告全域變數 TOS_MsgPtr msg; TOS_Msg msgBuf; initMsg_t* initMsg; 注意:星號必須貼著struct名稱 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; NesC Programming 讓mote向模擬器取得資訊 我們必須利用ADCC的模組來協助我們傳遞資 訊 NesC Programming 首先,在*.h宣告要使用的port enum { }; FAKE_LOCATION_X_PORT = 128, FAKE_LOCATION_Y_PORT = 129, FAKE_LOCATION_Z_PORT = 130, NesC Programming 在*.nc內,implementation中,在components 內使用ADCC,並且將自訂的函式與ADCC 中的函示連結關係 implementation { components ADCC; ………………… XM.ADC_X -> ADCC.ADC[FAKE_LOCATION_X_PORT]; XM.ADC_Y -> ADCC.ADC[FAKE_LOCATION_Y_PORT]; XM.ADC_Z -> ADCC.ADC[FAKE_LOCATION_Z_PORT]; } NesC Programming 實際取得資料 command result_t Location.getLocation() { call ADC_X.getData(); return SUCCESS; } NesC Programming TinyViz部分 必須在適當的程式裡加上與NesC溝通的部分 Ex:取得mote的位置,必須在 LocationPlugin.java中加上 public static final byte PORT_LOCATION_X = (byte)128; simComm.sendCommand( new SetADCPortValueCommand((short)mote.getID(), 0L, PORT_LOCATION_X, x)); NesC Programming TinyViz利用ADCC與mote溝通必須使用trycatch才能正常使用 try { simComm.sendCommand( new SetADCPortValueCommand((short)mote.getID(), 0L, PORT_Border, isBorder)); } catch (java.io.IOException ioe) { // Just ignore it return; } NesC Programming 注意:利用ADCC向TinyViz取得資料,如 果不是利用event驅動,而是使用command 通常為了驅動command,會將驅動條件放至 Timer.fired(),在console mode下,會有warning 產生,但是可以不理會他 NesC Programming 如果mote有資料想要傳給TinyViz 可以利用debug message加上MessagePlugin dbg(DBG_USR1, “[格式]”, 變數); “[格式]”, 變數 這部分同C的printf(“[格式]”, 變數) %d 為整數 %x 為十六進位