Skip to content

Commit 51f8328

Browse files
author
Jarkko Paso
authored
Merge pull request ARMmbed#1803 from ARMmbed/IOTTHD-2736
Iotthd 2736
2 parents c6e2457 + 537b60d commit 51f8328

File tree

7 files changed

+96
-46
lines changed

7 files changed

+96
-46
lines changed

source/Service_Libs/fhss/fhss.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#define TRACE_GROUP "fhss"
3636

37+
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
3738
static int fhss_reset(fhss_structure_t *fhss_structure);
3839
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure);
3940
static bool fhss_check_remaining_tx_time(fhss_structure_t *fhss_structure, uint16_t tx_length, uint8_t phy_header_length, uint8_t phy_tail_length);
@@ -67,6 +68,7 @@ fhss_structure_t *fhss_enable(fhss_api_t *fhss_api, const fhss_configuration_t *
6768
}
6869
memset(fhss_struct->bs, 0, sizeof(fhss_bs_t));
6970

71+
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
7072
fhss_struct->bs->fhss_configuration = *fhss_configuration;
7173
fhss_struct->bs->fhss_stats_ptr = fhss_statistics;
7274
fhss_struct->number_of_channels = channel_count;
@@ -99,6 +101,15 @@ bool fhss_is_synch_root(fhss_structure_t *fhss_structure)
99101
return true;
100102
}
101103

104+
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
105+
{
106+
(void) slots;
107+
fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
108+
if (fhss_structure) {
109+
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
110+
}
111+
}
112+
102113
static bool fhss_is_bc_sending_superframe(fhss_structure_t *fhss_structure)
103114
{
104115
if (fhss_structure->bs->current_superframe >= fhss_structure->bs->broadcast_start_superframe) {

source/Service_Libs/fhss/fhss_common.c

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434

3535
static fhss_structure_t *fhss_struct = NULL;
3636

37-
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
38-
static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id);
3937
static void fhss_set_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
4038
static bool fhss_read_active_event(fhss_structure_t *fhss_structure, uint8_t event_type);
4139

@@ -52,7 +50,6 @@ fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_
5250
memset(fhss_struct, 0, sizeof(fhss_structure_t));
5351
fhss_struct->fhss_api = fhss_api;
5452
fhss_struct->platform_functions = *fhss_timer;
55-
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
5653
if (!fhss_struct->platform_functions.fhss_resolution_divider) {
5754
fhss_struct->platform_functions.fhss_resolution_divider = 1;
5855
}
@@ -69,16 +66,7 @@ int8_t fhss_free_instance(fhss_api_t *fhss_api)
6966
return 0;
7067
}
7168

72-
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
73-
{
74-
(void) slots;
75-
fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
76-
if (fhss_structure) {
77-
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
78-
}
79-
}
80-
81-
static fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
69+
fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
8270
{
8371
if (timer_id < 0 || !fhss_struct) {
8472
return NULL;

source/Service_Libs/fhss/fhss_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct fhss_structure
5454
uint8_t synch_parent[8];
5555
};
5656

57+
fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id);
5758
fhss_structure_t *fhss_allocate_instance(fhss_api_t *fhss_api, const fhss_timer_t *fhss_timer);
5859
int8_t fhss_free_instance(fhss_api_t *fhss_api);
5960
int8_t fhss_set_datarate(fhss_structure_t *fhss_structure, uint32_t datarate);

source/Service_Libs/fhss/fhss_ws.c

Lines changed: 73 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ struct ws_ie_t {
5757
uint8_t id;
5858
};
5959

60+
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots);
6061
static void fhss_ws_update_uc_channel_callback(fhss_structure_t *fhss_structure);
6162
static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay);
62-
static void fhss_ws_start_tx_poll_timer(fhss_structure_t *fhss_structure, uint16_t queue_size, uint8_t channel_dwell_interval);
63+
static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure);
64+
static uint8_t fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure);
6365

