Вычисление задержки между записью и чтением на I2C в Linux

В настоящее время я работаю с I2C в Arch Linux Arm и не совсем уверен, как рассчитать абсолютную минимальную задержку, которая требуется между записью и чтением. Если у меня нет этой задержки, чтение, естественно, не проходит. Я только что применил usleep(1000) между двумя командами, что работает, но это просто сделано эмпирически и должно быть оптимизировано до реального значения (каким-то образом). Но как?.

Вот мой пример кода для функции write_and_read, которую я использую:

int write_and_read(int handler, char *buffer, const int bytesToWrite, const int bytesToRead) {
    write(handler, buffer, bytesToWrite);
    usleep(1000);
    int r = read(handler, buffer, bytesToRead);
    if(r != bytesToRead) {
        return -1;
    }
    return 0;
}

person JavaCake    schedule 22.01.2015    source источник


Ответы (1)


Обычно ждать не нужно. Если ваши функции записи и чтения каким-то образом работают в фоновом режиме (зачем вам это делать???), то их синхронизация обязательна.

I2C — это очень простая линейная связь, и все устройства, которые я использовал, могли выдавать выходные данные в течение микросекунд.

Вы используете 100 кГц, 400 кГц или 1 МГц I2C?

Отредактировано: после некоторого обсуждения я предлагаю вам попробовать:

void dataRequest() {
    Wire.write(0x76);
    x = 0;
}

void dataReceive(int numBytes)
{
    x = numBytes;
    for (int i = 0; i < numBytes; i++) {
        Wire.read();
    }
}

Где x — глобальная переменная, определенная в заголовке, которой присваивается значение 0 в setup(). Вы можете попробовать добавить простое условие if в основной цикл, например если x > 0, то отправьте что-нибудь в serial.print() в качестве отладочного сообщения, а затем сбросьте x до 0.

При этом вы не блокируете работу I2C с последовательным трафиком.

person KZD76    schedule 28.01.2015
comment
Сначала я так и думал, но это не работает без задержки между записью и чтением. - person JavaCake; 28.01.2015
comment
Что такое функция записи? С каким устройством вы общаетесь? - person KZD76; 28.01.2015
comment
Я использую linux/i2c-dev.h. Устройства представляют собой простые контроллеры Atmel/Arduino. - person JavaCake; 28.01.2015
comment
На Arduino есть ли задержка в вашем основном цикле или в событиях приема/запроса? - person KZD76; 28.01.2015
comment
У меня никогда не было задержек в моем цикле. На самом деле моя петля пуста, пока мы говорим. Есть только прерывания для функций приема и запроса. - person JavaCake; 28.01.2015
comment
Другие варианты, которые я думаю попробовать: очистить все в событиях получения и запроса, чтобы не блокировать там код, затем, если это сработает, попытаться сделать все в событии приема, событие запроса должно быть простой функцией ответа без какой-либо логики. - person KZD76; 28.01.2015
comment
Я только возвращаю данные в запросе и делаю почти все в получении, как вы описываете. У меня есть логический анализатор, который я собираюсь использовать для определения частоты, с которой работает шина I2C. - person JavaCake; 28.01.2015
comment
Является ли какая-то часть вашего кода Arduino общедоступной? Я бы попробовал запустить в своей архитектуре. - person KZD76; 28.01.2015
comment
Это в основном то, что у меня есть сейчас: gist.github.com/anonymous/0b62be94302c26b4c6fb - person JavaCake; 28.01.2015
comment
Последовательная связь может замедлить обработку, и в этом случае ваш код задерживает связь I2C. Я отредактировал свой ответ с помощью кода, не могли бы вы попробовать? - person KZD76; 28.01.2015
comment
Я только что сделал тест, и проходит только первая команда получения, все остальное после этого не вызывает обратный вызов получения. - person JavaCake; 28.01.2015
comment
Извините, забыл прочитать данные, которые вы отправили. Модифицировал код циклом for. - person KZD76; 28.01.2015
comment
Очень глупая ошибка. Я забыл прочитать в Arduino. К вашему сведению, я не минусовал. - person JavaCake; 28.01.2015
comment
Я рад, что смог помочь вам в конце концов. - person KZD76; 28.01.2015