Skip to content

Commit 160b5f2

Browse files
Daniel Jaecklemluis1
authored andcommitted
Issue #873 - Refactored and improved the way the duty-cycle management is handled.
1 parent b6527d4 commit 160b5f2

File tree

14 files changed

+125
-75
lines changed

14 files changed

+125
-75
lines changed

src/mac/LoRaMac.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -892,16 +892,15 @@ static void ProcessRadioTxDone( void )
892892

893893
// Update last tx done time for the current channel
894894
txDone.Channel = MacCtx.Channel;
895+
txDone.LastTxDoneTime = TxDoneParams.CurTime;
896+
txDone.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime );
897+
txDone.LastTxAirTime = MacCtx.TxTimeOnAir;
898+
txDone.Joined = true;
895899
if( MacCtx.NvmCtx->NetworkActivation == ACTIVATION_TYPE_NONE )
896900
{
897901
txDone.Joined = false;
898902
}
899-
else
900-
{
901-
txDone.Joined = true;
902-
}
903-
txDone.LastTxDoneTime = TxDoneParams.CurTime;
904-
txDone.LastTxAirTime = MacCtx.TxTimeOnAir;
903+
905904
RegionSetBandTxDone( MacCtx.NvmCtx->Region, &txDone );
906905

907906
if( MacCtx.NodeAckRequested == false )
@@ -2507,7 +2506,7 @@ static LoRaMacStatus_t ScheduleTx( bool allowDelayedTx )
25072506
nextChan.AggrTimeOff = MacCtx.NvmCtx->AggregatedTimeOff;
25082507
nextChan.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate;
25092508
nextChan.DutyCycleEnabled = MacCtx.NvmCtx->DutyCycleOn;
2510-
nextChan.ElapsedTime = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime );
2509+
nextChan.ElapsedTimeSinceStartUp = SysTimeSub( SysTimeGetMcuTime( ), MacCtx.NvmCtx->InitializationTime );
25112510
nextChan.LastAggrTx = MacCtx.NvmCtx->LastTxDoneTime;
25122511
nextChan.LastTxIsJoinRequest = false;
25132512
nextChan.Joined = true;

src/mac/region/Region.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,7 @@ extern "C"
7676
#define REGION_VERSION 0x00010003
7777
#endif
7878

79-
#ifndef DUTY_CYCLE_TIME_PERIOD
80-
/*!
81-
* Default duty cycle time period is 1 hour = 3600000 ms
82-
*/
83-
#define DUTY_CYCLE_TIME_PERIOD 3600000
84-
#endif
79+
8580

8681
/*!
8782
* Region | SF
@@ -974,6 +969,10 @@ typedef struct sSetBandTxDoneParams
974969
* Time-on-air of the last transmission.
975970
*/
976971
TimerTime_t LastTxAirTime;
972+
/*!
973+
* Elapsed time since initialization.
974+
*/
975+
SysTime_t ElapsedTimeSinceStartUp;
977976
}SetBandTxDoneParams_t;
978977

979978
/*!
@@ -1298,7 +1297,7 @@ typedef struct sNextChanParams
12981297
/*!
12991298
* Elapsed time since the start of the node.
13001299
*/
1301-
SysTime_t ElapsedTime;
1300+
SysTime_t ElapsedTimeSinceStartUp;
13021301
/*!
13031302
* Joined Set to true, if the last uplink was a join request
13041303
*/

src/mac/region/RegionAS923.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ PhyParam_t RegionAS923GetPhyParam( GetPhyParams_t* getPhy )
358358

359359
void RegionAS923SetBandTxDone( SetBandTxDoneParams_t* txDone )
360360
{
361-
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxAirTime );
361+
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
362+
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
362363
}
363364

364365
void RegionAS923InitDefaults( InitDefaultsParams_t* params )
@@ -899,7 +900,7 @@ LoRaMacStatus_t RegionAS923NextChannel( NextChanParams_t* nextChanParams, uint8_
899900
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
900901
identifyChannelsParam.MaxBands = AS923_MAX_NB_BANDS;
901902

902-
identifyChannelsParam.ElapsedTime = nextChanParams->ElapsedTime;
903+
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
903904
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
904905
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
905906

src/mac/region/RegionAU915.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,8 @@ PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )
380380

381381
void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone )
382382
{
383-
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxAirTime );
383+
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
384+
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
384385
}
385386

