gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+xcp/MeasurementList.m
classdef MeasurementList < handle % MeasurementList Class that implements an XCP DAQ or STIM measurement list. % Authors: JDP % Copyright 2012 The MathWorks, Inc. properties % Number - The absolute/relative ODT number for this ODT. Number % ODTObject - An array of ODT objects for the ODTs that make up this list. ODTObject % Resource - Defines whether this is a DAQ or STIM list. Resource % EventInfo - A structure of event information for this list's event. EventInfo % MeasurementInfo - An array of structures of measurement information % for all measurements in this list. MeasurementInfo % A2LFileObject - An xcp.A2L file object. A2LFileObject % ListMode - The XCP code for this list mode (ex. defines DAQ or STIM). ListMode % STIMPeriod - The rate for STIM message output for a STIM list. STIMPeriod % STIMCounter - A counter for STIM message output. STIMCounter end properties (Dependent) % MeasurementNames - Quick reference to the names of all measurements % used by the list as a cell array of strings. MeasurementNames % NumberOfMeasurements - Quick reference to the number of measurements % used by the list. NumberOfMeasurements % NumberOfODTs - Quick reference to the number of ODTs in this list. NumberOfODTs end methods function obj = MeasurementList(a2lFileObject, resource, eventInfo, measurementInfo) % MeasurementList Object constructor. % % resource - String which defines whether this a 'DAQ' or 'STIM' list. % eventInfo - A structure of event information for the event to which % this measurement list is configured. % measurementInfo - An array of structures with information about the % measurements configured for this list. % Set basic properties from the input. obj.A2LFileObject = a2lFileObject; obj.Resource = resource; obj.EventInfo = eventInfo; obj.MeasurementInfo = measurementInfo; % Construct the list mode value for this list. switch obj.Resource case 'DAQ' % PID on, Timestamp off, Direction DAQ, Alternating disabled. obj.ListMode = bin2dec('00000000'); case 'STIM' % PID on, Timestamp off, Direction STIM, Alternating disabled. obj.ListMode = bin2dec('00000010'); end % Create the first ODT for this list. obj.ODTObject = xcp.ODT(obj.A2LFileObject); % Add the measurements to ODTs. for ii = 1:numel(obj.MeasurementInfo) % Initialize a tracking variable for placement success. measurementPlaced = false; % Try to place the measurement in each ODT until all are attempted. for jj = 1:numel(obj.ODTObject) % Add the measurement. measurementPlaced = obj.ODTObject(jj).addMeasurement(obj.MeasurementInfo(ii)); % If the measurement was placed, then move on. if measurementPlaced break; end end % If the measurement did not fit into any existing ODT, there is % more work to do. if ~measurementPlaced % Create a new ODT. obj.ODTObject = [obj.ODTObject xcp.ODT(obj.A2LFileObject)]; % Place the measurement in the new ODT. obj.ODTObject(end).addMeasurement(obj.MeasurementInfo(ii)); end end % For STIM lists, set the additional property values. if strcmpi(obj.Resource, 'STIM') % Set the event period in seconds as the STIM period. obj.STIMPeriod = obj.EventInfo.ChannelTimeCycleInSeconds; % Set the STIM counter to zero so that on the first execution % of the STIM list task the messages will transmit. obj.STIMCounter = 0; end end function setODTNumbers(obj, firstNumber) % setODTNumbers Sets ODT numbers as absolute/relative values. % % firstNumber - The number to use for the first ODT in the list when % absolute numbering is used. % % We need to know the ODT number for each ODT in order to decode the ODT % messages when they are received for DAQ or sent for STIM. This % method is used to set those values regardless of whether absolute % or relative numbering is used. % If relative numbering is used, then force the first number to be % zero so the numbering starts fresh regardless of the input. if ~strcmpi(obj.A2LFileObject.DAQInfo.IdentificationFieldType, ... xcp.Utility.IDENTIFICATION_FIELD_TYPE_ABSOLUTE); firstNumber = 0; end % Index through the ODTs and set the numbers. for ii = 1:obj.NumberOfODTs % Using the first number as a base and given we loop starting % at an index value of 1, we need to also subtract 1 so that the % math works out properly for zero indexing on the ODT number. obj.ODTObject(ii).Number = firstNumber + ii - 1; end end function value = getODTObject(obj, number) % getODTObject Finds and returns a handle to a specific ODT by number. % % number - The ODT number for which to search. % % value - xcp.ODT object handle matching the ODT/PID number. % % This method searches all the ODT objects in this list to find a % match to the provided ODT number. If no match is found, the % method returns empty. The number may refer to an absolute or % relative number, but the methods works the same either way. % Use logical indexing to identify the requested ODT. This method % will automatically return empty if an ODT is not found. value = obj.ODTObject(number == [obj.ODTObject.Number]); end function configureSTIMMessageObjects(obj) % configureSTIMMessageObjects Configures STIM message objects for transmit. % % This methods triggers configuration of the messages for STIM to be % sent by this measurement list. % If this is a DAQ list, just return. if strcmpi(obj.Resource, 'DAQ') return; end % Configure a STIM message for output for each ODT. for ii = 1:obj.NumberOfODTs % Build the STIM message object. obj.ODTObject(ii).STIMMessageObject = can.Message( ... obj.A2LFileObject.TransportLayerCANInfo.CANIDMaster, ... obj.A2LFileObject.TransportLayerCANInfo.CANIDMasterIsExtended, ... 8); % Set the ODT number in the message data. obj.ODTObject(ii).STIMMessageObject.Data(1) = obj.ODTObject(ii).Number; % Set the list number in the message data if necessary based on % the identification field type. switch obj.A2LFileObject.DAQInfo.IdentificationFieldType case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_BYTE obj.ODTObject(ii).STIMMessageObject.Data(2) = obj.Number; case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD obj.ODTObject(ii).STIMMessageObject.Data(2:3) = ... xcp.Utility.packParameter( ... obj.A2LFileObject.ProtocolLayerInfo.ByteOrder, ..., ... xcp.Utility.BYTES_IN_WORD, ... obj.Number); case xcp.Utility.IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD_ALIGNED obj.ODTObject(ii).STIMMessageObject.Data(3:4) = ... xcp.Utility.packParameter( ... obj.A2LFileObject.ProtocolLayerInfo.ByteOrder, ..., ... xcp.Utility.BYTES_IN_WORD, ... obj.Number); end end end function result = writeSTIMData(obj, measurement, value) % writeSTIMData Writes STIM data into the ODT STIM messages. % % measurement - The name of the measurement to update. % value - The data value to pack into the STIM message. % % result - Boolean value indicating success or failed write. % % This method write the provided data value into the ODT STIM message % for the given measurement. The new data will then be sent via the % transport layer when appropriate according to the list % configuration. The method returns true if the value was written % to an ODT STIM message, otherwise false. % If this is a DAQ list, just return. if strcmpi(obj.Resource, 'DAQ') result = false; return; end % Check that the specified measurement is configured in this list. if ~any(strcmp(measurement, obj.MeasurementNames)) % If not found, then return as a failed action. result = false; return; end % Pack the data value. for ii = 1:obj.NumberOfODTs % Try to write the value to each ODT. result = obj.ODTObject(ii).writeSTIMData(measurement, value); % Check the result. If the write worked, then return. if result return; end end % If we get this far, the measurement could not be written to this % ODT, so return false; result = false; end end methods % Custom get/set methods for properties. function value = get.MeasurementNames(obj) value = {obj.MeasurementInfo.Name}'; end function value = get.NumberOfMeasurements(obj) value = numel(obj.MeasurementInfo); end function value = get.NumberOfODTs(obj) value = numel(obj.ODTObject); end end % Custom get/set methods for properties. end