From: mmaroti Date: Fri, 18 Sep 2009 08:27:02 +0000 (+0000) Subject: use new naming convention X-Git-Tag: rc_6_tinyos_2_1_1~243 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=25b65f2ba4c6024bc77105b9464e66574312036b use new naming convention --- diff --git a/tos/lib/diagmsg/DiagMsgC.nc b/tos/lib/diagmsg/DiagMsgC.nc index 5d53fa98..a3ab250c 100644 --- a/tos/lib/diagmsg/DiagMsgC.nc +++ b/tos/lib/diagmsg/DiagMsgC.nc @@ -40,13 +40,13 @@ components NoDiagMsgC; AM_DIAG_MSG = 0xB1, }; - components DiagMsgM, MainC, SerialActiveMessageC; + components DiagMsgP, MainC, SerialActiveMessageC; - DiagMsg = DiagMsgM.DiagMsg; + DiagMsg = DiagMsgP.DiagMsg; - MainC.SoftwareInit -> DiagMsgM.Init; - DiagMsgM.AMSend -> SerialActiveMessageC.AMSend[AM_DIAG_MSG]; - DiagMsgM.Packet -> SerialActiveMessageC; + MainC.SoftwareInit -> DiagMsgP.Init; + DiagMsgP.AMSend -> SerialActiveMessageC.AMSend[AM_DIAG_MSG]; + DiagMsgP.Packet -> SerialActiveMessageC; #endif } diff --git a/tos/lib/diagmsg/DiagMsgM.nc b/tos/lib/diagmsg/DiagMsgM.nc deleted file mode 100644 index 669a04b6..00000000 --- a/tos/lib/diagmsg/DiagMsgM.nc +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (c) 2002-2007, Vanderbilt University - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT - * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Author: Miklos Maroti - */ - -#include - -module DiagMsgM -{ - provides - { - interface DiagMsg; - interface Init; - } - - uses - { - interface AMSend; - interface Packet; - } -} - -#ifndef DIAGMSG_BASE_STATION -#define DIAGMSG_BASE_STATION AM_BROADCAST_ADDR -#endif - -#ifndef DIAGMSG_RETRY_COUNT -#define DIAGMSG_RETRY_COUNT 2 -#endif - -#ifndef DIAGMSG_RECORDED_MSGS -#define DIAGMSG_RECORDED_MSGS 10 -#endif - -implementation -{ - enum - { - STATE_READY = 1, - STATE_RECORDING_FIRST = 2, // recording the first 4-bit descriptor - STATE_RECORDING_SECOND = 3, // recording the second 4-bit descriptor - STATE_MSG_FULL = 4, - STATE_BUFFER_FULL = 5, - }; - - norace volatile uint8_t state; // the state of the recording - - message_t msgs[DIAGMSG_RECORDED_MSGS]; // circular buffer of messages - - norace message_t *recording; // the message that is beeing or going to be recorded - message_t *sending; // the message that is beeing sent, or the null pointer - - norace uint8_t nextData; // points to the next unsued byte - norace uint8_t prevType; // points to the type descriptor - norace uint8_t retries; // number of remaining retries - - command error_t Init.init() - { - state = STATE_READY; - recording = msgs; - sending = 0; - - return SUCCESS; - } - - // two type fields are stored in on byte - enum - { - TYPE_END = 0, - TYPE_INT8 = 1, - TYPE_UINT8 = 2, - TYPE_HEX8 = 3, - TYPE_INT16 = 4, - TYPE_UINT16 = 5, - TYPE_HEX16 = 6, - TYPE_INT32 = 7, - TYPE_UINT32 = 8, - TYPE_HEX32 = 9, - TYPE_FLOAT = 10, - TYPE_CHAR = 11, - TYPE_INT64 = 12, - TYPE_UINT64 = 13, - TYPE_ARRAY = 15, - }; - -/* - The format of the payload is as follows: - - Each value has an associated data type descriptor. The descriptor takes 4-bits, - and two descriptors are packed into one byte. The double-descriptor is followed - by the data bytes needed to store the corresponding value. Two sample layouts are: - - [D2, D1] [V1] ... [V1] [V2] ... [V2] - [D2, D1] [V1] ... [V1] [V2] ... [V2] [0, D3] [V3] ... [V3] - - where D1, D2, D3 denotes the data type descriptors, and V1, V2 and V3 - denotes the bytes where the corresponding values are stored. If there is an odd - number of data descriptors, then a zero data descriptor TYPE_END - is inserted. - - Each data type (except arrays) uses a fixed number of bytes to store the value. - For arrays, the first byte of the array holds the data type of the array (higer - 4 bits) and the length of the array (lower 4 bits). The actual data follows - this first byte. -*/ - - async command bool DiagMsg.record() - { - atomic - { - // currently recording or no more space - if( state != STATE_READY ) - return FALSE; - - state = STATE_RECORDING_FIRST; - nextData = 0; - } - - return TRUE; - } - - /** - * Allocates space in the message for size bytes - * and sets the type information to type. - * Returns the index in msg.data where the data - * should be stored or -1 if no more space is avaliable. - */ - int8_t allocate(uint8_t size, uint8_t type) - { - int8_t ret = -1; - - if( state == STATE_RECORDING_FIRST ) - { - if( nextData + 1 + size <= TOSH_DATA_LENGTH ) - { - state = STATE_RECORDING_SECOND; - - prevType = nextData++; - ((uint8_t*) &(recording->data))[prevType] = type; - ret = nextData; - nextData += size; - } - else - state = STATE_MSG_FULL; - } - else if( state == STATE_RECORDING_SECOND ) - { - if( nextData + size <= TOSH_DATA_LENGTH ) - { - state = STATE_RECORDING_FIRST; - - ((uint8_t*) &(recording->data))[prevType] += (type << 4); - ret = nextData; - nextData += size; - } - else - state = STATE_MSG_FULL; - } - - return ret; - } - -#define IMPLEMENT(NAME, TYPE, TYPE2) \ - async command void DiagMsg.NAME(TYPE value) \ - { \ - int8_t start = allocate(sizeof(TYPE), TYPE2); \ - if( start >= 0 ) \ - *(TYPE*)((uint8_t*) &(recording->data) + start) = value; \ - } \ - async command void DiagMsg.NAME##s(const TYPE *value, uint8_t len) \ - { \ - int8_t start; \ - if( len > 15 ) len = 15; \ - start = allocate(sizeof(TYPE)*len + 1, TYPE_ARRAY); \ - if( start >= 0 ) \ - { \ - ((uint8_t*) &(recording->data))[start++] = (TYPE2 << 4) + len; \ - while( len-- != 0 ) \ - ((TYPE*)((uint8_t*) &(recording->data) + start))[len] = value[len]; \ - } \ - } - - IMPLEMENT(int8, int8_t, TYPE_INT8) - IMPLEMENT(uint8, uint8_t, TYPE_UINT8) - IMPLEMENT(hex8, uint8_t, TYPE_HEX8) - IMPLEMENT(int16, int16_t, TYPE_INT16) - IMPLEMENT(uint16, uint16_t, TYPE_UINT16) - IMPLEMENT(hex16, uint16_t, TYPE_HEX16) - IMPLEMENT(int32, int32_t, TYPE_INT32) - IMPLEMENT(uint32, uint32_t, TYPE_UINT32) - IMPLEMENT(hex32, uint32_t, TYPE_HEX32) - IMPLEMENT(int64, int64_t, TYPE_INT64) - IMPLEMENT(uint64, uint64_t, TYPE_UINT64) - IMPLEMENT(real, float, TYPE_FLOAT) - IMPLEMENT(chr, char, TYPE_CHAR) - - async command void DiagMsg.str(const char* str) - { - int8_t len = 0; - while( str[len] != 0 && len < 15 ) - ++len; - - call DiagMsg.chrs(str, len); - } - - // TODO: this is a hack because setPayloadLength should be async - inline void setPayloadLength(message_t* msg, uint8_t length) - { - (*(uint8_t*) &(msg->header)) = length; - } - - inline uint8_t getPayloadLength(message_t* msg) - { - return *(uint8_t*) &(msg->header); - } - - task void send() - { - message_t* msg; - - atomic msg = sending; - - if( call AMSend.send(DIAGMSG_BASE_STATION, msg, getPayloadLength(msg)) != SUCCESS ) - post send(); - } - - // calculates the next message_t pointer in the msgs circular buffer - static inline message_t* nextPointer(message_t* ptr) - { - if( ++ptr >= msgs + DIAGMSG_RECORDED_MSGS ) - return msgs; - else - return ptr; - } - - async command void DiagMsg.send() - { - // no message recorded - if( state == STATE_READY ) - return; - - // store the length - setPayloadLength(recording, nextData); - - atomic - { - if( sending == 0 ) - { - sending = recording; - retries = DIAGMSG_RETRY_COUNT; - post send(); - } - - recording = nextPointer(recording); - - if( recording == sending ) - state = STATE_BUFFER_FULL; - else - state = STATE_READY; - } - } - - event void AMSend.sendDone(message_t* p, error_t error) - { - atomic - { - // retry if not successful - if( error != SUCCESS && --retries > 0 ) - post send(); - else - { - p = nextPointer(sending); - if( p != recording ) - { - sending = p; - retries = DIAGMSG_RETRY_COUNT; - post send(); - } - else - { - sending = 0; - - if( state == STATE_BUFFER_FULL ) - { - state = STATE_READY; - if( call DiagMsg.record() ) - { - call DiagMsg.str("DiagMsgOverflow"); - call DiagMsg.send(); - } - } - } - } - } - } -} diff --git a/tos/lib/diagmsg/DiagMsgP.nc b/tos/lib/diagmsg/DiagMsgP.nc new file mode 100644 index 00000000..371063c0 --- /dev/null +++ b/tos/lib/diagmsg/DiagMsgP.nc @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2002-2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +#include + +module DiagMsgP +{ + provides + { + interface DiagMsg; + interface Init; + } + + uses + { + interface AMSend; + interface Packet; + } +} + +#ifndef DIAGMSG_BASE_STATION +#define DIAGMSG_BASE_STATION AM_BROADCAST_ADDR +#endif + +#ifndef DIAGMSG_RETRY_COUNT +#define DIAGMSG_RETRY_COUNT 2 +#endif + +#ifndef DIAGMSG_RECORDED_MSGS +#define DIAGMSG_RECORDED_MSGS 10 +#endif + +implementation +{ + enum + { + STATE_READY = 1, + STATE_RECORDING_FIRST = 2, // recording the first 4-bit descriptor + STATE_RECORDING_SECOND = 3, // recording the second 4-bit descriptor + STATE_MSG_FULL = 4, + STATE_BUFFER_FULL = 5, + }; + + norace volatile uint8_t state; // the state of the recording + + message_t msgs[DIAGMSG_RECORDED_MSGS]; // circular buffer of messages + + norace message_t *recording; // the message that is beeing or going to be recorded + message_t *sending; // the message that is beeing sent, or the null pointer + + norace uint8_t nextData; // points to the next unsued byte + norace uint8_t prevType; // points to the type descriptor + norace uint8_t retries; // number of remaining retries + + command error_t Init.init() + { + state = STATE_READY; + recording = msgs; + sending = 0; + + return SUCCESS; + } + + // two type fields are stored in on byte + enum + { + TYPE_END = 0, + TYPE_INT8 = 1, + TYPE_UINT8 = 2, + TYPE_HEX8 = 3, + TYPE_INT16 = 4, + TYPE_UINT16 = 5, + TYPE_HEX16 = 6, + TYPE_INT32 = 7, + TYPE_UINT32 = 8, + TYPE_HEX32 = 9, + TYPE_FLOAT = 10, + TYPE_CHAR = 11, + TYPE_INT64 = 12, + TYPE_UINT64 = 13, + TYPE_ARRAY = 15, + }; + +/* + The format of the payload is as follows: + + Each value has an associated data type descriptor. The descriptor takes 4-bits, + and two descriptors are packed into one byte. The double-descriptor is followed + by the data bytes needed to store the corresponding value. Two sample layouts are: + + [D2, D1] [V1] ... [V1] [V2] ... [V2] + [D2, D1] [V1] ... [V1] [V2] ... [V2] [0, D3] [V3] ... [V3] + + where D1, D2, D3 denotes the data type descriptors, and V1, V2 and V3 + denotes the bytes where the corresponding values are stored. If there is an odd + number of data descriptors, then a zero data descriptor TYPE_END + is inserted. + + Each data type (except arrays) uses a fixed number of bytes to store the value. + For arrays, the first byte of the array holds the data type of the array (higer + 4 bits) and the length of the array (lower 4 bits). The actual data follows + this first byte. +*/ + + async command bool DiagMsg.record() + { + atomic + { + // currently recording or no more space + if( state != STATE_READY ) + return FALSE; + + state = STATE_RECORDING_FIRST; + nextData = 0; + } + + return TRUE; + } + + /** + * Allocates space in the message for size bytes + * and sets the type information to type. + * Returns the index in msg.data where the data + * should be stored or -1 if no more space is avaliable. + */ + int8_t allocate(uint8_t size, uint8_t type) + { + int8_t ret = -1; + + if( state == STATE_RECORDING_FIRST ) + { + if( nextData + 1 + size <= TOSH_DATA_LENGTH ) + { + state = STATE_RECORDING_SECOND; + + prevType = nextData++; + ((uint8_t*) &(recording->data))[prevType] = type; + ret = nextData; + nextData += size; + } + else + state = STATE_MSG_FULL; + } + else if( state == STATE_RECORDING_SECOND ) + { + if( nextData + size <= TOSH_DATA_LENGTH ) + { + state = STATE_RECORDING_FIRST; + + ((uint8_t*) &(recording->data))[prevType] += (type << 4); + ret = nextData; + nextData += size; + } + else + state = STATE_MSG_FULL; + } + + return ret; + } + +#define IMPLEMENT(NAME, TYPE, TYPE2) \ + async command void DiagMsg.NAME(TYPE value) \ + { \ + int8_t start = allocate(sizeof(TYPE), TYPE2); \ + if( start >= 0 ) \ + *(TYPE*)((uint8_t*) &(recording->data) + start) = value; \ + } \ + async command void DiagMsg.NAME##s(const TYPE *value, uint8_t len) \ + { \ + int8_t start; \ + if( len > 15 ) len = 15; \ + start = allocate(sizeof(TYPE)*len + 1, TYPE_ARRAY); \ + if( start >= 0 ) \ + { \ + ((uint8_t*) &(recording->data))[start++] = (TYPE2 << 4) + len; \ + while( len-- != 0 ) \ + ((TYPE*)((uint8_t*) &(recording->data) + start))[len] = value[len]; \ + } \ + } + + IMPLEMENT(int8, int8_t, TYPE_INT8) + IMPLEMENT(uint8, uint8_t, TYPE_UINT8) + IMPLEMENT(hex8, uint8_t, TYPE_HEX8) + IMPLEMENT(int16, int16_t, TYPE_INT16) + IMPLEMENT(uint16, uint16_t, TYPE_UINT16) + IMPLEMENT(hex16, uint16_t, TYPE_HEX16) + IMPLEMENT(int32, int32_t, TYPE_INT32) + IMPLEMENT(uint32, uint32_t, TYPE_UINT32) + IMPLEMENT(hex32, uint32_t, TYPE_HEX32) + IMPLEMENT(int64, int64_t, TYPE_INT64) + IMPLEMENT(uint64, uint64_t, TYPE_UINT64) + IMPLEMENT(real, float, TYPE_FLOAT) + IMPLEMENT(chr, char, TYPE_CHAR) + + async command void DiagMsg.str(const char* str) + { + int8_t len = 0; + while( str[len] != 0 && len < 15 ) + ++len; + + call DiagMsg.chrs(str, len); + } + + // TODO: this is a hack because setPayloadLength should be async + inline void setPayloadLength(message_t* msg, uint8_t length) + { + (*(uint8_t*) &(msg->header)) = length; + } + + inline uint8_t getPayloadLength(message_t* msg) + { + return *(uint8_t*) &(msg->header); + } + + task void send() + { + message_t* msg; + + atomic msg = sending; + + if( call AMSend.send(DIAGMSG_BASE_STATION, msg, getPayloadLength(msg)) != SUCCESS ) + post send(); + } + + // calculates the next message_t pointer in the msgs circular buffer + static inline message_t* nextPointer(message_t* ptr) + { + if( ++ptr >= msgs + DIAGMSG_RECORDED_MSGS ) + return msgs; + else + return ptr; + } + + async command void DiagMsg.send() + { + // no message recorded + if( state == STATE_READY ) + return; + + // store the length + setPayloadLength(recording, nextData); + + atomic + { + if( sending == 0 ) + { + sending = recording; + retries = DIAGMSG_RETRY_COUNT; + post send(); + } + + recording = nextPointer(recording); + + if( recording == sending ) + state = STATE_BUFFER_FULL; + else + state = STATE_READY; + } + } + + event void AMSend.sendDone(message_t* p, error_t error) + { + atomic + { + // retry if not successful + if( error != SUCCESS && --retries > 0 ) + post send(); + else + { + p = nextPointer(sending); + if( p != recording ) + { + sending = p; + retries = DIAGMSG_RETRY_COUNT; + post send(); + } + else + { + sending = 0; + + if( state == STATE_BUFFER_FULL ) + { + state = STATE_READY; + if( call DiagMsg.record() ) + { + call DiagMsg.str("DiagMsgOverflow"); + call DiagMsg.send(); + } + } + } + } + } + } +}