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 --- pcitool/cli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pcitool/cli.c') diff --git a/pcitool/cli.c b/pcitool/cli.c index 4d5d3d5..8350d24 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1385,7 +1385,7 @@ int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, const char *reg, const char *view, const char *unit, const char *attr) { int i; int err; - const char *format; + const char *format; pcilib_register_bank_t bank_id; pcilib_register_bank_addr_t bank_addr = 0; -- 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 --- CMakeLists.txt | 1 + docs/Doxyfile.in | 2 +- pcilib/CMakeLists.txt | 1 - pcilib/pcilib.h | 1 + pcilib/pcipywrap.c | 84 ++++++++++++++++++++++++++++++++++--------- pcilib/pcipywrap.i | 5 ++- pcilib/xml.c | 16 +++++++-- pcitool/cli.c | 6 ++-- xml/test_pywrap/props.xml | 3 +- xml/test_pywrap/test_prop2.py | 2 +- xml/types.xsd | 1 + 11 files changed, 95 insertions(+), 27 deletions(-) (limited to 'pcitool/cli.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index a0fe0f0..bebc41e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) find_package(PythonLibs 2.7 REQUIRED) +find_package(SWIG REQUIRED) set(EXTRA_SYSTEM_LIBS -lrt) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in index ef98587..f87b220 100644 --- a/docs/Doxyfile.in +++ b/docs/Doxyfile.in @@ -243,7 +243,7 @@ TCL_SUBST = # members will be omitted, etc. # The default value is: NO. -OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored 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; diff --git a/pcitool/cli.c b/pcitool/cli.c index 8350d24..cb87dcb 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1702,10 +1702,12 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) { const char *format = (val.format?val.format:"%u"); + err = pcilib_read_register(handle, bank, reg, &verify); if (err) Error("Error reading back register %s for verification\n", reg); - - if (verify != value) { + + if (!((model_info->registers[regid].mode&PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK) && + verify != value) { Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); } else { printf("%s = ", reg); diff --git a/xml/test_pywrap/props.xml b/xml/test_pywrap/props.xml index 59d593c..8e3078e 100644 --- a/xml/test_pywrap/props.xml +++ b/xml/test_pywrap/props.xml @@ -9,7 +9,8 @@ register="test_prop2" unit="C" script="test_prop2.py" - description="test python script #1"/> + description="test python script #1" + no_set_check="1"/> + -- 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. --- CMakeLists.txt | 1 + pcilib/CMakeLists.txt | 13 +- pcilib/pcilib.h | 2 +- pcilib/pcipywrap.c | 542 ---------------------------------------------- pcilib/pcipywrap.i | 21 -- pcilib/py.c | 8 +- pcilib/xml.c | 19 +- pcitool/cli.c | 2 +- pywrap/CMakeLists.txt | 22 ++ pywrap/pcipywrap.c | 542 ++++++++++++++++++++++++++++++++++++++++++++++ pywrap/pcipywrap.i | 21 ++ pywrap/server.py | 184 ++++++++++++++++ xml/test_pywrap/props.xml | 2 +- xml/types.xsd | 2 +- 14 files changed, 790 insertions(+), 591 deletions(-) delete mode 100644 pcilib/pcipywrap.c delete mode 100644 pcilib/pcipywrap.i create mode 100644 pywrap/CMakeLists.txt create mode 100644 pywrap/pcipywrap.c create mode 100644 pywrap/pcipywrap.i create mode 100644 pywrap/server.py (limited to 'pcitool/cli.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index bebc41e..204fe6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ add_subdirectory(dma) add_subdirectory(protocols) add_subdirectory(views) add_subdirectory(pcilib) +add_subdirectory(pywrap) add_subdirectory(pcitool) add_subdirectory(apps) add_subdirectory(xml) 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; } } diff --git a/pcitool/cli.c b/pcitool/cli.c index cb87dcb..3e69aac 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1706,7 +1706,7 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info err = pcilib_read_register(handle, bank, reg, &verify); if (err) Error("Error reading back register %s for verification\n", reg); - if (!((model_info->registers[regid].mode&PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK) && + if (!((model_info->registers[regid].mode&PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) && verify != value) { Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); } else { diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt new file mode 100644 index 0000000..e5f7ea7 --- /dev/null +++ b/pywrap/CMakeLists.txt @@ -0,0 +1,22 @@ +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/pcilib + ${CMAKE_BINARY_DIR}/pcilib + ${LIBXML2_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIR} + ${UTHASH_INCLUDE_DIRS} +) + +#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 pcipywrap.c) +SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) + +configure_file(server.py server.py) diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c new file mode 100644 index 0000000..c5164a8 --- /dev/null +++ b/pywrap/pcipywrap.c @@ -0,0 +1,542 @@ +#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_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) + 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_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) + 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_registers_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/pywrap/pcipywrap.i b/pywrap/pcipywrap.i new file mode 100644 index 0000000..3ff23a9 --- /dev/null +++ b/pywrap/pcipywrap.i @@ -0,0 +1,21 @@ +%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_registers_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/pywrap/server.py b/pywrap/server.py new file mode 100644 index 0000000..d308867 --- /dev/null +++ b/pywrap/server.py @@ -0,0 +1,184 @@ +import time +import os #delete later +import pcipywrap +import json +import BaseHTTPServer + +class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): + + def do_HEAD(s): + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + + def do_GET(s): + length = int(s.headers['Content-Length']) + + #deserialize input data + data = json.loads(s.rfile.read(length).decode('utf-8')) + + if 'command' in data: + command = data['command'] + if(command == 'help'): + s.help(data) + + elif(command == 'open'): + #check required arguments + if not 'device' in data: + s.error('message doesnt contains "device" field, ' + 'which is required for "open" command', data) + return + #parse command arguments and convert them to string + device = str(data.get('device', None)) + model = data.get('model', None) + if not model is None: + model = str(model) + + try: + s.openPcilibInstance(device, model) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + + elif(command == 'get_registers_list'): + #parse command arguments and convert them to string + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + registers = dict() + try: + registers = pcipywrap.get_registers_list(bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['registers'] = registers + s.wrapMessageAndSend(out, data) + + elif(command == 'get_register_info'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "get_register_info" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + register = dict() + try: + register = pcipywrap.get_register_info(reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['register'] = register + s.wrapMessageAndSend(out, data) + + elif(command == 'get_property_info'): + #parse command arguments and convert them to string + branch = data.get('branch', None) + if not branch is None: + branch = str(bank) + + properties = dict() + try: + properties = pcipywrap.get_property_info(branch) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['properties'] = properties + s.wrapMessageAndSend(out, data) + + else: + s.error('command "' + command + '" undefined', data) + return + else: + s.error('message doesnt contains "command" field, which is required', data) + return + + + #print str(s.headers['content-type']) + #print post_data['some'] + + """open device context """ + def openPcilibInstance(s, device, model): + pcipywrap.closeCurrentPcilibInstance() + + lib = pcipywrap.createPcilibInstance(device, model) + pcipywrap.setPcilib(lib) + + """Send help message""" + def help(s, received_message = None): + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = {'status': 'ok', 'help' : 'under construction'} + s.wrapMessageAndSend(out, received_message) + + """Send error message with text description""" + def error(s, info, received_message = None): + s.send_response(400) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + + out['status'] = 'error' + out['description'] = info + out['note'] = 'send {"command" : "help"} to get help' + s.wrapMessageAndSend(out, received_message) + + def wrapMessageAndSend(s, message, received_message = None): + if not received_message is None: + message['received_message'] = received_message + s.wfile.write(json.dumps(message)) + +HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! +PORT_NUMBER = 12412 # Maybe set this to 9000. + +if __name__ == '__main__': + #initialize variables test (to remove) + os.environ["APP_PATH"] = '/home/vchernov/1215N/pcitool' + os.environ["PCILIB_MODEL_DIR"] = os.environ["APP_PATH"] + "/xml" + os.environ["LD_LIBRARY_PATH"] = os.environ["APP_PATH"] + "/pcilib" + + pcilib_server = BaseHTTPServer.HTTPServer + httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) + print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) + try: + httpd.serve_forever() + except KeyboardInterrupt: + pass + httpd.server_close() + print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER) diff --git a/xml/test_pywrap/props.xml b/xml/test_pywrap/props.xml index 8e3078e..0d0078b 100644 --- a/xml/test_pywrap/props.xml +++ b/xml/test_pywrap/props.xml @@ -10,7 +10,7 @@ unit="C" script="test_prop2.py" description="test python script #1" - no_set_check="1"/> + write_verification="0"/> - + -- 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 --- CMakeLists.txt | 6 +- pci | 5 +- pcilib/pci.c | 14 +-- pcilib/py.c | 194 +++++++++++++++++++++-------------- pcilib/py.h | 13 ++- pcilib/xml.c | 53 +--------- pcitool/cli.c | 26 +++-- pywrap/pcipywrap.c | 50 +++------ pywrap/pcipywrap.i | 10 +- pywrap/server.py | 230 +++++++++++++++++++++++++++++++++++++++--- views/transform.c | 53 +++++----- views/transform.h | 2 +- xml/CMakeLists.txt | 27 ----- xml/test_pywrap/test_prop2.py | 2 +- 14 files changed, 416 insertions(+), 269 deletions(-) (limited to 'pcitool/cli.c') diff --git a/CMakeLists.txt b/CMakeLists.txt index 204fe6d..e5c8b82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ project(pcitool) set(PCILIB_VERSION "0.2.5") set(PCILIB_ABI_VERSION "2") -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8) #set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH true) #set(CMAKE_PREFIX_PATH ${CMAKE_SYSTEM_PREFIX_PATH}) @@ -89,14 +89,18 @@ set_target_properties(pcilib PROPERTIES SOVERSION ${PCILIB_ABI_VERSION} ) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xml DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/version.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/pci DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc diff --git a/pci b/pci index a07d93d..6992ae8 100644 --- a/pci +++ b/pci @@ -2,4 +2,7 @@ APP_PATH=`dirname $0` -PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $APP_PATH/pcitool/pci $* +PYTHONPATH="$PYTHONPATH:$APP_PATH/pywrap" \ +PCILIB_MODEL_DIR="$APP_PATH/xml" \ +LD_LIBRARY_PATH="$APP_PATH/pcilib" \ +$APP_PATH/pcitool/pci $* 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); } } diff --git a/pcitool/cli.c b/pcitool/cli.c index 3e69aac..3676a56 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1703,17 +1703,21 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info const char *format = (val.format?val.format:"%u"); - err = pcilib_read_register(handle, bank, reg, &verify); - if (err) Error("Error reading back register %s for verification\n", reg); - - if (!((model_info->registers[regid].mode&PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) && - verify != value) { - Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); - } else { - printf("%s = ", reg); - printf(format, verify); - printf("\n"); - } + if(!((model_info->registers[regid].mode&PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)) + { + err = pcilib_read_register(handle, bank, reg, &verify); + if (err) Error("Error reading back register %s for verification\n", reg); + + if ( verify != value) { + Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); + } else { + printf("%s = ", reg); + printf(format, verify); + printf("\n"); + } + } + else + printf("%s is written\n ", reg); } else { printf("%s is written\n ", reg); } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index c5164a8..fc0add1 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -4,7 +4,7 @@ /*! * \brief Global pointer to pcilib_t context. - * Used by setPcilib and read_register. + * Used by set_pcilib and read_register. */ pcilib_t* __ctx = 0; @@ -68,6 +68,7 @@ void pcilib_print_error_to_py(void *arg, const char *file, int line, */ void init_pcipywrap_module() { + printf("init_pcipywrap_module\n"); pcilib_set_logger(pcilib_get_logger_min_prio(), pcilib_print_error_to_py, pcilib_get_logger_argument()); @@ -79,7 +80,7 @@ void init_pcipywrap_module() * \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) +PyObject* create_pcilib_instance(const char *fpga_device, const char *model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); @@ -93,7 +94,7 @@ PyObject* createPcilibInstance(const char *fpga_device, const char *model) /*! * \brief Closes current pciliv instance, if its open. */ -void closeCurrentPcilibInstance() +void close_curr_pcilib_instance() { if(__ctx) { @@ -106,7 +107,7 @@ void closeCurrentPcilibInstance() * \brief Returns current opened pcilib_t instatnce * \return Pointer to pcilib_t, serialized to bytearray */ -PyObject* getCurrentPcilibInstance() +PyObject* get_curr_pcilib_instance() { return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*)); } @@ -116,7 +117,7 @@ PyObject* getCurrentPcilibInstance() * \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* set_pcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { @@ -156,19 +157,13 @@ PyObject* read_register(const char *regname, const char *bank) 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); + return pcilib_get_value_as_pyobject(__ctx, &val); } /*! @@ -190,26 +185,17 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) pcilib_register_value_t reg_value; int err; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__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); } @@ -232,12 +218,9 @@ PyObject* get_property(const char *prop) err = pcilib_get_property(__ctx, prop, &val); if(err) - { - pcilib_error("Failed pcilib_get_property (%i)", err); - return NULL; - } + return NULL; - return pcilib_convert_val_to_pyobject(__ctx, &val); + return pcilib_get_value_as_pyobject(__ctx, &val); } /*! @@ -246,7 +229,7 @@ PyObject* get_property(const char *prop) * \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) +PyObject* set_property(PyObject* val, const char *prop) { int err; @@ -257,27 +240,21 @@ PyObject* set_property(const char *prop, PyObject* val) } pcilib_value_t val_internal = {0}; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__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); + PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val); if(py_val) PyDict_SetItem(dict, @@ -506,7 +483,6 @@ PyObject* get_register_info(const char* reg,const char *bank) if(!info) { - pcilib_error("Failed pcilib_get_register_info"); return NULL; } diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 3ff23a9..95045f3 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -4,16 +4,16 @@ 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* create_pcilib_instance(const char *fpga_device, const char *model = NULL); +extern PyObject* set_pcilib(PyObject* addr); +extern void close_curr_pcilib_instance(); +extern PyObject* get_curr_pcilib_instance(); 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* set_property(PyObject* val, const char *prop); extern PyObject* get_registers_list(const char *bank = NULL); extern PyObject* get_register_info(const char* reg,const char *bank = NULL); diff --git a/pywrap/server.py b/pywrap/server.py index d308867..0da6bc8 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -1,8 +1,10 @@ import time -import os #delete later +import os import pcipywrap import json import BaseHTTPServer +import sys +import getopt class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): @@ -70,8 +72,8 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): out['registers'] = registers s.wrapMessageAndSend(out, data) - elif(command == 'get_register_info'): - #check required arguments + elif(command == 'get_register_info'): + #check required arguments if not 'reg' in data: s.error('message doesnt contains "reg" field, ' 'which is required for "get_register_info" command', data) @@ -81,7 +83,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): reg = str(data.get('reg', None)) bank = data.get('bank', None) if not bank is None: - bank = str(bank) + bank = str(bank) register = dict() try: @@ -120,6 +122,125 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): out['status'] = 'ok' out['properties'] = properties s.wrapMessageAndSend(out, data) + + elif(command == 'read_register'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "read_register" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + value = 0 + try: + value = pcipywrap.read_register(reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['value'] = value + s.wrapMessageAndSend(out, data) + + elif(command == 'write_register'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "write_register" command', data) + return + + if not 'value' in data: + s.error('message doesnt contains "value" field, ' + 'which is required for "write_register" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + value = str(data.get('value', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + try: + pcipywrap.write_register(value, reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + + elif(command == 'get_property'): + #check required arguments + if not 'prop' in data: + s.error('message doesnt contains "prop" field, ' + 'which is required for "get_property" command', data) + return + + #parse command arguments and convert them to string + prop = str(data.get('prop', None)) + + value = 0 + try: + value = pcipywrap.get_property(prop) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['value'] = value + s.wrapMessageAndSend(out, data) + + elif(command == 'set_property'): + #check required arguments + if not 'prop' in data: + s.error('message doesnt contains "prop" field, ' + 'which is required for "set_property" command', data) + return + + if not 'value' in data: + s.error('message doesnt contains "value" field, ' + 'which is required for "set_property" command', data) + return + + #parse command arguments and convert them to string + prop = str(data.get('prop', None)) + value = str(data.get('value', None)) + + try: + pcipywrap.set_property(value, prop) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + else: s.error('command "' + command + '" undefined', data) @@ -134,19 +255,78 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): """open device context """ def openPcilibInstance(s, device, model): - pcipywrap.closeCurrentPcilibInstance() + pcipywrap.close_curr_pcilib_instance() - lib = pcipywrap.createPcilibInstance(device, model) - pcipywrap.setPcilib(lib) + lib = pcipywrap.create_pcilib_instance(device, model) + pcipywrap.set_pcilib(lib) """Send help message""" def help(s, received_message = None): s.send_response(200) s.send_header('content-type', 'application/json') s.end_headers() - out = {'status': 'ok', 'help' : 'under construction'} + usage = str('Usage:\n' + ' Server receive commands via http GET with json packet.\n' + ' content-type should have value "application/json"\n' + ' Server could handle only commands. to set command, you\n' + ' should specify field "command" in packet with command name\n' + ' List of commands:\n' + '\n' + ' command: help - Get help. This will return usage\n' + '\n' + + ' command: open - Opens context of device. It will be reopened if already open.\n' + ' required fields\n' + ' device: - path to the device file [/dev/fpga0]\n' + ' optional fields\n' + ' model: - specifies the model of hardware, autodetected if doesnt exists\n' + '\n' + + ' command: get_registers_list - Returns the list of registers provided by the hardware model.\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be returned\n' + '\n' + + ' command: get_register_info - Returns the information about the specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be returned\n' + '\n' + + ' command: get_property_info - Returns the list of properties available under the specified path.\n' + ' optional fields\n' + ' branch: - Path. If not set, will return the top-level properties\n' + '\n' + + ' command: read_register - Reads the specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be processed\n' + '\n' + + ' command: write_register - Writes to specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' value: - the register value to write. Should be int, float or string (with number)\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be processed\n' + '\n' + + ' command: get_property - Reads / computes the property value.\n' + ' required fields\n' + ' prop: - full name including path\n' + '\n' + + ' command: set_property - Writes the property value or executes the code associated with property.\n' + ' required fields\n' + ' prop: - full name including path\n' + ' value: - the property value to write. Should be int, float or string (with number)\n' + '\n') + out = {'status': 'ok', 'usage' : usage} s.wrapMessageAndSend(out, received_message) - + """Send error message with text description""" def error(s, info, received_message = None): s.send_response(400) @@ -164,14 +344,34 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): message['received_message'] = received_message s.wfile.write(json.dumps(message)) -HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! -PORT_NUMBER = 12412 # Maybe set this to 9000. if __name__ == '__main__': - #initialize variables test (to remove) - os.environ["APP_PATH"] = '/home/vchernov/1215N/pcitool' - os.environ["PCILIB_MODEL_DIR"] = os.environ["APP_PATH"] + "/xml" - os.environ["LD_LIBRARY_PATH"] = os.environ["APP_PATH"] + "/pcilib" + + HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! + PORT_NUMBER = 12412 # Maybe set this to 9000. + + try: + opts, args = getopt.getopt(sys.argv[1:], "", []) + #opts, args = getopt.getopt(sys.argv[1:], "hop:v", ["help", "output="]) + #print opts, args + except getopt.GetoptError as err: + # print help information and exit: + print str(err) # will print something like "option -a not recognized" + #usage() + sys.exit(2) + + #Set enviroment variables, if it not setted already + if not 'APP_PATH' in os.environ: + APP_PATH = '' + file_dir = os.path.dirname(os.path.abspath(__file__)) + APP_PATH = str(os.path.abspath(file_dir + '/../..')) + os.environ["APP_PATH"] = APP_PATH + + if not 'PCILIB_MODEL_DIR' in os.environ: + os.environ['PCILIB_MODEL_DIR'] = os.environ["APP_PATH"] + "/xml" + + if not 'LD_LIBRARY_PATH' in os.environ: + os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" pcilib_server = BaseHTTPServer.HTTPServer httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) diff --git a/views/transform.c b/views/transform.c index 986cfd7..ba2f48f 100644 --- a/views/transform.c +++ b/views/transform.c @@ -15,53 +15,46 @@ static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); - if(v->script) - { - return pcilib_script_read(ctx, v->script, val); - } - else - { - int err; - - err = pcilib_set_value_from_register_value(ctx, val, regval); - if (err) return err; + int err; + err = pcilib_set_value_from_register_value(ctx, val, regval); + if (err) return err; + + if(v->module) + return pcilib_script_read(ctx, v->module, val); + else return pcilib_py_eval_string(ctx, v->read_from_reg, val); - } } static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, const pcilib_value_t *val) { - - - + const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); + int err = 0; + + pcilib_value_t val_copy = {0}; + err = pcilib_copy_value(ctx, &val_copy, val); + if (err) return err; - if(!v->script) - { - int err = 0; - - pcilib_value_t val_copy = {0}; - err = pcilib_copy_value(ctx, &val_copy, val); - if (err) return err; - - err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); - if (err) return err; - *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); - return err; - } + if(v->module) + err = pcilib_script_write(ctx, v->module, &val_copy); else - return pcilib_script_write(ctx, v->script, (pcilib_value_t *)val); + err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); + + if (err) return err; + + *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); + return err; } void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view) { pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view); - if(v->script) - pcilib_free_py_script(v->script); + if(v->module) + pcilib_py_free_script(v->module); } diff --git a/views/transform.h b/views/transform.h index 8ab4f4f..c2f0a98 100644 --- a/views/transform.h +++ b/views/transform.h @@ -9,7 +9,7 @@ typedef struct { pcilib_view_description_t base; const char *read_from_reg; /**< Formula explaining how to convert the register value to the view value */ const char *write_to_reg; /**< Formula explaining how to convert from the view value to the register value */ - pcilib_script_t *script; + char *module; /**< Python script module name (without extension) */ } pcilib_transform_view_description_t; #ifndef _PCILIB_VIEW_TRANSFORM_C diff --git a/xml/CMakeLists.txt b/xml/CMakeLists.txt index 0b12d87..a7ac800 100644 --- a/xml/CMakeLists.txt +++ b/xml/CMakeLists.txt @@ -1,30 +1,3 @@ install(FILES model.xsd references.xsd types.xsd DESTINATION ${PCILIB_MODEL_DIR} ) - -# Copy files from source directory to destination directory, substituting any -# variables. Create destination directory if it does not exist. - -macro(configure_files srcDir destDir) - message(STATUS "Configuring directory ${destDir}") - make_directory(${destDir}) - - file(GLOB templateFiles RELATIVE ${srcDir} ${srcDir}/*) - foreach(templateFile ${templateFiles}) - set(srcTemplatePath ${srcDir}/${templateFile}) - if(NOT IS_DIRECTORY ${srcTemplatePath}) - message(STATUS "Configuring file ${templateFile}") - configure_file( - ${srcTemplatePath} - ${destDir}/${templateFile} - @ONLY) - endif(NOT IS_DIRECTORY ${srcTemplatePath}) - endforeach(templateFile) -endmacro(configure_files) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/model.xsd ${CMAKE_CURRENT_BINARY_DIR}/model.xsd) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/references.xsd ${CMAKE_CURRENT_BINARY_DIR}/references.xsd) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/types.xsd ${CMAKE_CURRENT_BINARY_DIR}/types.xsd) - -configure_files(${CMAKE_CURRENT_SOURCE_DIR}/test ${CMAKE_CURRENT_BINARY_DIR}/test) -configure_files(${CMAKE_CURRENT_SOURCE_DIR}/test_pywrap ${CMAKE_CURRENT_BINARY_DIR}/test_pywrap) diff --git a/xml/test_pywrap/test_prop2.py b/xml/test_pywrap/test_prop2.py index a831fdd..69a2190 100644 --- a/xml/test_pywrap/test_prop2.py +++ b/xml/test_pywrap/test_prop2.py @@ -4,5 +4,5 @@ def read_from_register(): return pcipywrap.get_property('/registers/fpga/reg1') / 2 def write_to_register(value): - pcipywrap.set_property('/registers/fpga/reg1', value*3) + pcipywrap.set_property(value*3, '/registers/fpga/reg1') -- 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 --- pcitool/cli.c | 2 - pywrap/pcipywrap.c | 110 ++++++++++++++++++++++++++++++++++++++--------------- pywrap/pcipywrap.i | 4 +- pywrap/server.py | 3 ++ views/transform.c | 31 ++++++++++++++- 10 files changed, 124 insertions(+), 50 deletions(-) (limited to 'pcitool/cli.c') 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); diff --git a/pcitool/cli.c b/pcitool/cli.c index 3676a56..0b0c98d 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1716,8 +1716,6 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info printf("\n"); } } - else - printf("%s is written\n ", reg); } else { printf("%s is written\n ", reg); } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index fc0add1..8ef1dc0 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -8,6 +8,8 @@ */ pcilib_t* __ctx = 0; +char* full_log = NULL; + /*! * \brief Wraping for vsnprintf function, that saves string to char* * \return saved from vsnprintf string @@ -52,23 +54,51 @@ char* make_str(const char* msg, ...) */ 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); + va_list va) { + //wrap error message with file and line number + char* buf_raw_msg = vmake_str(msg, va); + char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); + + if(prio == PCILIB_LOG_ERROR) + { + if(!full_log) + full_log = make_str(""); - free(buf_wrapped_message); - free(buf_raw_msg); + if(strlen(buf_wrapped_message) >= 2 && + buf_wrapped_message[0] == '#' && + buf_wrapped_message[1] == 'E') + { + char* wrapped_exeption = make_str("%sprogramm error log:\n%s", &(buf_wrapped_message[2]), full_log); + free(full_log); + full_log = NULL; + + PyErr_SetString(PyExc_Exception, wrapped_exeption); + free(wrapped_exeption); + } + else + { + //copy received message to log + char* buf = full_log; + char* buf_start = buf; + full_log = make_str("%s%s", buf, buf_wrapped_message); + free(buf); + } + } + else + printf(buf_wrapped_message); + + free(buf_wrapped_message); + free(buf_raw_msg); } /*! - * \brief Inits pcipywrap module at importing + * \brief Redirect pcilib standart log stream to exeption text. + * Logger will accumulate errors untill get message, starts with "#E". + * After that, logger will write last error, and all accumulated errors + * to Python exeption text */ -void init_pcipywrap_module() +void __redirect_logs_to_exeption() { - printf("init_pcipywrap_module\n"); pcilib_set_logger(pcilib_get_logger_min_prio(), pcilib_print_error_to_py, pcilib_get_logger_argument()); @@ -78,17 +108,19 @@ void init_pcipywrap_module() * \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. + * \return Pointer to pcilib_t, created by pcilib_open; NULL with exeption text, if failed. */ PyObject* create_pcilib_instance(const char *fpga_device, const char *model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); if(!ctx) + { + pcilib_error("#E Failed pcilib_open(%s, %s)", fpga_device, model); return NULL; + } - //serializing object - return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)); + return PyCObject_FromVoidPtr((void*)ctx, NULL); } /*! @@ -114,23 +146,18 @@ PyObject* get_curr_pcilib_instance() /*! * \brief Sets pcilib context to wraper. - * \param[in] addr Pointer to pcilib_t, serialized to bytearray + * \param[in] addr Pointer to pcilib_t, serialized to PyCObject * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ PyObject* set_pcilib(PyObject* addr) { - if(!PyByteArray_Check(addr)) + if(!PyCObject_Check(addr)) { - pcilib_error("Incorrect addr type. Only bytearray is allowed"); + pcilib_error("#E Incorrect addr type. Only PyCObject 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]; + __ctx = (pcilib_t*)PyCObject_AsVoidPtr(addr); return PyInt_FromLong((long)1); } @@ -146,7 +173,7 @@ PyObject* read_register(const char *regname, const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -157,11 +184,17 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) + { + pcilib_error("#E Failed pcilib_read_register"); return NULL; + } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_register_value"); return NULL; + } return pcilib_get_value_as_pyobject(__ctx, &val); } @@ -187,15 +220,24 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) int err; err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject"); return NULL; + } reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } err = pcilib_write_register(__ctx, bank, regname, reg_value); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } return PyInt_FromLong((long)1); } @@ -208,7 +250,7 @@ PyObject* get_property(const char *prop) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -218,7 +260,10 @@ PyObject* get_property(const char *prop) err = pcilib_get_property(__ctx, prop, &val); if(err) + { + pcilib_error("#E Failed pcilib_get_property, (error %i)", err); return NULL; + } return pcilib_get_value_as_pyobject(__ctx, &val); } @@ -235,19 +280,24 @@ PyObject* set_property(PyObject* val, const char *prop) if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } pcilib_value_t val_internal = {0}; err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) + { + pcilib_error("#E pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } err = pcilib_set_property(__ctx, prop, &val_internal); - if(err) + { + pcilib_error("#E pcilib_set_property, (error %i)", err); return NULL; + } return PyInt_FromLong((long)1); } @@ -452,7 +502,7 @@ PyObject* get_registers_list(const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -475,7 +525,7 @@ PyObject* get_register_info(const char* reg,const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -497,7 +547,7 @@ PyObject* get_property_info(const char* branch) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 95045f3..4b735d2 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -1,8 +1,6 @@ %module pcipywrap -%init %{ - init_pcipywrap_module(); -%} +extern void __redirect_logs_to_exeption(); extern PyObject* create_pcilib_instance(const char *fpga_device, const char *model = NULL); extern PyObject* set_pcilib(PyObject* addr); diff --git a/pywrap/server.py b/pywrap/server.py index 0da6bc8..d2927fb 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -373,6 +373,9 @@ if __name__ == '__main__': if not 'LD_LIBRARY_PATH' in os.environ: os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" + #redirect logs to exeption + pcipywrap.__redirect_logs_to_exeption() + pcilib_server = BaseHTTPServer.HTTPServer httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) diff --git a/views/transform.c b/views/transform.c index ba2f48f..75b95b2 100644 --- a/views/transform.c +++ b/views/transform.c @@ -9,6 +9,7 @@ #include "model.h" #include "transform.h" #include "py.h" +#include "error.h" static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) { @@ -57,6 +58,34 @@ void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_descript pcilib_py_free_script(v->module); } +pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_view_description_t *desc) +{ + pcilib_transform_view_description_t *v_desc = (pcilib_transform_view_description_t*)desc; + + if(v_desc->module) + { + pcilib_access_mode_t mode = 0; + + int err = pcilib_py_init_script(ctx, v_desc->module, &mode); + if(err) + { + pcilib_error("Failed init script module (%s) - error %i", v_desc->module, err); + return NULL; + } + + v_desc->base.mode |= PCILIB_REGISTER_RW; + mode |= PCILIB_REGISTER_INCONSISTENT; + v_desc->base.mode &= mode; + } + + pcilib_view_context_t *view_ctx; + view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t)); + if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t)); + + return view_ctx; +} + + const pcilib_view_api_description_t pcilib_transform_view_api = - { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write }; + { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), pcilib_transform_view_init, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write }; -- cgit v1.2.3