RPi :: Закрепить объекты - можно ли их уничтожить? Чтобы можно было создать еще один, используя этот пин? - PullRequest
1 голос
/ 01 марта 2020

RPi :: Закрепить объекты - похоже, они не могут быть должным образом уничтожены?

В этом (perl) тестовом фрагменте Test :: More я создаю булавку, использую ее (наблюдаю за миганием индикатора), затем уничтожаю объект булавки и пытаюсь создать другой. Это терпит неудачу, как показано ниже.

subtest 'pin level reuse' => sub {
my $pinNumber = 4;
my $pin = $wpi->pin ($pinNumber);
$pin->mode (OUTPUT);

# Blink to show it's working
diag "Light will blink";
$pin->write(1); sleep (.2); $pin->write(0); sleep (.2);
$pin->write(1); sleep (.2); $pin->write(0);
pass ('link');

# Now, can I destroy the pin object?
$pin = 0;
pass ('delete pin');

# Now, new pin object?
$pin = $wpi->pin ($pinNumber);
$pin->mode (OUTPUT);
pass ('create new pin');

# Blink to show it's working
diag "Light will blink";
$pin->write(1); sleep (.2); $pin->write(0); sleep (.2);
$pin->write(1); sleep (.2); $pin->write(0);
pass ('link');
};                              # subtest 'pin level reuse'

Это терпит неудачу:

# Subtest: pin level reuse
    # Light will blink
    ok 1 - link
    ok 2 - delete pin
    1..2
ok 6 - pin level reuse
not ok 7 # TODO & SKIP Reusing pins not working yet
# Looks like you planned 6 tests but ran 7.
sc@ordovik:~/repo $ t/Button-002-PI.t
2020/02/29 23:06:11 onPi 1
1..6
ok 1 - 'buttonInterruptQ' isa 'MCE::Shared::Object'
ok 2 - use RPi::WiringPi;
ok 3 - use RPi::Pin;
ok 4 - use Slideshow::Light;
ok 5 - use Slideshow::Button;
# Subtest: pin level reuse
    # Light will blink
    ok 1 - link
    ok 2 - delete pin

cleaned up, exiting...

original error:
pin 4 is already in use... can't create second object

Это просто ограничение? Или есть другие вызовы API, которые я должен сделать, чтобы в конечном итоге освободить булавку? (Они обязательно должны быть в деструкторе объекта RPi :: Pin, если так?)

1 Ответ

1 голос
/ 30 марта 2020

RPi :: WiringPi очень чувствителен к произвольно сдуваемым контактам и другим устройствам. Все они зарегистрированы внутри компании, чтобы избежать неприятностей. Я написал это с менталитетом, ориентированным на безопасность.

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

Кроме того, если у вас есть RPi::Pin объект как $pin, вы не можете просто произвольно установить его на 0, так как теперь вы удалили все функциональные возможности и данные объекта. Объект является объектом типа RPi::Pin. Изменение его на 0 устанавливает его как целое число.

Когда объект $wpi выходит из области видимости или вызывается clean(), он сбрасывает все используемые контакты к их настройкам по умолчанию, как они были при вызове сценария и отменяли его регистрацию для повторного использования.

Неразумно просто уничтожать объект булавки, потому что тогда вы не знаете, в каком состоянии он остался. Если вы хотите повторно -используйте булавку:

$wpi->unregister_pin($pin);
$pin = $wpi->pin($pin_number);

Однако unregister_pin(), хотя и оставленный publi c, является скорее внутренней вещью. Вместо того, чтобы удалять пин-код и повторно инициализировать его, гораздо лучше просто изменить режим или другие параметры на активном пин-коде. По сути, булавка - это то, что почти всегда используется для полного запуска приложения, а не то, что генерируется и уничтожается много раз за один запуск.

Еще лучше, для модульного тестирования я делю вещи на маленькие область применения:

my $pin = 18;

{ # test 1
    my $wpi = RPi::WiringPi->new;
    my $pin = $wpi->pin($num);

    $pin->mode(OUTPUT);

    is $pin->mode, OUTPUT, "pin mode is output for pin $num";

    # end of scope; everything will be properly cleaned up and destroyed
}

{ # test 2
    my $wpi = RPi::WiringPi->new;
    my $pin = $wpi->pin($num);

    is $pin->mode, INPUT, "pin mode is input for pin $num";
}    
...