diff options
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | pci | 5 | ||||
-rw-r--r-- | pcilib/pci.c | 14 | ||||
-rw-r--r-- | pcilib/py.c | 194 | ||||
-rw-r--r-- | pcilib/py.h | 13 | ||||
-rw-r--r-- | pcilib/xml.c | 53 | ||||
-rw-r--r-- | pcitool/cli.c | 26 | ||||
-rw-r--r-- | pywrap/pcipywrap.c | 50 | ||||
-rw-r--r-- | pywrap/pcipywrap.i | 10 | ||||
-rw-r--r-- | pywrap/server.py | 230 | ||||
-rw-r--r-- | views/transform.c | 53 | ||||
-rw-r--r-- | views/transform.h | 2 | ||||
-rw-r--r-- | xml/CMakeLists.txt | 27 | ||||
-rw-r--r-- | xml/test_pywrap/test_prop2.py | 2 |
14 files changed, 416 insertions, 269 deletions
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 @@ -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') |