[Tinyos-devel] Testing FTSP
Branislav Kusy
kusy at stanford.edu
Fri Aug 15 09:29:04 PDT 2008
ok, seems to work now. 2 hour simulation, 9 motes, high traffic and cpu
load (base station receives more than 100 packets per second):
max abs error: 52 jiffies (happened once, all other errors<20)
avg abs error: 1.21 microsecond (dataset of 1/2 million timestamps)
i haven't changed the logic as miklos wanted me to - i used RX
timestamping queue. the reason is that it is hard to read what miklos
suggested and the situation it protects against doesn't actually seem to
happen. even if it happens (infrequently), FTSP should be able to filter
it out. the plan is to merge FTSP source code with harvard code that
protects against corrupted timestamps. that said, timestamping queue is
not really used since i reset it when it contains more than 1 timestamp.
maybe we should drop it completely.
as for the 65536 errors from the previous run, now i used
inline uint32_t getTime32(uint16_t time) {
uint32_t recent_time=call BackoffTimer.getNow();
return recent_time + (int16_t)(time - recent_time);
}
and moved this code to atomic (reading the recent_time twice didn't
help) - so it seems there is a race in Timer.getNow() function. someone
should look at it.
i'll test it next on telos. i remember while ago that there were
problems with LocalTime on msp430, when the clock source was async. i'm
not sure if it was fixed.
brano
Miklos Maroti wrote:
> Brano,
>
>>> timestamp is correct? I think the timestamp should be set only if
>>> there is a single timestamp in the timestamp queue AND a the RXFIFO is
>>> empty (that is this was the only message timestamped).
>> i only timestamp message if the timestamp queue size is 1, otherwise i clear
>> the timestamp and reset the queue. take a look at CC2420ReceiverP and
>> CC2420TransmitP in contrib/stanford-lgl/apps/tests/TestPacketTimeStamp
>
> I think that is bad logic! You should NOT clear the timestamp
> queue,because then a new message (C) arrives in the RXFIFO and then
> the timestamp queue will contain a single timestamp and then your next
> downloaded message (B) will be associated with the timestamp of the
> latest message (C)! This is BAD! I think you should kill the timestamp
> queue completely, and keep only the timestamp_size which would be
> maintained as before. Only when you switch from 0 to 1, that is when
> you want to timestamp the message. For example you could do the
> following (I do not guarantee that it even compiles):
>
> uint32_t m_timestamp;
> uint8_t m_timestamp_count;
>
> async command void CC2420Receive.sfd( uint32_t time ) {
> if( ++m_timestamp_count == 1 )
> m_timestamp = time;
> else if( m_timestamp_count == 2 )
> m_timestamp_count = 3;
> }
>
> async command void CC2420Receive.sfd_dropped() {
> if ( m_timestamp_count > 3 )
> --m_timestamp_count;
> else
> m_timestamp_count = 0;
> }
>
> async event void RXFIFO.readDone ...
> if ( m_timestamp_count == 1 && rxFrameLength > 10 )
> call PacketTimeStamp.set(m_p_rx_buf, m_timestamp);
> else
> call PacketTimeStamp.clear(m_p_rx_buf);
>
> if ( m_timestamp_count > 3 )
> --m_timestamp_count;
> else
> m_timestamp_count = 0;
>
> void reset_state() {
> m_bytes_left = RXFIFO_SIZE;
> atomic receivingPacket = FALSE;
> m_timestamp_count = 0;
> m_missed_packets = 0;
> }
>
>> the first two fixes didn't help (though i observed decreased frequency of
>> errors). after adding the last fix, i wasn't able to see these errors on
>> micaZ.
>
> Good news.
>
>> clearly, there is a problem in how the timestamp is converted from 16 to 32
>> bits. this is done in CC2420TransmitP.nc (the modified file in
>> TestPacketTimeStamp dir):
>>
>> 239 inline uint32_t time16to32(uint16_t time, uint32_t recent_time)
>> 240 {
>> 241 if ((recent_time&0xFFFF)<time)
>> 242 return ((recent_time-0x10000UL)&0xFFFF0000UL)|time;
>> 243 else
>> 244 return (recent_time&0xFFFF0000UL)|time;
>> 245 }
>
> Replace it with the following code adopted from the RF230 driver:
>
> inline uint32_t time16to32(uint16_t time, uint32_t recent_time)
> {
> return recent_time + ((int16_t)time - (int16_t)receint_time);
> }
>
>> which is called from
>> 260 async event void CaptureSFD.captured( uint16_t time ) {
>> 261 uint32_t time32 = time16to32(time, call BackoffTimer.getNow());
>
>> clearly CaptureSFD.captured() is async, so line 261 should be atomic. do you see any
>> other problems?
>
> Why should it? GetNow must be internally atomic, and then you are
> working on local variables only, so there is no race here.
>
> Miklos
More information about the Tinyos-devel
mailing list