386387
void RegionAU915InitDefaults( InitDefaultsParams_t* params )
@@ -897,7 +898,7 @@ LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_
897898
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
898899
identifyChannelsParam.MaxBands = AU915_MAX_NB_BANDS;
899900

900-
identifyChannelsParam.ElapsedTime = nextChanParams->ElapsedTime;
901+
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
901902
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
902903
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
903904

src/mac/region/RegionCN470.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ PhyParam_t RegionCN470GetPhyParam( GetPhyParams_t* getPhy )
336336

337337
void RegionCN470SetBandTxDone( SetBandTxDoneParams_t* txDone )
338338
{
339-
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxAirTime );
339+
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
340+
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
340341
}
341342

342343
void RegionCN470InitDefaults( InitDefaultsParams_t* params )
@@ -721,7 +722,7 @@ LoRaMacStatus_t RegionCN470NextChannel( NextChanParams_t* nextChanParams, uint8_
721722
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
722723
identifyChannelsParam.MaxBands = CN470_MAX_NB_BANDS;
723724

724-
identifyChannelsParam.ElapsedTime = nextChanParams->ElapsedTime;
725+
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
725726
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
726727
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
727728

src/mac/region/RegionCN779.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ PhyParam_t RegionCN779GetPhyParam( GetPhyParams_t* getPhy )
326326

327327
void RegionCN779SetBandTxDone( SetBandTxDoneParams_t* txDone )
328328
{
329-
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxAirTime );
329+
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
330+
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
330331
}
331332

332333
void RegionCN779InitDefaults( InitDefaultsParams_t* params )
@@ -852,7 +853,7 @@ LoRaMacStatus_t RegionCN779NextChannel( NextChanParams_t* nextChanParams, uint8_
852853
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
853854
identifyChannelsParam.MaxBands = CN779_MAX_NB_BANDS;
854855

855-
identifyChannelsParam.ElapsedTime = nextChanParams->ElapsedTime;
856+
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
856857
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
857858
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
858859

src/mac/region/RegionCommon.c

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,27 @@
3333
#include "utilities.h"
3434
#include "RegionCommon.h"
3535

36-
#define BACKOFF_DC_1_HOUR 100
37-
#define BACKOFF_DC_10_HOURS 1000
38-
#define BACKOFF_DC_24_HOURS 10000
36+
#define BACKOFF_DC_1_HOUR 100
37+
#define BACKOFF_DC_10_HOURS 1000
38+
#define BACKOFF_DC_24_HOURS 10000
39+
#define BACKOFF_DC_TIMER_PERIOD_FACTOR 100
3940

40-
static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedTime )
41+
#ifndef DUTY_CYCLE_TIME_PERIOD
42+
/*!
43+
* Default duty cycle time period is 1 hour = 3600000 ms
44+
*/
45+
#define DUTY_CYCLE_TIME_PERIOD 3600000
46+
#endif
47+
48+
static uint16_t GetDutyCycle( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup )
4149
{
42-
uint16_t joinDutyCycle = RegionCommonGetJoinDc( elapsedTime );
50+
uint16_t joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup );
4351
uint16_t dutyCycle = band->DCycle;
4452

4553
if( joined == false )
4654
{
4755
// Get the join duty cycle which depends on the runtime
48-
joinDutyCycle = RegionCommonGetJoinDc( elapsedTime );
56+
joinDutyCycle = RegionCommonGetJoinDc( elapsedTimeSinceStartup );
4957
// Take the most restrictive duty cycle
5058
dutyCycle = MAX( dutyCycle, joinDutyCycle );
5159
}
@@ -56,14 +64,32 @@ static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedT
5664
dutyCycle = 1;
5765
}
5866

