swig: Add support for isr/callbacks from python
Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
@@ -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 */
|
||||
/*@}*/
|
||||
|
||||
10
examples/python/hello_isr.py
Normal file
10
examples/python/hello_isr.py
Normal 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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
27
src/maa.i
27
src/maa.i
@@ -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 ####
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user