Bugfix and optimization: X-MAC did not properly switch the radio off after sending a packet, resulting in increased power consumption. For packets that require an ACK, we can let the radio be on in anticipation of the ACK (controlled with an WITH_ACK_OPTIMIZATION option)
This commit is contained in:
parent
64badeb282
commit
dc7491f810
1 changed files with 24 additions and 15 deletions
|
@ -28,7 +28,7 @@
|
|||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
* $Id: xmac.c,v 1.26 2009/03/01 20:38:57 adamdunkels Exp $
|
||||
* $Id: xmac.c,v 1.27 2009/03/05 19:37:52 adamdunkels Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -63,6 +63,7 @@
|
|||
#define WITH_CHANNEL_CHECK 0 /* Seems to work badly when enabled */
|
||||
#define WITH_TIMESYNCH 0
|
||||
#define WITH_QUEUE 0
|
||||
#define WITH_ACK_OPTIMIZATION 1
|
||||
|
||||
struct announcement_data {
|
||||
uint16_t id;
|
||||
|
@ -353,7 +354,7 @@ send_packet(void)
|
|||
rtimer_clock_t t;
|
||||
int strobes;
|
||||
struct xmac_hdr hdr;
|
||||
int got_ack = 0;
|
||||
int got_strobe_ack = 0;
|
||||
struct {
|
||||
struct xmac_hdr hdr;
|
||||
struct announcement_msg announcement;
|
||||
|
@ -421,9 +422,9 @@ send_packet(void)
|
|||
}
|
||||
|
||||
watchdog_stop();
|
||||
got_ack = 0;
|
||||
got_strobe_ack = 0;
|
||||
for(strobes = 0;
|
||||
got_ack == 0 &&
|
||||
got_strobe_ack == 0 &&
|
||||
RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_time);
|
||||
strobes++) {
|
||||
|
||||
|
@ -444,7 +445,7 @@ send_packet(void)
|
|||
|
||||
CPRINTF("+");
|
||||
|
||||
while(got_ack == 0 &&
|
||||
while(got_strobe_ack == 0 &&
|
||||
RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time)) {
|
||||
/* See if we got an ACK */
|
||||
len = radio->read((uint8_t *)&strobe, sizeof(struct xmac_hdr));
|
||||
|
@ -458,7 +459,7 @@ send_packet(void)
|
|||
CPRINTF("@");
|
||||
/* We got an ACK from the receiver, so we can immediately send
|
||||
the packet. */
|
||||
got_ack = 1;
|
||||
got_strobe_ack = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -466,28 +467,37 @@ send_packet(void)
|
|||
/* XXX: turn off radio if we haven't heard an ACK within a
|
||||
specified time interval. */
|
||||
|
||||
/* if(got_ack == 0) {
|
||||
/* if(got_strobe_ack == 0) {
|
||||
off();
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time));
|
||||
on();
|
||||
}*/
|
||||
}
|
||||
|
||||
if(got_ack /* XXX && needs_ack */) {
|
||||
/* If we have received the strobe ACK, and we are sending a packet
|
||||
that will need an upper layer ACK (as signified by the
|
||||
RIMEBUF_ATTR_RELIABLE packet attribute), we keep the radio on. */
|
||||
if(got_strobe_ack && rimebuf_attr(RIMEBUF_ATTR_RELIABLE)) {
|
||||
#if WITH_TIMETABLE
|
||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send got ack");
|
||||
#endif
|
||||
on(); /* Wait for possible ACK packet */
|
||||
} else if(!is_broadcast) {
|
||||
#if WITH_ACK_OPTIMIZATION
|
||||
on(); /* Wait for ACK packet */
|
||||
waiting_for_packet = 1;
|
||||
#else /* WITH_ACK_OPTIMIZATION */
|
||||
off();
|
||||
#endif /* WITH_ACK_OPTIMIZATION */
|
||||
|
||||
} else {
|
||||
#if WITH_TIMETABLE
|
||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send no ack received");
|
||||
#endif
|
||||
on(); /* shell ping don't seem to work with off() here, so we'll
|
||||
off(); /* shell ping don't seem to work with off() here, so we'll
|
||||
keep it on() for a while. */
|
||||
}
|
||||
|
||||
/* Send the data packet. */
|
||||
if(is_broadcast || got_ack) {
|
||||
if(is_broadcast || got_strobe_ack) {
|
||||
#if WITH_TIMETABLE
|
||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send packet");
|
||||
#endif
|
||||
|
@ -497,7 +507,7 @@ send_packet(void)
|
|||
watchdog_start();
|
||||
|
||||
PRINTF("xmac: send (strobes=%u,len=%u,%s), done\n", strobes,
|
||||
rimebuf_totlen(), got_ack ? "ack" : "no ack");
|
||||
rimebuf_totlen(), got_strobe_ack ? "ack" : "no ack");
|
||||
|
||||
#if XMAC_CONF_COMPOWER
|
||||
/* Accumulate the power consumption for the packet transmission. */
|
||||
|
@ -566,7 +576,7 @@ read_packet(void)
|
|||
rimebuf_clear();
|
||||
|
||||
len = radio->read(rimebuf_dataptr(), RIMEBUF_SIZE);
|
||||
|
||||
|
||||
if(len > 0) {
|
||||
rimebuf_set_datalen(len);
|
||||
hdr = rimebuf_dataptr();
|
||||
|
@ -640,7 +650,6 @@ read_packet(void)
|
|||
#if XMAC_CONF_COMPOWER
|
||||
/* Accumulate the power consumption for the packet reception. */
|
||||
compower_accumulate(¤t_packet);
|
||||
|
||||
/* Convert the accumulated power consumption for the received
|
||||
packet to packet attributes so that the higher levels can
|
||||
keep track of the amount of energy spent on receiving the
|
||||
|
|
Loading…
Reference in a new issue