67+
return dutyCycle;
68+
}
69+
70+
static uint16_t SetMaxTimeCredits( Band_t* band, bool joined, SysTime_t elapsedTimeSinceStartup )
71+
{
72+
uint16_t dutyCycle = band->DCycle;
73+
uint8_t timePeriodFactor = 1;
74+
75+
// Get the band duty cycle. If not joined, the function either returns the join duty cycle
76+
// or the band duty cycle, whichever is more restrictive.
77+
dutyCycle = GetDutyCycle( band, joined, elapsedTimeSinceStartup );
78+
79+
if( joined == false )
80+
{
81+
// Apply a factor to increase the maximum time period of observation
82+
timePeriodFactor = dutyCycle / BACKOFF_DC_TIMER_PERIOD_FACTOR;
83+
}
84+
5985
// Setup the maximum allowed credits
60-
band->MaxTimeCredits = DUTY_CYCLE_TIME_PERIOD / dutyCycle;
86+
band->MaxTimeCredits = DUTY_CYCLE_TIME_PERIOD * timePeriodFactor;
6187

6288
// In case if it is the first time, update also the current
6389
// time credits
6490
if( band->LastBandUpdateTime == 0 )
6591
{
66-
band->TimeCredits = DUTY_CYCLE_TIME_PERIOD / dutyCycle;
92+
band->TimeCredits = band->MaxTimeCredits;
6793
}
6894

6995
return dutyCycle;
@@ -96,7 +122,7 @@ static uint16_t UpdateTimeCredits( Band_t* band, bool joined, bool dutyCycleEnab
96122
}
97123

98124
// Get the difference between now and the last update
99-
band->TimeCredits += ( TimerGetElapsedTime( band->LastBandUpdateTime ) / dutyCycle );
125+
band->TimeCredits += TimerGetElapsedTime( band->LastBandUpdateTime );
100126

101127
// Limit band credits to maximum
102128
if( band->TimeCredits > band->MaxTimeCredits )
@@ -220,13 +246,17 @@ void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMas
220246
}
221247
}
222248

