2

GPIOドライバーによって提供される関数のPython拡張機能を書いています。set_bit()やclear_bit()のような単純な関数でかなり簡単に進歩しました。しかし、今度はwait_int()を実装する必要があります。これは、入力ピンでイベントが検出されるまでスリープし、cとpythonの間でこれを調整する正しい方法がわかりません。これは、cで関数を使用する簡単な例です。

main(int argc, char *argv[])
{
    int c;

    //some setup like testing port availability, clearing interrupts, etc
    ...

    while(1)
    {
        printf("**\n");
        c = wait_int(1);//sleeps until an interrupt occurs on chip 1
        if(c > 0) {
            printf("Event sense occured on Chip 1 bit %d\n",c);
            ++event_count;
        }
        else
            break;
    }

    printf("Event count = %05d\r",event_count);
    printf("\nExiting Now\n");
}

wait_intをほとんど直接公開してから、Pythonで同等の無限ループのイディオムを実行しますか?実行する必要のあるデバウンスもいくつかあります。私はcでそれをしました、しかし多分それはpython側に移されるかもしれません。

4

1 に答える 1

3

Python側では何もする必要はなく、同期関数として扱うことができます。C側では、イベントが発生するまでブロックするだけで、割り込みが許可される可能性があります。たとえば、関数の実装を見てみましょう。time.sleep

/* LICENSE: http://docs.python.org/license.html */

/* Implement floatsleep() for various platforms.
   When interrupted (or when another error occurs), return -1 and
   set an exception; else return 0. */

static int
floatsleep(double secs)
{
/* XXX Should test for MS_WINDOWS first! */
#if defined(HAVE_SELECT) && !defined(__BEOS__) && !defined(__EMX__)
    struct timeval t;
    double frac;
    frac = fmod(secs, 1.0);
    secs = floor(secs);
    t.tv_sec = (long)secs;
    t.tv_usec = (long)(frac*1000000.0);
    Py_BEGIN_ALLOW_THREADS
    if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
#ifdef EINTR
        if (errno != EINTR) {
#else
        if (1) {
#endif
            Py_BLOCK_THREADS
            PyErr_SetFromErrno(PyExc_IOError);
            return -1;
        }
    }
    Py_END_ALLOW_THREADS
#elif defined(__WATCOMC__) && !defined(__QNX__)
    ...

関数を使用しselectて、指定された時間スリープするだけです。 select信号が受信された場合(SIGINT端末でCtrl + Cを押すなど)、システムコールが中断され、制御がPythonに戻るように使用されます。

したがって。実装はCwait_int関数を呼び出すだけです。シグナルによる割り込みをサポートしている場合は、ユーザーがCtrl + Cを押すことで割り込みできるようになりますが、例外がスローされるように適切に対応するようにしてください(これがどのように機能するかはわかりませんが、NULLトップレベルの関数(この例では)から戻るtime_sleepとうまくいくようです)。

同様に、マルチスレッドのパフォーマンスを向上させるには、待機呼び出しをPy_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADSマクロのペアで囲みますが、特にマルチスレッドをまったく使用していない場合は、これは必須ではありません。

于 2012-10-10T21:41:02.457 に答える