Merge pull request #380 from simonduq/contrib/tsch-burst-mode

TSCH burst mode
This commit is contained in:
Simon Duquennoy 2018-05-14 17:29:20 +02:00 committed by GitHub
commit 73103de195
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 111 additions and 14 deletions

View File

@ -317,6 +317,15 @@
#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL (!(BUILD_WITH_ORCHESTRA))
#endif
/* Set an upper bound on burst length. Set to 0 to never set the frame pending
* bit, i.e., never trigger a burst. Note that receiver-side support for burst
* is always enabled, as it is part of IEEE 802.1.5.4-2015 (Section 7.2.1.3)*/
#ifdef TSCH_CONF_BURST_MAX_LEN
#define TSCH_BURST_MAX_LEN TSCH_CONF_BURST_MAX_LEN
#else
#define TSCH_BURST_MAX_LEN 32
#endif
/* 6TiSCH Minimal schedule slotframe length */
#ifdef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH
#define TSCH_SCHEDULE_DEFAULT_LENGTH TSCH_SCHEDULE_CONF_DEFAULT_LENGTH

View File

@ -82,10 +82,11 @@ tsch_log_process_pending(void)
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link-NULL} ", log->asn.ms1b, log->asn.ls4b);
} else {
struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle);
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u ch %2u} ",
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u %2u ch %2u} ",
log->asn.ms1b, log->asn.ls4b,
log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset,
tsch_calculate_channel(&log->asn, log->link->channel_offset));
log->link->slotframe_handle, sf ? sf->size.val : 0,
log->burst_count, log->link->timeslot + log->burst_count, log->link->channel_offset,
log->channel);
}
switch(log->type) {
case tsch_log_tx:
@ -135,6 +136,8 @@ tsch_log_prepare_add(void)
struct tsch_log_t *log = &log_array[log_index];
log->asn = tsch_current_asn;
log->link = current_link;
log->burst_count = tsch_current_burst_count;
log->channel = tsch_current_channel;
return log;
} else {
log_dropped++;

View File

@ -80,6 +80,8 @@ struct tsch_log_t {
} type;
struct tsch_asn_t asn;
struct tsch_link *link;
uint8_t burst_count;
uint8_t channel;
union {
char message[48];
struct {

View File

@ -70,6 +70,9 @@
*/
static struct packetbuf_attr eackbuf_attrs[PACKETBUF_NUM_ATTRS];
/* The offset of the frame pending bit flag within the first byte of FCF */
#define IEEE802154_FRAME_PENDING_BIT_OFFSET 4
/*---------------------------------------------------------------------------*/
static int
tsch_packet_eackbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
@ -459,4 +462,18 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
return curr_len;
}
/*---------------------------------------------------------------------------*/
/* Set frame pending bit in a packet (whose header was already build) */
void
tsch_packet_set_frame_pending(uint8_t *buf, int buf_size)
{
buf[0] |= (1 << IEEE802154_FRAME_PENDING_BIT_OFFSET);
}
/*---------------------------------------------------------------------------*/
/* Get frame pending bit from a packet */
int
tsch_packet_get_frame_pending(uint8_t *buf, int buf_size)
{
return (buf[0] >> IEEE802154_FRAME_PENDING_BIT_OFFSET) & 1;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -101,6 +101,19 @@ int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offse
int tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
frame802154_t *frame, struct ieee802154_ies *ies,
uint8_t *hdrlen, int frame_without_mic);
/**
* \brief Set frame pending bit in a packet (whose header was already build)
* \param buf The buffer where the packet resides
* \param buf_size The buffer size
*/
void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size);
/**
* \brief Get frame pending bit from a packet
* \param buf The buffer where the packet resides
* \param buf_size The buffer size
* \return The value of the frame pending bit, 1 or 0
*/
int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size);
#endif /* __TSCH_PACKET_H__ */
/** @} */

View File

@ -423,7 +423,7 @@ tsch_schedule_create_minimal(void)
* but is required according to 802.15.4e if also used for EB transmission.
* Timeslot: 0, channel offset: 0. */
tsch_schedule_add_link(sf_min,
LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING,
(LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING),
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
0, 0);
}

View File

