summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-02-11 10:37:24 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-02-11 10:37:24 +0100
commitd9a31945a92a76e590657dc2e65bb20b6ea95d90 (patch)
tree22dd29b528d62625ec8801504282d33445646d1f
parentdce856c1a16098fe7a1df2338df60073261da94a (diff)
downloadpcitool-d9a31945a92a76e590657dc2e65bb20b6ea95d90.tar.gz
pcitool-d9a31945a92a76e590657dc2e65bb20b6ea95d90.tar.bz2
pcitool-d9a31945a92a76e590657dc2e65bb20b6ea95d90.tar.xz
pcitool-d9a31945a92a76e590657dc2e65bb20b6ea95d90.zip
Merge script and transform view. Add get register and properties info to python wrap.
-rw-r--r--docs/Doxyfile.in2
-rw-r--r--pcilib/pcipywrap.c331
-rw-r--r--pcilib/pcipywrap.i12
-rw-r--r--pcilib/py.c187
-rw-r--r--pcilib/py.h9
-rw-r--r--pcilib/xml.c44
-rw-r--r--views/CMakeLists.txt4
-rw-r--r--views/script.c206
-rw-r--r--views/script.h18
-rw-r--r--views/transform.c52
-rw-r--r--views/transform.h2
11 files changed, 579 insertions, 288 deletions
diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in
index f87b220..9303846 100644
--- a/docs/Doxyfile.in
+++ b/docs/Doxyfile.in
@@ -1486,7 +1486,7 @@ MATHJAX_CODEFILE =
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
-SEARCHENGINE = NO
+SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c
index 50a3074..d950de3 100644
--- a/pcilib/pcipywrap.c
+++ b/pcilib/pcipywrap.c
@@ -4,30 +4,18 @@
/*!
* \brief Global pointer to pcilib_t context.
- * Used by __setPcilib and read_register.
+ * Used by setPcilib and read_register.
*/
pcilib_t* __ctx = 0;
/*!
- * \brief Wraps for pcilib_open function.
- * \param[in] fpga_device path to the device file [/dev/fpga0]
- * \param[in] model specifies the model of hardware, autodetected if NULL is passed
- * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray
- */
-PyObject* __createPcilibInstance(const char *fpga_device, const char *model)
-{
- //opening device
- pcilib_t* ctx = pcilib_open(fpga_device, model);
-
- //serializing object
- return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
-}
-
-/*!
* \brief Sets python exeption text. Function interface same as printf.
*/
void __setPyExeptionText(const char* msg, ...)
{
+ if(!Py_IsInitialized())
+ Py_Initialize();
+
char *buf;
size_t sz;
@@ -53,16 +41,57 @@ void __setPyExeptionText(const char* msg, ...)
}
/*!
+ * \brief Wraps for pcilib_open function.
+ * \param[in] fpga_device path to the device file [/dev/fpga0]
+ * \param[in] model specifies the model of hardware, autodetected if NULL is passed
+ * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray; NULL with exeption text, if failed.
+ */
+PyObject* createPcilibInstance(const char *fpga_device, const char *model)
+{
+ //opening device
+ pcilib_t* ctx = pcilib_open(fpga_device, model);
+ if(!ctx)
+ {
+ __setPyExeptionText("Failed pcilib_open(%s, %s)", fpga_device, model);
+ return NULL;
+ }
+
+ //serializing object
+ return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
+}
+
+/*!
+ * \brief Closes current pciliv instance, if its open.
+ */
+void closeCurrentPcilibInstance()
+{
+ if(__ctx)
+ {
+ pcilib_close(__ctx);
+ __ctx = NULL;
+ }
+}
+
+/*!
+ * \brief Returns current opened pcilib_t instatnce
+ * \return Pointer to pcilib_t, serialized to bytearray
+ */
+PyObject* getCurrentPcilibInstance()
+{
+ return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*));
+}
+
+/*!
* \brief Sets pcilib context to wraper.
* \param[in] addr Pointer to pcilib_t, serialized to bytearray
* \return 1, serialized to PyObject or NULL with exeption text, if failed.
*/
-PyObject* __setPcilib(PyObject* addr)
+PyObject* setPcilib(PyObject* addr)
{
if(!PyByteArray_Check(addr))
{
- __setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed");
- return;
+ __setPyExeptionText("Incorrect addr type. Only bytearray is allowed");
+ return NULL;
}
//deserializing adress
@@ -71,8 +100,6 @@ PyObject* __setPcilib(PyObject* addr)
//hard copy context adress
for(int i = 0; i < sizeof(pcilib_t*) + 10; i++)
((char*)&__ctx)[i] = pAddr[i];
-
- free(pAddr);
return PyInt_FromLong((long)1);
}
@@ -84,11 +111,13 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
switch(val->type)
{
case PCILIB_TYPE_INVALID:
- errstream("Invalid register output type (PCILIB_TYPE_INVALID)");
+ if(errstream)
+ errstream("Invalid register output type (PCILIB_TYPE_INVALID)");
return NULL;
case PCILIB_TYPE_STRING:
- errstream("Invalid register output type (PCILIB_TYPE_STRING)");
+ if(errstream)
+ errstream("Invalid register output type (PCILIB_TYPE_STRING)");
return NULL;
case PCILIB_TYPE_LONG:
@@ -98,7 +127,8 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
if(err)
{
- errstream("Failed: pcilib_get_value_as_int (%i)", err);
+ if(errstream)
+ errstream("Failed: pcilib_get_value_as_int (%i)", err);
return NULL;
}
return PyInt_FromLong((long) ret);
@@ -111,14 +141,16 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
if(err)
{
- errstream("Failed: pcilib_get_value_as_int (%i)", err);
+ if(errstream)
+ errstream("Failed: pcilib_get_value_as_int (%i)", err);
return NULL;
}
return PyFloat_FromDouble((double) ret);
}
default:
- errstream("Invalid register output type (unknown)");
+ if(errstream)
+ errstream("Invalid register output type (unknown)");
return NULL;
}
}
@@ -289,3 +321,250 @@ PyObject* set_property(const char *prop, PyObject* val)
return PyInt_FromLong((long)1);
}
+void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name)
+{
+ PyObject *py_val = pcilib_convert_val_to_pyobject(__ctx, val, NULL);
+
+ if(py_val)
+ PyDict_SetItem(dict,
+ PyString_FromString(name),
+ val);
+ else
+ PyDict_SetItem(dict,
+ PyString_FromString("defvalue"),
+ PyString_FromString("invalid"));
+}
+
+PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listItem)
+{
+ PyObject* pylistItem = PyDict_New();
+
+ if(listItem.name)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("name"),
+ PyString_FromString(listItem.name));
+
+ if(listItem.description)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("description"),
+ PyString_FromString(listItem.description));
+
+ if(listItem.path)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("path"),
+ PyString_FromString(listItem.path));
+
+ //serialize types
+ const char* type = "invalid";
+ switch(listItem.type)
+ {
+ case PCILIB_TYPE_INVALID:
+ type = "invalid";
+ break;
+ case PCILIB_TYPE_STRING:
+ type = "string";
+ break;
+ case PCILIB_TYPE_DOUBLE:
+ type = "double";
+ break;
+ case PCILIB_TYPE_LONG :
+ type = "long";
+ break;
+ default:
+ break;
+ }
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("type"),
+ PyString_FromString(type));
+
+
+ //serialize modes
+ PyObject* modes = PyList_New(0);
+
+ if((listItem.mode & PCILIB_ACCESS_R ) == PCILIB_REGISTER_R)
+ PyList_Append(modes, PyString_FromString("R"));
+ if((listItem.mode & PCILIB_ACCESS_W ) == PCILIB_REGISTER_W)
+ PyList_Append(modes, PyString_FromString("W"));
+ if((listItem.mode & PCILIB_ACCESS_RW ) == PCILIB_REGISTER_RW)
+ PyList_Append(modes, PyString_FromString("RW"));
+ if((listItem.mode & PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK)
+ PyList_Append(modes, PyString_FromString("NO_CHK"));
+
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("mode"),
+ modes);
+
+ //serialize flags
+ PyObject* flags = PyList_New(0);
+
+ if((listItem.flags & PCILIB_LIST_FLAG_CHILDS ) == PCILIB_LIST_FLAG_CHILDS)
+ PyList_Append(flags, PyString_FromString("childs"));
+
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("flags"),
+ flags);
+
+ if(listItem.unit)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("unit"),
+ PyString_FromString(listItem.unit));
+
+ return pylistItem;
+}
+
+PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listItem)
+{
+ PyObject* pylistItem = PyDict_New();
+
+ if(listItem.name)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("name"),
+ PyString_FromString(listItem.name));
+
+ if(listItem.description)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("description"),
+ PyString_FromString(listItem.description));
+
+ if(listItem.bank)
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("bank"),
+ PyString_FromString(listItem.bank));
+
+ //serialize modes
+ PyObject* modes = PyList_New(0);
+
+ if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R)
+ PyList_Append(modes, PyString_FromString("R"));
+ if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W)
+ PyList_Append(modes, PyString_FromString("W"));
+ if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW)
+ PyList_Append(modes, PyString_FromString("RW"));
+ if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C)
+ PyList_Append(modes, PyString_FromString("W1C"));
+ if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C)
+ PyList_Append(modes, PyString_FromString("RW1C"));
+ if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I)
+ PyList_Append(modes, PyString_FromString("W1I"));
+ if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I)
+ PyList_Append(modes, PyString_FromString("RW1I"));
+ if((listItem.mode & PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK)
+ PyList_Append(modes, PyString_FromString("NO_CHK"));
+
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("mode"),
+ modes);
+ add_pcilib_value_to_dict(pylistItem, &listItem.defvalue, "defvalue");
+
+ if(listItem.range)
+ {
+ PyObject* range = PyDict_New();
+ add_pcilib_value_to_dict(range, &(listItem.range->min), "min");
+ add_pcilib_value_to_dict(range, &(listItem.range->max), "max");
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("range"),
+ range);
+ }
+
+ if(listItem.values)
+ {
+ PyObject* values = PyList_New(0);
+
+ for (int j = 0; listItem.values[j].name; j++)
+ {
+ PyObject* valuesItem = PyDict_New();
+
+ add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].value), "value");
+ add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].min), "min");
+ add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].max), "max");
+
+ if(listItem.values[j].name)
+ PyDict_SetItem(valuesItem,
+ PyString_FromString("name"),
+ PyString_FromString(listItem.values[j].name));
+
+ if(listItem.values[j].description)
+ PyDict_SetItem(valuesItem,
+ PyString_FromString("name"),
+ PyString_FromString(listItem.values[j].description));
+
+ PyList_Append(values, valuesItem);
+ }
+
+ PyDict_SetItem(pylistItem,
+ PyString_FromString("values"),
+ values);
+ }
+
+ return pylistItem;
+}
+
+PyObject* get_register_list(const char *bank)
+{
+ if(!__ctx)
+ {
+ __setPyExeptionText("pcilib_t handler not initialized");
+ return NULL;
+ }
+
+ pcilib_register_info_t *list = pcilib_get_register_list(__ctx, bank, PCILIB_LIST_FLAGS_DEFAULT);
+
+ PyObject* pyList = PyList_New(0);
+ for(int i = 0; i < __ctx->num_reg; i++)
+ {
+ //serialize item attributes
+ PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(list[i]);
+ PyList_Append(pyList, pylistItem);
+ }
+
+ pcilib_free_register_info(__ctx, list);
+
+ return pyList;
+}
+
+PyObject* get_register_info(const char* reg,const char *bank)
+{
+ if(!__ctx)
+ {
+ __setPyExeptionText("pcilib_t handler not initialized");
+ return NULL;
+ }
+
+ pcilib_register_info_t *info = pcilib_get_register_info(__ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT);
+
+ if(!info)
+ {
+ __setPyExeptionText("Failed pcilib_get_register_info");
+ return NULL;
+ }
+
+ PyObject* py_info = pcilib_convert_register_info_to_pyobject(info[0]);
+
+ pcilib_free_register_info(__ctx, info);
+
+ return py_info;
+}
+
+PyObject* get_property_info(const char* branch)
+{
+ if(!__ctx)
+ {
+ __setPyExeptionText("pcilib_t handler not initialized");
+ return NULL;
+ }
+
+ pcilib_property_info_t *list = pcilib_get_property_list(__ctx, branch, PCILIB_LIST_FLAGS_DEFAULT);
+
+ PyObject* pyList = PyList_New(0);
+
+ for(int i = 0; i < list[i].path; i++)
+ {
+ //serialize item attributes
+ PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(list[i]);
+ PyList_Append(pyList, pylistItem);
+ }
+
+ pcilib_free_property_info(__ctx, list);
+
+ return pyList;
+}
diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i
index cd632f8..10a95a7 100644
--- a/pcilib/pcipywrap.i
+++ b/pcilib/pcipywrap.i
@@ -1,10 +1,18 @@
%module pcipywrap
-extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL);
-extern PyObject* __setPcilib(PyObject* addr);
+
+extern PyObject* createPcilibInstance(const char *fpga_device, const char *model = NULL);
+extern PyObject* setPcilib(PyObject* addr);
+extern void closeCurrentPcilibInstance();
+extern PyObject* getCurrentPcilibInstance();
extern PyObject* read_register(const char *regname, const char *bank = NULL);
extern PyObject* write_register(PyObject* val, const char *regname, const char *bank = NULL);
extern PyObject* get_property(const char *prop);
extern PyObject* set_property(const char *prop, PyObject* val);
+
+extern PyObject* get_register_list(const char *bank = NULL);
+extern PyObject* get_register_info(const char* reg,const char *bank = NULL);
+
+extern PyObject* get_property_info(const char* branch = NULL);
diff --git a/pcilib/py.c b/pcilib/py.c
index 13113d7..20b85a1 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -16,11 +16,18 @@ struct pcilib_py_s {
PyObject *global_dict;
};
+struct pcilib_script_s {
+ PyObject *py_script_module; /**< PyModule object, contains script enviroment */
+ PyObject *dict;
+ char* script_name;
+};
+
int pcilib_init_py(pcilib_t *ctx) {
ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
if (!ctx->py) return PCILIB_ERROR_MEMORY;
- Py_Initialize();
+ if(!Py_IsInitialized())
+ Py_Initialize();
ctx->py->main_module = PyImport_AddModule("__parser__");
if (!ctx->py->main_module)
@@ -35,12 +42,11 @@ int pcilib_init_py(pcilib_t *ctx) {
void pcilib_free_py(pcilib_t *ctx) {
if (ctx->py) {
- // Dict and module references are borrowed
+ // Dict and module references are borrowed
free(ctx->py);
ctx->py = NULL;
}
-
- Py_Finalize();
+ //Py_Finalize();
}
/*
@@ -189,3 +195,176 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
}
+
+
+int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode)
+{
+ int err;
+
+ //Initialize python script, if it has not initialized already.
+ if(!module_name)
+ {
+ pcilib_error("Invalid script name specified in XML property (NULL)");
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+ //create path string to scripts
+ char* model_dir = getenv("PCILIB_MODEL_DIR");
+ char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2);
+ if (!model_path) return PCILIB_ERROR_MEMORY;
+ sprintf(model_path, "%s/%s", model_dir, ctx->model);
+
+ //set model path to python
+ PySys_SetPath(model_path);
+ free(model_path);
+ model_path = NULL;
+
+ //create path string to pcipywrap library
+ char* app_dir = getenv("APP_PATH");
+ char* pcipywrap_path;
+ if(app_dir)
+ {
+ pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib"));
+ if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
+ sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model);
+ }
+ else
+ {
+ pcipywrap_path = malloc(strlen("./pcilib"));
+ if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
+ sprintf(pcipywrap_path, "%s", "./pcilib");
+
+ }
+
+ //set pcipywrap library path to python
+ PyObject* path = PySys_GetObject("path");
+ if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1)
+ {
+ pcilib_error("Cant set pcipywrap library path to python.");
+ return PCILIB_ERROR_FAILED;
+ }
+ free(pcipywrap_path);
+ pcipywrap_path = NULL;
+
+
+ //extract module name from script name
+ char* py_module_name = strtok(module_name, ".");
+
+ if(!py_module_name)
+ {
+ pcilib_error("Invalid script name specified in XML property (%s)."
+ " Seems like name doesnt contains extension", module_name);
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+ //import python script
+ PyObject* py_script_module = PyImport_ImportModule(py_module_name);
+
+ if(!py_script_module)
+ {
+ printf("Error in import python module: ");
+ PyErr_Print();
+ return PCILIB_ERROR_INVALID_DATA;
+ }
+
+
+ //Initializing pcipywrap module if script use it
+ PyObject* dict = PyModule_GetDict(py_script_module);
+ if(PyDict_Contains(dict, PyString_FromString("pcipywrap")))
+ {
+ PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap");
+ if(!pcipywrap_module)
+ {
+ pcilib_error("Cant extract pcipywrap module from script dictionary");
+ return PCILIB_ERROR_FAILED;
+ }
+
+ //setting pcilib_t instance
+ PyObject_CallMethodObjArgs(pcipywrap_module,
+ PyUnicode_FromString("setPcilib"),
+ PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)),
+ NULL);
+ }
+
+ //Success. Create struct and initialize values
+ module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
+ module[0]->py_script_module = py_script_module;
+ module[0]->script_name = module_name;
+ module[0]->dict = dict;
+
+ //Setting correct mode
+ mode[0] = 0;
+ if(PyDict_Contains(dict, PyString_FromString("read_from_register")))
+ mode[0] |= PCILIB_ACCESS_R;
+ if(PyDict_Contains(dict, PyString_FromString("write_to_register")))
+ mode[0] |= PCILIB_ACCESS_W;
+
+ return 0;
+}
+
+int pcilib_free_py_script(pcilib_script_t *module)
+{
+ if(module)
+ {
+ if(module->script_name)
+ {
+ free(module->script_name);
+ module->script_name = NULL;
+ }
+
+ if(module->py_script_module)
+ {
+ //PyObject_Free(module->py_script_module);
+ module->py_script_module = NULL;
+ }
+ }
+}
+
+int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val)
+{
+
+ int err;
+
+ PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()");
+ if (!ret)
+ {
+ printf("Python script error: ");
+ PyErr_Print();
+ return PCILIB_ERROR_FAILED;
+ }
+
+ err = pcilib_convert_pyobject_to_val(ctx, ret, val);
+
+ if(err)
+ {
+ pcilib_error("Failed to convert python script return value to internal type: %i", err);
+ return err;
+ }
+ return 0;
+}
+
+int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val)
+{
+ int err;
+
+ PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf);
+ if(!input)
+ {
+ printf("Failed to convert input value to Python object");
+ PyErr_Print();
+ return PCILIB_ERROR_FAILED;
+ }
+
+ PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module,
+ PyUnicode_FromString("write_to_register"),
+ input,
+ NULL);
+ if (!ret)
+ {
+ printf("Python script error: ");
+ PyErr_Print();
+ return PCILIB_ERROR_FAILED;
+ }
+
+ return 0;
+}
diff --git a/pcilib/py.h b/pcilib/py.h
index 21c31e9..8fd749c 100644
--- a/pcilib/py.h
+++ b/pcilib/py.h
@@ -1,7 +1,10 @@
#ifndef _PCILIB_PY_H
#define _PCILIB_PY_H
+#include "pcilib.h"
+
typedef struct pcilib_py_s pcilib_py_t;
+typedef struct pcilib_script_s pcilib_script_t;
#ifdef __cplusplus
extern "C" {
@@ -11,6 +14,12 @@ int pcilib_init_py(pcilib_t *ctx);
int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value);
void pcilib_free_py(pcilib_t *ctx);
+
+int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode);
+int pcilib_free_py_script(pcilib_script_t *module);
+int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val);
+int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val);
+
#ifdef __cplusplus
}
#endif
diff --git a/pcilib/xml.c b/pcilib/xml.c
index 099da76..f21480c 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -42,7 +42,7 @@
#include "view.h"
#include "views/enum.h"
#include "views/transform.h"
-#include "views/script.h"
+#include "py.h"
#define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */
@@ -559,15 +559,15 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath
xmlAttrPtr cur;
const char *value, *name;
pcilib_view_context_t *view_ctx;
+
- pcilib_access_mode_t mode = PCILIB_REGISTER_NO_CHK;
- pcilib_script_view_description_t desc = {{0}};
+ pcilib_access_mode_t mode = 0;
+ pcilib_transform_view_description_t desc = {{0}};
- desc.base.api = &pcilib_script_view_api;
+ desc.base.api = &pcilib_transform_view_api;
desc.base.type = PCILIB_TYPE_DOUBLE;
desc.base.mode = PCILIB_ACCESS_RW;
- desc.py_script_module = NULL;
- desc.script_name = NULL;
+ desc.script = NULL;
err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
if (err) return err;
@@ -580,14 +580,16 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath
value = (char*)cur->children->content;
if (!value) continue;
- if (!strcasecmp(name, "script")) {
+ if (!strcasecmp(name, "script"))
+ {
//write script name to struct
- desc.script_name = malloc(strlen(value));
- sprintf(desc.script_name, "%s", value);
- //set read write access
- mode |= PCILIB_ACCESS_R;
- mode |= PCILIB_ACCESS_W;
- }
+ char* script_name = malloc(strlen(value));
+ sprintf(script_name, "%s", value);
+
+ err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode);
+ if(err) return err;
+ mode |= PCILIB_REGISTER_NO_CHK;
+ }
}
desc.base.mode &= mode;
@@ -611,6 +613,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
desc.base.api = &pcilib_transform_view_api;
desc.base.type = PCILIB_TYPE_DOUBLE;
desc.base.mode = PCILIB_ACCESS_RW;
+ desc.script = NULL;
err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
if (err) return err;
@@ -641,7 +644,15 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
}
desc.write_to_reg = value;
if ((value)&&(*value)) mode |= PCILIB_ACCESS_W;
- }
+ } else if (!strcasecmp(name, "script")) {
+ char* script_name = malloc(strlen(value));
+ sprintf(script_name, "%s", value);
+
+ err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode);
+ if(err) return err;
+ mode |= PCILIB_REGISTER_NO_CHK;
+ break;
+ }
}
desc.base.mode &= mode;
@@ -654,6 +665,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
}
static int pcilib_xml_create_script_or_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+ /*
int err;
xmlAttrPtr cur;
const char *name;
@@ -688,9 +700,11 @@ static int pcilib_xml_create_script_or_transform_view(pcilib_t *ctx, xmlXPathCon
}
if(has_script)
+
return pcilib_xml_create_script_view(ctx, xpath, doc, node);
else
- return pcilib_xml_create_transform_view(ctx, xpath, doc, node);
+ */
+ return pcilib_xml_create_transform_view(ctx, xpath, doc, node);
}
diff --git a/views/CMakeLists.txt b/views/CMakeLists.txt
index c060067..0e0c20b 100644
--- a/views/CMakeLists.txt
+++ b/views/CMakeLists.txt
@@ -8,6 +8,6 @@ include_directories(
${UTHASH_INCLUDE_DIRS}
)
-set(HEADERS ${HEADERS} enum.h transform.h register.h script.h)
+set(HEADERS ${HEADERS} enum.h transform.h register.h)
-add_library(views STATIC enum.c transform.c register.c script.c)
+add_library(views STATIC enum.c transform.c register.c)
diff --git a/views/script.c b/views/script.c
deleted file mode 100644
index 3d018e9..0000000
--- a/views/script.c
+++ /dev/null
@@ -1,206 +0,0 @@
-#define _PCILIB_VIEW_TRANSFORM_C
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pci.h"
-#include "pcipywrap.h"
-#include "error.h"
-
-#include "model.h"
-#include "script.h"
-
-static int pcilib_script_view_module_init(pcilib_t *ctx, pcilib_script_view_description_t *v)
-{
- int err;
-
- //Initialize python script, if it has not initialized already.
- if(!v->py_script_module)
- {
- if(!v->script_name)
- {
- pcilib_error("Invalid script name specified in XML property (NULL)");
- return PCILIB_ERROR_INVALID_DATA;
- }
-
- //create path string to scripts
- char* model_dir = getenv("PCILIB_MODEL_DIR");
- char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2);
- if (!model_path) return PCILIB_ERROR_MEMORY;
- sprintf(model_path, "%s/%s", model_dir, ctx->model);
-
- //set model path to python
- PySys_SetPath(model_path);
- free(model_path);
- model_path = NULL;
-
- //create path string to pcipywrap library
- char* app_dir = getenv("APP_PATH");
- char* pcipywrap_path;
- if(app_dir)
- {
- pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib"));
- if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
- sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model);
- }
- else
- {
- pcipywrap_path = malloc(strlen("./pcilib"));
- if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
- sprintf(pcipywrap_path, "%s", "./pcilib");
-
- }
-
- //set pcipywrap library path to python
- PyObject* path = PySys_GetObject("path");
- if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1)
- {
- pcilib_error("Cant set pcipywrap library path to python.");
- return PCILIB_ERROR_FAILED;
- }
- free(pcipywrap_path);
- pcipywrap_path = NULL;
-
-
- //extract module name from script name
- char* py_module_name = strtok(v->script_name, ".");
-
- if(!py_module_name)
- {
- pcilib_error("Invalid script name specified in XML property (%s)."
- " Seems like name doesnt contains extension", v->script_name);
- return PCILIB_ERROR_INVALID_DATA;
- }
-
- //import python script
- v->py_script_module = PyImport_ImportModule(py_module_name);
-
- if(!v->py_script_module)
- {
- printf("Error in import python module: ");
- PyErr_Print();
- return PCILIB_ERROR_INVALID_DATA;
- }
- }
-
- //Initializing pcipywrap module if script use it
- PyObject* dict = PyModule_GetDict(v->py_script_module);
- if(PyDict_Contains(dict, PyString_FromString("pcipywrap")))
- {
- PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap");
- if(!pcipywrap_module)
- {
- pcilib_error("Cant extract pcipywrap module from script dictionary");
- return PCILIB_ERROR_FAILED;
- }
-
- //setting pcilib_t instance
- PyObject_CallMethodObjArgs(pcipywrap_module,
- PyUnicode_FromString("__setPcilib"),
- PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)),
- NULL);
- }
-
- return 0;
-}
-
-static int pcilib_script_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) {
-
- int err;
-
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(model_info->views[view_ctx->view]);
-
- err = pcilib_script_view_module_init(ctx, v);
- if(err)
- return err;
-
- PyObject *ret = PyObject_CallMethod(v->py_script_module, "read_from_register", "()");
- if (!ret)
- {
- printf("Python script error: ");
- PyErr_Print();
- return PCILIB_ERROR_FAILED;
- }
-
- err = pcilib_convert_pyobject_to_val(ctx, ret, val);
-
- if(err)
- {
- pcilib_error("Failed to convert python script return value to internal type: %i", err);
- return err;
- }
- return 0;
-}
-
-static int pcilib_script_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, pcilib_value_t *val) {
-
- int err;
-
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(model_info->views[view_ctx->view]);
-
- err = pcilib_script_view_module_init(ctx, v);
- if(err)
- return err;
-
- PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf);
- if(!input)
- {
- printf("Failed to convert input value to Python object");
- PyErr_Print();
- return PCILIB_ERROR_FAILED;
- }
-
- PyObject *ret = PyObject_CallMethodObjArgs(v->py_script_module,
- PyUnicode_FromString("write_to_register"),
- input,
- NULL);
- if (!ret)
- {
- printf("Python script error: ");
- PyErr_Print();
- return PCILIB_ERROR_FAILED;
- }
-
- //convert output value back to pcilib_value_t
- //no need because it wont be used later, and the script return could be none
- /*
- err = pcilib_convert_pyobject_to_val(ctx, ret, val);
- if(err)
- {
- pcilib_error("failed to convert script write_to_register function return value to internal type: %i", err);
- return err;
- }
-
- uint64_t output = pcilib_get_value_as_register_value(ctx, val, &err);
- if(err)
- {
- pcilib_error("failed to convert value to register value (%i)", err);
- return err;
- }
- regval[0] = output;
- */
-
- return 0;
-}
-
-void pcilib_script_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view)
-{
- pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(view);
-
- if(v->script_name)
- {
- free(v->script_name);
- v->script_name = NULL;
- }
-
- if(v->py_script_module)
- {
- PyObject_Free(v->py_script_module);
- v->py_script_module = NULL;
- }
-}
-
-const pcilib_view_api_description_t pcilib_script_view_api =
- { PCILIB_VERSION, sizeof(pcilib_script_view_description_t), NULL, NULL, pcilib_script_view_free_description, pcilib_script_view_read, pcilib_script_view_write};
diff --git a/views/script.h b/views/script.h
deleted file mode 100644
index 2929f4c..0000000
--- a/views/script.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _PCILIB_VIEW_SCRIPT_H
-#define _PCILIB_VIEW_SCRIPT_H
-
-#include <pcilib.h>
-#include <pcilib/view.h>
-#include <Python.h>
-
-typedef struct {
- pcilib_view_description_t base;
- PyObject *py_script_module; /**< PyModule object, contains script enviroment */
- char* script_name;
-} pcilib_script_view_description_t;
-
-#ifndef _PCILIB_VIEW_SCRIPT_C
-const pcilib_view_api_description_t pcilib_script_view_api;
-#endif /* _PCILIB_VIEW_SCRIPT_C */
-
-#endif /* _PCILIB_VIEW_SCRIPT_H */
diff --git a/views/transform.c b/views/transform.c
index de7ee0e..f47e4ef 100644
--- a/views/transform.c
+++ b/views/transform.c
@@ -12,34 +12,58 @@
static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) {
- int err;
-
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]);
- err = pcilib_set_value_from_register_value(ctx, val, regval);
- if (err) return err;
+ if(v->script)
+ {
+ return pcilib_script_read(ctx, v->script, val);
+ }
+ else
+ {
+ int err;
+
+ err = pcilib_set_value_from_register_value(ctx, val, regval);
+ if (err) return err;
- return pcilib_py_eval_string(ctx, v->read_from_reg, val);
+ return pcilib_py_eval_string(ctx, v->read_from_reg, val);
+ }
}
static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, const pcilib_value_t *val) {
- int err = 0;
- pcilib_value_t val_copy = {0};
+
+
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]);
- err = pcilib_copy_value(ctx, &val_copy, val);
- if (err) return err;
- err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
- if (err) return err;
+ if(!v->script)
+ {
+ int err = 0;
+
+ pcilib_value_t val_copy = {0};
+ err = pcilib_copy_value(ctx, &val_copy, val);
+ if (err) return err;
+
+ err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
+ if (err) return err;
+
+ *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err);
+ return err;
+ }
+ else
+ pcilib_script_write(ctx, v->script, val);
+}
- *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err);
- return err;
+void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view)
+{
+ pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view);
+
+ if(v->script)
+ pcilib_free_py_script(v->script);
}
const pcilib_view_api_description_t pcilib_transform_view_api =
- { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, NULL, pcilib_transform_view_read, pcilib_transform_view_write };
+ { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write };
diff --git a/views/transform.h b/views/transform.h
index f474552..8ab4f4f 100644
--- a/views/transform.h
+++ b/views/transform.h
@@ -3,11 +3,13 @@
#include <pcilib.h>
#include <pcilib/view.h>
+#include <py.h>
typedef struct {
pcilib_view_description_t base;
const char *read_from_reg; /**< Formula explaining how to convert the register value to the view value */
const char *write_to_reg; /**< Formula explaining how to convert from the view value to the register value */
+ pcilib_script_t *script;
} pcilib_transform_view_description_t;
#ifndef _PCILIB_VIEW_TRANSFORM_C