From 99c165c078222c789d5fc90a79c756c8fffdafea Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 3 Feb 2016 16:48:45 +0100 Subject: Add python wrap for pcilib --- pcilib/CMakeLists.txt | 13 ++++ pcilib/pcipywrap.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++ pcilib/pcipywrap.i | 6 ++ 3 files changed, 209 insertions(+) create mode 100644 pcilib/pcipywrap.c create mode 100644 pcilib/pcipywrap.i (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index cdc9c3f..ea275a3 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -13,6 +13,19 @@ add_library(pcilib SHARED pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c expo target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols views) +#Creating python wrapping +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +SET(CMAKE_SWIG_FLAGS "") + +SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") +SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c) +SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES}) +#wrapping end + install(TARGETS pcilib LIBRARY DESTINATION lib${LIB_SUFFIX} ) diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c new file mode 100644 index 0000000..5abd56c --- /dev/null +++ b/pcilib/pcipywrap.c @@ -0,0 +1,190 @@ +#include "pcilib.h" + +//Remove unused headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "pcitool/sysinfo.h" +#include "pcitool/formaters.h" + +#include "views/transform.h" +#include "views/enum.h" +#include "pci.h" +#include "plugin.h" +#include "config.h" +#include "tools.h" +#include "kmem.h" +#include "error.h" +#include "debug.h" +#include "model.h" +#include "locking.h" + +pcilib_t* __ctx = 0; +pcilib_model_description_t *model_info = 0; + +/*! + * \brief присваивание указателя на устройство. Закрытая функция. Будет проходить при парсинге xml. + * \param ctx + */ +void __initCtx(void* ctx) +{ + __ctx = ctx; +} + +/*! + * \brief создание хэндлера устройства, для тестирования скрипта не из программы. + * \return + */ +void __createCtxInstance(const char *fpga_device, const char *model) +{ + __ctx = pcilib_open(fpga_device, model); + model_info = pcilib_get_model_description(__ctx); +} + +int read_register(const char *bank, const char *regname, void *value) +{ + int ret = pcilib_read_register(__ctx, bank, regname, (pcilib_register_value_t*)value); + return ret; +} + +void Error(const char *message, const char *attr, ...) +{ + printf("Catch error: %s, %s\n", message, attr); +} + +int ReadRegister(const char *bank, const char *reg) { + + const char *view = NULL; + const char *unit = NULL; + const char *attr = NULL; + pcilib_t *handle = __ctx; + int i; + int err; + const char *format; + + pcilib_register_bank_t bank_id; + pcilib_register_bank_addr_t bank_addr = 0; + + pcilib_register_value_t value; + + // Adding DMA registers + pcilib_get_dma_description(handle); + + if (reg||view||attr) { + pcilib_value_t val = {0}; + if (attr) { + if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val); + else if (view) err = pcilib_get_property_attr(handle, view, attr, &val); + else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val); + else err = PCILIB_ERROR_INVALID_ARGUMENT; + + if (err) { + if (err == PCILIB_ERROR_NOTFOUND) + Error("Attribute %s is not found", attr); + else + Error("Error (%i) reading attribute %s", err, attr); + } + + err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); + if (err) Error("Error converting attribute %s to string", attr); + + printf("%s = %s", attr, val.sval); + if ((val.unit)&&(strcasecmp(val.unit, "name"))) + printf(" %s", val.unit); + printf(" (for %s)\n", (reg?reg:(view?view:bank))); + } else if (view) { + if (reg) { + err = pcilib_read_register_view(handle, bank, reg, view, &val); + if (err) Error("Error reading view %s of register %s", view, reg); + } else { + err = pcilib_get_property(handle, view, &val); + if (err) Error("Error reading property %s", view); + } + + if (unit) { + err = pcilib_convert_value_unit(handle, &val, unit); + if (err) { + if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit); + else Error("Error converting property %s to unit %s", view, unit); + } + } + + err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); + if (err) { + if (reg) Error("Error converting view %s of register %s to string", view); + else Error("Error converting property %s to string", view); + } + + printf("%s = %s", (reg?reg:view), val.sval); + if ((val.unit)&&(strcasecmp(val.unit, "name"))) + printf(" %s", val.unit); + printf("\n"); + } else { + pcilib_register_t regid = pcilib_find_register(handle, bank, reg); + bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); + format = model_info->banks[bank_id].format; + if (!format) format = "%lu"; + err = pcilib_read_register_by_id(handle, regid, &value); + if (err) Error("Error reading register %s", reg); + + printf("%s = ", reg); + printf(format, value); + printf("\n"); + } + } else { + if (model_info->registers) { + if (bank) { + bank_id = pcilib_find_register_bank(handle, bank); + bank_addr = model_info->banks[bank_id].addr; + } + + printf("Registers:\n"); + for (i = 0; model_info->registers[i].bits; i++) { + if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { + bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank); + format = model_info->banks[bank_id].format; + if (!format) format = "%lu"; + + err = pcilib_read_register_by_id(handle, i, &value); + if (err) printf(" %s = error reading value", model_info->registers[i].name); + else { + printf(" %s = ", model_info->registers[i].name); + printf(format, value); + } + + printf(" ["); + printf(format, model_info->registers[i].defvalue); + printf("]"); + printf("\n"); + } + } + } else { + printf("No registers"); + } + printf("\n"); + } + + return 0; +} diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i new file mode 100644 index 0000000..fc7f4ef --- /dev/null +++ b/pcilib/pcipywrap.i @@ -0,0 +1,6 @@ +%module pcipywrap +/*extern void* __ctx;*/ +extern void __initCtx(void* ctx); +extern void __createCtxInstance(const char *fpga_device, const char *model); +extern int read_register(const char *bank, const char *regname, void *value); +extern int ReadRegister(const char *reg); -- cgit v1.2.3 From 5349163e93a107fdfea2ad58760f6149a8d749b0 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 5 Feb 2016 12:33:48 +0100 Subject: Add support for python script properties. Correct pcilib python wrapping. Update examples. Update cmakelists for work in shadow build mode. --- pcilib/CMakeLists.txt | 1 - pcilib/pcipywrap.c | 271 +++++++++++++++++++------------------------------- pcilib/pcipywrap.i | 9 +- pcilib/py.c | 1 - pcilib/xml.c | 65 +++++++++++- 5 files changed, 168 insertions(+), 179 deletions(-) (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index ea275a3..db74775 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -24,7 +24,6 @@ SET(CMAKE_SWIG_FLAGS "") SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c) SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES}) -#wrapping end install(TARGETS pcilib LIBRARY DESTINATION lib${LIB_SUFFIX} diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index 5abd56c..efce909 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -1,190 +1,125 @@ #include "pcilib.h" - -//Remove unused headers -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "pcitool/sysinfo.h" -#include "pcitool/formaters.h" - -#include "views/transform.h" -#include "views/enum.h" +#include #include "pci.h" -#include "plugin.h" -#include "config.h" -#include "tools.h" -#include "kmem.h" #include "error.h" -#include "debug.h" -#include "model.h" -#include "locking.h" +/*! + * \brief Global pointer to pcilib_t context. + * Used by __setPcilib and read_register. + */ pcilib_t* __ctx = 0; -pcilib_model_description_t *model_info = 0; /*! - * \brief присваивание указателя на устройство. Закрытая функция. Будет проходить при парсинге xml. - * \param ctx + * \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 */ -void __initCtx(void* ctx) +PyObject* __createPcilibInstance(const char *fpga_device, const char *model) { - __ctx = ctx; + //opening device + pcilib_t* ctx = pcilib_open(fpga_device, model); + + //serializing object + return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)); } /*! - * \brief создание хэндлера устройства, для тестирования скрипта не из программы. - * \return + * \brief Sets pcilib context to wraper. + * \param[in] addr Pointer to pcilib_t, serialized to bytearray */ -void __createCtxInstance(const char *fpga_device, const char *model) +void __setPcilib(PyObject* addr) { - __ctx = pcilib_open(fpga_device, model); - model_info = pcilib_get_model_description(__ctx); -} - -int read_register(const char *bank, const char *regname, void *value) -{ - int ret = pcilib_read_register(__ctx, bank, regname, (pcilib_register_value_t*)value); - return ret; -} - -void Error(const char *message, const char *attr, ...) -{ - printf("Catch error: %s, %s\n", message, attr); + if(!PyByteArray_Check(addr)) + { + PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); + return NULL; + } + + //deserializing adress + char* pAddr = PyByteArray_AsString(addr); + + //hard copy context adress + for(int i = 0; i < sizeof(pcilib_t*) + 10; i++) + ((char*)&__ctx)[i] = pAddr[i]; + + free(pAddr); } -int ReadRegister(const char *bank, const char *reg) { +/*! + * \brief Reads register value. + * \param[in] regname the name of the register + * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise + * \return register value, can be integer or float type + */ +PyObject* read_register(const char *regname, const char *bank) +{ + if(!__ctx) + { + PyErr_SetString(PyExc_Exception, "pcilib_t handler not initialized"); + return NULL; + } - const char *view = NULL; - const char *unit = NULL; - const char *attr = NULL; - pcilib_t *handle = __ctx; - int i; - int err; - const char *format; - - pcilib_register_bank_t bank_id; - pcilib_register_bank_addr_t bank_addr = 0; - - pcilib_register_value_t value; - - // Adding DMA registers - pcilib_get_dma_description(handle); - - if (reg||view||attr) { - pcilib_value_t val = {0}; - if (attr) { - if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val); - else if (view) err = pcilib_get_property_attr(handle, view, attr, &val); - else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val); - else err = PCILIB_ERROR_INVALID_ARGUMENT; - - if (err) { - if (err == PCILIB_ERROR_NOTFOUND) - Error("Attribute %s is not found", attr); - else - Error("Error (%i) reading attribute %s", err, attr); - } - - err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); - if (err) Error("Error converting attribute %s to string", attr); - - printf("%s = %s", attr, val.sval); - if ((val.unit)&&(strcasecmp(val.unit, "name"))) - printf(" %s", val.unit); - printf(" (for %s)\n", (reg?reg:(view?view:bank))); - } else if (view) { - if (reg) { - err = pcilib_read_register_view(handle, bank, reg, view, &val); - if (err) Error("Error reading view %s of register %s", view, reg); - } else { - err = pcilib_get_property(handle, view, &val); - if (err) Error("Error reading property %s", view); - } - - if (unit) { - err = pcilib_convert_value_unit(handle, &val, unit); - if (err) { - if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit); - else Error("Error converting property %s to unit %s", view, unit); - } - } - - err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING); - if (err) { - if (reg) Error("Error converting view %s of register %s to string", view); - else Error("Error converting property %s to string", view); - } - - printf("%s = %s", (reg?reg:view), val.sval); - if ((val.unit)&&(strcasecmp(val.unit, "name"))) - printf(" %s", val.unit); - printf("\n"); - } else { - pcilib_register_t regid = pcilib_find_register(handle, bank, reg); - bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - err = pcilib_read_register_by_id(handle, regid, &value); - if (err) Error("Error reading register %s", reg); - - printf("%s = ", reg); - printf(format, value); - printf("\n"); + pcilib_get_dma_description(__ctx); + + pcilib_value_t val = {0}; + pcilib_register_value_t reg_value; + + int err; + + err = pcilib_read_register(__ctx, bank, regname, ®_value); + if(err) + { + PyErr_SetString(PyExc_Exception, "Failed: read_register"); + return NULL; + } + + err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); + + if(err) + { + PyErr_SetString(PyExc_Exception, "Failed: pcilib_set_value_from_register_value"); + return NULL; } - } else { - if (model_info->registers) { - if (bank) { - bank_id = pcilib_find_register_bank(handle, bank); - bank_addr = model_info->banks[bank_id].addr; - } - - printf("Registers:\n"); - for (i = 0; model_info->registers[i].bits; i++) { - if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { - bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank); - format = model_info->banks[bank_id].format; - if (!format) format = "%lu"; - - err = pcilib_read_register_by_id(handle, i, &value); - if (err) printf(" %s = error reading value", model_info->registers[i].name); - else { - printf(" %s = ", model_info->registers[i].name); - printf(format, value); - } - printf(" ["); - printf(format, model_info->registers[i].defvalue); - printf("]"); - printf("\n"); + switch(val.type) + { + case PCILIB_TYPE_INVALID: + PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_INVALID)"); + return NULL; + + case PCILIB_TYPE_STRING: + PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_STRING)"); + return NULL; + + case PCILIB_TYPE_LONG: + { + long ret; + ret = pcilib_get_value_as_int(__ctx, &val, &err); + + if(err) + { + PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); + return NULL; + } + return PyInt_FromLong((long) ret); } - } - } else { - printf("No registers"); + + case PCILIB_TYPE_DOUBLE: + { + double ret; + ret = pcilib_get_value_as_float(__ctx, &val, &err); + + if(err) + { + PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); + return NULL; + } + return PyFloat_FromDouble((double) ret); + } + + default: + PyErr_SetString(PyExc_Exception, "Invalid register output type (unknown)"); + return NULL; } - printf("\n"); - } - - return 0; } diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i index fc7f4ef..ed5ca62 100644 --- a/pcilib/pcipywrap.i +++ b/pcilib/pcipywrap.i @@ -1,6 +1,5 @@ %module pcipywrap -/*extern void* __ctx;*/ -extern void __initCtx(void* ctx); -extern void __createCtxInstance(const char *fpga_device, const char *model); -extern int read_register(const char *bank, const char *regname, void *value); -extern int ReadRegister(const char *reg); + +extern PyObject* read_register(const char *regname, const char *bank = NULL); +extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL); +extern void __setPcilib(PyObject* addr); diff --git a/pcilib/py.c b/pcilib/py.c index 4256afc..13113d7 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -5,7 +5,6 @@ #include #include - #include "pci.h" #include "debug.h" #include "pcilib.h" diff --git a/pcilib/xml.c b/pcilib/xml.c index 50aaa35..76ed38c 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -42,17 +42,19 @@ #include "view.h" #include "views/enum.h" #include "views/transform.h" +#include "views/script.h" #define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */ #define REGISTERS_PATH ((xmlChar*)"./register") /**< all standard registers nodes */ #define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */ #define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */ -#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */ +#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */ +#define SCRIPT_VIEWS_PATH ((xmlChar*)"/model/script") /**< path to complete nodes of views */ #define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */ #define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */ #define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */ -#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */ +#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */ @@ -543,6 +545,51 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc return 0; } +static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { + int err; + xmlAttrPtr cur; + const char *value, *name; + pcilib_view_context_t *view_ctx; + + pcilib_access_mode_t mode = 0; + pcilib_script_view_description_t desc = {{0}}; + + desc.base.api = &pcilib_script_view_api; + desc.base.type = PCILIB_TYPE_DOUBLE; + desc.base.mode = PCILIB_ACCESS_RW; + desc.py_script_module = NULL; + desc.script_name = NULL; + + err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc); + if (err) return err; + + for (cur = node->properties; cur != NULL; cur = cur->next) { + if (!cur->children) continue; + if (!xmlNodeIsText(cur->children)) continue; + + name = (char*)cur->name; + value = (char*)cur->children->content; + if (!value) continue; + + if (!strcasecmp(name, "script")) { + //write script name to struct + desc.script_name = malloc(strlen(value)); + sprintf(desc.script_name, "%s", value); + //set read access + mode |= PCILIB_ACCESS_R; + } + } + + desc.base.mode &= mode; + + err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); + if (err) return err; + + view_ctx->xml = node; + return 0; +} + + static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { int err; xmlAttrPtr cur; @@ -822,14 +869,16 @@ static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo */ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) { int err; - xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL; + xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL, script_nodes = NULL; xmlNodeSetPtr nodeset; int i; bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath); if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath); - if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); + if (transform_nodes) script_nodes = xmlXPathEvalExpression(SCRIPT_VIEWS_PATH, xpath); + if (script_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath); + if (!unit_nodes) { const unsigned char *expr = (enum_nodes?UNITS_PATH:(transform_nodes?ENUM_VIEWS_PATH:(bank_nodes?TRANSFORM_VIEWS_PATH:BANKS_PATH))); @@ -850,6 +899,14 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon if (err) pcilib_error("Error (%i) creating unit", err); } } + + nodeset = script_nodes->nodesetval; + if(!xmlXPathNodeSetIsEmpty(nodeset)) { + for(i=0; i < nodeset->nodeNr; i++) { + err = pcilib_xml_create_script_view(ctx, xpath, doc, nodeset->nodeTab[i]); + if (err) pcilib_error("Error (%i) creating script transform", err); + } + } nodeset = transform_nodes->nodesetval; if (!xmlXPathNodeSetIsEmpty(nodeset)) { -- cgit v1.2.3 From e10e102b8b0ff3bf35f16b5276d56059d242e1fd Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 8 Feb 2016 11:55:33 +0100 Subject: Add support for setting register value to script transfrom. Add set_property and get_property functions to pcipywrap. Cleaning cmakelists from unused dependencies --- pcilib/CMakeLists.txt | 8 +- pcilib/pcipywrap.c | 210 +++++++++++++++++++++++++++++++++++++++----------- pcilib/pcipywrap.i | 4 +- pcilib/xml.c | 60 +++++++++++---- 4 files changed, 215 insertions(+), 67 deletions(-) (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index db74775..41a1169 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -8,8 +8,8 @@ include_directories( ${UTHASH_INCLUDE_DIRS} ) -set(HEADERS pcilib.h pci.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) -add_library(pcilib SHARED pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) +set(HEADERS pcilib.h pci.h pcipywrap.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) +add_library(pcilib SHARED pci.c pcipywrap.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols views) @@ -22,8 +22,8 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) SET(CMAKE_SWIG_FLAGS "") SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") -SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c) -SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES}) +SWIG_ADD_MODULE(pcipywrap python pcipywrap.i) +SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) install(TARGETS pcilib LIBRARY DESTINATION lib${LIB_SUFFIX} diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index efce909..bed4b31 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -1,7 +1,6 @@ -#include "pcilib.h" -#include #include "pci.h" #include "error.h" +#include "pcipywrap.h" /*! * \brief Global pointer to pcilib_t context. @@ -24,16 +23,46 @@ PyObject* __createPcilibInstance(const char *fpga_device, const char *model) return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)); } +/*! + * \brief Sets python exeption text. Function interface same as printf. + */ +void setPyExeptionText(const char* msg, ...) +{ + char *buf; + size_t sz; + + va_list vl, vl_copy; + va_start(vl, msg); + va_copy(vl_copy, vl); + + sz = vsnprintf(NULL, 0, msg, vl); + buf = (char *)malloc(sz + 1); + + if(!buf) + { + PyErr_SetString(PyExc_Exception, "Memory error"); + return; + } + + vsnprintf(buf, sz+1, msg, vl_copy); + va_end(vl_copy); + va_end(vl); + + PyErr_SetString(PyExc_Exception, buf); + free(buf); +} + /*! * \brief Sets pcilib context to wraper. * \param[in] addr Pointer to pcilib_t, serialized to bytearray + * \return true, serialized to PyObject, NULL with exeption text, if failed. */ -void __setPcilib(PyObject* addr) +PyObject* __setPcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { - PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); - return NULL; + setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); + return; } //deserializing adress @@ -44,8 +73,82 @@ void __setPcilib(PyObject* addr) ((char*)&__ctx)[i] = pAddr[i]; free(pAddr); + + return PyInt_FromLong((long)1); } +PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, void (*errstream)(const char* msg, ...)) +{ + int err; + + switch(val->type) + { + case PCILIB_TYPE_INVALID: + errstream("Invalid register output type (PCILIB_TYPE_INVALID)"); + return NULL; + + case PCILIB_TYPE_STRING: + errstream("Invalid register output type (PCILIB_TYPE_STRING)"); + return NULL; + + case PCILIB_TYPE_LONG: + { + long ret; + ret = pcilib_get_value_as_int(__ctx, val, &err); + + if(err) + { + errstream("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return PyInt_FromLong((long) ret); + } + + case PCILIB_TYPE_DOUBLE: + { + double ret; + ret = pcilib_get_value_as_float(__ctx, val, &err); + + if(err) + { + errstream("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return PyFloat_FromDouble((double) ret); + } + + default: + errstream("Invalid register output type (unknown)"); + return NULL; + } +} + +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_t *val) +{ + int err; + + if(PyInt_Check(pyVal)) + { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); + } + else + if(PyFloat_Check(pyVal)) + err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); + else + if(PyString_Check(pyVal)) + err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); + else + { + pcilib_error("Invalid input. Input type should be int, float or string."); + return PCILIB_ERROR_NOTSUPPORTED; + } + if(err) + return err; + + return 0; +} + + /*! * \brief Reads register value. * \param[in] regname the name of the register @@ -53,10 +156,10 @@ void __setPcilib(PyObject* addr) * \return register value, can be integer or float type */ PyObject* read_register(const char *regname, const char *bank) -{ +{ if(!__ctx) { - PyErr_SetString(PyExc_Exception, "pcilib_t handler not initialized"); + setPyExeptionText("pcilib_t handler not initialized"); return NULL; } @@ -70,56 +173,69 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) { - PyErr_SetString(PyExc_Exception, "Failed: read_register"); + setPyExeptionText("Failed: read_register (%i)", err); return NULL; } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); - if(err) { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_set_value_from_register_value"); + setPyExeptionText("Failed: pcilib_set_value_from_register_value (%i)", err); return NULL; } - switch(val.type) + return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); +} + + +PyObject* get_property(const char *prop) +{ + if(!__ctx) { - case PCILIB_TYPE_INVALID: - PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_INVALID)"); - return NULL; - - case PCILIB_TYPE_STRING: - PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_STRING)"); - return NULL; - - case PCILIB_TYPE_LONG: - { - long ret; - ret = pcilib_get_value_as_int(__ctx, &val, &err); - - if(err) - { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); - return NULL; - } - return PyInt_FromLong((long) ret); - } - - case PCILIB_TYPE_DOUBLE: - { - double ret; - ret = pcilib_get_value_as_float(__ctx, &val, &err); - - if(err) - { - PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int"); - return NULL; - } - return PyFloat_FromDouble((double) ret); - } - - default: - PyErr_SetString(PyExc_Exception, "Invalid register output type (unknown)"); + setPyExeptionText("pcilib_t handler not initialized"); + return NULL; + } + + int err; + pcilib_value_t val = {0}; + + err = pcilib_get_property(__ctx, prop, &val); + + if(err) + { + setPyExeptionText("Failed pcilib_get_property (%i)", err); return NULL; } + + return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); +} + +PyObject* set_property(const char *prop, PyObject* val) +{ + int err; + + if(!__ctx) + { + setPyExeptionText("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val_internal = {0}; + err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + if(err) + { + setPyExeptionText("pcilib_convert_pyobject_to_val (%i)", err); + return NULL; + } + + err = pcilib_set_property(__ctx, prop, &val_internal); + + if(err) + { + setPyExeptionText("Failed pcilib_get_property (%i)", err); + return NULL; + } + + return PyInt_FromLong((long)1); } + diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i index ed5ca62..8d0f74e 100644 --- a/pcilib/pcipywrap.i +++ b/pcilib/pcipywrap.i @@ -2,4 +2,6 @@ extern PyObject* read_register(const char *regname, const char *bank = NULL); extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL); -extern void __setPcilib(PyObject* addr); +extern PyObject* __setPcilib(PyObject* addr); +extern PyObject* get_property(const char *prop); +extern PyObject* set_property(const char *prop, PyObject* val); diff --git a/pcilib/xml.c b/pcilib/xml.c index 76ed38c..2384e95 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -50,7 +50,6 @@ #define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */ #define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */ #define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */ -#define SCRIPT_VIEWS_PATH ((xmlChar*)"/model/script") /**< path to complete nodes of views */ #define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */ #define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */ #define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */ @@ -575,8 +574,9 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath //write script name to struct desc.script_name = malloc(strlen(value)); sprintf(desc.script_name, "%s", value); - //set read access + //set read write access mode |= PCILIB_ACCESS_R; + mode |= PCILIB_ACCESS_W; } } @@ -589,7 +589,6 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath return 0; } - static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { int err; xmlAttrPtr cur; @@ -644,6 +643,46 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp return 0; } +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; + + int has_read_from_register = 0; + int has_write_to_register = 0; + int has_script = 0; + + //getting transform name in case of error + pcilib_view_description_t desc = {0}; + err = pcilib_xml_parse_view(ctx, xpath, doc, node, &desc); + + for (cur = node->properties; cur != NULL; cur = cur->next) { + if (!cur->children) continue; + if (!xmlNodeIsText(cur->children)) continue; + + name = (char*)cur->name; + + if (!strcasecmp(name, "read_from_register")) + has_read_from_register = 1; + if (!strcasecmp(name, "write_to_register")) + has_write_to_register = 1; + if (!strcasecmp(name, "script")) + has_script = 1; + } + + if (has_script && (has_read_from_register || has_write_to_register)) { + pcilib_error("Invalid transform group attributes specified in XML property (%s)." + "Transform could not contains both script and read_from_register" + " or write_to_register attributes at same time.", desc.name); + return PCILIB_ERROR_INVALID_DATA; + } + + if(has_script) + return pcilib_xml_create_script_view(ctx, xpath, doc, node); + else + return pcilib_xml_create_transform_view(ctx, xpath, doc, node); +} + static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_value_name_t *desc) { xmlAttr *cur; @@ -869,14 +908,13 @@ static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo */ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) { int err; - xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL, script_nodes = NULL; + xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL; xmlNodeSetPtr nodeset; int i; bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath); if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath); - if (transform_nodes) script_nodes = xmlXPathEvalExpression(SCRIPT_VIEWS_PATH, xpath); - if (script_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); + if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath); @@ -899,19 +937,11 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon if (err) pcilib_error("Error (%i) creating unit", err); } } - - nodeset = script_nodes->nodesetval; - if(!xmlXPathNodeSetIsEmpty(nodeset)) { - for(i=0; i < nodeset->nodeNr; i++) { - err = pcilib_xml_create_script_view(ctx, xpath, doc, nodeset->nodeTab[i]); - if (err) pcilib_error("Error (%i) creating script transform", err); - } - } nodeset = transform_nodes->nodesetval; if (!xmlXPathNodeSetIsEmpty(nodeset)) { for(i=0; i < nodeset->nodeNr; i++) { - err = pcilib_xml_create_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); + err = pcilib_xml_create_script_or_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); if (err) pcilib_error("Error (%i) creating register transform", err); } } -- cgit v1.2.3 From aaac7b80d1e003a3dbc4fe0f831a68e5449c846d Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 8 Feb 2016 12:09:58 +0100 Subject: Add pcipywrap.h to repository --- pcilib/pcipywrap.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 pcilib/pcipywrap.h (limited to 'pcilib') diff --git a/pcilib/pcipywrap.h b/pcilib/pcipywrap.h new file mode 100644 index 0000000..c2bb749 --- /dev/null +++ b/pcilib/pcipywrap.h @@ -0,0 +1,25 @@ +#ifndef _PCITOOL_PCIPYWRAP_H +#define _PCITOOL_PCIPYWRAP_H +#include +#include "pcilib.h" + +/*! + * \brief Converts pcilib_value_t to PyObject. + * \param ctx pointer to pcilib_t context + * \param val pointer to pcilib_value_t to convert + * \return PyObject, containing value. NULL with error message, sended to errstream. + */ +PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, void (*errstream)(const char* msg, ...)); + + +/*! + * \brief Converts PyObject to pcilib_value_t. + * \param ctx pcilib context + * \param pyVal python object, containing value + * \param val initialized polymorphic value + * \return 0 on success or memory error + */ +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_t *val); + + +#endif /* _PCITOOL_PCIPYWRAP_H */ -- cgit v1.2.3 From dce856c1a16098fe7a1df2338df60073261da94a Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Tue, 9 Feb 2016 17:32:11 +0100 Subject: Add write_register python wrap. Add no_set_check attribute to pcilib_view_t type --- pcilib/CMakeLists.txt | 1 - pcilib/pcilib.h | 1 + pcilib/pcipywrap.c | 84 ++++++++++++++++++++++++++++++++++++++++----------- pcilib/pcipywrap.i | 5 ++- pcilib/xml.c | 16 ++++++++-- 5 files changed, 85 insertions(+), 22 deletions(-) (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index 41a1169..b1f5251 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -14,7 +14,6 @@ target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFO add_dependencies(pcilib dma protocols views) #Creating python wrapping -FIND_PACKAGE(SWIG REQUIRED) INCLUDE(${SWIG_USE_FILE}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index 3e7cf2b..4d2b7e9 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -54,6 +54,7 @@ typedef enum { PCILIB_REGISTER_RW1C = 5, PCILIB_REGISTER_W1I = 8, /**< writting 1 inversts the bit, writting 0 keeps the value */ PCILIB_REGISTER_RW1I = 9, + PCILIB_REGISTER_NO_CHK = 16 /**< dont check register value after set*/ } pcilib_register_mode_t; typedef enum { diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index bed4b31..50a3074 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -26,7 +26,7 @@ PyObject* __createPcilibInstance(const char *fpga_device, const char *model) /*! * \brief Sets python exeption text. Function interface same as printf. */ -void setPyExeptionText(const char* msg, ...) +void __setPyExeptionText(const char* msg, ...) { char *buf; size_t sz; @@ -55,13 +55,13 @@ void setPyExeptionText(const char* msg, ...) /*! * \brief Sets pcilib context to wraper. * \param[in] addr Pointer to pcilib_t, serialized to bytearray - * \return true, serialized to PyObject, NULL with exeption text, if failed. + * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ PyObject* __setPcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { - setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); + __setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed"); return; } @@ -150,20 +150,18 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_ /*! - * \brief Reads register value. + * \brief Reads register value. Wrap for pcilib_read_register function. * \param[in] regname the name of the register * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise - * \return register value, can be integer or float type + * \return register value, can be integer or float type; NULL with exeption text, if failed. */ PyObject* read_register(const char *regname, const char *bank) { if(!__ctx) { - setPyExeptionText("pcilib_t handler not initialized"); + __setPyExeptionText("pcilib_t handler not initialized"); return NULL; } - - pcilib_get_dma_description(__ctx); pcilib_value_t val = {0}; pcilib_register_value_t reg_value; @@ -173,26 +171,72 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) { - setPyExeptionText("Failed: read_register (%i)", err); + __setPyExeptionText("Failed: pcilib_read_register (%i)", err); return NULL; } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) { - setPyExeptionText("Failed: pcilib_set_value_from_register_value (%i)", err); + __setPyExeptionText("Failed: pcilib_set_value_from_register_value (%i)", err); return NULL; } - return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); + return pcilib_convert_val_to_pyobject(__ctx, &val, __setPyExeptionText); } +/*! + * \brief Writes value to register. Wrap for pcilib_write_register function. + * \param[in] val Register value, that needs to be set. Can be int, float or string. + * \param[in] regname the name of the register + * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise + * \return 1, serialized to PyObject or NULL with exeption text, if failed. + */ +PyObject* write_register(PyObject* val, const char *regname, const char *bank) +{ + if(!__ctx) + { + __setPyExeptionText("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val_internal = {0}; + pcilib_register_value_t reg_value; + + int err; + err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + if(err) + { + __setPyExeptionText("Failed pcilib_convert_pyobject_to_val (%i)", err); + return NULL; + } + + reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); + if(err) + { + __setPyExeptionText("Failed: pcilib_get_value_as_register_value (%i)", err); + return NULL; + } + + err = pcilib_write_register(__ctx, bank, regname, reg_value); + if(err) + { + __setPyExeptionText("Failed: pcilib_write_register (%i)", err); + return NULL; + } + return PyInt_FromLong((long)1); +} +/*! + * \brief Reads propety value. Wrap for pcilib_get_property function. + * \param[in] prop property name (full name including path) + * \return property value, can be integer or float type; NULL with exeption text, if failed. + */ PyObject* get_property(const char *prop) { if(!__ctx) { - setPyExeptionText("pcilib_t handler not initialized"); + __setPyExeptionText("pcilib_t handler not initialized"); return NULL; } @@ -203,20 +247,26 @@ PyObject* get_property(const char *prop) if(err) { - setPyExeptionText("Failed pcilib_get_property (%i)", err); + __setPyExeptionText("Failed pcilib_get_property (%i)", err); return NULL; } - return pcilib_convert_val_to_pyobject(__ctx, &val, setPyExeptionText); + return pcilib_convert_val_to_pyobject(__ctx, &val, __setPyExeptionText); } +/*! + * \brief Writes value to property. Wrap for pcilib_set_property function. + * \param[in] prop property name (full name including path) + * \param[in] val Property value, that needs to be set. Can be int, float or string. + * \return 1, serialized to PyObject or NULL with exeption text, if failed. + */ PyObject* set_property(const char *prop, PyObject* val) { int err; if(!__ctx) { - setPyExeptionText("pcilib_t handler not initialized"); + __setPyExeptionText("pcilib_t handler not initialized"); return NULL; } @@ -224,7 +274,7 @@ PyObject* set_property(const char *prop, PyObject* val) err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); if(err) { - setPyExeptionText("pcilib_convert_pyobject_to_val (%i)", err); + __setPyExeptionText("Failed pcilib_convert_pyobject_to_val (%i)", err); return NULL; } @@ -232,7 +282,7 @@ PyObject* set_property(const char *prop, PyObject* val) if(err) { - setPyExeptionText("Failed pcilib_get_property (%i)", err); + __setPyExeptionText("Failed pcilib_get_property (%i)", err); return NULL; } diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i index 8d0f74e..cd632f8 100644 --- a/pcilib/pcipywrap.i +++ b/pcilib/pcipywrap.i @@ -1,7 +1,10 @@ %module pcipywrap -extern PyObject* read_register(const char *regname, const char *bank = NULL); extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL); extern PyObject* __setPcilib(PyObject* addr); + +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); diff --git a/pcilib/xml.c b/pcilib/xml.c index 2384e95..099da76 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -492,6 +492,8 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_view_description_t *desc) { xmlAttrPtr cur; const char *value, *name; + + int register_no_chk = 0; for (cur = node->properties; cur != NULL; cur = cur->next) { if (!cur->children) continue; @@ -539,7 +541,15 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc return PCILIB_ERROR_INVALID_DATA; } } - } + else if (!strcasecmp(name, "no_set_check")) { + if (!strcasecmp(value, "1")) + register_no_chk = 1; + } + } + if(register_no_chk) + { + desc->mode |= PCILIB_REGISTER_NO_CHK; + } return 0; } @@ -550,7 +560,7 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath const char *value, *name; pcilib_view_context_t *view_ctx; - pcilib_access_mode_t mode = 0; + pcilib_access_mode_t mode = PCILIB_REGISTER_NO_CHK; pcilib_script_view_description_t desc = {{0}}; desc.base.api = &pcilib_script_view_api; @@ -595,7 +605,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp const char *value, *name; pcilib_view_context_t *view_ctx; - pcilib_access_mode_t mode = 0; + pcilib_access_mode_t mode = PCILIB_REGISTER_NO_CHK; pcilib_transform_view_description_t desc = {{0}}; desc.base.api = &pcilib_transform_view_api; -- cgit v1.2.3 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. --- pcilib/pcipywrap.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++----- pcilib/pcipywrap.i | 12 +- pcilib/py.c | 187 +++++++++++++++++++++++++++++- pcilib/py.h | 9 ++ pcilib/xml.c | 44 ++++--- 5 files changed, 536 insertions(+), 47 deletions(-) (limited to 'pcilib') 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); } -- cgit v1.2.3 From f526c4a5a3e4f35bb1c4b03af1f3244a8c0db48a Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 12:00:54 +0100 Subject: Change error logging method in Python wrap. Move functions, that converts values between PyObject and pcilib_value_t to py.c --- pcilib/CMakeLists.txt | 2 +- pcilib/error.c | 11 ++++ pcilib/pcilib.h | 15 +++++ pcilib/pcipywrap.c | 177 ++++++++++++++++++-------------------------------- pcilib/pcipywrap.h | 25 ------- pcilib/pcipywrap.i | 3 + pcilib/py.c | 73 ++++++++++++++++++++- pcilib/py.h | 20 ++++++ 8 files changed, 187 insertions(+), 139 deletions(-) delete mode 100644 pcilib/pcipywrap.h (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index b1f5251..faebcab 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -8,7 +8,7 @@ include_directories( ${UTHASH_INCLUDE_DIRS} ) -set(HEADERS pcilib.h pci.h pcipywrap.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) +set(HEADERS pcilib.h pci.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) add_library(pcilib SHARED pci.c pcipywrap.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols views) diff --git a/pcilib/error.c b/pcilib/error.c index 06af292..87380e7 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -76,3 +76,14 @@ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, vo return 0; } + +pcilib_logger_t pcilib_get_logger() { + return pcilib_logger; +} +pcilib_log_priority_t pcilib_get_logger_min_prio() { + return pcilib_logger_min_prio; +} +void* pcilib_get_logger_argument() { + return pcilib_logger_argument; +} + diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index 4d2b7e9..23fe9be 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -263,6 +263,21 @@ extern "C" { */ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg); +/** + * Gets current logger function. + */ +pcilib_logger_t pcilib_get_logger(); + +/** + * Gets current logger min priority. + */ +pcilib_log_priority_t pcilib_get_logger_min_prio(); + +/** + * Gets current logger argument. + */ +void* pcilib_get_logger_argument(); + /** public_api_global * @} */ diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index d950de3..db0e412 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -1,6 +1,6 @@ #include "pci.h" #include "error.h" -#include "pcipywrap.h" +#include /*! * \brief Global pointer to pcilib_t context. @@ -9,18 +9,15 @@ pcilib_t* __ctx = 0; /*! - * \brief Sets python exeption text. Function interface same as printf. + * \brief Wraping for vsnprintf function, that saves string to char* + * \return saved from vsnprintf string */ -void __setPyExeptionText(const char* msg, ...) +char* vmake_str(const char* msg, va_list vl) { - if(!Py_IsInitialized()) - Py_Initialize(); - char *buf; size_t sz; - va_list vl, vl_copy; - va_start(vl, msg); + va_list vl_copy; va_copy(vl_copy, vl); sz = vsnprintf(NULL, 0, msg, vl); @@ -28,16 +25,51 @@ void __setPyExeptionText(const char* msg, ...) if(!buf) { - PyErr_SetString(PyExc_Exception, "Memory error"); - return; + return NULL; } vsnprintf(buf, sz+1, msg, vl_copy); va_end(vl_copy); - va_end(vl); - PyErr_SetString(PyExc_Exception, buf); - free(buf); + return buf; +} + +/*! + * \brief Wraping for vsnprintf function, that saves string to char* + * \return saved from vsnprintf string + */ +char* make_str(const char* msg, ...) +{ + va_list vl; + va_start(vl, msg); + char *buf = vmake_str(msg, vl); + va_end(vl); +} + +/*! + * \brief Version of pcilib_logger_t, that saves error text to Python exeption + */ +void pcilib_print_error_to_py(void *arg, const char *file, int line, + pcilib_log_priority_t prio, const char *msg, + va_list va) { + char* buf_raw_msg = vmake_str(msg, va); + char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); + + printf("%s", buf_wrapped_message); + PyErr_SetString(PyExc_Exception, buf_wrapped_message); + + free(buf_wrapped_message); + free(buf_raw_msg); +} + +/*! + * \brief Inits pcipywrap module at importing + */ +void init_pcipywrap_module() +{ + pcilib_set_logger(pcilib_get_logger_min_prio(), + pcilib_print_error_to_py, + pcilib_get_logger_argument()); } /*! @@ -51,10 +83,7 @@ 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*)); @@ -90,7 +119,7 @@ PyObject* setPcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { - __setPyExeptionText("Incorrect addr type. Only bytearray is allowed"); + pcilib_error("Incorrect addr type. Only bytearray is allowed"); return NULL; } @@ -104,82 +133,6 @@ PyObject* setPcilib(PyObject* addr) return PyInt_FromLong((long)1); } -PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, void (*errstream)(const char* msg, ...)) -{ - int err; - - switch(val->type) - { - case PCILIB_TYPE_INVALID: - if(errstream) - errstream("Invalid register output type (PCILIB_TYPE_INVALID)"); - return NULL; - - case PCILIB_TYPE_STRING: - if(errstream) - errstream("Invalid register output type (PCILIB_TYPE_STRING)"); - return NULL; - - case PCILIB_TYPE_LONG: - { - long ret; - ret = pcilib_get_value_as_int(__ctx, val, &err); - - if(err) - { - if(errstream) - errstream("Failed: pcilib_get_value_as_int (%i)", err); - return NULL; - } - return PyInt_FromLong((long) ret); - } - - case PCILIB_TYPE_DOUBLE: - { - double ret; - ret = pcilib_get_value_as_float(__ctx, val, &err); - - if(err) - { - if(errstream) - errstream("Failed: pcilib_get_value_as_int (%i)", err); - return NULL; - } - return PyFloat_FromDouble((double) ret); - } - - default: - if(errstream) - errstream("Invalid register output type (unknown)"); - return NULL; - } -} - -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_t *val) -{ - int err; - - if(PyInt_Check(pyVal)) - { - err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); - } - else - if(PyFloat_Check(pyVal)) - err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); - else - if(PyString_Check(pyVal)) - err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); - else - { - pcilib_error("Invalid input. Input type should be int, float or string."); - return PCILIB_ERROR_NOTSUPPORTED; - } - if(err) - return err; - - return 0; -} - /*! * \brief Reads register value. Wrap for pcilib_read_register function. @@ -191,7 +144,7 @@ PyObject* read_register(const char *regname, const char *bank) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -203,18 +156,18 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) { - __setPyExeptionText("Failed: pcilib_read_register (%i)", err); + pcilib_error("Failed: pcilib_read_register (%i)", err); return NULL; } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) { - __setPyExeptionText("Failed: pcilib_set_value_from_register_value (%i)", err); + pcilib_error("Failed: pcilib_set_value_from_register_value (%i)", err); return NULL; } - return pcilib_convert_val_to_pyobject(__ctx, &val, __setPyExeptionText); + return pcilib_convert_val_to_pyobject(__ctx, &val); } /*! @@ -228,7 +181,7 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -239,21 +192,21 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); if(err) { - __setPyExeptionText("Failed pcilib_convert_pyobject_to_val (%i)", err); + pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); return NULL; } reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) { - __setPyExeptionText("Failed: pcilib_get_value_as_register_value (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_register_value (%i)", err); return NULL; } err = pcilib_write_register(__ctx, bank, regname, reg_value); if(err) { - __setPyExeptionText("Failed: pcilib_write_register (%i)", err); + pcilib_error("Failed: pcilib_write_register (%i)", err); return NULL; } return PyInt_FromLong((long)1); @@ -268,7 +221,7 @@ PyObject* get_property(const char *prop) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -279,11 +232,11 @@ PyObject* get_property(const char *prop) if(err) { - __setPyExeptionText("Failed pcilib_get_property (%i)", err); + pcilib_error("Failed pcilib_get_property (%i)", err); return NULL; } - return pcilib_convert_val_to_pyobject(__ctx, &val, __setPyExeptionText); + return pcilib_convert_val_to_pyobject(__ctx, &val); } /*! @@ -298,7 +251,7 @@ PyObject* set_property(const char *prop, PyObject* val) if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -306,7 +259,7 @@ PyObject* set_property(const char *prop, PyObject* val) err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); if(err) { - __setPyExeptionText("Failed pcilib_convert_pyobject_to_val (%i)", err); + pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); return NULL; } @@ -314,7 +267,7 @@ PyObject* set_property(const char *prop, PyObject* val) if(err) { - __setPyExeptionText("Failed pcilib_get_property (%i)", err); + pcilib_error("Failed pcilib_get_property (%i)", err); return NULL; } @@ -323,7 +276,7 @@ PyObject* set_property(const char *prop, PyObject* val) 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); + PyObject *py_val = pcilib_convert_val_to_pyobject(__ctx, val); if(py_val) PyDict_SetItem(dict, @@ -503,7 +456,7 @@ PyObject* get_register_list(const char *bank) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -526,7 +479,7 @@ PyObject* get_register_info(const char* reg,const char *bank) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } @@ -534,7 +487,7 @@ PyObject* get_register_info(const char* reg,const char *bank) if(!info) { - __setPyExeptionText("Failed pcilib_get_register_info"); + pcilib_error("Failed pcilib_get_register_info"); return NULL; } @@ -549,7 +502,7 @@ PyObject* get_property_info(const char* branch) { if(!__ctx) { - __setPyExeptionText("pcilib_t handler not initialized"); + pcilib_error("pcilib_t handler not initialized"); return NULL; } diff --git a/pcilib/pcipywrap.h b/pcilib/pcipywrap.h deleted file mode 100644 index c2bb749..0000000 --- a/pcilib/pcipywrap.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _PCITOOL_PCIPYWRAP_H -#define _PCITOOL_PCIPYWRAP_H -#include -#include "pcilib.h" - -/*! - * \brief Converts pcilib_value_t to PyObject. - * \param ctx pointer to pcilib_t context - * \param val pointer to pcilib_value_t to convert - * \return PyObject, containing value. NULL with error message, sended to errstream. - */ -PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, void (*errstream)(const char* msg, ...)); - - -/*! - * \brief Converts PyObject to pcilib_value_t. - * \param ctx pcilib context - * \param pyVal python object, containing value - * \param val initialized polymorphic value - * \return 0 on success or memory error - */ -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, PyObject* pyVal, pcilib_value_t *val); - - -#endif /* _PCITOOL_PCIPYWRAP_H */ diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i index 10a95a7..2da8654 100644 --- a/pcilib/pcipywrap.i +++ b/pcilib/pcipywrap.i @@ -1,5 +1,8 @@ %module pcipywrap +%init %{ + init_pcipywrap_module(); +%} extern PyObject* createPcilibInstance(const char *fpga_device, const char *model = NULL); extern PyObject* setPcilib(PyObject* addr); diff --git a/pcilib/py.c b/pcilib/py.c index 20b85a1..acc18df 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -196,6 +196,77 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } +void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) +{ + int err; + + switch(val->type) + { + case PCILIB_TYPE_INVALID: + pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + return NULL; + + case PCILIB_TYPE_STRING: + pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + return NULL; + + case PCILIB_TYPE_LONG: + { + long ret; + ret = pcilib_get_value_as_int(ctx, val, &err); + + if(err) + { + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return (PyObject*)PyInt_FromLong((long) ret); + } + + case PCILIB_TYPE_DOUBLE: + { + double ret; + ret = pcilib_get_value_as_float(ctx, val, &err); + + if(err) + { + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + return NULL; + } + return (PyObject*)PyFloat_FromDouble((double) ret); + } + + default: + pcilib_error("Invalid register output type (unknown)"); + return NULL; + } +} + +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +{ + PyObject* pyVal = pyObjVal; + int err; + + if(PyInt_Check(pyVal)) + { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); + } + else + if(PyFloat_Check(pyVal)) + err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); + else + if(PyString_Check(pyVal)) + err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); + else + { + pcilib_error("Invalid input. Input type should be int, float or string."); + return PCILIB_ERROR_NOTSUPPORTED; + } + if(err) + return err; + + return 0; +} int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) { @@ -347,7 +418,7 @@ int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t * { int err; - PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf); + PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); if(!input) { printf("Failed to convert input value to Python object"); diff --git a/pcilib/py.h b/pcilib/py.h index 8fd749c..d0f1328 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -20,6 +20,26 @@ 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); + +/*! + * \brief Converts pcilib_value_t to PyObject. + * \param ctx pointer to pcilib_t context + * \param val pointer to pcilib_value_t to convert + * \return PyObject, containing value. NULL with error message, sended to errstream. + */ +void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val); + + +/*! + * \brief Converts PyObject to pcilib_value_t. + * \param ctx pcilib context + * \param pyVal python object, containing value + * \param val initialized polymorphic value + * \return 0 on success or memory error + */ +int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 76ee5a167add1c169a982ab59aa0544f827cb365 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 12:28:37 +0100 Subject: Solve errors in serialing register_info function. Clear unused code --- pcilib/pcipywrap.c | 39 +++++++++++++++++++++++++++++---------- pcilib/py.c | 10 ++++------ pcilib/xml.c | 47 ----------------------------------------------- 3 files changed, 33 insertions(+), 63 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c index db0e412..18874af 100644 --- a/pcilib/pcipywrap.c +++ b/pcilib/pcipywrap.c @@ -44,6 +44,7 @@ char* make_str(const char* msg, ...) va_start(vl, msg); char *buf = vmake_str(msg, vl); va_end(vl); + return buf; } /*! @@ -276,12 +277,12 @@ PyObject* set_property(const char *prop, PyObject* val) 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); + PyObject *py_val = (PyObject*)pcilib_convert_val_to_pyobject(__ctx, val); if(py_val) PyDict_SetItem(dict, PyString_FromString(name), - val); + py_val); else PyDict_SetItem(dict, PyString_FromString("defvalue"), @@ -407,13 +408,22 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI PyDict_SetItem(pylistItem, PyString_FromString("mode"), modes); - add_pcilib_value_to_dict(pylistItem, &listItem.defvalue, "defvalue"); + + pcilib_value_t defval = {0}; + pcilib_set_value_from_register_value(__ctx, &defval, listItem.defvalue); + add_pcilib_value_to_dict(pylistItem, &defval, "defvalue"); if(listItem.range) { + pcilib_value_t minval = {0}; + pcilib_set_value_from_register_value(__ctx, &minval, listItem.range->min); + + pcilib_value_t maxval = {0}; + pcilib_set_value_from_register_value(__ctx, &maxval, listItem.range->max); + PyObject* range = PyDict_New(); - add_pcilib_value_to_dict(range, &(listItem.range->min), "min"); - add_pcilib_value_to_dict(range, &(listItem.range->max), "max"); + add_pcilib_value_to_dict(range, &minval, "min"); + add_pcilib_value_to_dict(range, &maxval, "max"); PyDict_SetItem(pylistItem, PyString_FromString("range"), range); @@ -426,10 +436,19 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI 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"); + + pcilib_value_t val = {0}; + pcilib_set_value_from_register_value(__ctx, &val, listItem.values[j].value); + + pcilib_value_t min = {0}; + pcilib_set_value_from_register_value(__ctx, &min, listItem.values[j].min); + + pcilib_value_t max = {0}; + pcilib_set_value_from_register_value(__ctx, &max, listItem.values[j].max); + + add_pcilib_value_to_dict(valuesItem, &val, "value"); + add_pcilib_value_to_dict(valuesItem, &min, "min"); + add_pcilib_value_to_dict(valuesItem, &max, "max"); if(listItem.values[j].name) PyDict_SetItem(valuesItem, @@ -510,7 +529,7 @@ PyObject* get_property_info(const char* branch) PyObject* pyList = PyList_New(0); - for(int i = 0; i < list[i].path; i++) + for(int i = 0; list[i].path; i++) { //serialize item attributes PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(list[i]); diff --git a/pcilib/py.c b/pcilib/py.c index acc18df..57a5f46 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -269,9 +269,7 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t } 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) { @@ -389,6 +387,8 @@ int pcilib_free_py_script(pcilib_script_t *module) module->py_script_module = NULL; } } + + return 0; } int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) @@ -415,9 +415,7 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v } 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); if(!input) { diff --git a/pcilib/xml.c b/pcilib/xml.c index f21480c..38bb917 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -554,53 +554,6 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc return 0; } -static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { - int err; - xmlAttrPtr cur; - const char *value, *name; - pcilib_view_context_t *view_ctx; - - - pcilib_access_mode_t mode = 0; - pcilib_transform_view_description_t desc = {{0}}; - - 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; - - for (cur = node->properties; cur != NULL; cur = cur->next) { - if (!cur->children) continue; - if (!xmlNodeIsText(cur->children)) continue; - - name = (char*)cur->name; - value = (char*)cur->children->content; - if (!value) continue; - - if (!strcasecmp(name, "script")) - { - //write script name to struct - 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; - - err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); - if (err) return err; - - view_ctx->xml = node; - return 0; -} - static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { int err; xmlAttrPtr cur; -- cgit v1.2.3 From d7fc669bf0dbe37f46d2efec4940feb8504017c2 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 14:24:01 +0100 Subject: Change no_set_check parameter name. Move Python wrap to separate directory. --- pcilib/CMakeLists.txt | 13 +- pcilib/pcilib.h | 2 +- pcilib/pcipywrap.c | 542 -------------------------------------------------- pcilib/pcipywrap.i | 21 -- pcilib/py.c | 8 +- pcilib/xml.c | 19 +- 6 files changed, 17 insertions(+), 588 deletions(-) delete mode 100644 pcilib/pcipywrap.c delete mode 100644 pcilib/pcipywrap.i (limited to 'pcilib') diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index faebcab..cdc9c3f 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -9,21 +9,10 @@ include_directories( ) set(HEADERS pcilib.h pci.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) -add_library(pcilib SHARED pci.c pcipywrap.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) +add_library(pcilib SHARED pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols views) -#Creating python wrapping -INCLUDE(${SWIG_USE_FILE}) - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - -SET(CMAKE_SWIG_FLAGS "") - -SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") -SWIG_ADD_MODULE(pcipywrap python pcipywrap.i) -SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) - install(TARGETS pcilib LIBRARY DESTINATION lib${LIB_SUFFIX} ) diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index 23fe9be..2458320 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -54,7 +54,7 @@ typedef enum { PCILIB_REGISTER_RW1C = 5, PCILIB_REGISTER_W1I = 8, /**< writting 1 inversts the bit, writting 0 keeps the value */ PCILIB_REGISTER_RW1I = 9, - PCILIB_REGISTER_NO_CHK = 16 /**< dont check register value after set*/ + PCILIB_REGISTER_INCONSISTENT = 0x1000 /**< dont check register value after set*/ } pcilib_register_mode_t; typedef enum { diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c deleted file mode 100644 index 18874af..0000000 --- a/pcilib/pcipywrap.c +++ /dev/null @@ -1,542 +0,0 @@ -#include "pci.h" -#include "error.h" -#include - -/*! - * \brief Global pointer to pcilib_t context. - * Used by setPcilib and read_register. - */ -pcilib_t* __ctx = 0; - -/*! - * \brief Wraping for vsnprintf function, that saves string to char* - * \return saved from vsnprintf string - */ -char* vmake_str(const char* msg, va_list vl) -{ - char *buf; - size_t sz; - - va_list vl_copy; - va_copy(vl_copy, vl); - - sz = vsnprintf(NULL, 0, msg, vl); - buf = (char *)malloc(sz + 1); - - if(!buf) - { - return NULL; - } - - vsnprintf(buf, sz+1, msg, vl_copy); - va_end(vl_copy); - - return buf; -} - -/*! - * \brief Wraping for vsnprintf function, that saves string to char* - * \return saved from vsnprintf string - */ -char* make_str(const char* msg, ...) -{ - va_list vl; - va_start(vl, msg); - char *buf = vmake_str(msg, vl); - va_end(vl); - return buf; -} - -/*! - * \brief Version of pcilib_logger_t, that saves error text to Python exeption - */ -void pcilib_print_error_to_py(void *arg, const char *file, int line, - pcilib_log_priority_t prio, const char *msg, - va_list va) { - char* buf_raw_msg = vmake_str(msg, va); - char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); - - printf("%s", buf_wrapped_message); - PyErr_SetString(PyExc_Exception, buf_wrapped_message); - - free(buf_wrapped_message); - free(buf_raw_msg); -} - -/*! - * \brief Inits pcipywrap module at importing - */ -void init_pcipywrap_module() -{ - pcilib_set_logger(pcilib_get_logger_min_prio(), - pcilib_print_error_to_py, - pcilib_get_logger_argument()); -} - -/*! - * \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) - 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) -{ - if(!PyByteArray_Check(addr)) - { - pcilib_error("Incorrect addr type. Only bytearray is allowed"); - return NULL; - } - - //deserializing adress - char* pAddr = PyByteArray_AsString(addr); - - //hard copy context adress - for(int i = 0; i < sizeof(pcilib_t*) + 10; i++) - ((char*)&__ctx)[i] = pAddr[i]; - - return PyInt_FromLong((long)1); -} - - -/*! - * \brief Reads register value. Wrap for pcilib_read_register function. - * \param[in] regname the name of the register - * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise - * \return register value, can be integer or float type; NULL with exeption text, if failed. - */ -PyObject* read_register(const char *regname, const char *bank) -{ - if(!__ctx) - { - pcilib_error("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_value_t val = {0}; - pcilib_register_value_t reg_value; - - int err; - - err = pcilib_read_register(__ctx, bank, regname, ®_value); - if(err) - { - pcilib_error("Failed: pcilib_read_register (%i)", err); - return NULL; - } - - err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); - if(err) - { - pcilib_error("Failed: pcilib_set_value_from_register_value (%i)", err); - return NULL; - } - - return pcilib_convert_val_to_pyobject(__ctx, &val); -} - -/*! - * \brief Writes value to register. Wrap for pcilib_write_register function. - * \param[in] val Register value, that needs to be set. Can be int, float or string. - * \param[in] regname the name of the register - * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise - * \return 1, serialized to PyObject or NULL with exeption text, if failed. - */ -PyObject* write_register(PyObject* val, const char *regname, const char *bank) -{ - if(!__ctx) - { - pcilib_error("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_value_t val_internal = {0}; - pcilib_register_value_t reg_value; - - int err; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); - if(err) - { - pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); - return NULL; - } - - reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); - if(err) - { - pcilib_error("Failed: pcilib_get_value_as_register_value (%i)", err); - return NULL; - } - - err = pcilib_write_register(__ctx, bank, regname, reg_value); - if(err) - { - pcilib_error("Failed: pcilib_write_register (%i)", err); - return NULL; - } - return PyInt_FromLong((long)1); -} - -/*! - * \brief Reads propety value. Wrap for pcilib_get_property function. - * \param[in] prop property name (full name including path) - * \return property value, can be integer or float type; NULL with exeption text, if failed. - */ -PyObject* get_property(const char *prop) -{ - if(!__ctx) - { - pcilib_error("pcilib_t handler not initialized"); - return NULL; - } - - int err; - pcilib_value_t val = {0}; - - err = pcilib_get_property(__ctx, prop, &val); - - if(err) - { - pcilib_error("Failed pcilib_get_property (%i)", err); - return NULL; - } - - return pcilib_convert_val_to_pyobject(__ctx, &val); -} - -/*! - * \brief Writes value to property. Wrap for pcilib_set_property function. - * \param[in] prop property name (full name including path) - * \param[in] val Property value, that needs to be set. Can be int, float or string. - * \return 1, serialized to PyObject or NULL with exeption text, if failed. - */ -PyObject* set_property(const char *prop, PyObject* val) -{ - int err; - - if(!__ctx) - { - pcilib_error("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_value_t val_internal = {0}; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); - if(err) - { - pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); - return NULL; - } - - err = pcilib_set_property(__ctx, prop, &val_internal); - - if(err) - { - pcilib_error("Failed pcilib_get_property (%i)", err); - return NULL; - } - - return PyInt_FromLong((long)1); -} - -void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) -{ - PyObject *py_val = (PyObject*)pcilib_convert_val_to_pyobject(__ctx, val); - - if(py_val) - PyDict_SetItem(dict, - PyString_FromString(name), - py_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); - - pcilib_value_t defval = {0}; - pcilib_set_value_from_register_value(__ctx, &defval, listItem.defvalue); - add_pcilib_value_to_dict(pylistItem, &defval, "defvalue"); - - if(listItem.range) - { - pcilib_value_t minval = {0}; - pcilib_set_value_from_register_value(__ctx, &minval, listItem.range->min); - - pcilib_value_t maxval = {0}; - pcilib_set_value_from_register_value(__ctx, &maxval, listItem.range->max); - - PyObject* range = PyDict_New(); - add_pcilib_value_to_dict(range, &minval, "min"); - add_pcilib_value_to_dict(range, &maxval, "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(); - - pcilib_value_t val = {0}; - pcilib_set_value_from_register_value(__ctx, &val, listItem.values[j].value); - - pcilib_value_t min = {0}; - pcilib_set_value_from_register_value(__ctx, &min, listItem.values[j].min); - - pcilib_value_t max = {0}; - pcilib_set_value_from_register_value(__ctx, &max, listItem.values[j].max); - - add_pcilib_value_to_dict(valuesItem, &val, "value"); - add_pcilib_value_to_dict(valuesItem, &min, "min"); - add_pcilib_value_to_dict(valuesItem, &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) - { - pcilib_error("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) - { - pcilib_error("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) - { - pcilib_error("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) - { - pcilib_error("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; 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 deleted file mode 100644 index 2da8654..0000000 --- a/pcilib/pcipywrap.i +++ /dev/null @@ -1,21 +0,0 @@ -%module pcipywrap - -%init %{ - init_pcipywrap_module(); -%} - -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 57a5f46..664e170 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -293,15 +293,15 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo char* pcipywrap_path; if(app_dir) { - pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib")); + pcipywrap_path = malloc(strlen(app_dir) + strlen("/pywrap")); if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model); + sprintf(pcipywrap_path, "%s/%s", "/pywrap", ctx->model); } else { - pcipywrap_path = malloc(strlen("./pcilib")); + pcipywrap_path = malloc(strlen("./pywrap")); if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s", "./pcilib"); + sprintf(pcipywrap_path, "%s", "./pywrap"); } diff --git a/pcilib/xml.c b/pcilib/xml.c index 38bb917..ca07ad3 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -493,7 +493,7 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc xmlAttrPtr cur; const char *value, *name; - int register_no_chk = 0; + int register_incosistent = 0; for (cur = node->properties; cur != NULL; cur = cur->next) { if (!cur->children) continue; @@ -541,14 +541,17 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc return PCILIB_ERROR_INVALID_DATA; } } - else if (!strcasecmp(name, "no_set_check")) { - if (!strcasecmp(value, "1")) - register_no_chk = 1; + else if (!strcasecmp(name, "write_verification")) { + if (!strcasecmp(value, "0")) + { + register_incosistent = 1; + } } } - if(register_no_chk) + + if(register_incosistent) { - desc->mode |= PCILIB_REGISTER_NO_CHK; + desc->mode |= PCILIB_REGISTER_INCONSISTENT; } return 0; @@ -560,7 +563,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp const char *value, *name; pcilib_view_context_t *view_ctx; - pcilib_access_mode_t mode = PCILIB_REGISTER_NO_CHK; + pcilib_access_mode_t mode = PCILIB_REGISTER_INCONSISTENT; pcilib_transform_view_description_t desc = {{0}}; desc.base.api = &pcilib_transform_view_api; @@ -603,7 +606,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode); if(err) return err; - mode |= PCILIB_REGISTER_NO_CHK; + mode |= PCILIB_REGISTER_INCONSISTENT; break; } } -- cgit v1.2.3 From 55eab7196d0104c71e40136b3b22e9501d234e17 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 14:43:20 +0100 Subject: 1. Cmakelists - move copy xml folder command to root file 2. - Move set python paths code to python module init funtction - pci.c move python module init block code after checking model to get paths before it runs. - Fix set python path code to work with PYTHONPATH - Update pci run script to work with PYTHONPATH - Fix python finalize code 3. Change pcilib_script_s interacting method. Now it stores in hash. 4. Change names of some fucntions to more unified ones 5. Remove old unused function pcilib_xml_create_script_or_transform_view 6. cli - disable reading register after set if write_verification flag is off 7. Remove uninformative error messages fro Python wrap. 8. - Server.py - add read/write property/register command handling - Add help message - Correcting paths --- pcilib/pci.c | 14 ++--- pcilib/py.c | 194 +++++++++++++++++++++++++++++++++++------------------------ pcilib/py.h | 13 ++-- pcilib/xml.c | 53 ++-------------- 4 files changed, 134 insertions(+), 140 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index eaf41ac..cc2a67a 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -144,13 +144,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } - - err = pcilib_init_py(ctx); - if (err) { - pcilib_error("Error (%i) initializing python subsystem", err); - pcilib_close(ctx); - return NULL; - } ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE; ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE; @@ -191,6 +184,13 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); + + err = pcilib_init_py(ctx); + if (err) { + pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_close(ctx); + return NULL; + } xmlerr = pcilib_init_xml(ctx, ctx->model); if ((xmlerr)&&(xmlerr != PCILIB_ERROR_NOTFOUND)) { diff --git a/pcilib/py.c b/pcilib/py.c index 664e170..7b1ae79 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,37 @@ #include "py.h" #include "error.h" + + struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class }; -struct pcilib_script_s { +typedef struct pcilib_script_s { + char* script_name; PyObject *py_script_module; /**< PyModule object, contains script enviroment */ PyObject *dict; - char* script_name; -}; + pcilib_access_mode_t mode; + + UT_hash_handle hh; +} pcilib_script_s; + +struct pcilib_script_s *scripts = NULL; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; if(!Py_IsInitialized()) + { Py_Initialize(); - + ctx->py->py_initialized_inside = 1; + } + else + ctx->py->py_initialized_inside = 0; + ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) return PCILIB_ERROR_FAILED; @@ -36,17 +49,45 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; - + + + //create path string, where the model scripts should be + static int model_dir_added = 0; + if(!model_dir_added) + { + 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); + //add path to python + PyObject* path = PySys_GetObject("path"); + if(PyList_Append(path, PyString_FromString(model_path)) == -1) + { + pcilib_error("Cant set PCILIB_MODEL_DIR library path to python."); + free(model_path); + return PCILIB_ERROR_FAILED; + } + free(model_path); + model_dir_added = 1; + } return 0; } void pcilib_free_py(pcilib_t *ctx) { - if (ctx->py) { + + int py_initialized_inside = 0; + + if (ctx->py) { + if(ctx->py->py_initialized_inside) + py_initialized_inside = 1; + // Dict and module references are borrowed free(ctx->py); ctx->py = NULL; } - //Py_Finalize(); + + if(py_initialized_inside) + Py_Finalize(); } /* @@ -196,7 +237,7 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) +void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) { int err; @@ -242,7 +283,7 @@ void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) } } -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) { PyObject* pyVal = pyObjVal; int err; @@ -268,61 +309,30 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t return 0; } -int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) +int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) { - //Initialize python script, if it has not initialized already. - if(!module_name) + //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 (NULL)"); + pcilib_error("Invalid script name specified in XML property (%s)." + " Seems like name doesnt contains extension", module_name); 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("/pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s/%s", "/pywrap", ctx->model); - } - else - { - pcipywrap_path = malloc(strlen("./pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s", "./pywrap"); - - } - - //set pcipywrap library path to python - PyObject* path = PySys_GetObject("path"); - if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1) + pcilib_script_s* module = NULL; + HASH_FIND_STR( scripts, module_name, module); + if(module) { - pcilib_error("Cant set pcipywrap library path to python."); - return PCILIB_ERROR_FAILED; + pcilib_warning("Python module %s is already in hash. Skip init step", module_name); + mode[0] = module->mode; + return 0; } - free(pcipywrap_path); - pcipywrap_path = NULL; - - - //extract module name from script name - char* py_module_name = strtok(module_name, "."); - if(!py_module_name) + //Initialize python module + if(!module_name) { - pcilib_error("Invalid script name specified in XML property (%s)." - " Seems like name doesnt contains extension", module_name); + pcilib_error("Invalid script name specified in XML property (NULL)"); return PCILIB_ERROR_INVALID_DATA; } @@ -336,7 +346,6 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo 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"))) @@ -350,16 +359,18 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, - PyUnicode_FromString("setPcilib"), + PyUnicode_FromString("set_pcilib"), 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; + module = malloc(sizeof(pcilib_script_s)); + module->py_script_module = py_script_module; + module->script_name = malloc(strlen(module_name)); + sprintf(module->script_name, "%s", module_name); + module->dict = dict; + //Setting correct mode mode[0] = 0; @@ -367,32 +378,52 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo mode[0] |= PCILIB_ACCESS_R; if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) mode[0] |= PCILIB_ACCESS_W; + + module->mode = mode[0]; + HASH_ADD_STR( scripts, script_name, module); return 0; } -int pcilib_free_py_script(pcilib_script_t *module) +int pcilib_py_free_script(char* module_name) { - if(module) + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) { - if(module->script_name) - { - free(module->script_name); - module->script_name = NULL; - } + //For some reason it will crash if uncomment. printf same warning is ok + //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + return 0; + } + + 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; - } + if(module->py_script_module) + { + //PyObject_Free(module->py_script_module); + module->py_script_module = NULL; } + HASH_DEL(scripts, module); + free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } int err; @@ -404,7 +435,7 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return PCILIB_ERROR_FAILED; } - err = pcilib_convert_pyobject_to_val(ctx, ret, val); + err = pcilib_set_value_from_pyobject(ctx, ret, val); if(err) { @@ -414,9 +445,18 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return 0; } -int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { - PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } + + PyObject *input = pcilib_get_value_as_pyobject(ctx, val); if(!input) { printf("Failed to convert input value to Python object"); diff --git a/pcilib/py.h b/pcilib/py.h index d0f1328..09e2b87 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -4,7 +4,6 @@ #include "pcilib.h" typedef struct pcilib_py_s pcilib_py_t; -typedef struct pcilib_script_s pcilib_script_t; #ifdef __cplusplus extern "C" { @@ -15,10 +14,10 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va 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); +int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); +int pcilib_py_free_script(char* module_name); +int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val); +int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); /*! @@ -27,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t * * \param val pointer to pcilib_value_t to convert * \return PyObject, containing value. NULL with error message, sended to errstream. */ -void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val); +void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); /*! @@ -37,7 +36,7 @@ void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val); * \param val initialized polymorphic value * \return 0 on success or memory error */ -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); +int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); #ifdef __cplusplus diff --git a/pcilib/xml.c b/pcilib/xml.c index ca07ad3..f118491 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -569,7 +569,6 @@ 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; @@ -601,10 +600,10 @@ 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); + desc.module = malloc(strlen(value)); + sprintf(desc.module, "%s", value); - err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode); + err = pcilib_py_init_script(ctx, desc.module, &mode); if(err) return err; mode |= PCILIB_REGISTER_INCONSISTENT; break; @@ -620,50 +619,6 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp return 0; } -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; - - int has_read_from_register = 0; - int has_write_to_register = 0; - int has_script = 0; - - //getting transform name in case of error - pcilib_view_description_t desc = {0}; - err = pcilib_xml_parse_view(ctx, xpath, doc, node, &desc); - - for (cur = node->properties; cur != NULL; cur = cur->next) { - if (!cur->children) continue; - if (!xmlNodeIsText(cur->children)) continue; - - name = (char*)cur->name; - - if (!strcasecmp(name, "read_from_register")) - has_read_from_register = 1; - if (!strcasecmp(name, "write_to_register")) - has_write_to_register = 1; - if (!strcasecmp(name, "script")) - has_script = 1; - } - - if (has_script && (has_read_from_register || has_write_to_register)) { - pcilib_error("Invalid transform group attributes specified in XML property (%s)." - "Transform could not contains both script and read_from_register" - " or write_to_register attributes at same time.", desc.name); - return PCILIB_ERROR_INVALID_DATA; - } - - if(has_script) - - return pcilib_xml_create_script_view(ctx, xpath, doc, node); - else - */ - return pcilib_xml_create_transform_view(ctx, xpath, doc, node); -} - - static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_value_name_t *desc) { xmlAttr *cur; char *value, *name; @@ -921,7 +876,7 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon nodeset = transform_nodes->nodesetval; if (!xmlXPathNodeSetIsEmpty(nodeset)) { for(i=0; i < nodeset->nodeNr; i++) { - err = pcilib_xml_create_script_or_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); + err = pcilib_xml_create_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); if (err) pcilib_error("Error (%i) creating register transform", err); } } -- cgit v1.2.3 From 1b3342649294c6ce99aeb82664a29eac47687ee5 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 17:50:57 +0100 Subject: Move python module init code to transfom view constructor Update python logger and python exeption messages Change serialization method in create_pcilib_instance set_pcilib functions --- pcilib/pci.c | 3 ++- pcilib/py.c | 12 ++++++------ pcilib/view.c | 2 +- pcilib/view.h | 2 +- pcilib/xml.c | 5 ----- 5 files changed, 10 insertions(+), 14 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index cc2a67a..c38097f 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -192,12 +192,14 @@ pcilib_t *pcilib_open(const char *device, const char *model) { return NULL; } + xmlerr = pcilib_init_xml(ctx, ctx->model); if ((xmlerr)&&(xmlerr != PCILIB_ERROR_NOTFOUND)) { pcilib_error("Error (%i) initializing XML subsystem for model %s", xmlerr, ctx->model); pcilib_close(ctx); return NULL; } + // We have found neither standard model nor XML if ((err)&&(xmlerr)) { @@ -219,7 +221,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } - err = pcilib_init_event_engine(ctx); if (err) { pcilib_error("Error (%i) initializing event engine\n", err); diff --git a/pcilib/py.c b/pcilib/py.c index 7b1ae79..e448d21 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -244,11 +244,11 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); return NULL; case PCILIB_TYPE_STRING: - pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); return NULL; case PCILIB_TYPE_LONG: @@ -258,7 +258,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyInt_FromLong((long) ret); @@ -271,14 +271,14 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyFloat_FromDouble((double) ret); } default: - pcilib_error("Invalid register output type (unknown)"); + pcilib_warning("Invalid register output type (unknown)"); return NULL; } } @@ -360,7 +360,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, PyUnicode_FromString("set_pcilib"), - PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), + PyCObject_FromVoidPtr(ctx, NULL), NULL); } diff --git a/pcilib/view.c b/pcilib/view.c index e31fdba..797f4ae 100644 --- a/pcilib/view.c +++ b/pcilib/view.c @@ -70,7 +70,7 @@ int pcilib_add_views_custom(pcilib_t *ctx, size_t n, const pcilib_view_descripti } if (v->api->init) - view_ctx = v->api->init(ctx); + view_ctx = v->api->init(ctx, v); else { view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t)); if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t)); diff --git a/pcilib/view.h b/pcilib/view.h index 33d4d96..1a1d277 100644 --- a/pcilib/view.h +++ b/pcilib/view.h @@ -19,7 +19,7 @@ typedef enum { typedef struct { pcilib_version_t version; /**< Version */ size_t description_size; /**< The actual size of the description */ - pcilib_view_context_t *(*init)(pcilib_t *ctx); /**< Optional function which should allocated context used by read/write functions */ + pcilib_view_context_t *(*init)(pcilib_t *ctx, const pcilib_view_description_t *desc); /**< Optional function which should allocated context used by read/write functions */ void (*free)(pcilib_t *ctx, pcilib_view_context_t *view); /**< Optional function which should clean context */ void (*free_description)(pcilib_t *ctx, pcilib_view_description_t *view); /**< Optional function which shoud clean required parts of the extended description if non-static memory was used to initialize it */ int (*read_from_reg)(pcilib_t *ctx, pcilib_view_context_t *view, pcilib_register_value_t regval, pcilib_value_t *val); /**< Function which computes view value based on the passed the register value (view-based properties should not use register value) */ diff --git a/pcilib/xml.c b/pcilib/xml.c index f118491..4e95437 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -602,14 +602,9 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp } else if (!strcasecmp(name, "script")) { desc.module = malloc(strlen(value)); sprintf(desc.module, "%s", value); - - err = pcilib_py_init_script(ctx, desc.module, &mode); - if(err) return err; - mode |= PCILIB_REGISTER_INCONSISTENT; break; } } - desc.base.mode &= mode; err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); -- cgit v1.2.3 From 398e756263502a98a0c1887dcf38f7ef1fafa84b Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 15 Feb 2016 13:41:25 +0100 Subject: Fix memory leaks Add GIL states for int pcilib_script_read and pcilib_script_write functions Correct desctructor for create_pcilib_instance return object --- pcilib/property.c | 7 ++++++- pcilib/py.c | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'pcilib') diff --git a/pcilib/property.c b/pcilib/property.c index a7d1a61..3a7ebb3 100644 --- a/pcilib/property.c +++ b/pcilib/property.c @@ -165,7 +165,6 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran continue; } - dir = (struct dir_hash_s*)malloc(sizeof(struct dir_hash_s)); if (!dir) { err = PCILIB_ERROR_MEMORY; @@ -226,6 +225,12 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran }; } + + + HASH_ITER(hh, dir_hash, dir, dir_tmp) { + HASH_DEL(dir_hash, dir); + free(dir); + } HASH_CLEAR(hh, dir_hash); memset(&info[pos], 0, sizeof(pcilib_property_info_t)); diff --git a/pcilib/py.c b/pcilib/py.c index e448d21..20fa546 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -427,7 +427,9 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) int err; + PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyGILState_Release(gstate); if (!ret) { printf("Python script error: "); @@ -436,6 +438,7 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) } err = pcilib_set_value_from_pyobject(ctx, ret, val); + Py_XDECREF(ret); if(err) { @@ -463,17 +466,26 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) PyErr_Print(); return PCILIB_ERROR_FAILED; } + PyObject *func_name = PyUnicode_FromString("write_to_register"); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - PyUnicode_FromString("write_to_register"), + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, + func_name, input, NULL); + PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); PyErr_Print(); return PCILIB_ERROR_FAILED; } + + //release objects + Py_XDECREF(func_name); + Py_XDECREF(ret); + Py_XDECREF(input); return 0; } -- cgit v1.2.3 From ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Tue, 16 Feb 2016 16:30:40 +0100 Subject: 1. Add python thread initialization to pcilib_init_py() -Fix pcilib_script_run_func() work in multithread mode 2. pcilib_close() - Move free_py() code after free views to make view destructors work properly 3. Move script hash to pcilib_py_s 4. Move pcilib_get_logger() pcilib_get_logger_min_prio() and pcilib_get_logger_argument() declarations to error.h 5. Refactor pcilib_get_value_as_pyobject pcilib_set_value_from_pyobject to more unified form 6. Add more memory checks. Fix some string memory allocations. 7. Refactor pcilib_py_s member names. 8. Merge pcilib_script_read() and pcilib_script_write() to pcilib_script_run_func() 9. Update test_pywrap views scripts --- pcilib/error.h | 14 +++++ pcilib/pci.c | 4 +- pcilib/pcilib.h | 15 ----- pcilib/py.c | 180 ++++++++++++++++++++++++++------------------------------ pcilib/py.h | 12 ++-- pcilib/xml.c | 2 +- 6 files changed, 108 insertions(+), 119 deletions(-) (limited to 'pcilib') diff --git a/pcilib/error.h b/pcilib/error.h index a9f4c0b..95774e9 100644 --- a/pcilib/error.h +++ b/pcilib/error.h @@ -40,6 +40,20 @@ extern "C" { void pcilib_log_message(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...); void pcilib_log_vmessage(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, va_list va); +/** + * Gets current logger function. + */ +pcilib_logger_t pcilib_get_logger(); + +/** + * Gets current logger min priority. + */ +pcilib_log_priority_t pcilib_get_logger_min_prio(); + +/** + * Gets current logger argument. + */ +void* pcilib_get_logger_argument(); #ifdef __cplusplus } diff --git a/pcilib/pci.c b/pcilib/pci.c index c38097f..58ee4b0 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -306,8 +306,6 @@ void pcilib_close(pcilib_t *ctx) { if (ctx->event_plugin) pcilib_plugin_close(ctx->event_plugin); - - pcilib_free_py(ctx); if (ctx->locks.kmem) pcilib_free_locking(ctx); @@ -349,6 +347,8 @@ void pcilib_close(pcilib_t *ctx) { if (ctx->registers) free(ctx->registers); + + pcilib_free_py(ctx); if (ctx->model) free(ctx->model); diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index 2458320..c32d1fb 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -263,21 +263,6 @@ extern "C" { */ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg); -/** - * Gets current logger function. - */ -pcilib_logger_t pcilib_get_logger(); - -/** - * Gets current logger min priority. - */ -pcilib_log_priority_t pcilib_get_logger_min_prio(); - -/** - * Gets current logger argument. - */ -void* pcilib_get_logger_argument(); - /** public_api_global * @} */ diff --git a/pcilib/py.c b/pcilib/py.c index 20fa546..038dba6 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,20 @@ #include "py.h" #include "error.h" - - -struct pcilib_py_s { - PyObject *main_module; - PyObject *global_dict; - int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class -}; - typedef struct pcilib_script_s { - char* script_name; - PyObject *py_script_module; /**< PyModule object, contains script enviroment */ - PyObject *dict; + char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ pcilib_access_mode_t mode; UT_hash_handle hh; } pcilib_script_s; -struct pcilib_script_s *scripts = NULL; +struct pcilib_py_s { + PyObject *main_module; + PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class + struct pcilib_script_s *scripts; +}; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); @@ -37,6 +33,12 @@ int pcilib_init_py(pcilib_t *ctx) { if(!Py_IsInitialized()) { Py_Initialize(); + + //Since python is being initializing from c programm, it needs + //to initialize threads to works properly with c threads + PyEval_InitThreads(); + PyEval_ReleaseLock(); + ctx->py->py_initialized_inside = 1; } else @@ -70,6 +72,8 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } + + ctx->py->scripts = NULL; return 0; } @@ -237,53 +241,60 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) -{ +pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) +{ int err; switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_STRING: - pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_LONG: { - long ret; - ret = pcilib_get_value_as_int(ctx, val, &err); + long ret_val; + ret_val = pcilib_get_value_as_int(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyInt_FromLong((long) ret); + + if (ret) *ret = 0; + return (PyObject*)PyInt_FromLong((long) ret_val); } case PCILIB_TYPE_DOUBLE: { - double ret; - ret = pcilib_get_value_as_float(ctx, val, &err); + double ret_val; + ret_val = pcilib_get_value_as_float(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyFloat_FromDouble((double) ret); + + if (ret) *ret = 0; + return (PyObject*)PyFloat_FromDouble((double) ret_val); } default: - pcilib_warning("Invalid register output type (unknown)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; + pcilib_error("Invalid register output type (unknown)"); return NULL; } } -int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { PyObject* pyVal = pyObjVal; int err; @@ -321,7 +332,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t } pcilib_script_s* module = NULL; - HASH_FIND_STR( scripts, module_name, module); + HASH_FIND_STR( ctx->py->scripts, module_name, module); if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); @@ -366,10 +377,16 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); - module->py_script_module = py_script_module; - module->script_name = malloc(strlen(module_name)); - sprintf(module->script_name, "%s", module_name); - module->dict = dict; + if (!module) + return PCILIB_ERROR_MEMORY; + module->module = py_script_module; + module->name = strdup(module_name); + if(!(module->name)) + { + free(module); + return PCILIB_ERROR_MEMORY; + } + sprintf(module->name, "%s", module_name); //Setting correct mode @@ -380,15 +397,15 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t mode[0] |= PCILIB_ACCESS_W; module->mode = mode[0]; - HASH_ADD_STR( scripts, script_name, module); + HASH_ADD_STR( ctx->py->scripts, name, module); return 0; } -int pcilib_py_free_script(char* module_name) +int pcilib_py_free_script(pcilib_t *ctx,char* module_name) { pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { @@ -397,39 +414,51 @@ int pcilib_py_free_script(char* module_name) return 0; } - if(module->script_name) + if(module->name) { - free(module->script_name); - module->script_name = NULL; + free(module->name); + module->name = NULL; } - if(module->py_script_module) + if(module->module) { - //PyObject_Free(module->py_script_module); - module->py_script_module = NULL; + module->module = NULL; } - HASH_DEL(scripts, module); + HASH_DEL(ctx->py->scripts, module); free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) -{ +int pcilib_script_run_func(pcilib_t *ctx, char* module_name, + const char* func_name, pcilib_value_t *val) +{ + int err; pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { pcilib_error("Failed to find script module (%s) in hash", module_name); return PCILIB_ERROR_NOTFOUND; } - int err; - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyObject *input = pcilib_get_value_as_pyobject(ctx, val, &err); + if(err) + return err; + + PyObject *py_func_name = PyUnicode_FromString(func_name); + PyObject *ret = PyObject_CallMethodObjArgs(module->module, + py_func_name, + input, + NULL); + + + + Py_XDECREF(py_func_name); + Py_XDECREF(input); PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); @@ -437,55 +466,16 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) return PCILIB_ERROR_FAILED; } - err = pcilib_set_value_from_pyobject(ctx, ret, val); - Py_XDECREF(ret); - - 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, char* module_name, pcilib_value_t *val) -{ - pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - - if(!module) - { - pcilib_error("Failed to find script module (%s) in hash", module_name); - return PCILIB_ERROR_NOTFOUND; - } - - PyObject *input = pcilib_get_value_as_pyobject(ctx, val); - if(!input) + if(ret != Py_None) { - printf("Failed to convert input value to Python object"); - PyErr_Print(); - return PCILIB_ERROR_FAILED; - } - PyObject *func_name = PyUnicode_FromString("write_to_register"); + err = pcilib_set_value_from_pyobject(ctx, val, ret); + Py_XDECREF(ret); - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - func_name, - input, - NULL); - PyGILState_Release(gstate); - - if (!ret) - { - printf("Python script error: "); - PyErr_Print(); - return PCILIB_ERROR_FAILED; + if(err) + { + pcilib_error("Failed to convert python script return value to internal type: %i", err); + return err; + } } - - //release objects - Py_XDECREF(func_name); - Py_XDECREF(ret); - Py_XDECREF(input); - return 0; } diff --git a/pcilib/py.h b/pcilib/py.h index 09e2b87..9703706 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -4,6 +4,7 @@ #include "pcilib.h" typedef struct pcilib_py_s pcilib_py_t; +typedef void pcilib_py_object; #ifdef __cplusplus extern "C" { @@ -15,10 +16,9 @@ void pcilib_free_py(pcilib_t *ctx); int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); -int pcilib_py_free_script(char* module_name); -int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val); -int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); - +int pcilib_py_free_script(pcilib_t *ctx,char* module_name); +int pcilib_script_run_func(pcilib_t *ctx, char* module_name, + const char* func_name, pcilib_value_t *val); /*! * \brief Converts pcilib_value_t to PyObject. @@ -26,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); * \param val pointer to pcilib_value_t to convert * \return PyObject, containing value. NULL with error message, sended to errstream. */ -void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); +pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *err); /*! @@ -36,7 +36,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); * \param val initialized polymorphic value * \return 0 on success or memory error */ -int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal); #ifdef __cplusplus diff --git a/pcilib/xml.c b/pcilib/xml.c index 4e95437..adca34e 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -600,7 +600,7 @@ 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")) { - desc.module = malloc(strlen(value)); + desc.module = strdup(value); sprintf(desc.module, "%s", value); break; } -- cgit v1.2.3 From 3269dce32883e14b45cc490a0cc0037b4c808a68 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 11:01:22 +0100 Subject: 1. Add cmake BUILD_PYTHON_MODULES option. 2. Rename log options getting functions. 3. py: - pcilib_init_py() - extract pcilib_py_add_script_dir() - pcilib_py_init_script() - extract view-specialized code to pcilib_py_get_transform_script_properties() 3. pcilib_open(): - move pcilib_init_py() to previous position. - add extract pcilib_py_add_script_dir() 4. pcilib_script_s - change hash key. Now it is (const char*) and contains script file name with extension 5. pcipywrap: - Add pcipywrap.h to remove swig generated file complile warnings - remove -includeall swig flag to prevent crash in multi-thread scripts - change set python expetion mechanic --- pcilib/error.c | 4 +- pcilib/error.h | 4 +- pcilib/pci.c | 11 ++++- pcilib/py.c | 124 +++++++++++++++++++++++++++++++++++++-------------------- pcilib/py.h | 11 +++-- pcilib/xml.c | 3 +- 6 files changed, 102 insertions(+), 55 deletions(-) (limited to 'pcilib') diff --git a/pcilib/error.c b/pcilib/error.c index 87380e7..a2e5a04 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -80,10 +80,10 @@ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, vo pcilib_logger_t pcilib_get_logger() { return pcilib_logger; } -pcilib_log_priority_t pcilib_get_logger_min_prio() { +pcilib_log_priority_t pcilib_get_log_level() { return pcilib_logger_min_prio; } -void* pcilib_get_logger_argument() { +void* pcilib_get_logger_context() { return pcilib_logger_argument; } diff --git a/pcilib/error.h b/pcilib/error.h index 95774e9..051ecd8 100644 --- a/pcilib/error.h +++ b/pcilib/error.h @@ -48,12 +48,12 @@ pcilib_logger_t pcilib_get_logger(); /** * Gets current logger min priority. */ -pcilib_log_priority_t pcilib_get_logger_min_prio(); +pcilib_log_priority_t pcilib_get_log_level(); /** * Gets current logger argument. */ -void* pcilib_get_logger_argument(); +void* pcilib_get_logger_context(); #ifdef __cplusplus } diff --git a/pcilib/pci.c b/pcilib/pci.c index 58ee4b0..2b7b97b 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -144,6 +144,13 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } + + err = pcilib_init_py(ctx); + if (err) { + pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_close(ctx); + return NULL; + } ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE; ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE; @@ -185,9 +192,9 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - err = pcilib_init_py(ctx); + err = pcilib_py_add_script_dir(ctx); if (err) { - pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_error("Error (%i) add script path to python path", err); pcilib_close(ctx); return NULL; } diff --git a/pcilib/py.c b/pcilib/py.c index 038dba6..8f8040e 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -1,4 +1,6 @@ +#ifdef BUILD_PYTHON_MODULES #include +#endif #include #include @@ -11,11 +13,10 @@ #include "py.h" #include "error.h" +#ifdef BUILD_PYTHON_MODULES typedef struct pcilib_script_s { - char* name; - PyObject *module; /**< PyModule object, contains script enviroment */ - pcilib_access_mode_t mode; - + const char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ UT_hash_handle hh; } pcilib_script_s; @@ -25,8 +26,10 @@ struct pcilib_py_s { int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; +#endif int pcilib_init_py(pcilib_t *ctx) { +#ifdef BUILD_PYTHON_MODULES ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; @@ -53,6 +56,16 @@ int pcilib_init_py(pcilib_t *ctx) { return PCILIB_ERROR_FAILED; + + + ctx->py->scripts = NULL; +#endif + return 0; +} + +int pcilib_py_add_script_dir(pcilib_t *ctx) +{ +#ifdef BUILD_PYTHON_MODULES //create path string, where the model scripts should be static int model_dir_added = 0; if(!model_dir_added) @@ -72,13 +85,12 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } - - ctx->py->scripts = NULL; - return 0; +#endif + return 0; } void pcilib_free_py(pcilib_t *ctx) { - +#ifdef BUILD_PYTHON_MODULES int py_initialized_inside = 0; if (ctx->py) { @@ -92,6 +104,7 @@ void pcilib_free_py(pcilib_t *ctx) { if(py_initialized_inside) Py_Finalize(); +#endif } /* @@ -110,7 +123,7 @@ static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size return 0; } */ - +#ifdef BUILD_PYTHON_MODULES static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { int i; int err = 0; @@ -216,8 +229,10 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v return dst; } +#endif int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { +#ifdef BUILD_PYTHON_MODULES PyGILState_STATE gstate; char *code; PyObject* obj; @@ -239,10 +254,15 @@ 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)); +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; switch(val->type) @@ -292,10 +312,16 @@ pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va pcilib_error("Invalid register output type (unknown)"); return NULL; } +#else + pcilib_error("Current build not support python."); + if (ret) *ret = PCILIB_ERROR_NOTAVAILABLE; + return NULL; +#endif } int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { +#ifdef BUILD_PYTHON_MODULES PyObject* pyVal = pyObjVal; int err; @@ -318,12 +344,18 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py return err; return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } -int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) -{ +int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) +{ +#ifdef BUILD_PYTHON_MODULES //extract module name from script name - char* py_module_name = strtok(module_name, "."); + char* py_module_name = strdup(module_name); + py_module_name = strtok(py_module_name, "."); if(!py_module_name) { pcilib_error("Invalid script name specified in XML property (%s)." @@ -336,26 +368,19 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); - mode[0] = module->mode; return 0; } - //Initialize python module - if(!module_name) - { - pcilib_error("Invalid script name specified in XML property (NULL)"); - 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(); + free(py_module_name); return PCILIB_ERROR_INVALID_DATA; } + free(py_module_name); //Initializing pcipywrap module if script use it PyObject* dict = PyModule_GetDict(py_script_module); @@ -380,45 +405,50 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if (!module) return PCILIB_ERROR_MEMORY; module->module = py_script_module; - module->name = strdup(module_name); - if(!(module->name)) + module->name = module_name; + HASH_ADD_STR( ctx->py->scripts, name, module); +#endif + return 0; +} + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char* module_name, +pcilib_access_mode_t *mode) +{ +#ifdef BUILD_PYTHON_MODULES + pcilib_script_s *module; + + HASH_FIND_STR(ctx->py->scripts, module_name, module); + if(!module) { - free(module); - return PCILIB_ERROR_MEMORY; + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; } - sprintf(module->name, "%s", module_name); - + PyObject* dict = PyModule_GetDict(module->module); //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; - - module->mode = mode[0]; - HASH_ADD_STR( ctx->py->scripts, name, module); - + mode[0] |= PCILIB_ACCESS_W; return 0; +#else + mode[0] = PCILIB_ACCESS_RW; + return 0; +#endif } -int pcilib_py_free_script(pcilib_t *ctx,char* module_name) +int pcilib_py_free_script(pcilib_t *ctx, const char* module_name) { +#ifdef BUILD_PYTHON_MODULES pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { - //For some reason it will crash if uncomment. printf same warning is ok - //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); return 0; } - - if(module->name) - { - free(module->name); - module->name = NULL; - } if(module->module) { @@ -427,12 +457,14 @@ int pcilib_py_free_script(pcilib_t *ctx,char* module_name) HASH_DEL(ctx->py->scripts, module); free(module); +#endif return 0; } -int pcilib_script_run_func(pcilib_t *ctx, char* module_name, +int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, const char* func_name, pcilib_value_t *val) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); @@ -478,4 +510,8 @@ int pcilib_script_run_func(pcilib_t *ctx, char* module_name, } } return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } diff --git a/pcilib/py.h b/pcilib/py.h index 9703706..04b4e8b 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -11,14 +11,19 @@ extern "C" { #endif int pcilib_init_py(pcilib_t *ctx); +int pcilib_py_add_script_dir(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_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); -int pcilib_py_free_script(pcilib_t *ctx,char* module_name); -int pcilib_script_run_func(pcilib_t *ctx, char* module_name, +int pcilib_py_init_script(pcilib_t *ctx, const char* module_name); +int pcilib_py_free_script(pcilib_t *ctx, const char* module_name); +int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, const char* func_name, pcilib_value_t *val); + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, + const char* module_name, + pcilib_access_mode_t *mode); /*! * \brief Converts pcilib_value_t to PyObject. diff --git a/pcilib/xml.c b/pcilib/xml.c index adca34e..35721aa 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -600,8 +600,7 @@ 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")) { - desc.module = strdup(value); - sprintf(desc.module, "%s", value); + desc.module = value; break; } } -- cgit v1.2.3 From 9a9ffd5594a5d27bbecf6160de2c33d44870f5bd Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 17:20:25 +0100 Subject: Refactor pcipywrap to object --- pcilib/py.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'pcilib') diff --git a/pcilib/py.c b/pcilib/py.c index 8f8040e..372d475 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -23,6 +23,7 @@ typedef struct pcilib_script_s { struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + PyObject *pcilib_pywrap; int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; @@ -54,9 +55,30 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; + + + + PyObject* py_script_module = PyImport_ImportModule("pcipywrap"); + if(!py_script_module) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + PyObject* mod_name = PyString_FromString("Pcipywrap"); + ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(py_script_module, + mod_name, + PyCObject_FromVoidPtr(ctx, NULL), + NULL); + Py_XDECREF(mod_name); - + if(!ctx->py->pcilib_pywrap) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } ctx->py->scripts = NULL; #endif @@ -381,24 +403,6 @@ int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) return PCILIB_ERROR_INVALID_DATA; } free(py_module_name); - - //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("set_pcilib"), - PyCObject_FromVoidPtr(ctx, NULL), - NULL); - } //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); @@ -482,10 +486,9 @@ int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, PyObject *py_func_name = PyUnicode_FromString(func_name); PyObject *ret = PyObject_CallMethodObjArgs(module->module, py_func_name, + ctx->py->pcilib_pywrap, input, NULL); - - Py_XDECREF(py_func_name); Py_XDECREF(input); -- cgit v1.2.3 From 52eb7f4fb76ddf99dedf44332aae7af4df76ab36 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 18:13:36 +0100 Subject: Add test to repository. Add GIL states to pcilib_set_value_from_pyobject --- pcilib/py.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'pcilib') diff --git a/pcilib/py.c b/pcilib/py.c index 372d475..a288043 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -347,6 +347,7 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py PyObject* pyVal = pyObjVal; int err; + PyGILState_STATE gstate = PyGILState_Ensure(); if(PyInt_Check(pyVal)) { err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); @@ -359,9 +360,11 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); else { + PyGILState_Release(gstate); pcilib_error("Invalid input. Input type should be int, float or string."); return PCILIB_ERROR_NOTSUPPORTED; } + PyGILState_Release(gstate); if(err) return err; -- cgit v1.2.3