TSCH: implement burst mode

This commit is contained in:
Simon Duquennoy 2018-03-26 11:15:17 -07:00
parent 644f2ac0f2
commit a5a2a05101
5 changed files with 65 additions and 5 deletions

View File

@ -53,6 +53,7 @@
#define LINK_OPTION_RX 2
#define LINK_OPTION_SHARED 4
#define LINK_OPTION_TIME_KEEPING 8
#define LINK_OPTION_BURST 16
/* Default IEEE 802.15.4e hopping sequences, obtained from https://gist.github.com/twatteyne/2e22ee3c1a802b685695 */
/* 16 channels, sequence length 16 */

View File

@ -459,4 +459,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 << 4);
}
/*---------------------------------------------------------------------------*/
/* Get frame pending bit from a packet */
int
tsch_packet_get_frame_pending(uint8_t *buf, int buf_size)
{
return (buf[0] >> 4) & 1;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -101,6 +101,10 @@ 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);
/* Set frame pending bit in a packet (whose header was already build) */
void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size);
/* Get frame pending bit from a packet */
int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size);
#endif /* __TSCH_PACKET_H__ */
/** @} */

View File

@ -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,13 @@ 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 && (current_link->link_options & LINK_OPTION_BURST)
&& 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 +632,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;
}
@ -844,6 +864,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);
}
}
@ -930,6 +953,8 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
/* Reset drift correction */
drift_correction = 0;
is_drift_correction_used = 0;
/* For the packet burst mechanism */
burst_link_scheduled = 0;
/* Get a packet ready to be sent */
current_packet = get_packet_and_neighbor_for_link(current_link, &current_neighbor);
/* There is no packet to send, and this link does not have Rx flag. Instead of doing
@ -993,13 +1018,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 *********/