6466
fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configuration_t *fhss_configuration, const fhss_timer_t *fhss_timer)
6567
{
@@ -83,13 +85,25 @@ fhss_structure_t *fhss_ws_enable(fhss_api_t *fhss_api, const fhss_ws_configurati
8385
}
8486
memset(fhss_struct->ws, 0, sizeof(fhss_ws_t));
8587

88+
fhss_struct->fhss_event_timer = eventOS_callback_timer_register(fhss_event_timer_cb);
8689
fhss_struct->ws->fhss_configuration = *fhss_configuration;
8790
fhss_struct->number_of_channels = channel_count;
8891
fhss_struct->own_hop = 0xff;
92+
fhss_set_txrx_slot_length(fhss_struct);
8993
ns_list_init(&fhss_struct->fhss_failed_tx_list);
9094
return fhss_struct;
9195
}
9296

97+
static uint8_t fhss_set_txrx_slot_length(fhss_structure_t *fhss_structure)
98+
{
99+
uint8_t number_of_tx_slots = ((fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / WS_MAX_TXRX_SLOT_LEN_MS) / 2;
100+
if (!number_of_tx_slots) {
101+
return 0;
102+
}
103+
fhss_structure->ws->txrx_slot_length_ms = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / (number_of_tx_slots * 2);
104+
return number_of_tx_slots;
105+
}
106+
93107
static int32_t fhss_ws_calc_bc_channel(fhss_structure_t *fhss_structure)
94108
{
95109
int32_t next_channel = fhss_structure->rx_channel;
@@ -130,12 +144,37 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
130144
fhss_start_timer(fhss_structure, fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval*1000 - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
131145
fhss_structure->ws->is_on_bc_channel = true;
132146
next_channel = fhss_structure->ws->bc_channel = fhss_ws_calc_bc_channel(fhss_structure);
147+
148+
/* Start timer with random timeout to trigger broadcast TX queue poll event.
149+
* Min random is 1/50 of the channel dwell interval.
150+
* Max random is 1/10 of the channel dwell interval.
151+
* Event timer resolution is 50us.
152+
*/
153+
uint32_t bc_dwell_us = fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval*1000;
154+
uint16_t bc_min_random = (bc_dwell_us / 50) / 50;
155+
uint16_t bc_max_random = (bc_dwell_us / 10) / 50;
156+
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(bc_min_random, bc_max_random));
133157
} else {
134158
uint32_t timeout = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) * 1000;
135159
fhss_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_broadcast_handler);
136160
fhss_structure->ws->is_on_bc_channel = false;
137161
// Should return to own (unicast) listening channel after broadcast channel
138162
next_channel = fhss_structure->rx_channel;
163+
/* Start timer with random timeout to trigger unicast TX queue poll event.
164+
* Min random is 50us.
165+
* Max random is 1/10 of the TX slot length.
166+
* Event timer resolution is 50us.
167+
*/
168+
uint32_t txrx_slot_length_us = fhss_structure->ws->txrx_slot_length_ms * 1000;
169+
uint16_t uc_min_random = 1;
170+
uint16_t uc_max_random = (txrx_slot_length_us / 10) / 50;
171+
bool tx_allowed = fhss_ws_check_tx_allowed(fhss_structure);
172+
if (!tx_allowed) {
173+
uc_min_random += (txrx_slot_length_us)/50;
174+
uc_max_random += (txrx_slot_length_us)/50;
175+
}
176+
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(uc_min_random, uc_max_random));
177+
139178
#ifdef FHSS_CHANNEL_DEBUG
140179
tr_info("%"PRIu32" UC %u", fhss_structure->platform_functions.fhss_get_timestamp(fhss_structure->fhss_api), fhss_structure->rx_channel);
141180
#endif /*FHSS_CHANNEL_DEBUG*/
@@ -146,8 +185,6 @@ static void fhss_broadcast_handler(const fhss_api_t *fhss_api, uint16_t delay)
146185
fhss_bc_switch();
147186
}
148187
#endif /*FHSS_CHANNEL_DEBUG_CBS*/
149-
fhss_ws_start_tx_poll_timer(fhss_structure, fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true),
150-
fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval);
151188
}
152189

