Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers timing_drift_auto.py Source File

timing_drift_auto.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2013 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 
00018 from mbed_host_tests import BaseHostTest
00019 import time
00020 
00021 
00022 class TimingDriftSync (BaseHostTest):
00023     """
00024     This works as master-slave fashion
00025     1) Device says its booted up and ready to run the test, wait for host to respond
00026     2) Host sends the message to get the device current time i.e base time
00027 
00028     #
00029     # *
00030     #   *                   |
00031     #<---* DUT<- base_time  | - round_trip_base_time ------
00032     #   *                   |                              |
00033     # *                    -                               |
00034     #                      -                               |
00035     #                       |                              |
00036     #                       |                              |
00037     #                       | - measurement_stretch        | - nominal_time
00038     #                       |                              |
00039     #                       |                              |
00040     #                      -                               |
00041     # *                    -                               |
00042     #   *                   |                              |
00043     #<---* DUT <-final_time | - round_trip_final_time------
00044     #   *                   |
00045     # *                    -
00046     #
00047     #
00048     # As we increase the measurement_stretch, the error because of transport delay diminishes.
00049     # The values of measurement_stretch is propotional to round_trip_base_time(transport delays)
00050     # by factor time_measurement_multiplier.This multiplier is used is 80 to tolerate 2 sec of
00051     # transport delay and test time ~ 180 secs
00052     #
00053     # Failure in timing can occur if we are ticking too fast or we are ticking too slow, hence we have
00054     # min_range and max_range. if we cross on either side tests would be marked fail. The range is a function of
00055     # tolerance/acceptable drift currently its 5%.
00056     #
00057 
00058     """
00059     __result = None
00060     mega = 1000000.0
00061     max_measurement_time = 180
00062 
00063     # this value is obtained for measurements when there is 0 transport delay and we want accurancy of 5%
00064     time_measurement_multiplier = 80
00065 
00066     def _callback_timing_drift_check_start(self, key, value, timestamp):
00067         self.round_trip_base_start  = timestamp
00068         self.send_kv("base_time", 0)
00069 
00070     def _callback_base_time(self, key, value, timestamp):
00071         self.round_trip_base_end  = timestamp
00072         self.device_time_base  = float(value)
00073         self.round_trip_base_time  = self.round_trip_base_end  - self.round_trip_base_start 
00074 
00075         self.log("Device base time {}".format(value))
00076         measurement_stretch = (self.round_trip_base_time  * self.time_measurement_multiplier ) + 5
00077 
00078         if measurement_stretch > self.max_measurement_time :
00079             self.log("Time required {} to determine device timer is too high due to transport delay, skipping".format(measurement_stretch))
00080         else:
00081             self.log("sleeping for {} to measure drift accurately".format(measurement_stretch))
00082             time.sleep(measurement_stretch)
00083         self.round_trip_final_start  = time.time()
00084         self.send_kv("final_time", 0)
00085 
00086     def _callback_final_time(self, key, value, timestamp):
00087         self.round_trip_final_end  = timestamp
00088         self.device_time_final  = float(value)
00089         self.round_trip_final_time  = self.round_trip_final_end  - self.round_trip_final_start 
00090         self.log("Device final time {} ".format(value))
00091 
00092         # compute the test results and send to device
00093         results = "pass" if self.compute_parameter () else "fail"
00094         self.send_kv(results, "0")
00095 
00096     def setup(self):
00097         self.register_callback('timing_drift_check_start', self._callback_timing_drift_check_start )
00098         self.register_callback('base_time', self._callback_base_time )
00099         self.register_callback('final_time', self._callback_final_time )
00100 
00101     def compute_parameter(self, failure_criteria=0.05):
00102         t_max = self.round_trip_final_end  - self.round_trip_base_start 
00103         t_min = self.round_trip_final_start  - self.round_trip_base_end 
00104         t_max_hi = t_max * (1 + failure_criteria)
00105         t_max_lo = t_max * (1 - failure_criteria)
00106         t_min_hi = t_min * (1 + failure_criteria)
00107         t_min_lo = t_min * (1 - failure_criteria)
00108         device_time = (self.device_time_final  - self.device_time_base ) / self.mega 
00109 
00110         self.log("Compute host events")
00111         self.log("Transport delay 0: {}".format(self.round_trip_base_time ))
00112         self.log("Transport delay 1: {}".format(self.round_trip_final_time ))
00113         self.log("DUT base time : {}".format(self.device_time_base ))
00114         self.log("DUT end time  : {}".format(self.device_time_final ))
00115 
00116         self.log("min_pass : {} , max_pass : {} for {}%%".format(t_max_lo, t_min_hi, failure_criteria * 100))
00117         self.log("min_inconclusive : {} , max_inconclusive : {}".format(t_min_lo, t_max_hi))
00118         self.log("Time reported by device: {}".format(device_time))
00119 
00120         if t_max_lo <= device_time <= t_min_hi:
00121             self.log("Test passed !!!")
00122             self.__result  = True
00123         elif t_min_lo <= device_time <= t_max_hi:
00124             self.log("Test inconclusive due to transport delay, retrying")
00125             self.__result  = False
00126         else:
00127             self.log("Time outside of passing range. Timing drift seems to be present !!!")
00128             self.__result  = False
00129         return self.__result 
00130 
00131     def result(self):
00132         return self.__result 
00133 
00134     def teardown(self):
00135         pass