Как бы вы смоделировали это устройство? - PullRequest
0 голосов
/ 27 августа 2009

Я создаю собственное диагностическое приложение для продукта, который имеет несколько устройств с индивидуальной адресацией на шине I2C.

Общая идея заключается в том, что я запрашиваю каждое устройство на шине и получаю байтовый массив «необработанных данных». Длина байтового массива зависит от конкретного устройства.

Я создал абстрактный класс с именем «FormattedData» с одним свойством «RawData».

public abstract class FormattedData {

    protected byte[] _rawData;

    public FormattedData(int rawDataLength) {
        _rawData = new byte[rawDataLength];
    }

    public byte[] RawData {
        get { return _rawData; }
        set {
            if (value.Length != _rawData.Length) {
                throw new ArgumentOutOfRangeException("RawData",
                    "The Raw Data byte array for a " + this.GetType().Name +
                    " must be " + _rawData.Length.ToString() + "-bytes long." +
                    Environment.NewLine +
                    "Length of supplied array: [" + value.Length.ToString() + "]");
            }

            _rawData = value;
        }
    }
}

Каждое устройство на шине I2C получает свою собственную модель, наследуя от FormattedData.

Затем я могу предоставить кучу свойств для устройства, манипулируя данными из байтового массива RawData по мере необходимости. Для моих целей данные все только для чтения. Например:

public class MyTestDevice : FormattedData {

    public MyTestDevice()
        : base(256) {
    }

    public string VendorName {
        get { return (ASCIIEncoding.ASCII.GetString(_rawData, 20, 16)); }
        set { ;}
    }

    public bool LossOfSignal {
        get { return ((_rawData[110] & 0x02) == 0x02); }
        set { ;}
    }
}

Итак, на мой вопрос.

Я создаю модель для приемопередатчика SFP на основе спецификации SFF-8472 .

Короче говоря, одно физическое устройство SFP имеет 2 таблицы необработанных данных (AO и A2). Каждая таблица данных должна запрашиваться независимо и может возвращать до 256 байтов.

Проблема состоит в том, что пара свойств из таблицы A2 зависит от значений из таблицы A0 (некоторые аналоговые значения из таблицы A2 масштабируются по-разному в зависимости от флага, установленного в таблице A0).

Как лучше всего смоделировать подобное устройство с помощью более одного байтового массива «Сырые данные», и где возможно, что значения из одного массива могут зависеть от значений из другого?

Я бы хотел поддерживать какой-то стандартный интерфейс для всех устройств, если это возможно.

Ответы [ 2 ]

0 голосов
/ 27 августа 2009

В итоге я изменил FormattedData, чтобы он мог содержать переменное число байтовых массивов RawData.

Конструктор принимает список KeyValuePairs. Каждый ключ представляет собой описание массива RawData, а каждое значение указывает длину этого массива.

Затем я могу индексировать любой массив RawData, используя его описание.

public abstract class FormattedData {

    protected Dictionary<string, byte[]> _rawData = new Dictionary<string, byte[]>();

    public FormattedData(IEnumerable<KeyValuePair<string, int>> rawDataConfigs) {
        rawDataConfigs.ToList()
            .ForEach(kvp => _rawData.Add(kvp.Key, new byte[kvp.Value]));
    }

    public IEnumerable<string> RawDataNames {
        get {
            foreach (var kvp in _rawData) {
                yield return kvp.Key;
            }
        }
    }

    public byte[] this[string rawDataName] {
        get {
            return _rawData[rawDataName];
        }
        set {
            if (value.Length != _rawData[rawDataName].Length) {
                throw new ArgumentOutOfRangeException("RawData",
                    "The Raw Data byte array for a " + this.GetType().Name +
                    " must be " + _rawData[rawDataName].Length.ToString() + "-bytes long." +
                    Environment.NewLine +
                    "Length of supplied array: [" + value.Length.ToString() + "]");
            }

            _rawData[rawDataName] = value;
        }
    }
}

Мое обновленное тестовое устройство выглядит следующим образом (два массива RawData - один называется «A0», а другой - «A2»):

public class MyTestDevice: FormattedData {

    const string A0 = "A0";
    const string A2 = "A2";
    const int _rawDataLength_A0 = 256;
    const int _rawDataLength_A2 = 256;

    static readonly Dictionary<string, int> _rawDataConfigs =
        new Dictionary<string, int> {
            {A0, _rawDataLength_A0},
            {A2, _rawDataLength_A2}    
        };

    public MyTestDevice()
        : base(_rawDataConfigs) {
    }

    public string VendorName {
        get { return (ASCIIEncoding.ASCII.GetString(_rawData[A0], 20, 16)); }
        set { ;}
    }

     public bool LossOfSignal {
        get { return ((_rawData[A0][110] & 0x02) == 0x02); }
        set { ;}

    }
}

Я думаю, что смогу смоделировать практически любое устройство I2C, используя этот подход - любое устройство с несколькими страницами (например, EEPROM или XFP) или несколькими таблицами необработанных данных (например, SFP) должно подойти.

Комментарии или критика?

0 голосов
/ 27 августа 2009
  • Создайте класс, который отформатировал данные в качестве одного из его членов.
  • Это должно выглядеть так же, как MyTestDevice.
  • Расширьте этот класс, чтобы иметь 2 члена formattedData для локальных устройств.
  • Измените функции VendorName и т. Д. Для использования обеих таблиц.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...