153190
static int own_floor(float value)
@@ -164,6 +201,28 @@ static int own_ceil(float value)
164201
return ivalue + 1;
165202
}
166203

204+
static void fhss_event_timer_cb(int8_t timer_id, uint16_t slots)
205+
{
206+
(void) slots;
207+
uint16_t queue_size = 0;
208+
fhss_structure_t *fhss_structure = fhss_get_object_with_timer_id(timer_id);
209+
210+
211+
if (fhss_structure->ws->is_on_bc_channel == true) {
212+
queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, true);
213+
} else {
214+
// On unicast, start timer to trigger polling event on next TX slot
215+
uint32_t delay_between_tx_slots_us = fhss_structure->ws->txrx_slot_length_ms*1000*2;
216+
if (delay_between_tx_slots_us < fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api)) {
217+
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, delay_between_tx_slots_us/50);
218+
}
219+
queue_size = fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false);
220+
}
221+
if (queue_size) {
222+
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
223+
}
224+
}
225+
167226
static uint32_t fhss_ws_calculate_ufsi(fhss_structure_t *fhss_structure, uint32_t tx_time)
168227
{
169228
uint8_t dwell_time = fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval;
@@ -348,23 +407,22 @@ static bool fhss_ws_check_tx_allowed(fhss_structure_t *fhss_structure)
348407
if (fhss_structure->ws->is_on_bc_channel == true) {
349408
return true;
350409
}
351-
uint8_t number_of_tx_slots = ((fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / WS_MAX_TXRX_SLOT_LEN_MS) / 2;
410+
uint8_t number_of_tx_slots = fhss_set_txrx_slot_length(fhss_structure);
352411
// Allow transmission when broadcast interval is very short comparing to MAX slot length
353412
if (!number_of_tx_slots) {
354413
return true;
355414
}
356-
uint32_t slot_len_ms = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) / (number_of_tx_slots * 2);
357415
uint32_t remaining_time_ms = fhss_structure->platform_functions.fhss_get_remaining_slots(fhss_broadcast_handler, fhss_structure->fhss_api) / 1000;
358-
uint32_t tx_slot_begin = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (slot_len_ms * (fhss_structure->own_hop & 1));
359-
uint32_t rx_slot_begin = tx_slot_begin - slot_len_ms;
416+
uint32_t tx_slot_begin = (fhss_structure->ws->fhss_configuration.fhss_broadcast_interval - fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) - (fhss_structure->ws->txrx_slot_length_ms * (fhss_structure->own_hop & 1));
417+
uint32_t rx_slot_begin = tx_slot_begin - fhss_structure->ws->txrx_slot_length_ms;
360418
uint8_t n_o_tx_slots = number_of_tx_slots;
361419

362420
while (n_o_tx_slots--) {
363421
if ((remaining_time_ms <= tx_slot_begin) && (remaining_time_ms > rx_slot_begin)) {
364422
return true;
365423
}
366-
tx_slot_begin -= (2*slot_len_ms);
367-
rx_slot_begin = tx_slot_begin - slot_len_ms;
424+
tx_slot_begin -= (2*fhss_structure->ws->txrx_slot_length_ms);
425+
rx_slot_begin = tx_slot_begin - fhss_structure->ws->txrx_slot_length_ms;
368426
}
369427

370428
return false;
@@ -564,24 +622,12 @@ static void fhss_unicast_handler(const fhss_api_t *fhss_api, uint16_t delay)
564622
timeout = fhss_ws_get_sf_timeout_callback(fhss_structure);
565623
fhss_start_timer(fhss_structure, timeout - (delay * fhss_structure->platform_functions.fhss_resolution_divider), fhss_unicast_handler);
566624
fhss_ws_update_uc_channel_callback(fhss_structure);
567-
fhss_ws_start_tx_poll_timer(fhss_structure, fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false),
568-
fhss_structure->ws->fhss_configuration.fhss_uc_dwell_interval);
569-
}
570-
571-
static void fhss_ws_start_tx_poll_timer(fhss_structure_t *fhss_structure, uint16_t queue_size, uint8_t channel_dwell_interval)
572-
{
573-
if (!queue_size) {
574-
return;
625+
// Unless we have broadcast schedule, we have to poll unicast queue when changing channel. This is randomized by the unicast schedule.
626+
if (!fhss_structure->ws->fhss_configuration.fhss_broadcast_interval || !fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval) {
627+
if (fhss_structure->callbacks.read_tx_queue_size(fhss_structure->fhss_api, false)) {
628+
fhss_structure->callbacks.tx_poll(fhss_structure->fhss_api);
629+
}
575630
}
576-
/* Start timer with random timeout to trigger TX queue poll event.
577-
* Min random is 1/50 of the channel dwell interval.
578-
* Max random is 1/10 of the channel dwell interval.
579-
* Event timer resolution is 50us.
580-
* Divide random with TX queue size to transmit faster when TX queue is growing
581-
*/
582-
uint16_t min_random = ((((uint32_t)channel_dwell_interval * 1000) / 50) / 50) / queue_size;
583-
uint16_t max_random = ((((uint32_t)channel_dwell_interval * 1000) / 10) / 50) / queue_size;
584-
eventOS_callback_timer_start(fhss_structure->fhss_event_timer, randLIB_get_random_in_range(min_random, max_random));
585631
}
586632

587633
int fhss_ws_set_callbacks(fhss_structure_t *fhss_structure)
@@ -623,6 +669,7 @@ int fhss_ws_set_parent(fhss_structure_t *fhss_structure, const uint8_t eui64[8],
623669
// TODO: Calculate drift error
624670
fhss_structure->ws->fhss_configuration.fhss_bc_dwell_interval = bc_timing_info->broadcast_dwell_interval;
625671
fhss_structure->ws->fhss_configuration.fhss_broadcast_interval = bc_timing_info->broadcast_interval;
672+
fhss_set_txrx_slot_length(fhss_structure);
626673
fhss_structure->ws->bc_slot = bc_timing_info->broadcast_slot + slots_since_reception;
627674

628675
//TODO: support multiple parents

source/Service_Libs/fhss/fhss_ws.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct fhss_ws
3030
uint8_t bc_channel;
3131
uint16_t uc_slot;
3232
uint16_t bc_slot;
33+
uint32_t txrx_slot_length_ms;
3334
bool is_on_bc_channel;
3435
struct fhss_ws_configuration fhss_configuration;
3536
const struct broadcast_timing_info *parent_bc_info;

test/nanostack/unittest/service_libs/fhss_common/test_fhss_common.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,6 @@ bool test_fhss_allocate_instance()
8484
if (NULL == fhss_ptr) {
8585
return false;
8686
}
87-
// Test event timer cb with invalid timer id
88-
fhss_ptr->callbacks.tx_poll = &mac_poll_tx_queue;
89-
ns_timer_stub.cb(-1, 10);
90-
// Test event timer cb with random timer id
91-
ns_timer_stub.cb(1, 10);
92-
// Test event timer cb with valid timer id
93-
ns_timer_stub.cb(0, 10);
9487
// Free allocated instance
9588
fhss_free_instance(&fhss_api);
9689

test/nanostack/unittest/stub/fhss_common_stub.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ fhss_structure_t *fhss_get_object_with_api(const fhss_api_t *fhss_api)
5555
return &fhss_common_stub.fhss_struct;
5656
}
5757

58+
fhss_structure_t *fhss_get_object_with_timer_id(const int8_t timer_id)
59+
{
60+
if (fhss_common_stub.bool_value == false) {
61+
return NULL;
62+
}
63+
fhss_common_stub.fhss_struct.fhss_event_timer = timer_id;
64+
return &fhss_common_stub.fhss_struct;
65+
}
66+
5867
void fhss_clear_active_event(fhss_structure_t *fhss_structure, uint8_t event_type)
5968
{
6069

0 commit comments

Comments
 (0)