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
|
@ -28,7 +28,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* 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_CHANNEL_CHECK 0 /* Seems to work badly when enabled */
|
||||||
#define WITH_TIMESYNCH 0
|
#define WITH_TIMESYNCH 0
|
||||||
#define WITH_QUEUE 0
|
#define WITH_QUEUE 0
|
||||||
|
#define WITH_ACK_OPTIMIZATION 1
|
||||||
|
|
||||||
struct announcement_data {
|
struct announcement_data {
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
|
@ -353,7 +354,7 @@ send_packet(void)
|
||||||
rtimer_clock_t t;
|
rtimer_clock_t t;
|
||||||
int strobes;
|
int strobes;
|
||||||
struct xmac_hdr hdr;
|
struct xmac_hdr hdr;
|
||||||
int got_ack = 0;
|
int got_strobe_ack = 0;
|
||||||
struct {
|
struct {
|
||||||
struct xmac_hdr hdr;
|
struct xmac_hdr hdr;
|
||||||
struct announcement_msg announcement;
|
struct announcement_msg announcement;
|
||||||
|
@ -421,9 +422,9 @@ send_packet(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
watchdog_stop();
|
watchdog_stop();
|
||||||
got_ack = 0;
|
got_strobe_ack = 0;
|
||||||
for(strobes = 0;
|
for(strobes = 0;
|
||||||
got_ack == 0 &&
|
got_strobe_ack == 0 &&
|
||||||
RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_time);
|
RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + xmac_config.strobe_time);
|
||||||
strobes++) {
|
strobes++) {
|
||||||
|
|
||||||
|
@ -444,7 +445,7 @@ send_packet(void)
|
||||||
|
|
||||||
CPRINTF("+");
|
CPRINTF("+");
|
||||||
|
|
||||||
while(got_ack == 0 &&
|
while(got_strobe_ack == 0 &&
|
||||||
RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time)) {
|
RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time)) {
|
||||||
/* See if we got an ACK */
|
/* See if we got an ACK */
|
||||||
len = radio->read((uint8_t *)&strobe, sizeof(struct xmac_hdr));
|
len = radio->read((uint8_t *)&strobe, sizeof(struct xmac_hdr));
|
||||||
|
@ -458,7 +459,7 @@ send_packet(void)
|
||||||
CPRINTF("@");
|
CPRINTF("@");
|
||||||
/* We got an ACK from the receiver, so we can immediately send
|
/* We got an ACK from the receiver, so we can immediately send
|
||||||
the packet. */
|
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
|
/* XXX: turn off radio if we haven't heard an ACK within a
|
||||||
specified time interval. */
|
specified time interval. */
|
||||||
|
|
||||||
/* if(got_ack == 0) {
|
/* if(got_strobe_ack == 0) {
|
||||||
off();
|
off();
|
||||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time));
|
while(RTIMER_CLOCK_LT(RTIMER_NOW(), t + xmac_config.strobe_wait_time));
|
||||||
on();
|
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
|
#if WITH_TIMETABLE
|
||||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send got ack");
|
TIMETABLE_TIMESTAMP(xmac_timetable, "send got ack");
|
||||||
#endif
|
#endif
|
||||||
on(); /* Wait for possible ACK packet */
|
#if WITH_ACK_OPTIMIZATION
|
||||||
} else if(!is_broadcast) {
|
on(); /* Wait for ACK packet */
|
||||||
|
waiting_for_packet = 1;
|
||||||
|
#else /* WITH_ACK_OPTIMIZATION */
|
||||||
|
off();
|
||||||
|
#endif /* WITH_ACK_OPTIMIZATION */
|
||||||
|
|
||||||
|
} else {
|
||||||
#if WITH_TIMETABLE
|
#if WITH_TIMETABLE
|
||||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send no ack received");
|
TIMETABLE_TIMESTAMP(xmac_timetable, "send no ack received");
|
||||||
#endif
|
#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. */
|
keep it on() for a while. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the data packet. */
|
/* Send the data packet. */
|
||||||
if(is_broadcast || got_ack) {
|
if(is_broadcast || got_strobe_ack) {
|
||||||
#if WITH_TIMETABLE
|
#if WITH_TIMETABLE
|
||||||
TIMETABLE_TIMESTAMP(xmac_timetable, "send packet");
|
TIMETABLE_TIMESTAMP(xmac_timetable, "send packet");
|
||||||
#endif
|
#endif
|
||||||
|
@ -497,7 +507,7 @@ send_packet(void)
|
||||||
watchdog_start();
|
watchdog_start();
|
||||||
|
|
||||||
PRINTF("xmac: send (strobes=%u,len=%u,%s), done\n", strobes,
|
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
|
#if XMAC_CONF_COMPOWER
|
||||||
/* Accumulate the power consumption for the packet transmission. */
|
/* Accumulate the power consumption for the packet transmission. */
|
||||||
|
@ -566,7 +576,7 @@ read_packet(void)
|
||||||
rimebuf_clear();
|
rimebuf_clear();
|
||||||
|
|
||||||
len = radio->read(rimebuf_dataptr(), RIMEBUF_SIZE);
|
len = radio->read(rimebuf_dataptr(), RIMEBUF_SIZE);
|
||||||
|
|
||||||
if(len > 0) {
|
if(len > 0) {
|
||||||
rimebuf_set_datalen(len);
|
rimebuf_set_datalen(len);
|
||||||
hdr = rimebuf_dataptr();
|
hdr = rimebuf_dataptr();
|
||||||
|
@ -640,7 +650,6 @@ read_packet(void)
|
||||||
#if XMAC_CONF_COMPOWER
|
#if XMAC_CONF_COMPOWER
|
||||||
/* Accumulate the power consumption for the packet reception. */
|
/* Accumulate the power consumption for the packet reception. */
|
||||||
compower_accumulate(¤t_packet);
|
compower_accumulate(¤t_packet);
|
||||||
|
|
||||||
/* Convert the accumulated power consumption for the received
|
/* Convert the accumulated power consumption for the received
|
||||||
packet to packet attributes so that the higher levels can
|
packet to packet attributes so that the higher levels can
|
||||||
keep track of the amount of energy spent on receiving the
|
keep track of the amount of energy spent on receiving the
|
||||||
|
|
Loading…
Reference in a new issue