Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Automated Python Test Frameworks for Hardware Verification and Validation

12,318 views

Published on

Codemash 2012

  • Be the first to comment

Automated Python Test Frameworks for Hardware Verification and Validation

  1. 1. Automated Python Test Frameworks for HardwareValidation and Verification Barbara Jones
  2. 2. About Me Barbara Jones bjones@vtiinstruments.com  Test & Measurement  Data Acquisition
  3. 3. Boeing 787 Fatigue Test Rack of instruments to measure strain
  4. 4. Definitions & Theory Strain gauge Thermocouple Channel Sample rate Waveform Waveform generator
  5. 5. Why test hardware? Verification Validation
  6. 6. Software Techniques Don’t Help Unit Tests Mocking TDD
  7. 7. What does help? Spec-based testing Test stand automation A good test framework
  8. 8. Bed-of-nails tester Engineering test rig
  9. 9. Test Framework Requirements Easily design broad tests from spec def module_test_1(suite, cl, slave_cls): def verify(result, success, args): if not success: Control external return False if result[-1] != args: equipment return False return True Easy math handling arg1 = 0.1 arg2 = 0.2 calls = [Call(cl.InstrumentSpecific.ThisIsAMethod, arg1, arg2), Set(cl.InstrumentSpecific, "ThisIsAProperty", arg1), Get(cl.InstrumentSpecific, "ThisIsAProperty")] suite.add(calls, verify, arg1) def add(suite, cl, slave_cls): module_test_1(suite, cl, slave_cls)
  10. 10. Designing tests based on hardware specs Phase alignment on multiple instruments must be within 0.000010 arc seconds Discrete Fourier Transform Amplitude Phase
  11. 11. Phase AlignmentAligned Out of Phase
  12. 12. Controlling external equipment Specifications  IEEE 488.2 (1975)  SCPI (1990)  VXI-11 (1995)Agilent 33220A Waveform Generator
  13. 13. Controlling external equipmentfrom vxi11client import *class ag33120(TCPVXI11Client): timeout = 10000 def __init__(self, hostname, gpib): TCPVXI11Client.__init__(self, hostname, 1, gpib) def query(self, str): self.device_write(self.lid, self.timeout, self.timeout, 0, str) return self.device_read(self.lid, 256, self.timeout, self.timeout, 0x80,0x0a) def check_error(self): res = self.query(":SYST:ERR?n") err, msg = res.data.split(",") if int(err) != 0: raise Exception(res.data) def reset(self): self.device_write(self.lid, self.timeout, self.timeout, 0, "*RST;n") def apply(self, func, freq=None, amp=None, off=None): freq = self._defopt(freq) amp = self._defopt(amp) off = self._defopt(off) return self.query("APPLY:%s %s, %s, %s; *OPC?n" % (func, freq, amp, off)) def _defopt(self, arg): if arg == None: return "DEF" return "%12.7e" % arg
  14. 14. Controlling external equipment def dc(self, off=None): return self.query("APPLY:DC 1, 1, %s; *OPC?n" % (off)) def set_highimpedance_mode(self): return self.query("OUTP:LOAD 9.9E37; *OPC?n") def sine(self, freq=None, amp=None, off=None): return self.apply("SIN", freq, amp, off) def square(self, freq=None, amp=None, off=None): return self.apply("SQU", freq, amp, off) def triangle(self, freq=None, amp=None, off=None): return self.apply("TRI", freq, amp, off) def ramp(self, freq=None, amp=None, off=None): return self.apply("RAMP", freq, amp, off)
  15. 15. Phase Alignment Test# Data acquisition characteristics:FILTER_TYPE = ex1629constants.IIRFILTER_TYPE_NONESAMP_FREQ = 1000.0SAMPLE_COUNT = 1000# Expected input: 1V peak (2V peak-to-peak) sine wave at 10Hz.INPUT_AMPLITUDE = 1INPUT_FREQ = 10# Maximum tolerated skew (in seconds):MAX_PERMISSIBLE_SKEW = 0.000010def add_phase_test(suite, cl, slave_cls, wavegen)def add(suite, cl, slave_cls): wavegen = require_slaves(slave_cls, "ag33120") slaves = require_slaves(slave_cls, "ex1629") add_phase_test(suite, cl, slaves, wavegen)
  16. 16. Setup & Verifydef add_phase_test(suite, cl, slave_cls, wavegen): # Constant parameters PI = 4*atan(1) if suite.test_level == test.FULL_TEST: NUM_INNER_LOOPS = 2000 # approximately 13 hours with two devices else: NUM_INNER_LOOPS = 10 # approximately 4 minutes with 2 devices def verify(result, success, args): # Since the actual data analysis was performed in analyze_data, # we only need to check the function call returns to determine # overall success/failure. for call_result in result: if call_result == False: return False return success # set up the waveform generator # Sine wave at 10Hz, 1V peak (2V peak-to-peak), no offset calls = [Call(wavegen.reset), Call(wavegen.set_highimpedance_mode), Call(wavegen.sine(INPUT_FREQ, INPUT_AMPLITUDE, 0)] suite.add(calls) for config_name in config_sequence
  17. 17. Test Sequencefor config_name in config_sequence: calls = [] # Configure the master & slave devices calls += configure_device(cl) calls += configure_device_trigger(cl, configs[config_name][master]) for slave_cl in slave_cls: calls += configure_device(slave_cl) calls += configure_device_trigger(slave_cl, configs[config_name][slave]) suite.add(calls, verify, None) for inner_loop in range(0, NUM_INNER_LOOPS): calls = [] # Instruct the master device to issue a sync pulse calls += [Call(cl.soft_sync)] # Start acquiring data on each slave device for slave_cl in slave_cls: calls += [Call(slave_cl.trig_init)] # Start acquiring data on the master device calls += [Call(cl.trig_init)] # Issue a soft trigger command to the master device calls += [Call(cl.soft_trig)] # Read the data calls += [Call(analyze_data, cl, slave_cls, config_name)] suite.add(calls, verify, None) # Reset the slave devices & the master device calls = [] for slave_cl in slave_cls: calls += [Call(slave_cl.reset)] calls += [Call(cl.reset)] suite.add(calls, verify, None)
  18. 18. DFT CalculationN = len(device_result.datapages)n = INPUT_FREQ * N / SAMP_FREQval_dft_real = val_dft_imag = 0.0k = 0for page in device_result.datapages: val_dft_real += page.dataset[board][0].data[0] * cos(2*PI*n*k/N) val_dft_imag -= page.dataset[board][0].data[0] * sin(2*PI*n*k/N) k += 1val_magnitude = sqrt(pow(val_dft_imag, 2) + pow(val_dft_real, 2))/Nval_phase = atan2(val_dft_imag , val_dft_real)
  19. 19. Phase Alignment Test Data
  20. 20. Questions?

×