223-
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime )
249+
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime, bool joined, SysTime_t elapsedTimeSinceStartup )
224250
{
251+
// Get the band duty cycle. If not joined, the function either returns the join duty cycle
252+
// or the band duty cycle, whichever is more restrictive.
253+
uint16_t dutyCycle = GetDutyCycle( band, joined, elapsedTimeSinceStartup );
254+
225255
// Reduce with transmission time
226-
if( band->TimeCredits > lastTxAirTime )
256+
if( band->TimeCredits > ( lastTxAirTime * dutyCycle ) )
227257
{
228258
// Reduce time credits by the time of air
229-
band->TimeCredits -= lastTxAirTime;
259+
band->TimeCredits -= ( lastTxAirTime * dutyCycle );
230260
}
231261
else
232262
{
@@ -239,56 +269,64 @@ TimerTime_t RegionCommonUpdateBandTimeOff( bool joined, Band_t* bands,
239269
bool lastTxIsJoinRequest, SysTime_t elapsedTimeSinceStartup,
240270
TimerTime_t expectedTimeOnAir )
241271
{
242-
TimerTime_t maxCredits = 0;
272+
TimerTime_t minTimeToWait = TIMERTIME_T_MAX;
243273
TimerTime_t currentTime = TimerGetCurrentTime( );
274+
TimerTime_t creditCosts = 0;
244275
uint16_t dutyCycle = 1;
245-
uint16_t maxDutyCycle = 0;
276+
uint8_t validBands = 0;
246277

247-
// Update bands
248278
for( uint8_t i = 0; i < nbBands; i++ )
249279
{
250-
// Synchronization
280+
// Synchronization of bands and credits
251281
dutyCycle = UpdateTimeCredits( &bands[i], joined, dutyCycleEnabled,
252282
lastTxIsJoinRequest, elapsedTimeSinceStartup,
253283
currentTime );
254284

285+
// Calculate the credit costs for the next transmission
286+
// with the duty cycle and the expected time on air
287+
creditCosts = expectedTimeOnAir * dutyCycle;
288+
255289
// Check if the band is ready for transmission. Its ready,
256290
// when the duty cycle is off, or the TimeCredits of the band
257-
// is higher than the expected time on air.
258-
if( ( bands[i].TimeCredits > expectedTimeOnAir ) ||
291+
// is higher than the credit costs for the transmission.
292+
if( ( bands[i].TimeCredits > creditCosts ) ||
259293
( dutyCycleEnabled == false ) )
260294
{
261295
bands[i].ReadyForTransmission = true;
296+
// This band is a potential candidate for an
297+
// upcoming transmission, so increase the counter.
298+
validBands++;
262299
}
263300
else
264301
{
302+
// In this case, the band has not enough credits
303+
// for the next transmission.
265304
bands[i].ReadyForTransmission = false;
266-
}
267305

268-
// Get the band with the maximum credits
269-
if( ( maxCredits < bands[i].TimeCredits ) &&
270-
( bands[i].TimeCredits != bands[i].MaxTimeCredits ) )
271-
{
272-
maxCredits = bands[i].TimeCredits;
273-
maxDutyCycle = dutyCycle;
306+
if( bands[i].MaxTimeCredits > creditCosts )
307+
{
308+
// The band can only be taken into account, if the maximum credits
309+
// of the band are higher than the credit costs.
310+
// We calculate the minTimeToWait among the bands which are not
311+
// ready for transmission and which are potentially available
312+
// for a transmission in the future.
313+
minTimeToWait = MIN( minTimeToWait, ( creditCosts - bands[i].TimeCredits ) );
314+
// This band is a potential candidate for an
315+
// upcoming transmission (even if its time credits are not enough
316+
// at the moment), so increase the counter.
317+
validBands++;
318+
}
274319
}
275320
}
276321

277-
// Calculate the difference to the expected time on air, if the
278-
// expected time on air is greater than the credits of the band with highest
279-
// time credit value
280-
if( maxCredits < expectedTimeOnAir )
281-
{
282-
maxCredits = expectedTimeOnAir - maxCredits;
283-
}
284-
else
322+
323+
if( validBands == 0 )
285324
{
286-
maxCredits = 0;
325+
// There is no valid band available to handle a transmission
326+
// in the given DUTY_CYCLE_TIME_PERIOD.
327+
return TIMERTIME_T_MAX;
287328
}
288-
289-
// Calculate the return value which shall be
290-
// the waiting time for the next transmission
291-
return maxCredits * maxDutyCycle;
329+
return minTimeToWait;
292330
}
293331

294332
uint8_t RegionCommonParseLinkAdrReq( uint8_t* payload, RegionCommonLinkAdrParams_t* linkAdrParams )
@@ -490,7 +528,7 @@ LoRaMacStatus_t RegionCommonIdentifyChannels( RegionCommonIdentifyChannelsParam_
490528
identifyChannelsParam->MaxBands,
491529
identifyChannelsParam->DutyCycleEnabled,
492530
identifyChannelsParam->LastTxIsJoinRequest,
493-
identifyChannelsParam->ElapsedTime,
531+
identifyChannelsParam->ElapsedTimeSinceStartUp,
494532
identifyChannelsParam->ExpectedTimeOnAir );
495533

496534
RegionCommonCountNbOfEnabledChannels( identifyChannelsParam->CountNbOfEnabledChannelsParam, enabledChannels,

src/mac/region/RegionCommon.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ typedef struct sRegionCommonIdentifyChannelsParam
231231
/*!
232232
* Elapsed time since the start of the node.
233233
*/
234-
SysTime_t ElapsedTime;
234+
SysTime_t ElapsedTimeSinceStartUp;
235235
/*!
236236
* Joined Set to true, if the last uplink was a join request
237237
*/
@@ -354,8 +354,12 @@ void RegionCommonChanMaskCopy( uint16_t* channelsMaskDest, uint16_t* channelsMas
354354
* \param [IN] band The band to be updated.
355355
*
356356
* \param [IN] lastTxAirTime The time on air of the last TX frame.
357+
*
358+
* \param [IN] joined Set to true if the device has joined.
359+
*
360+
* \param [IN] elapsedTimeSinceStartup Elapsed time since initialization.
357361
*/
358-
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime );
362+
void RegionCommonSetBandTxDone( Band_t* band, TimerTime_t lastTxAirTime, bool joined, SysTime_t elapsedTimeSinceStartup );
359363

360364
/*!
361365
* \brief Updates the time-offs of the bands.

src/mac/region/RegionEU433.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ PhyParam_t RegionEU433GetPhyParam( GetPhyParams_t* getPhy )
326326

327327
void RegionEU433SetBandTxDone( SetBandTxDoneParams_t* txDone )
328328
{
329-
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band], txDone->LastTxAirTime );
329+
RegionCommonSetBandTxDone( &NvmCtx.Bands[NvmCtx.Channels[txDone->Channel].Band],
330+
txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );
330331
}
331332

332333
void RegionEU433InitDefaults( InitDefaultsParams_t* params )
@@ -852,7 +853,7 @@ LoRaMacStatus_t RegionEU433NextChannel( NextChanParams_t* nextChanParams, uint8_
852853
identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;
853854
identifyChannelsParam.MaxBands = EU433_MAX_NB_BANDS;
854855

855-
identifyChannelsParam.ElapsedTime = nextChanParams->ElapsedTime;
856+
identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;
856857
identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;
857858
identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );
858859

0 commit comments

Comments
 (0)