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 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