tinyos
play

TinyOS Determine when Fill message Specify Pass buffer message - PDF document

Inter-Node Communication General idea: Sender: TinyOS Determine when Fill message Specify Pass buffer message buffer Network Communication buffer with data Recipients to OS can be reused Computer Network Receiver:


  1. Inter-Node Communication � General idea: � Sender: TinyOS Determine when Fill message Specify Pass buffer message buffer Network Communication buffer with data Recipients to OS can be reused Computer Network � Receiver: Programming OS obtains free OS Buffers Signal buffer to store incoming message application with Wenyuan Xu next message in a free buffer new message 1 2 TOS Active Messages TOS Active Messages (continue) � Message is “active” because it typedef struct TOS_Msg { contains the destination address, group ID, and type. // the following are transmitted uint16_t addr; � ‘group’: group IDs create a uint8_t type; virtual network uint8_t group; � an 8 bit value specified in uint8_t length; <tos>/apps/Makelocal int8_t data [TOSH_DATA_LENGTH ]; uint16_t crc; � The address is a 16-bit value specified by “make” // the following are not transmitted � – make install.<id> mica2 uint16_t strength; uint8_t ack; uint16_t time; � “length” specifies the size of the message . uint8_t sendSecurityMode; uint8_t receiveSecurityMode; � “crc” is the check sum } TOS_Msg; Preamble Sync Header (5) Payload (29) CRC (2) 3 4 Receiving a message Sending a message includes Int16Msg; includes Int16Msg; � Define the message � Define the message module ForwarderM { module ForwarderM { Message received format //interface declaration format //interface declaration } } � Define a unique � Define a unique implementation { implementation { active message active message event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m) event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m) number number { call Leds.yellowToggle(); { call Leds.yellowToggle(); � How does TOS � How does TOS call SendMsg.send(TOS_BCAST_ADDR, call SendMsg.send(TOS_BCAST_ADDR, know the AM know the AM sizeof(IntMsg), m); sizeof(IntMsg), m); number? number? destination return m; return m; } } length event result_t SendMsg.sendDone(TOS_MsgPtr msg, bool success) event result_t SendMsg.sendDone(TOS_MsgPtr msg, bool success) { call Leds.greenToggle(); { call Leds.greenToggle(); return success; return success; } } } } File: Int16Msg.h File: Int16Msg.h struct Int16Msg { struct Int16Msg { configuration Forwarder { } configuration Forwarder { } uint16_t val; uint16_t val; implementation implementation }; }; { … { … ForwarderM.SendMsg -> Comm.SendMsg[AM_INTMSG]; ForwarderM.SendMsg -> Comm.SendMsg[AM_INTMSG]; enum { enum { ForwarderM.ReceiveMsg -> Comm.ReceiveMsg[AM_INTMSG]; ForwarderM.ReceiveMsg -> Comm.ReceiveMsg[AM_INTMSG]; AM_INTMSG = 47 AM_INTMSG = 47 } } }; }; 5 6

  2. Where exactly is the radio stuff? Spi bus interrupt handler � Connection between Chipcon CC1000 radio and the ATmega128 processor: SPI bus. � Spibus interrupt handler: SpiByteFifo.dataReady() Mica2 � SpiByteFifo.dataReady() will be called every 8 ticks. file:CC1000RadioIntM.nc StdControl async event result_t SpiByteFifo.dataReady(uint8_t data_in) { StdControl … CC1000RadioC switch (RadioState) { BareSendMsg case RX_STATE: {...} case DISABLED_STATE: {…} BareSendMsg ReceiveMsg case IDLE_STATE: {...} case PRETX_STATE: {...} case SYNC_STATE: {...} ReceiveMsg case RX_STATE: {...} return SUCCESS; } CC1000RadioIntM Preamble Sync Header (5) Payload (29) CRC (2) 7 8 Receiving a message (1) Receiving a message (2) SYNC_STATE � RX_STATE � IDLE_STATE � SYNC_STATE � � look for a SYNC_WORD (0x33cc). � Listen to the preamble, if the enough bytes of preamble are received, entering � Save the last received byte and current received byte SYCN_STATE � Use a bit shift compare to find the byte boundary for the sync byte � Retain the shift value and use it to collect all of the packet data file:CC1000RadioIntM.nc async event result_t SpiByteFifo.dataReady(uint8_t data_in) { SYNC_STATE � IDLE_STATE � … � didn't find the SYNC_WORD after a reasonable number of tries, so set the radio switch (RadioState) { state back to idle: … case IDLE_STATE: � RadioState = IDLE_STATE; { if (((data_in == (0xaa)) || (data_in == (0x55)))) { file:CC1000RadioIntM.nc PreambleCount++; async event result_t SpiByteFifo.dataReady(uint8_t data_in) { if (PreambleCount > CC1K_ValidPrecursor) { … PreambleCount = SOFCount = 0; switch (RadioState) { RxBitOffset = RxByteCnt = 0; case SYNC_STATE: … usRunningCRC = 0; { if ( find SYCN_WORD) { rxlength = MSG_DATA_SIZE-2; … RadioState = SYNC_STATE; RadioState = RX_STATE; } } else if ( too many preamble) { } … } … RadioState = IDLE_STATE; } } } … } Preamble Sync Header (5) Payload (29) CRC (2) Preamble Sync Header (5) Payload (29) CRC (2) 9 10 Receiving a message (3) Error Detection – CRC � RX_STATE � IDLE_STATE/SENDING_ACK � CRC – Cyclic Redundancy Check � Keep receiving bytes and calculate CRC until the end of the packet. � The end of the packet are specified by the length in the packet header � Polynomial codes or checksums � Pass the message to the application layer, no matter whether the message passed the CRC check file:CC1000RadioIntM.nc � Procedure: async event result_t SpiByteFifo.dataReady(uint8_t data_in) { … switch (RadioState) { 1. Let r be the degree of the code polynomial. Append r zero bits to … case RX_STATE: the end of the transmitted bit string. Call the entire bit string S(x) { …RxByteCnt++; if (RxByteCnt <= rxlength) { 2. Divide S(x) by the code polynomial using modulo 2 division. usRunningCRC = crcByte(usRunningCRC,Byte); if (RxByteCnt == HEADER_LENGTH_OFFSET) { 3. Subtract the remainder from S(x) using modulo 2 subtraction. rxlength = rxbufptr->length;} } else if (RxByteCnt == rxlength-CRCBYTE_OFFSET) { if (rxbufptr->crc == usRunningCRC) { rxbufptr->crc = 1; } else { � The result is the checksummed message rxbufptr->crc = 0; } … RadioState = IDLE_STATE; post PacketRcvd(); } … Preamble Header (5) Payload (29) CRC (2) Sync 11 12

  3. Generating a CRC – example Decoding a CRC – example � Message : 1011 � Procedure � 1 * x 3 + 0 * x 2 + 1 * x + 1= x 3 + x + 1 1. Let n be the length of the checksummed message in bits � Code Polynomial : x 2 + 1 (101) 2. Divide the checksummed message by the code polynomial using modulo 2 division. If the remainder is zero, there is no error detected. Step 2: Modulo 2 divide Case 1: Case 2: Step 1: Compute S(x) Step 3: Modulo 2 subtract 1001 1000 Checksummed the remainder from S(x) 1001 message (n=6): 101 101101 101 101001 r = 2 101 101100 101 101 S(x) = 101100 101101 101 001 000 101100 001 000 000 - 01 000 010 000 101101 1011 010 000 000 000 101 001 Original message 100 101 000 101 00 01 01 Checksummed Message Remainder = 0 Remainder = 1 (No error detected) (Error detected) Remainder 13 14 CRC in TinyOS � Calculate the CRC byte by byte file: system/crc.h crc=0x0000; uint16_t crcByte(uint16_t crc, uint8_t b) while (more bytes) { { uint8_t i; crc=crc^b<<8; crc = crc ^ b << 8; calculate the high byte of crc i = 8; } do if (crc & 0x8000) � Code Polynomial: CRC-CCITT crc = crc << 1 ^ 0x1021; 0x1021 = 0001 0000 0010 0001 else crc = crc << 1; while (--i); x 16 + x 12 + x 5 + 1 return crc; } Example: 10… 10001 0000 0010 0001 10110110110110110110110110110100 10001000000100001 01111101100101111 00000000000000000 11111011001011111 … 15

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend