Major re-factor of the common_time (formally aah_timesrv) service in preparation for up-integration into Android master. This work includes bug fixes, new features, and general code cleanup. High points are listed below. + CommonClock interface has been enhanced to allow querying of many more low level synchronization details; mostly for debugging, but in theory useful to an application as well. + CommonTimeConfig interface has been implemented. This allows a management process to configure a number of different parameters (many of them new) to control the behavior of the common_time service. Most importantly, the time service can be bound to a specific network interface and should only operate on that interface an no others. + Enhance log messages to be more useful in determining what the time service state machine is doing and why. + Enhance information provided by dumpsys to provide many more details about the quality of time sync and the network conditions which gave rise to the current quality conditions. Features, features, features.... + Add a feature which lets the high level choose a different master election endpoint so that multiple time synchronization domains can co-exist on the same subnet (mostly to support a potential use case of multiple home domains in a multiple dwelling environment like a hotel, dormitory or apartment complex). + Add a feature which lets the high level assign a 64-bit group ID which allows partitioning of time synchronization domains even when the master election endpoint is shared (as it might be if broadcast is being used instead of multicast) + Add an auto-disable feature which lets the time service drop into network-less mode when there are no active clients of the common_time service in the device. Mostly for phones, this allows phones to not consume network/battery resources when they don't need to maintain common time. + Add a feature which lets the high level choose the priority of the common_time service in the master election protocol. This allows high level decisions about things like mobile vs non-mobile, wired ethernet vs WiFi to affect who ends up with the job of master on a given network. Priority overrides at the low level also allow clients coming in from network-less mode to lower their effective priority as they join a new network so as to not disrupt any stable long-running timeline which may already be active on the network. + Add the ability to control some of the core parameters of the time sync service which effect network load (like the sync polling interval and the master announce interval) Change-Id: I71af15a83cfa5ef0417b406928967fb9e02f55c6
124 lines
3.8 KiB
C++
124 lines
3.8 KiB
C++
/*
|
|
* Copyright (C) 2011 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef __CLOCK_RECOVERY_H__
|
|
#define __CLOCK_RECOVERY_H__
|
|
|
|
#include <stdint.h>
|
|
#include <common_time/ICommonClock.h>
|
|
#include <utils/LinearTransform.h>
|
|
#include <utils/threads.h>
|
|
|
|
#ifdef TIME_SERVICE_DEBUG
|
|
#include "diag_thread.h"
|
|
#endif
|
|
|
|
namespace android {
|
|
|
|
class CommonClock;
|
|
class LocalClock;
|
|
|
|
class ClockRecoveryLoop {
|
|
public:
|
|
ClockRecoveryLoop(LocalClock* local_clock, CommonClock* common_clock);
|
|
~ClockRecoveryLoop();
|
|
|
|
void reset(bool position, bool frequency);
|
|
bool pushDisciplineEvent(int64_t local_time,
|
|
int64_t nominal_common_time,
|
|
int64_t data_point_rtt);
|
|
int32_t getLastErrorEstimate();
|
|
|
|
private:
|
|
typedef struct {
|
|
// Limits for the correction factor supplied to set_counter_slew_rate.
|
|
// The controller will always clamp its output to the range expressed by
|
|
// correction_(min|max)
|
|
int32_t correction_min;
|
|
int32_t correction_max;
|
|
|
|
// Limits for the internal integration accumulator in the PID
|
|
// controller. The value of the accumulator is scaled by gain_I to
|
|
// produce the integral component of the PID controller output.
|
|
// Platforms can use these limits to prevent windup in the system
|
|
// if/when the correction factor needs to be driven to saturation for
|
|
// extended periods of time.
|
|
int32_t integrated_delta_min;
|
|
int32_t integrated_delta_max;
|
|
|
|
// Gain for the P, I and D components of the controller.
|
|
LinearTransform gain_P;
|
|
LinearTransform gain_I;
|
|
LinearTransform gain_D;
|
|
} PIDParams;
|
|
|
|
typedef struct {
|
|
int64_t local_time;
|
|
int64_t observed_common_time;
|
|
int64_t nominal_common_time;
|
|
int64_t rtt;
|
|
bool point_used;
|
|
} DisciplineDataPoint;
|
|
|
|
static uint32_t findMinRTTNdx(DisciplineDataPoint* data, uint32_t count);
|
|
|
|
void computePIDParams();
|
|
void reset_l(bool position, bool frequency);
|
|
static int32_t doGainScale(const LinearTransform& gain, int32_t val);
|
|
void applySlew();
|
|
|
|
// The local clock HW abstraction we use as the basis for common time.
|
|
LocalClock* local_clock_;
|
|
bool local_clock_can_slew_;
|
|
|
|
// The common clock we end up controlling along with the lock used to
|
|
// serialize operations.
|
|
CommonClock* common_clock_;
|
|
Mutex lock_;
|
|
|
|
// The parameters computed to be used for the PID Controller.
|
|
PIDParams pid_params_;
|
|
|
|
// The maximum allowed error (as indicated by a pushDisciplineEvent) before
|
|
// we panic.
|
|
int32_t panic_thresh_;
|
|
|
|
// parameters maintained while running and reset during a reset
|
|
// of the frequency correction.
|
|
bool last_delta_valid_;
|
|
int32_t last_delta_;
|
|
int32_t integrated_error_;
|
|
int32_t correction_cur_;
|
|
|
|
// State kept for filtering the discipline data.
|
|
static const uint32_t kFilterSize = 6;
|
|
DisciplineDataPoint filter_data_[kFilterSize];
|
|
uint32_t filter_wr_;
|
|
bool filter_full_;
|
|
|
|
static const uint32_t kStartupFilterSize = 4;
|
|
DisciplineDataPoint startup_filter_data_[kStartupFilterSize];
|
|
uint32_t startup_filter_wr_;
|
|
|
|
#ifdef TIME_SERVICE_DEBUG
|
|
sp<DiagThread> diag_thread_;
|
|
#endif
|
|
};
|
|
|
|
} // namespace android
|
|
|
|
#endif // __CLOCK_RECOVERY_H__
|