modified timesync after join logic

This commit is contained in:
Verkehrsrot 2019-04-07 14:06:47 +02:00
parent 3aa8e73b86
commit 0b40d0df70
3 changed files with 36 additions and 30 deletions

View File

@ -10,6 +10,8 @@
#define TIME_SYNC_FRAME_LENGTH 0x05 // timeserver answer frame length [bytes] #define TIME_SYNC_FRAME_LENGTH 0x05 // timeserver answer frame length [bytes]
#define TIME_SYNC_FIXUP 6 // calibration to fixup processing time [milliseconds] #define TIME_SYNC_FIXUP 6 // calibration to fixup processing time [milliseconds]
extern TaskHandle_t timeSyncReqTask;
void send_timesync_req(void); void send_timesync_req(void);
int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len); int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len);
void process_timesync_req(void *taskparameter); void process_timesync_req(void *taskparameter);

View File

@ -223,6 +223,11 @@ void onEvent(ev_t ev) {
// show effective LoRa parameters after join // show effective LoRa parameters after join
ESP_LOGI(TAG, "ADR=%d, SF=%d, TXPOWER=%d", cfg.adrmode, cfg.lorasf, ESP_LOGI(TAG, "ADR=%d, SF=%d, TXPOWER=%d", cfg.adrmode, cfg.lorasf,
cfg.txpower); cfg.txpower);
#if (TIME_SYNC_LORASERVER)
// kick off timesync task if pending
if (timeSyncReqTask)
xTaskNotifyGive(timeSyncReqTask);
#endif
break; break;
case EV_RFU1: case EV_RFU1:
@ -241,9 +246,8 @@ void onEvent(ev_t ev) {
#if (TIME_SYNC_LORASERVER) #if (TIME_SYNC_LORASERVER)
// if last packet sent was a timesync request, store TX timestamp // if last packet sent was a timesync request, store TX timestamp
if (LMIC.pendTxPort == TIMEPORT) { if (LMIC.pendTxPort == TIMEPORT)
store_time_sync_req(osticks2ms(LMIC.txend)); // milliseconds store_time_sync_req(osticks2ms(LMIC.txend)); // milliseconds
}
#endif #endif
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK")
@ -263,10 +267,10 @@ void onEvent(ev_t ev) {
rcommand(LMIC.frame + LMIC.dataBeg, LMIC.dataLen); rcommand(LMIC.frame + LMIC.dataBeg, LMIC.dataLen);
break; break;
default: // unknown port -> display info default:
#if (TIME_SYNC_LORASERVER) #if (TIME_SYNC_LORASERVER)
// timesync answer -> call timesync processor // timesync answer -> call timesync processor
if ((LMIC.frame[LMIC.dataBeg - 1] >= TIMEANSWERPORT_MIN) && if ((LMIC.frame[LMIC.dataBeg - 1] >= TIMEANSWERPORT_MIN) &&
(LMIC.frame[LMIC.dataBeg - 1] <= TIMEANSWERPORT_MAX)) { (LMIC.frame[LMIC.dataBeg - 1] <= TIMEANSWERPORT_MAX)) {
recv_timesync_ans(LMIC.frame[LMIC.dataBeg - 1], recv_timesync_ans(LMIC.frame[LMIC.dataBeg - 1],
@ -274,6 +278,7 @@ void onEvent(ev_t ev) {
break; break;
} }
#endif #endif
// unknown port -> display info
ESP_LOGI(TAG, "Received data on unsupported port #%d", ESP_LOGI(TAG, "Received data on unsupported port #%d",
LMIC.frame[LMIC.dataBeg - 1]); LMIC.frame[LMIC.dataBeg - 1]);
break; break;
@ -309,7 +314,13 @@ void onEvent(ev_t ev) {
case EV_TXSTART: case EV_TXSTART:
if (!(LMIC.opmode & OP_JOINING)) if (!(LMIC.opmode & OP_JOINING))
strcpy_P(buff, PSTR("TX START")); #if (TIME_SYNC_LORASERVER)
// if last packet sent was a timesync request, store TX time
if ((LMIC.pendTxPort == TIMEPORT) && timeSyncReqTask)
strcpy_P(buff, PSTR("SYNCING TIME"));
else
#endif
strcpy_P(buff, PSTR("TX START"));
break; break;
case EV_TXCANCELED: case EV_TXCANCELED:

View File

@ -18,10 +18,9 @@ using namespace std::chrono;
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
TaskHandle_t timeSyncReqTask; TaskHandle_t timeSyncReqTask = NULL;
static uint8_t time_sync_seqNo = TIMEANSWERPORT_MIN; static uint8_t time_sync_seqNo = TIMEANSWERPORT_MIN;
static bool lora_time_sync_pending = false;
typedef std::chrono::system_clock myClock; typedef std::chrono::system_clock myClock;
typedef myClock::time_point myClock_timepoint; typedef myClock::time_point myClock_timepoint;
@ -35,14 +34,12 @@ myClock_timepoint time_sync_rx[TIME_SYNC_SAMPLES];
void send_timesync_req() { void send_timesync_req() {
// if a timesync handshake is pending then exit // if a timesync handshake is pending then exit
if (lora_time_sync_pending) { if (timeSyncReqTask) {
// ESP_LOGI(TAG, "Timeserver sync request already pending"); ESP_LOGD(TAG, "Timeserver sync request already pending");
return; return;
} else { } else {
ESP_LOGI(TAG, "[%0.3f] Timeserver sync request started", millis() / 1000.0); ESP_LOGI(TAG, "[%0.3f] Timeserver sync request started", millis() / 1000.0);
lora_time_sync_pending = true;
// clear timestamp array // clear timestamp array
for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++) for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++)
time_sync_tx[i] = time_sync_rx[i] = myClock_timepoint(); time_sync_tx[i] = time_sync_rx[i] = myClock_timepoint();
@ -51,7 +48,7 @@ void send_timesync_req() {
if (!timeSyncReqTask) if (!timeSyncReqTask)
xTaskCreatePinnedToCore(process_timesync_req, // task function xTaskCreatePinnedToCore(process_timesync_req, // task function
"timesync_req", // name of task "timesync_req", // name of task
2048, // stack size of task 4096, // stack size of task
(void *)1, // task parameter (void *)1, // task parameter
4, // priority of the task 4, // priority of the task
&timeSyncReqTask, // task handle &timeSyncReqTask, // task handle
@ -68,13 +65,11 @@ void process_timesync_req(void *taskparameter) {
auto time_offset_ms = myClock_msecTick::zero(); auto time_offset_ms = myClock_msecTick::zero();
// wait until we are joined // wait until we are joined
while (!LMIC.devaddr) { if (!LMIC.devaddr)
vTaskDelay(pdMS_TO_TICKS(2000)); ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
}
// enqueue timestamp samples in lora sendqueue // enqueue timestamp samples in lora sendqueue
for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++) { for (uint8_t i = 0; i < TIME_SYNC_SAMPLES; i++) {
// send sync request to server // send sync request to server
payload.reset(); payload.reset();
payload.addByte(time_sync_seqNo); payload.addByte(time_sync_seqNo);
@ -103,11 +98,11 @@ void process_timesync_req(void *taskparameter) {
vTaskDelay(pdMS_TO_TICKS(TIME_SYNC_CYCLE * 1000)); vTaskDelay(pdMS_TO_TICKS(TIME_SYNC_CYCLE * 1000));
} else { // before sending last time sample... } else { // before sending last time sample...
// ...send flush to open a receive window for last time_sync_answer // ...send flush to open a receive window for last time_sync_answer
// payload.reset(); payload.reset();
// payload.addByte(0x99); payload.addByte(0x99);
// SendPayload(RCMDPORT, prio_high); SendPayload(RCMDPORT, prio_high);
// ...send a alive open a receive window for last time_sync_answer // ...send a alive open a receive window for last time_sync_answer
LMIC_sendAlive(); //LMIC_sendAlive();
} }
} }
} // for } // for
@ -136,28 +131,26 @@ void process_timesync_req(void *taskparameter) {
// end of time critical section: release I2C bus // end of time critical section: release I2C bus
unmask_user_IRQ(); unmask_user_IRQ();
finish: goto finish; // end task
lora_time_sync_pending = false;
timeSyncReqTask = NULL;
vTaskDelete(NULL); // end task
error: error:
ESP_LOGW(TAG, "[%0.3f] Timeserver error: handshake timed out", ESP_LOGW(TAG, "[%0.3f] Timeserver error: handshake timed out",
millis() / 1000.0); millis() / 1000.0);
goto finish; // end task
finish:
vTaskDelete(NULL); // end task
} }
// called from lorawan.cpp after time_sync_req was sent // called from lorawan.cpp after time_sync_req was sent
void store_time_sync_req(uint32_t timestamp) { void store_time_sync_req(uint32_t timestamp) {
if (lora_time_sync_pending) { if (timeSyncReqTask) {
uint8_t k = time_sync_seqNo % TIME_SYNC_SAMPLES; uint8_t k = time_sync_seqNo % TIME_SYNC_SAMPLES;
time_sync_tx[k] += milliseconds(timestamp); time_sync_tx[k] += milliseconds(timestamp);
ESP_LOGD(TAG, "[%0.3f] Timesync request #%d sent at %d.%03d", ESP_LOGD(TAG, "[%0.3f] Timesync request #%d sent at %d.%03d",
millis() / 1000.0, time_sync_seqNo, timestamp / 1000, millis() / 1000.0, k, timestamp / 1000,
timestamp % 1000); timestamp % 1000);
} }
} }
@ -166,7 +159,7 @@ void store_time_sync_req(uint32_t timestamp) {
int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) { int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
// if no timesync handshake is pending then exit // if no timesync handshake is pending then exit
if (!lora_time_sync_pending) if (!timeSyncReqTask)
return 0; // failure return 0; // failure
// if no time is available or spurious buffer then exit // if no time is available or spurious buffer then exit
@ -201,7 +194,7 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
// guess timepoint is recent if newer than code compile date // guess timepoint is recent if newer than code compile date
if (timeIsValid(myClock::to_time_t(time_sync_rx[k]))) { if (timeIsValid(myClock::to_time_t(time_sync_rx[k]))) {
ESP_LOGD(TAG, "[%0.3f] Timesync request #%d rcvd at %d.%03d", ESP_LOGD(TAG, "[%0.3f] Timesync request #%d rcvd at %d.%03d",
millis() / 1000.0, seq_no, timestamp_sec, timestamp_msec); millis() / 1000.0, k, timestamp_sec, timestamp_msec);
// inform processing task // inform processing task
if (timeSyncReqTask) if (timeSyncReqTask)