F
fredbasset1000
Hi,
I've written a C extension, see code below, to provide a Python
interface to a hardware watchdog timer. As part of the initialization
it makes some calls to mmap, I am wondering should I be making
balanced calls to munmap in some kind of de-init function? Do Python
extensions have d'tors?
Thanks for any help,
Fred
----------------------------------------------------------------------------------------------
#include <Python.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <inttypes.h>
#include <errno.h>
static const uint8_t WD_PAT_VALUE = 0x05; // hard coded value to
indicate a pat to the watchdog
static uint8_t* wdt_control = NULL;
static uint8_t* wdt_feed = NULL;
/*!
\brief Initialize the watchdog timer and start it.
\param[in] int timeout_period, value to pass to timeout register
0x00 - 0x07, see table above.
\return void
*/
static PyObject* init(PyObject *self, PyObject *args) {
int period;
int fd;
if (!PyArg_Parse(args, "(i)", &period)) {
PyErr_SetString(PyExc_TypeError, "single integer argument
expected");
return NULL;
}
if (period <= 0x00 || period >= 0x07) {
PyErr_SetString(PyExc_ValueError, "watchdog reg. value out of
range (0x00 to 0x07 only)");
return NULL;
}
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
wdt_control = mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0x23800000);
if (wdt_control == MAP_FAILED) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
wdt_feed = mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0x23C00000);
if (wdt_feed == MAP_FAILED) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
*wdt_feed = WD_PAT_VALUE; // must first pat the w.d. before
setting period
*wdt_control = period;
Py_INCREF(Py_None);
return Py_None;
}
/*!
\brief Pat the watchdog timer once.
Always call init() before calling this function.
\return void
*/
static PyObject* pat(PyObject *self, PyObject *args)
{
if (!PyArg_Parse(args, "( )")) { // verify no args passed
return NULL;
}
if (wdt_feed != NULL) {
*wdt_feed = WD_PAT_VALUE;
}
Py_INCREF(Py_None);
return Py_None;
}
// method registration table
static struct PyMethodDef wdt_methods[] = {
{"init", init, METH_VARARGS},
{"pat", pat, METH_VARARGS},
{NULL, NULL}
};
// module initializer, called on first import
void initwdtmodule() {
(void) Py_InitModule("wdtmodule", wdt_methods);
}
I've written a C extension, see code below, to provide a Python
interface to a hardware watchdog timer. As part of the initialization
it makes some calls to mmap, I am wondering should I be making
balanced calls to munmap in some kind of de-init function? Do Python
extensions have d'tors?
Thanks for any help,
Fred
----------------------------------------------------------------------------------------------
#include <Python.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <inttypes.h>
#include <errno.h>
static const uint8_t WD_PAT_VALUE = 0x05; // hard coded value to
indicate a pat to the watchdog
static uint8_t* wdt_control = NULL;
static uint8_t* wdt_feed = NULL;
/*!
\brief Initialize the watchdog timer and start it.
\param[in] int timeout_period, value to pass to timeout register
0x00 - 0x07, see table above.
\return void
*/
static PyObject* init(PyObject *self, PyObject *args) {
int period;
int fd;
if (!PyArg_Parse(args, "(i)", &period)) {
PyErr_SetString(PyExc_TypeError, "single integer argument
expected");
return NULL;
}
if (period <= 0x00 || period >= 0x07) {
PyErr_SetString(PyExc_ValueError, "watchdog reg. value out of
range (0x00 to 0x07 only)");
return NULL;
}
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd == -1) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
wdt_control = mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0x23800000);
if (wdt_control == MAP_FAILED) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
wdt_feed = mmap(0, getpagesize(), PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0x23C00000);
if (wdt_feed == MAP_FAILED) {
PyErr_SetString(PyExc_SystemError, strerror(errno));
return NULL;
}
*wdt_feed = WD_PAT_VALUE; // must first pat the w.d. before
setting period
*wdt_control = period;
Py_INCREF(Py_None);
return Py_None;
}
/*!
\brief Pat the watchdog timer once.
Always call init() before calling this function.
\return void
*/
static PyObject* pat(PyObject *self, PyObject *args)
{
if (!PyArg_Parse(args, "( )")) { // verify no args passed
return NULL;
}
if (wdt_feed != NULL) {
*wdt_feed = WD_PAT_VALUE;
}
Py_INCREF(Py_None);
return Py_None;
}
// method registration table
static struct PyMethodDef wdt_methods[] = {
{"init", init, METH_VARARGS},
{"pat", pat, METH_VARARGS},
{NULL, NULL}
};
// module initializer, called on first import
void initwdtmodule() {
(void) Py_InitModule("wdtmodule", wdt_methods);
}