@ -155,7 +155,7 @@ static rtimer_clock_t volatile current_slot_start;
static volatile int tsch_in_slot_operation = 0;
/* If we are inside a slot, this tells the current channel */
static uint8_t current_channel;
uint8_t tsch_current_channel;
/* Info about the link, packet and neighbor of
* the current (or next) slot */
@ -167,6 +167,11 @@ static struct tsch_link *backup_link = NULL;
static struct tsch_packet *current_packet = NULL;
static struct tsch_neighbor *current_neighbor = NULL;
/* Indicates whether an extra link is needed to handle the current burst */
static int burst_link_scheduled = 0;
/* Counts the length of the current burst */
int tsch_current_burst_count = 0;
/* Protothread for association */
PT_THREAD(tsch_scan(struct pt *pt));
/* Protothread for slot operation, called from rtimer interrupt
@ -456,6 +461,8 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
/* is this a broadcast packet? (wait for ack?) */
static uint8_t is_broadcast;
static rtimer_clock_t tx_start_time;
/* Did we set the frame pending bit to request an extra burst link? */
static int burst_link_requested;
#if CCA_ENABLED
static uint8_t cca_status;
@ -466,6 +473,14 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet_len = queuebuf_datalen(current_packet->qb);
/* is this a broadcast packet? (wait for ack?) */
is_broadcast = current_neighbor->is_broadcast;
/* Unicast. More packets in queue for the neighbor? */
burst_link_requested = 0;
if(!is_broadcast
&& tsch_current_burst_count + 1 < TSCH_BURST_MAX_LEN
&& tsch_queue_packet_count(&current_neighbor->addr) > 1) {
burst_link_requested = 1;
tsch_packet_set_frame_pending(packet, packet_len);
}
/* read seqno from payload */
seqno = ((uint8_t *)(packet))[2];
/* if this is an EB, then update its Sync-IE */
@ -618,6 +633,12 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
tsch_schedule_keepalive();
}
mac_tx_status = MAC_TX_OK;
/* We requested an extra slot and got an ack. This means
the extra slot will be scheduled at the received */
if(burst_link_requested) {
burst_link_scheduled = 1;
}
} else {
mac_tx_status = MAC_TX_NOACK;
}
@ -749,7 +770,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi);
current_input->rx_asn = tsch_current_asn;
current_input->rssi = (signed)radio_last_rssi;
current_input->channel = current_channel;
current_input->channel = tsch_current_channel;
header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame);
frame_valid = header_len > 0 &&
frame802154_check_dest_panid(&frame) &&
@ -844,6 +865,9 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
TSCH_DEBUG_RX_EVENT();
NETSTACK_RADIO.transmit(ack_len);
tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT);
/* Schedule a burst link iff the frame pending bit was set */
burst_link_scheduled = tsch_packet_get_frame_pending(current_input->payload, current_input->len);
}
}
@ -940,9 +964,16 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
}
is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX);
if(is_active_slot) {
/* Hop channel */
current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset);
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel);
/* If we are in a burst, we stick to current channel instead of
* doing channel hopping, as per IEEE 802.15.4-2015 */
if(burst_link_scheduled) {
/* Reset burst_link_scheduled flag. Will be set again if burst continue. */
burst_link_scheduled = 0;
} else {
/* Hop channel */
tsch_current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset);
}
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, tsch_current_channel);
/* Turn the radio on already here if configured so; necessary for radios with slow startup */
tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT);
/* Decide whether it is a TX/RX/IDLE or OFF slot */
@ -960,6 +991,10 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
static struct pt slot_rx_pt;
PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t));
}
} else {
/* Make sure to end the burst in cast, for some reason, we were
* in a burst but now without any more packet to send. */
burst_link_scheduled = 0;
}
TSCH_DEBUG_SLOT_END();
}
@ -993,13 +1028,27 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
tsch_queue_update_all_backoff_windows(&current_link->addr);
}
/* Get next active link */
current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, &timeslot_diff, &backup_link);
if(current_link == NULL) {
/* There is no next link. Fall back to default
* behavior: wake up at the next slot. */
/* A burst link was scheduled. Replay the current link at the
next time offset */
if(burst_link_scheduled) {
timeslot_diff = 1;
backup_link = NULL;
/* Keep track of the number of repetitions */
tsch_current_burst_count++;
} else {
/* Get next active link */
current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, &timeslot_diff, &backup_link);
if(current_link == NULL) {
/* There is no next link. Fall back to default
* behavior: wake up at the next slot. */
timeslot_diff = 1;
} else {
/* Reset burst index now that the link was scheduled from
normal schedule (as opposed to from ongoing burst) */
tsch_current_burst_count = 0;
}
}
/* Update ASN */
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
/* Time to next wake up */

View File

@ -57,6 +57,8 @@ extern struct ringbufindex input_ringbuf;
extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
/* Last clock_time_t where synchronization happened */
extern clock_time_t last_sync_time;
/* Counts the length of the current burst */
extern int tsch_current_burst_count;
/********** Functions *********/

View File

@ -164,6 +164,8 @@ extern const linkaddr_t tsch_eb_address;
extern struct tsch_asn_t tsch_current_asn;
extern uint8_t tsch_join_priority;
extern struct tsch_link *current_link;
/* If we are inside a slot, this tells the current channel */
extern uint8_t tsch_current_channel;
/* TSCH channel hopping sequence */
extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN];
extern struct tsch_asn_divisor_t tsch_hopping_sequence_length;