Bug fix for mysterious packet loss : check FIFO pin instead of FIFOP pin for any unread RX FIFO data;

Added protection of packet timestamp across interrupts. Note that race condition can still occur as interrupts and self-scheduled reads of the RX FIFO interleave in certain unusual patterns. More investigation is needed.
This commit is contained in:
zhitao 2009-12-11 18:32:54 +00:00
parent a628b0c581
commit 93c748cc74

View file

@ -28,7 +28,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* @(#)$Id: cc2420.c,v 1.35 2009/11/13 10:07:53 fros4943 Exp $ * @(#)$Id: cc2420.c,v 1.36 2009/12/11 18:32:54 zhitao Exp $
*/ */
/* /*
* This code is almost device independent and should be easy to port. * This code is almost device independent and should be easy to port.
@ -572,8 +572,10 @@ int
cc2420_interrupt(void) cc2420_interrupt(void)
{ {
#if CC2420_CONF_TIMESTAMPS #if CC2420_CONF_TIMESTAMPS
interrupt_time = timesynch_time(); if(!interrupt_time_set) {
interrupt_time_set = 1; interrupt_time = timesynch_time();
interrupt_time_set = 1;
}
#endif /* CC2420_CONF_TIMESTAMPS */ #endif /* CC2420_CONF_TIMESTAMPS */
CLEAR_FIFOP_INT(); CLEAR_FIFOP_INT();
@ -627,20 +629,11 @@ cc2420_read(void *buf, unsigned short bufsize)
struct timestamp t; struct timestamp t;
#endif /* CC2420_CONF_TIMESTAMPS */ #endif /* CC2420_CONF_TIMESTAMPS */
if(!FIFOP_IS_1) { if(!FIFO_IS_1) {
/* If FIFOP is 0, there is no packet in the RXFIFO. */ /* If FIFO is 0, there is no packet in the RXFIFO. */
return 0; return 0;
} }
#if CC2420_CONF_TIMESTAMPS
if(interrupt_time_set) {
cc2420_time_of_arrival = interrupt_time;
interrupt_time_set = 0;
} else {
cc2420_time_of_arrival = 0;
}
cc2420_time_of_departure = 0;
#endif /* CC2420_CONF_TIMESTAMPS */
GET_LOCK(); GET_LOCK();
getrxbyte(&len); getrxbyte(&len);
@ -697,12 +690,19 @@ cc2420_read(void *buf, unsigned short bufsize)
RIMESTATS_ADD(llrx); RIMESTATS_ADD(llrx);
#if CC2420_CONF_TIMESTAMPS #if CC2420_CONF_TIMESTAMPS
cc2420_time_of_departure = if(interrupt_time_set) {
t.time + cc2420_time_of_arrival = interrupt_time;
setup_time_for_transmission + cc2420_time_of_departure =
(total_time_for_transmission * (len - 2)) / total_transmission_len; t.time +
setup_time_for_transmission +
(total_time_for_transmission * (len - 2)) / total_transmission_len;
cc2420_authority_level_of_sender = t.authority_level; cc2420_authority_level_of_sender = t.authority_level;
interrupt_time_set = 0;
} else {
/* Bypass timesynch */
cc2420_authority_level_of_sender = timesynch_authority_level();
}
packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, t.time); packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, t.time);
#endif /* CC2420_CONF_TIMESTAMPS */ #endif /* CC2420_CONF_TIMESTAMPS */
@ -718,7 +718,7 @@ cc2420_read(void *buf, unsigned short bufsize)
if(FIFOP_IS_1 && !FIFO_IS_1) { if(FIFOP_IS_1 && !FIFO_IS_1) {
/* printf("cc2420_read: FIFOP_IS_1 1\n");*/ /* printf("cc2420_read: FIFOP_IS_1 1\n");*/
flushrx(); flushrx();
} else if(FIFOP_IS_1) { } else if(FIFO_IS_1) {
/* Another packet has been received and needs attention. */ /* Another packet has been received and needs attention. */
process_poll(&cc2420_process); process_poll(&cc2420_process);
} }