Изчисляване на забавянето между запис и четене на 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 е много проста линейна комуникация и всички използвани устройства успяха да произведат изходните данни в рамките на микросекунди.

Използвате ли 100kHz, 400kHz или 1MHz 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. FYI, не гласувах против. - person JavaCake; 28.01.2015
comment
Радвам се, че успях да ти помогна в крайна сметка. - person KZD76; 28.01.2015