@@ -77,12 +77,12 @@ static void running_run(void *o);
77
77
static void triggering_entry (void * o );
78
78
static void triggering_run (void * o );
79
79
80
- static void requesting_location_entry (void * o );
81
- static void requesting_location_run (void * o );
80
+ static void sample_data_entry (void * o );
81
+ static void sample_data_run (void * o );
82
82
83
- static void requesting_sensors_and_polling_entry (void * o );
84
- static void requesting_sensors_and_polling_run (void * o );
85
- static void requesting_sensors_and_polling_exit (void * o );
83
+ static void wait_for_trigger_entry (void * o );
84
+ static void wait_for_trigger_run (void * o );
85
+ static void wait_for_trigger_exit (void * o );
86
86
87
87
static void idle_entry (void * o );
88
88
static void idle_run (void * o );
@@ -110,10 +110,13 @@ enum state {
110
110
STATE_IDLE ,
111
111
/* Triggers are periodically sent at a configured interval */
112
112
STATE_TRIGGERING ,
113
- /* Requesting location from the location module */
114
- STATE_REQUESTING_LOCATION ,
115
- /* Requesting sensor values and polling for downlink data */
116
- STATE_REQUESTING_SENSORS_AND_POLLING ,
113
+ /* Requesting data samples from relevant modules.
114
+ * Location data is requested first, upon state entry.
115
+ * After location data is received, the other modules are polled.
116
+ */
117
+ STATE_SAMPLE_DATA ,
118
+ /* Wait for timer or button press to trigger the next sample */
119
+ STATE_WAIT_FOR_TRIGGER ,
117
120
/* Ongoing FOTA process, triggers are blocked */
118
121
STATE_FOTA ,
119
122
/* FOTA image is being downloaded */
@@ -144,10 +147,15 @@ struct main_state {
144
147
uint8_t msg_buf [MAX_MSG_SIZE ];
145
148
146
149
/* Trigger interval */
147
- uint64_t interval_sec ;
150
+ uint32_t interval_sec ;
148
151
149
152
/* Cloud connection status */
150
153
bool connected ;
154
+
155
+ /* Start time of the most recent sampling. This is used to calculate the correct
156
+ * time when scheduling the next sampling trigger.
157
+ */
158
+ uint32_t sample_start_time ;
151
159
};
152
160
153
161
/* Construct state table */
@@ -171,19 +179,19 @@ static const struct smf_state states[] = {
171
179
triggering_run ,
172
180
NULL ,
173
181
& states [STATE_RUNNING ],
174
- & states [STATE_REQUESTING_LOCATION ]
182
+ & states [STATE_SAMPLE_DATA ]
175
183
),
176
- [STATE_REQUESTING_LOCATION ] = SMF_CREATE_STATE (
177
- requesting_location_entry ,
178
- requesting_location_run ,
184
+ [STATE_SAMPLE_DATA ] = SMF_CREATE_STATE (
185
+ sample_data_entry ,
186
+ sample_data_run ,
179
187
NULL ,
180
188
& states [STATE_TRIGGERING ],
181
189
NULL
182
190
),
183
- [STATE_REQUESTING_SENSORS_AND_POLLING ] = SMF_CREATE_STATE (
184
- requesting_sensors_and_polling_entry ,
185
- requesting_sensors_and_polling_run ,
186
- requesting_sensors_and_polling_exit ,
191
+ [STATE_WAIT_FOR_TRIGGER ] = SMF_CREATE_STATE (
192
+ wait_for_trigger_entry ,
193
+ wait_for_trigger_run ,
194
+ wait_for_trigger_exit ,
187
195
& states [STATE_TRIGGERING ],
188
196
NULL
189
197
),
@@ -293,18 +301,6 @@ static void sensor_and_poll_triggers_send(void)
293
301
SEND_FATAL_ERROR ();
294
302
return ;
295
303
}
296
-
297
- /* Send trigger for shadow polling */
298
- struct cloud_msg cloud_msg = {
299
- .type = CLOUD_POLL_SHADOW
300
- };
301
-
302
- err = zbus_chan_pub (& CLOUD_CHAN , & cloud_msg , K_SECONDS (1 ));
303
- if (err ) {
304
- LOG_ERR ("zbus_chan_pub shadow trigger, error: %d" , err );
305
- SEND_FATAL_ERROR ();
306
- return ;
307
- }
308
304
}
309
305
310
306
/* Delayable work used to send messages on the TIMER_CHAN */
@@ -464,7 +460,7 @@ static void triggering_run(void *o)
464
460
return ;
465
461
}
466
462
467
- LOG_WRN ("Received new interval: %lld seconds" , state_object -> interval_sec );
463
+ LOG_WRN ("Received new interval: %d seconds" , state_object -> interval_sec );
468
464
469
465
err = k_work_reschedule (& trigger_work ,
470
466
K_SECONDS (state_object -> interval_sec ));
@@ -476,17 +472,30 @@ static void triggering_run(void *o)
476
472
}
477
473
}
478
474
479
- /* STATE_REQUESTING_LOCATION */
475
+ /* STATE_SAMPLE_DATA */
480
476
481
- static void requesting_location_entry (void * o )
477
+ static void sample_data_entry (void * o )
482
478
{
483
479
int err ;
484
480
enum location_msg_type location_msg = LOCATION_SEARCH_TRIGGER ;
481
+ struct cloud_msg cloud_msg = {
482
+ .type = CLOUD_POLL_SHADOW
483
+ };
484
+ struct main_state * state_object = (struct main_state * )o ;
485
485
486
- ARG_UNUSED (o );
487
486
488
487
LOG_DBG ("%s" , __func__ );
489
488
489
+ /* Record the start time of sampling */
490
+ state_object -> sample_start_time = k_uptime_seconds ();
491
+
492
+ err = zbus_chan_pub (& CLOUD_CHAN , & cloud_msg , K_SECONDS (1 ));
493
+ if (err ) {
494
+ LOG_ERR ("zbus_chan_pub shadow trigger, error: %d" , err );
495
+ SEND_FATAL_ERROR ();
496
+ return ;
497
+ }
498
+
490
499
err = zbus_chan_pub (& LOCATION_CHAN , & location_msg , K_SECONDS (1 ));
491
500
if (err ) {
492
501
LOG_ERR ("zbus_chan_pub data sample trigger, error: %d" , err );
@@ -495,62 +504,77 @@ static void requesting_location_entry(void *o)
495
504
}
496
505
}
497
506
498
- static void requesting_location_run (void * o )
507
+ static void sample_data_run (void * o )
499
508
{
500
509
const struct main_state * state_object = (const struct main_state * )o ;
501
510
502
511
if (state_object -> chan == & LOCATION_CHAN ) {
503
512
enum location_msg_type msg = MSG_TO_LOCATION_TYPE (state_object -> msg_buf );
504
513
505
514
if (msg == LOCATION_SEARCH_DONE ) {
506
- smf_set_state ( SMF_CTX ( state_object ),
507
- & states [STATE_REQUESTING_SENSORS_AND_POLLING ]);
515
+ sensor_and_poll_triggers_send ();
516
+ smf_set_state ( SMF_CTX ( state_object ), & states [STATE_WAIT_FOR_TRIGGER ]);
508
517
return ;
509
518
}
510
519
}
511
520
521
+ /* We are already sampling, ignore any new triggers */
512
522
if (state_object -> chan == & BUTTON_CHAN ) {
513
523
smf_set_handled (SMF_CTX (state_object ));
514
524
return ;
515
525
}
526
+
527
+ if (state_object -> chan == & TIMER_CHAN ) {
528
+ smf_set_handled (SMF_CTX (state_object ));
529
+ return ;
530
+ }
516
531
}
517
532
518
- /* STATE_REQUESTING_SENSORS_AND_POLLING */
533
+ /* STATE_WAIT_FOR_TRIGGER */
519
534
520
- static void requesting_sensors_and_polling_entry (void * o )
535
+ static void wait_for_trigger_entry (void * o )
521
536
{
522
537
int err ;
523
538
const struct main_state * state_object = (const struct main_state * )o ;
539
+ uint32_t time_elapsed = k_uptime_seconds () - state_object -> sample_start_time ;
540
+ uint32_t time_remaining ;
541
+
542
+ if (time_elapsed > state_object -> interval_sec ) {
543
+ LOG_WRN ("Sampling took longer than the interval, skipping next trigger" );
544
+ time_remaining = 0 ;
545
+ } else {
546
+ time_remaining = state_object -> interval_sec - time_elapsed ;
547
+ }
524
548
525
549
LOG_DBG ("%s" , __func__ );
526
550
527
- sensor_and_poll_triggers_send ( );
551
+ LOG_DBG ( "Next trigger in %d seconds" , time_remaining );
528
552
529
- LOG_DBG ("Next trigger in %lld seconds" , state_object -> interval_sec );
530
-
531
- err = k_work_reschedule (& trigger_work , K_SECONDS (state_object -> interval_sec ));
553
+ (void )k_work_cancel_delayable (& trigger_work );
554
+ err = k_work_reschedule (& trigger_work , K_SECONDS (time_remaining ));
532
555
if (err < 0 ) {
533
556
LOG_ERR ("k_work_reschedule, error: %d" , err );
534
557
SEND_FATAL_ERROR ();
535
558
}
536
559
}
537
560
538
- static void requesting_sensors_and_polling_run (void * o )
561
+ static void wait_for_trigger_run (void * o )
539
562
{
540
563
const struct main_state * state_object = (const struct main_state * )o ;
541
564
542
565
if (state_object -> chan == & TIMER_CHAN ) {
543
- smf_set_state (SMF_CTX (state_object ), & states [STATE_REQUESTING_LOCATION ]);
566
+ LOG_DBG ("Timer trigger received" );
567
+ smf_set_state (SMF_CTX (state_object ), & states [STATE_SAMPLE_DATA ]);
544
568
return ;
545
569
}
546
570
547
571
if (state_object -> chan == & BUTTON_CHAN ) {
548
- smf_set_state (SMF_CTX (state_object ), & states [STATE_REQUESTING_LOCATION ]);
572
+ smf_set_state (SMF_CTX (state_object ), & states [STATE_SAMPLE_DATA ]);
549
573
return ;
550
574
}
551
575
}
552
576
553
- static void requesting_sensors_and_polling_exit (void * o )
577
+ static void wait_for_trigger_exit (void * o )
554
578
{
555
579
ARG_UNUSED (o );
556
580
0 commit comments