From d9a31945a92a76e590657dc2e65bb20b6ea95d90 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 10:37:24 +0100 Subject: Merge script and transform view. Add get register and properties info to python wrap. --- docs/Doxyfile.in | 2 +- pcilib/pcipywrap.c | 331 +++++++++++++++++++++++++++++++++++++++++++++++---- pcilib/pcipywrap.i | 12 +- pcilib/py.c | 187 ++++++++++++++++++++++++++++- pcilib/py.h | 9 ++ pcilib/xml.c | 44 ++++--- views/CMakeLists.txt | 4 +- views/script.c | 206 -------------------------------- views/script.h | 18 --- views/transform.c | 52 +++++--- views/transform.h | 2 + 11 files changed, 579 insertions(+), 288 deletions(-) delete mode 100644 views/script.c delete mode 100644 views/script.h 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; @@ -52,17 +40,58 @@ void __setPyExeptionText(const char* msg, ...) free(buf); } +/*! + * \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 -#include - -#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 -#include -#include - -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 #include +#include 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 -- cgit v1.2.3