Private
Public Access
2
0

swig: Add support for isr/callbacks from python

Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
Brendan Le Foll
2014-05-13 20:45:00 +00:00
parent b8e0ca76b1
commit f7169cc5c5
6 changed files with 70 additions and 0 deletions

View File

@@ -34,6 +34,10 @@
extern "C" {
#endif
#ifdef SWIG
#include <Python.h>
#endif
#include <stdio.h>
#include <pthread.h>
@@ -46,7 +50,11 @@ typedef struct {
/*@{*/
int pin; /**< the pin number, as known to the os. */
int value_fp; /**< the file pointer to the value of the gpio */
#ifdef SWIG
PyObject *isr; /**< the interupt service request */
#else
void (* isr)(); /**< the interupt service request */
#endif
pthread_t thread_id; /**< the isr handler thread id */
int isr_value_fp; /**< the isr file pointer on the value */
/*@}*/

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env python
import pymaa as maa
def test():
print("wooo")
x = maa.Gpio(6)
x.dir(maa.MAA_GPIO_IN)
x.set_isr(test)

View File

@@ -124,7 +124,19 @@ maa_gpio_interrupt_handler(void* arg)
for (;;) {
ret = maa_gpio_wait_interrupt(dev->isr_value_fp);
if (ret == MAA_SUCCESS) {
#ifdef SWIG
// In order to call a python object (all python functions are objects) we
// need to aquire the GIL (Global Interpreter Lock). This may not always be
// nessecary but especially if doing IO (like print()) python will segfault
// if we do not hold a lock on the GIL
PyGILState_STATE gilstate = PyGILState_Ensure();
PyEval_CallObject(dev->isr, NULL);
PyGILState_Release (gilstate);
#else
dev->isr();
#endif
} else {
// we must have got an error code so die nicely
close(dev->isr_value_fp);
@@ -190,6 +202,11 @@ maa_gpio_isr_exit(maa_gpio_context *dev)
{
maa_result_t ret = MAA_SUCCESS;
#ifdef SWIG
// Dereference our Python call back function
Py_DECREF(dev->isr);
#endif
if (dev->thread_id == 0) {
return ret;
}

View File

@@ -55,6 +55,12 @@ maa_init()
if (plat != NULL) {
return MAA_ERROR_PLATFORM_ALREADY_INITIALISED;
}
#ifdef SWIG
// Initialise python threads, this allows use to grab the GIL when we are
// required to do so
Py_InitializeEx(0);
PyEval_InitThreads();
#endif
plat = maa_intel_galileo_rev_d();
return MAA_SUCCESS;
}

View File

@@ -8,6 +8,7 @@
%}
%init %{
//Adding maa_init() to the module initialisation process
maa_init();
%}
@@ -45,9 +46,19 @@ typedef struct {
/*@{*/
int pin; /**< the pin number, as known to the os. */
FILE *value_fp; /**< the file pointer to the value of the gpio */
#if defined(SWIGPYTHON)
PyObject *isr; /**< the interupt service request */
#endif
pthread_t thread_id; /**< the isr handler thread id */
int isr_value_fp; /**< the isr file pointer on the value */
/*@}*/
} maa_gpio_context;
%typemap(check) PyObject *pyfunc {
if (!PyCallable_Check($1))
SWIG_exception(SWIG_TypeError,"Expected function.");
}
%extend maa_gpio_context {
maa_gpio_context(int pin, int raw=0)
{
@@ -95,6 +106,22 @@ typedef struct {
{
return maa_gpio_mode($self, mode);
}
#if defined(SWIGPYTHON)
//set python method as the isr function
int set_isr(PyObject *pyfunc)
{
Py_INCREF(pyfunc);
// do a nasty cast to get away from the warnings
maa_gpio_isr(self, MAA_GPIO_EDGE_BOTH, pyfunc);
return 0;
}
#else
%ignore maa_gpio_isr;
#endif
int isr_exit()
{
maa_gpio_isr_exit(self);
}
}
#### i2c ####

View File

@@ -9,6 +9,8 @@ include_directories(
swig_add_module (pymaa python pymaa.i ${maa_LIB_SRCS})
swig_link_libraries (pymaa ${PYTHON_LIBRARIES})
set (CMAKE_C_FLAGS -DSWIG=${SWIG_FOUND})
if (DOXYGEN_FOUND)
foreach (_file ${DOCFILES})
add_dependencies (${SWIG_MODULE_pymaa_REAL_NAME} ${_file}doc_i)