diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2016-03-02 23:36:19 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2016-03-02 23:36:19 +0100 |
commit | f7636162ba124c0d6b5accaa72c842033f3e2309 (patch) | |
tree | 9ae5ceddde46e7c511bba899b869f54c6fef6283 | |
parent | 7e39a6c8ae5c3f95b3b2895c4ce8d858c7ad3b79 (diff) | |
parent | 02d0026e2df2ba5c68c0c1a67aec4437c9e8e8f3 (diff) | |
download | pcitool-f7636162ba124c0d6b5accaa72c842033f3e2309.tar.gz pcitool-f7636162ba124c0d6b5accaa72c842033f3e2309.tar.bz2 pcitool-f7636162ba124c0d6b5accaa72c842033f3e2309.tar.xz pcitool-f7636162ba124c0d6b5accaa72c842033f3e2309.zip |
Further improvements of Python scripting and web-interface API for register manipulations by Vasiliy Chernov
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | apps/test_multithread.c | 14 | ||||
-rw-r--r-- | pcilib/error.c | 13 | ||||
-rw-r--r-- | pcilib/py.c | 69 | ||||
-rw-r--r-- | pyserver/api_server.py (renamed from pywrap/server.py) | 270 | ||||
-rw-r--r-- | pyserver/html_server.py | 231 | ||||
-rw-r--r-- | pyserver/scripts/test_script.py | 10 | ||||
-rw-r--r-- | pyserver/scripts/test_script2.py | 4 | ||||
-rw-r--r-- | pyserver/static/base.css | 46 | ||||
-rw-r--r-- | pyserver/static/check_err.js | 4 | ||||
-rw-r--r-- | pyserver/static/codebase/dhtmlx.css (renamed from pywrap/static/codebase/dhtmlx.css) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/dhtmlx.js (renamed from pywrap/static/codebase/dhtmlx.js) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/dhtmlx_deprecated.js (renamed from pywrap/static/codebase/dhtmlx_deprecated.js) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/ext/dhxupload.xap (renamed from pywrap/static/codebase/ext/dhxupload.xap) | bin | 23436 -> 23436 bytes | |||
-rw-r--r-- | pyserver/static/codebase/ext/swfobject.js (renamed from pywrap/static/codebase/ext/swfobject.js) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/ext/uploader.swf (renamed from pywrap/static/codebase/ext/uploader.swf) | bin | 3646 -> 3646 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif) | bin | 56 -> 56 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/but_cut.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/but_cut.gif) | bin | 87 -> 87 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif) | bin | 579 -> 579 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif) | bin | 571 -> 571 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif) | bin | 155 -> 155 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif) | bin | 155 -> 155 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif) | bin | 155 -> 155 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif) | bin | 92 -> 92 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif) | bin | 878 -> 878 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif) | bin | 361 -> 361 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif) | bin | 79 -> 79 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif) | bin | 79 -> 79 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif) | bin | 79 -> 79 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif) | bin | 74 -> 74 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif) | bin | 76 -> 76 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif) | bin | 81 -> 81 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif) | bin | 81 -> 81 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif) | bin | 67 -> 67 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif) | bin | 69 -> 69 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif) | bin | 208 -> 208 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif) | bin | 107 -> 107 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif) | bin | 107 -> 107 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif) | bin | 119 -> 119 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif) | bin | 121 -> 121 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif) | bin | 125 -> 125 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif) | bin | 125 -> 125 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif) | bin | 117 -> 117 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif) | bin | 117 -> 117 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif) | bin | 111 -> 111 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif) | bin | 111 -> 111 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif) | bin | 111 -> 111 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif) | bin | 111 -> 111 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif) | bin | 123 -> 123 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif) | bin | 124 -> 124 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif) | bin | 128 -> 128 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif) | bin | 120 -> 120 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif) | bin | 119 -> 119 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif) | bin | 114 -> 114 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif) | bin | 113 -> 113 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/radio_off.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/radio_off.gif) | bin | 213 -> 213 bytes | |||
-rw-r--r-- | pyserver/static/codebase/imgs/dhxtree_skyblue/radio_on.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/radio_on.gif) | bin | 223 -> 223 bytes | |||
-rw-r--r-- | pyserver/static/codebase/thirdparty/excanvas/AUTHORS (renamed from pywrap/static/codebase/thirdparty/excanvas/AUTHORS) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/thirdparty/excanvas/COPYING (renamed from pywrap/static/codebase/thirdparty/excanvas/COPYING) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/thirdparty/excanvas/README (renamed from pywrap/static/codebase/thirdparty/excanvas/README) | 0 | ||||
-rw-r--r-- | pyserver/static/codebase/thirdparty/excanvas/excanvas.js (renamed from pywrap/static/codebase/thirdparty/excanvas/excanvas.js) | 0 | ||||
-rw-r--r-- | pyserver/static/jquery-2.2.1.js (renamed from pywrap/static/jquery-2.2.1.js) | 0 | ||||
-rw-r--r-- | pyserver/templates/base.html | 194 | ||||
-rw-r--r-- | pyserver/templates/property_info.html | 91 | ||||
-rw-r--r-- | pyserver/templates/register_info.html | 9 | ||||
-rw-r--r-- | pyserver/templates/registers/table_cell.html | 100 | ||||
-rw-r--r-- | pyserver/templates/registers/table_header.html | 10 | ||||
-rw-r--r-- | pyserver/templates/registers/table_scripts.html | 42 | ||||
-rw-r--r-- | pyserver/templates/registers_list.html | 12 | ||||
-rw-r--r-- | pywrap/CMakeLists.txt | 9 | ||||
-rw-r--r-- | pywrap/html_server.py | 197 | ||||
-rw-r--r-- | pywrap/pcilib.py | 38 | ||||
-rw-r--r-- | pywrap/pcipywrap.c | 176 | ||||
-rw-r--r-- | pywrap/pcipywrap.h | 38 | ||||
-rw-r--r-- | pywrap/pcipywrap.i | 10 | ||||
-rw-r--r-- | pywrap/templates/base.html | 347 | ||||
-rw-r--r-- | pywrap/templates/property_info.html | 91 | ||||
-rw-r--r-- | pywrap/templates/register_info.html | 106 | ||||
-rw-r--r-- | pywrap/templates/registers_list.html | 26 | ||||
-rw-r--r-- | pywrap/test_pcilib.py (renamed from pywrap/test_pcipywrap.py) | 57 | ||||
-rwxr-xr-x | run | 2 | ||||
-rw-r--r-- | xml/test/cmosis.xml | 50 | ||||
-rw-r--r-- | xml/test/props.xml | 1 | ||||
-rw-r--r-- | xml/test/test_prop2.py | 3 | ||||
-rw-r--r-- | xml/test/test_prop4.py | 24 |
86 files changed, 1191 insertions, 1113 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 33be2fb..5c2d45b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(pcitool) -set(PCILIB_VERSION "0.2.6") +set(PCILIB_VERSION "0.2.7") set(PCILIB_ABI_VERSION "2") cmake_minimum_required(VERSION 2.8) @@ -38,8 +38,11 @@ find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) if (NOT DISABLE_PYTHON) - find_package(PythonLibs 2.7 REQUIRED) - find_package(PythonInterp 2.7 REQUIRED) + set(PYTHON_VERSION 2.7 CACHE STRING "python version") + + find_package(PythonInterp ${PYTHON_VERSION} REQUIRED) + find_package(PythonLibs ${PYTHON_VERSION_STRING} EXACT REQUIRED) + find_package(SWIG REQUIRED) if (NOT PYTHON_VERSION_STRING VERSION_EQUAL PYTHONLIBS_VERSION_STRING) message (FATAL_ERROR "Version mismatch between python interpreter and libraries") @@ -128,6 +131,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINA if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) file(COPY ${CMAKE_SOURCE_DIR}/xml DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY ${CMAKE_SOURCE_DIR}/pyserver DESTINATION ${CMAKE_BINARY_DIR}) file(COPY ${CMAKE_SOURCE_DIR}/pci DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE diff --git a/apps/test_multithread.c b/apps/test_multithread.c index 4d0e8f2..f6afae7 100644 --- a/apps/test_multithread.c +++ b/apps/test_multithread.c @@ -1,8 +1,10 @@ #include <stdio.h> #include <pthread.h> -#include "pcilib.h" #include <stdlib.h> +#include "pcilib.h" +#include "pcilib/error.h" + const char* prop = "/registers/fpga/reg1"; char* reg; int stop = 0; @@ -18,14 +20,14 @@ void *get_prop(void *arg) err = pcilib_get_property(ctx, prop, &val); if(err) { - printf("err pcilib_read_register\n"); + pcilib_error("Error in pcilib_read_register"); return NULL; } long value = pcilib_get_value_as_int(ctx, &val, &err); pcilib_clean_value(ctx, &val); if(err) { - printf("err pcilib_get_value_as_int\n"); + pcilib_error("Error in pcilib_get_value_as_int"); return NULL; } printf("reg = %li\n", value); @@ -47,20 +49,20 @@ void *read_reg(void *arg) if(err) { - printf("err pcilib_read_register\n"); + pcilib_error("Error in pcilib_read_register"); return NULL; } err = pcilib_set_value_from_register_value(ctx, &val, reg_val); if(err) { - printf("err pcilib_set_value_from_register_value\n"); + pcilib_error("Error in pcilib_set_value_from_register_value"); return NULL; } long value = pcilib_get_value_as_int(ctx, &val, &err); pcilib_clean_value(ctx, &val); if(err) { - printf("err pcilib_get_value_as_int\n"); + pcilib_error("Error in pcilib_get_value_as_int"); return NULL; } printf("reg = %li\n", value); diff --git a/pcilib/error.c b/pcilib/error.c index ae8bacb..8d25c82 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -12,8 +12,17 @@ #define PCILIB_LOGGER_HISTORY 16 void pcilib_print_error(void *arg, const char *file, int line, pcilib_log_priority_t prio, const char *msg, va_list va) { - vprintf(msg, va); - printf(" [%s:%d]\n", file, line); + size_t size = strlen(msg) + strlen(file) + 64; + char *stmp = alloca(size * sizeof(char*)); + + if (stmp) { + sprintf(stmp, "%s [%s:%d]\n", msg, file, line); + vprintf(stmp, va); + } else { + // Bad for multithreading... + vprintf(msg, va); + printf(" [%s:%d]\n", file, line); + } } static void *pcilib_logger_argument = NULL; diff --git a/pcilib/py.c b/pcilib/py.c index 3e1f38d..9e4ca90 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -17,6 +17,8 @@ #include "error.h" #ifdef HAVE_PYTHON +#define PCILIB_PYTHON_WRAPPER "pcipywrap" + typedef struct pcilib_script_s pcilib_script_t; struct pcilib_script_s { @@ -43,18 +45,41 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag PyGILState_STATE gstate; PyObject *pytype = NULL; PyObject *pyval = NULL; + PyObject *pystr = NULL; PyObject *pytraceback = NULL; gstate = PyGILState_Ensure(); if (PyErr_Occurred()) { PyErr_Fetch(&pytype, &pyval, &pytraceback); - type = PyString_AsString(pytype); - val = PyString_AsString(pyval); + PyErr_NormalizeException(&pytype, &pyval, &pytraceback); + if (pyval) pystr = PyObject_Str(pyval); + +# if PY_MAJOR_VERSION >= 3 + if (pytype) { + if (PyUnicode_Check(pytype)) + type = PyUnicode_AsUTF8(pytype); + else + type = PyExceptionClass_Name(pytype); + } + if (pystr) { + val = PyUnicode_AsUTF8(pystr); + } +# else /* PY_MAJOR_VERSION >= 3 */ + if (pytype) { + if (PyString_Check(pytype)) + type = PyString_AsString(pytype); + else + type = PyExceptionClass_Name(pytype); + } + if (pystr) { + val = PyString_AsString(pystr); + } +# endif /*PY_MAJOR_VERSION >= 3*/ } PyGILState_Release(gstate); #endif /* HAVE_PYTHON */ - + va_start(va, msg); if (type) { char *str; @@ -83,6 +108,7 @@ void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flag va_end(va); #ifdef HAVE_PYTHON + if (pystr) Py_DECREF(pystr); if (pytype) Py_DECREF(pytype); if (pyval) Py_DECREF(pyval); if (pytraceback) Py_DECREF(pytraceback); @@ -119,14 +145,14 @@ int pcilib_init_py(pcilib_t *ctx) { return PCILIB_ERROR_FAILED; } - PyObject *pywrap = PyImport_ImportModule("pcipywrap"); + PyObject *pywrap = PyImport_ImportModule(PCILIB_PYTHON_WRAPPER); if (!pywrap) { pcilib_python_error("Error importing pcilib python wrapper"); return PCILIB_ERROR_FAILED; } - PyObject *mod_name = PyString_FromString("Pcipywrap"); - PyObject *pyctx = PyCObject_FromVoidPtr(ctx, NULL); + PyObject *mod_name = PyUnicode_FromString(PCILIB_PYTHON_WRAPPER); + PyObject *pyctx = PyCapsule_New(ctx, "pcilib", NULL); ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, pyctx, NULL); Py_XDECREF(pyctx); Py_XDECREF(mod_name); @@ -166,7 +192,7 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { return PCILIB_ERROR_FAILED; } - pynewdir = PyString_FromString(script_dir); + pynewdir = PyUnicode_FromString(script_dir); if (!pynewdir) { pcilib_python_error("Can't create python string"); return PCILIB_ERROR_MEMORY; @@ -175,13 +201,13 @@ int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { // Checking if the directory already in the path? pydict = PyDict_New(); if (pydict) { - pystr = PyString_FromString("cur"); + pystr = PyUnicode_FromString("cur"); if (pystr) { PyDict_SetItem(pydict, pystr, pynewdir); Py_DECREF(pystr); } - pystr = PyString_FromString("path"); + pystr = PyUnicode_FromString("path"); if (pystr) { PyDict_SetItem(pydict, pystr, pypath); Py_DECREF(pystr); @@ -292,13 +318,13 @@ int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_ return PCILIB_ERROR_FAILED; } - pystr = PyString_FromString("read_from_register"); + pystr = PyUnicode_FromString("read_from_register"); if (pystr) { if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R; Py_DECREF(pystr); } - pystr = PyString_FromString("write_to_register"); + pystr = PyUnicode_FromString("write_to_register"); if (pystr) { if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; Py_DECREF(pystr); @@ -322,7 +348,7 @@ pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va switch(val->type) { case PCILIB_TYPE_LONG: ival = pcilib_get_value_as_int(ctx, val, &err); - if (!err) res = (PyObject*)PyInt_FromLong(ival); + if (!err) res = (PyObject*)PyLong_FromLong(ival); break; case PCILIB_TYPE_DOUBLE: fval = pcilib_get_value_as_float(ctx, val, &err); @@ -359,12 +385,27 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py PyGILState_STATE gstate; gstate = PyGILState_Ensure(); - if (PyInt_Check(pyval)) { - err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval)); + if (PyLong_Check(pyval)) { + err = pcilib_set_value_from_int(ctx, val, PyLong_AsLong(pyval)); } else if (PyFloat_Check(pyval)) { err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyval)); +#if PY_MAJOR_VERSION < 3 + } else if (PyInt_Check(pyval)) { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval)); } else if (PyString_Check(pyval)) { err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval)); + } else if (PyUnicode_Check(pyval)) { + PyObject *buf = PyUnicode_AsASCIIString(pyval); + if (buf) { + err = pcilib_set_value_from_string(ctx, val, PyString_AsString(buf)); + Py_DecRef(buf); + } else { + err = PCILIB_ERROR_FAILED; + } +#else /* PY_MAJOR_VERSION < 3 */ + } else if (PyUnicode_Check(pyval)) { + err = pcilib_set_value_from_string(ctx, val, PyUnicode_AsUTF8(pyval)); +#endif /* PY_MAJOR_VERSION < 3 */ } else { PyGILState_Release(gstate); pcilib_error("Can't convert PyObject to polymorphic pcilib value"); diff --git a/pywrap/server.py b/pyserver/api_server.py index b59ae55..7e8b7ef 100644 --- a/pywrap/server.py +++ b/pyserver/api_server.py @@ -1,26 +1,28 @@ -import time import os -import pcipywrap -import json import sys -from optparse import OptionParser -from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler -from SocketServer import ThreadingMixIn -import threading +import pcilib -pcilib = None +import time +import json +from optparse import OptionParser +from multiprocessing import Process + +if sys.version_info >= (3,0): + from http.server import HTTPServer, BaseHTTPRequestHandler + from socketserver import ThreadingMixIn +else: + from SocketServer import ThreadingMixIn + from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler class MultiThreadedHTTPServer(ThreadingMixIn, HTTPServer): pass class PcilibServerHandler(BaseHTTPRequestHandler): - locks = list() - lock_global = 0 - #def __init__(s, pcilib, *args): - # s.pcilib = pcilib - # BaseHTTPRequestHandler.__init__(s, *args) + def __init__(s, pcilib, *args): + s.pcilib = pcilib + BaseHTTPRequestHandler.__init__(s, *args) def do_HEAD(s): s.send_response(200) @@ -28,6 +30,12 @@ class PcilibServerHandler(BaseHTTPRequestHandler): s.end_headers() def do_GET(s): + #run request in separate process + p = Process(target=s.do_GET_worker, args=()) + p.start() + p.join() + + def do_GET_worker(s): length = int(s.headers['Content-Length']) #deserialize input data @@ -73,7 +81,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler): registers = dict() try: - registers = pcilib.get_registers_list(bank) + registers = s.pcilib.get_registers_list(bank) except Exception as e: s.error(str(e), data) return @@ -101,7 +109,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler): register = dict() try: - register = pcilib.get_register_info(reg, bank) + register = s.pcilib.get_register_info(reg, bank) except Exception as e: s.error(str(e), data) return @@ -119,7 +127,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler): properties = dict() try: - properties = pcilib.get_property_list(branch) + properties = s.pcilib.get_property_list(branch) except Exception as e: s.error(str(e), data) return @@ -142,12 +150,12 @@ class PcilibServerHandler(BaseHTTPRequestHandler): #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) + if(not bank is None): + bank = str(bank) value = 0 try: - value = pcilib.read_register(reg, bank) + value = s.pcilib.read_register(reg, bank) except Exception as e: s.error(str(e), data) return @@ -174,13 +182,13 @@ class PcilibServerHandler(BaseHTTPRequestHandler): #parse command arguments and convert them to string reg = str(data.get('reg', None)) - value = str(data.get('value', None)) + value = data.get('value', None) bank = data.get('bank', None) - if not bank is None: - bank = str(bank) + if(not bank is None): + bank = str(bank) try: - pcilib.write_register(value, reg, bank) + s.pcilib.write_register(value, reg, bank) except Exception as e: s.error(str(e), data) return @@ -202,7 +210,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler): value = 0 try: - value = pcilib.get_property(prop) + value = s.pcilib.get_property(prop) except Exception as e: s.error(str(e), data) return @@ -226,13 +234,13 @@ class PcilibServerHandler(BaseHTTPRequestHandler): 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)) + value = data.get('value', None) try: - pcilib.set_property(value, prop) + s.pcilib.set_property(value, prop) except Exception as e: s.error(str(e), data) return @@ -252,20 +260,11 @@ class PcilibServerHandler(BaseHTTPRequestHandler): #parse command arguments and convert them to string lock_id = str(data.get('lock_id')) - #check if lock already setted - #if lock_id in PcilibServerHandler.locks: - # s.error('Lock with id: ' + lock_id + - # 'already setted by this server', - # data) - # return - try: - pcilib.lock(lock_id) + s.pcilib.lock(lock_id) except Exception as e: s.error(str(e), data) return - - PcilibServerHandler.locks.append(lock_id) #Success! Create and send reply s.wrapMessageAndSend({'status': 'ok'}, data) @@ -283,7 +282,7 @@ class PcilibServerHandler(BaseHTTPRequestHandler): lock_id = str(data.get('lock_id')) try: - pcilib.try_lock(lock_id) + s.pcilib.try_lock(lock_id) except Exception as e: s.error(str(e), data) return @@ -295,45 +294,75 @@ class PcilibServerHandler(BaseHTTPRequestHandler): elif(command == 'unlock'): #check required arguments - #if not 'lock_id' in data: - # s.error('message doesnt contains "lock_id" field, ' - # 'which is required for "unlock" command', data) - # return + if not 'lock_id' in data: + s.error('message doesnt contains "lock_id" field, ' + 'which is required for "unlock" command', data) + return #parse command arguments and convert them to string - #lock_id = str(data.get('lock_id')) - - #try: - # pcilib.unlock(lock_id) - #except Exception as e: - # s.error(str(e), data) - # return - # - #remove lock from locks list - #if lock_id in PcilibServerHandler.locks: - # PcilibServerHandler.locks.remove(lock_id) - time.sleep(20) + lock_id = str(data.get('lock_id')) + + try: + s.pcilib.unlock(lock_id) + except Exception as e: + s.error(str(e), data) + return + #Success! Create and send reply s.wrapMessageAndSend({'status': 'ok'}, data) + elif(command == 'get_scripts_list'): + scripts = list() + try: + scripts = s.pcilib.get_scripts_list() + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.wrapMessageAndSend({'status': 'ok', 'scripts': scripts}, data) + + + + elif(command == 'run_script'): + #check required arguments + if not 'script_name' in data: + s.error('message doesnt contains "script_name" field, ' + 'which is required for "run_script" command', data) + return + #parse command arguments and convert them to string + script_name = str(data.get('script_name')) + value = data.get('value', None) + + out = None + try: + out = s.pcilib.run_script(script_name, value) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + if(type(out) == bytearray or type(out) == bytes): + s.send_response(200) + s.send_header('content-disposition', 'inline; filename=value') + s.send_header('content-type', 'application/octet-stream') + s.end_headers() + s.wfile.write(out) + else: + s.wrapMessageAndSend({'status': 'ok', 'value': out}, data) + + + #elif(command == 'lock_global'): # #check if global_lock already setted by server - # print 'aaa' - # if PcilibServerHandler.lock_global: - # - # s.error('global lock already setted by this server', data) - # return - # # try: - # pcilib.lock_global() + # s.pcilib.lock_global() # except Exception as e: # s.error(str(e), data) # return # - # PcilibServerHandler.lock_global = 1 - # # #Success! Create and send reply # s.wrapMessageAndSend({'status': 'ok'}, data) @@ -341,34 +370,29 @@ class PcilibServerHandler(BaseHTTPRequestHandler): #elif(command == 'unlock_global'): # try: - # pcilib.unlock_global() + # s.pcilib.unlock_global() # except Exception as e: # s.error(str(e), data) # return # - # PcilibServerHandler.lock_global = 0 - # # #Success! Create and send reply # s.wrapMessageAndSend({'status': 'ok'}, data) - - + else: - s.error('command "' + command + '" undefined', data) - return + 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'] + s.error('message doesnt contains "command" field, which is required', data) + return + + - #"""open device context """ + #open device context #def openPcilibInstance(s, device, model): - # pcilib = pcipywrap.create_pcilib_instance(device, model) + # s.pcilib = pcipywrap.create_pcilib_instance(device, model) - """Send help message""" + #Send help message def help(s, received_message = None): usage = str('Usage:\n' ' Server receive commands via http GET with json packet.\n' @@ -446,11 +470,27 @@ class PcilibServerHandler(BaseHTTPRequestHandler): ' lock_id: - lock id\n' '\n' + ' command: get_scripts_list - Get aviable scripts with description\n' + '\n' + + ' command: run_script - Run specified script\n' + ' required fields\n' + ' script_name: - script name (without extension)\n' + ' value: - input value in json format\n' + '\n' + '\n') - out = {'status': 'ok', 'usage' : usage} - s.wrapMessageAndSend(out, received_message) + + #send help as plain text + s.send_response(200) + s.send_header('content-type', 'text/plain') + s.end_headers() + if sys.version_info >= (3,0): + s.wfile.write(bytes(usage, 'UTF-8')) + else: + s.wfile.write(usage) - """Send error message with text description""" + #Send error message with text description def error(s, info, received_message = None): out = dict() @@ -465,8 +505,21 @@ class PcilibServerHandler(BaseHTTPRequestHandler): s.end_headers() if not received_message is None: message['received_message'] = received_message - message['thread'] = threading.currentThread().getName() - s.wfile.write(json.dumps(message)) + if sys.version_info >= (3,0): + s.wfile.write(bytes(json.dumps(message), 'UTF-8')) + else: + s.wfile.write(json.dumps(message)) + + +class ApiServer(MultiThreadedHTTPServer): + def __init__(self, device='/dev/fpga0', model=None, adress=('0.0.0.0', 9000)): + #redirect logs to exeption + pcilib.redirect_logs_to_exeption() + #pass Pcipywrap to to server handler + self.lib = pcilib.pcilib(device, model) + def handler(*args): + PcilibServerHandler(self.lib, *args) + MultiThreadedHTTPServer.__init__(self, adress, handler) if __name__ == '__main__': @@ -481,59 +534,24 @@ if __name__ == '__main__': parser.add_option("-m", "--model", action="store", type="string", dest="model", default=None, help="Memory model (autodetected)") + opts = parser.parse_args()[0] - HOST_NAME = '' + HOST_NAME = '0.0.0.0' PORT_NUMBER = opts.port MODEL = opts.model DEVICE = opts.device - - - #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" - - - - #redirect logs to exeption - pcipywrap.__redirect_logs_to_exeption() - - #pass Pcipywrap to to server handler - global pcilib - pcilib = pcipywrap.Pcipywrap(DEVICE, MODEL) - #def handler(*args): - # PcilibServerHandler(lib, *args) - #start server - httpd = MultiThreadedHTTPServer((HOST_NAME, PORT_NUMBER), PcilibServerHandler) + httpd = ApiServer(DEVICE, MODEL, (HOST_NAME, PORT_NUMBER)) + + print(time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)) - print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) try: httpd.serve_forever() except KeyboardInterrupt: - #unlocking global lock - if PcilibServerHandler.lock_global: - lib.unlock_global() - PcilibServerHandler.lock_global = False - - #delete created locks - for lock in PcilibServerHandler.locks: - lib.unlock(lock) - del PcilibServerHandler.locks[:] pass - - - httpd.server_close() - print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER) + + print(time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)) diff --git a/pyserver/html_server.py b/pyserver/html_server.py new file mode 100644 index 0000000..22194cd --- /dev/null +++ b/pyserver/html_server.py @@ -0,0 +1,231 @@ +import json + +from optparse import OptionParser, OptionGroup +from multiprocessing import Process + +import requests +from api_server import ApiServer + +#import flask elements +from flask import render_template +from flask import Flask +from flask import request +from flask import url_for +from flask import redirect +from flask import send_from_directory +from flask import make_response + +app = Flask(__name__) +api_server_port = 9000 +api_server_host = '0.0.0.0' + +@app.route("/json/<command>") +def process_json_command(command): + headers = {'content-type': 'application/json'} + message = {'command': command} + + for arg in request.args: + message[arg] = request.args[arg] + + r = 0; + try: + r = requests.get('http://' + api_server_host + ':' + str(api_server_port), + data=json.dumps(message), + headers=headers) + except Exception as e: + return str(json.dumps({'status':'error', 'description': e})) + + #application/octet-stream + response = make_response(r.content) + for header in r.headers: + response.headers[header] = r.headers[header] + + return response + +#html api +@app.route('/register_info') +def get_register_info(): + #get parameters + name = request.args.get('name') + bank = request.args.get('bank') + + #load register info + reg_info = 0 + value = dict() + try: + r = requests.get(url_for('process_json_command', + command = 'get_register_info', + bank = bank, + reg = name, _external = True)) + if(r.json().get('status') == 'error'): + return 'Error: ' + r.json()['description'] + + reg_info = r.json()['register'] + + #get register value + r = requests.get(url_for('process_json_command', + command = 'read_register', + bank = bank, + reg = name, _external = True)) + if(r.json().get('status') == 'error'): + return 'Error: ' + r.json()['description'] + + value[name] = r.json()['value'] + except Exception as e: + return str(e) + + return render_template('register_info.html', + register=reg_info, + value=value) + +@app.route("/registers_list") +def get_registers_list(): + #get parameters + bank = request.args.get('bank') + if not bank is None: + bank = str(bank) + + #load registers list + reg_list = [] + try: + r = requests.get(url_for('process_json_command', + command = 'get_registers_list', + bank = bank, _external = True)) + if(r.json().get('status') == 'error'): + return 'Error: ' + r.json()['description'] + reg_list = r.json()['registers'] + except Exception as e: + return str(e) + + #get register values + value = dict() + for reg in reg_list: + try: + r = requests.get(url_for('process_json_command', + command = 'read_register', + bank = str(reg['bank']), + reg = str(reg['name']), _external = True)) + if(r.json().get('status') == 'error'): + value[reg['name']] = 'Error: ' + r.json()['description'] + else: + value[reg['name']] = r.json()['value'] + + except Exception as e: + value[reg['name']] = 'Error: ' + str(e) + + #render result + return render_template('registers_list.html', + registers = reg_list, + render_template = render_template, + value = value + ) + +@app.route("/property_info") +def get_property_list(): + #get parameters + branch = request.args.get('branch') + if not branch is None: + branch = str(branch) + + #get properties info + prop_info = 0 + try: + r = requests.get(url_for('process_json_command', + command = 'get_property_list', + branch = branch, _external = True)) + + if(r.json().get('status') == 'error'): + return 'Error: ' + r.json()['description'] + + prop_info = r.json()['properties'] + + except Exception as e: + return str(e) + + value = dict() + for prop in prop_info: + try: + path = prop['path'] + r = requests.get(url_for('process_json_command', + command = 'get_property', + prop = path, _external = True)) + if(r.json().get('status') == 'error'): + value[path] = 'Error: ' + r.json()['description'] + else: + value[path] = r.json()['value'] + + except Exception as e: + value[path] = str(e) + + return render_template('property_info.html', + value = value, + branch = branch, + properties = prop_info, + json = json + ) + +@app.route("/") +def greet(): + return render_template('base.html', + device = device, + model = model) + +if __name__ == "__main__": + #parse command line options + parser = OptionParser() + parser.add_option("-p", "--port", action="store", + type="int", dest="port", default=5000, + help="Set server port (5000)") + + pcilib_group = OptionGroup(parser, "Api server", + "Api server options group") + pcilib_group.add_option("-e", "--external", action="store_true", + dest="external_api_server", + default=False, + help="Dont start own api server. Use external" + " server instead"); + pcilib_group.add_option("--api-server-host", action="store", + type="string", dest="api_server_host", + default='0.0.0.0', + help="Api server ip adress (0.0.0.0)") + pcilib_group.add_option("--api-server-port", action="store", + type="int", dest="api_server_port", + default=9000, + help="Api server port (9000)") + pcilib_group.add_option("-d", "--device", action="store", + type="string", dest="device", + default=str('/dev/fpga0'), + help="FPGA device (/dev/fpga0)") + pcilib_group.add_option("-m", "--model", action="store", + type="string", dest="model", default=None, + help="Memory model (autodetected)") + + parser.add_option_group(pcilib_group) + + opts = parser.parse_args()[0] + + HOST_NAME = '0.0.0.0' + PORT_NUMBER = opts.port + + device = opts.device + model = opts.model + + #start api server in separate process + api_server_host = opts.api_server_host + api_server_port = opts.api_server_port + if(not opts.external_api_server): + api_server = ApiServer(device, model, (api_server_host, api_server_port)) + def serve_forever(server): + try: + server.serve_forever() + except KeyboardInterrupt: + pass + + Process(target=serve_forever, args=(api_server,)).start() + + #start Flask html server + app.run(host = HOST_NAME, + port = PORT_NUMBER, + threaded=True, + #debug=True + ) diff --git a/pyserver/scripts/test_script.py b/pyserver/scripts/test_script.py new file mode 100644 index 0000000..8f236e9 --- /dev/null +++ b/pyserver/scripts/test_script.py @@ -0,0 +1,10 @@ +import sys +if sys.version_info >= (3,0): + import binascii + +def run(ctx, inpt): + if sys.version_info >= (3,0): + return binascii.a2b_uu('111') + else: + return bytearray('111') + diff --git a/pyserver/scripts/test_script2.py b/pyserver/scripts/test_script2.py new file mode 100644 index 0000000..16e4adb --- /dev/null +++ b/pyserver/scripts/test_script2.py @@ -0,0 +1,4 @@ +description='this is a test script' + +def run(ctx, inpt): + return ctx.get_registers_list(); diff --git a/pyserver/static/base.css b/pyserver/static/base.css new file mode 100644 index 0000000..15c2249 --- /dev/null +++ b/pyserver/static/base.css @@ -0,0 +1,46 @@ +.tabs > div, .tabs > input { display: none; } + +.tabs label { + padding: 5px; + border: 1px solid #aaa; + line-height: 28px; + cursor: pointer; + position: relative; + bottom: 1px; + background: #fff; +} + +.tabs input[type="radio"]:checked + label { border-bottom: 2px solid #fff; } + +.tabs > input:nth-of-type(1):checked ~ div:nth-of-type(1), +.tabs > input:nth-of-type(2):checked ~ div:nth-of-type(2) { + display: block; + padding: 5px; + border: + 1px solid #aaa; +} +.tree { + height: 85vh; + padding: 5px; + border: 1px solid #aaa; + line-height: 28px; + cursor: pointer; + position: relative; + bottom: 1px; + background: #fff; + overflow:auto; +} + +.infoTable { + padding: 2px; + + border: 1px solid #aaa; + line-height: 28px; + cursor: pointer; + position: relative; + background: #fff; + overflow:auto; + bottom: 1px; + + text-align: left; +} diff --git a/pyserver/static/check_err.js b/pyserver/static/check_err.js new file mode 100644 index 0000000..66519ea --- /dev/null +++ b/pyserver/static/check_err.js @@ -0,0 +1,4 @@ +function checkError(json) { + if(json.status === 'error') + alert('Error: ' + json.description) +} diff --git a/pywrap/static/codebase/dhtmlx.css b/pyserver/static/codebase/dhtmlx.css index 9b89ec5..9b89ec5 100644 --- a/pywrap/static/codebase/dhtmlx.css +++ b/pyserver/static/codebase/dhtmlx.css diff --git a/pywrap/static/codebase/dhtmlx.js b/pyserver/static/codebase/dhtmlx.js index 5e560b1..5e560b1 100644 --- a/pywrap/static/codebase/dhtmlx.js +++ b/pyserver/static/codebase/dhtmlx.js diff --git a/pywrap/static/codebase/dhtmlx_deprecated.js b/pyserver/static/codebase/dhtmlx_deprecated.js index 5731d3f..5731d3f 100644 --- a/pywrap/static/codebase/dhtmlx_deprecated.js +++ b/pyserver/static/codebase/dhtmlx_deprecated.js diff --git a/pywrap/static/codebase/ext/dhxupload.xap b/pyserver/static/codebase/ext/dhxupload.xap Binary files differindex f2deecd..f2deecd 100644 --- a/pywrap/static/codebase/ext/dhxupload.xap +++ b/pyserver/static/codebase/ext/dhxupload.xap diff --git a/pywrap/static/codebase/ext/swfobject.js b/pyserver/static/codebase/ext/swfobject.js index 7a9d26f..7a9d26f 100644 --- a/pywrap/static/codebase/ext/swfobject.js +++ b/pyserver/static/codebase/ext/swfobject.js diff --git a/pywrap/static/codebase/ext/uploader.swf b/pyserver/static/codebase/ext/uploader.swf Binary files differindex 2fa8674..2fa8674 100644 --- a/pywrap/static/codebase/ext/uploader.swf +++ b/pyserver/static/codebase/ext/uploader.swf diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif Binary files differindex d7ae406..d7ae406 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/but_cut.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/but_cut.gif Binary files differindex 942bd18..942bd18 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/but_cut.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/but_cut.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif Binary files differindex e0a88ce..e0a88ce 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif Binary files differindex 1680dbc..1680dbc 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif Binary files differindex a61302a..a61302a 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif Binary files differindex 42447b8..42447b8 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif Binary files differindex 0350b2a..0350b2a 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif Binary files differindex 9f3fe50..9f3fe50 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif Binary files differindex f15d9f7..f15d9f7 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif Binary files differindex 9c3e531..9c3e531 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif Binary files differindex b4f560c..b4f560c 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif Binary files differindex b4f560c..b4f560c 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif Binary files differindex bf32db2..bf32db2 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif Binary files differindex 23b2ce3..23b2ce3 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif Binary files differindex 6ec17b5..6ec17b5 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif Binary files differindex 43152c5..43152c5 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif Binary files differindex 74a874c..74a874c 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif Binary files differindex 907fe7a..907fe7a 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif Binary files differindex 5c7e162..5c7e162 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif Binary files differindex 67456b1..67456b1 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif Binary files differindex caa3f57..caa3f57 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif Binary files differindex 2ab1070..2ab1070 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif Binary files differindex 036e5b3..036e5b3 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif Binary files differindex b4672bf..b4672bf 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif Binary files differindex 3242cca..3242cca 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif Binary files differindex 8c279e0..8c279e0 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif Binary files differindex 1c7c0a7..1c7c0a7 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif Binary files differindex 70992fe..70992fe 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif Binary files differindex 031c160..031c160 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif Binary files differindex 47e25cd..47e25cd 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif Binary files differindex 019cfbd..019cfbd 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif Binary files differindex 34dee94..34dee94 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif Binary files differindex d57afa9..d57afa9 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif Binary files differindex fde3a58..fde3a58 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif Binary files differindex 2b6546b..2b6546b 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif Binary files differindex 863d34c..863d34c 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif Binary files differindex a4fe8c0..a4fe8c0 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif Binary files differindex 635e6f6..635e6f6 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif Binary files differindex 88c35a4..88c35a4 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif Binary files differindex 2ae5444..2ae5444 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_off.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_off.gif Binary files differindex a050afd..a050afd 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_off.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_off.gif diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_on.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_on.gif Binary files differindex 4d594b5..4d594b5 100644 --- a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_on.gif +++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_on.gif diff --git a/pywrap/static/codebase/thirdparty/excanvas/AUTHORS b/pyserver/static/codebase/thirdparty/excanvas/AUTHORS index 90decb3..90decb3 100644 --- a/pywrap/static/codebase/thirdparty/excanvas/AUTHORS +++ b/pyserver/static/codebase/thirdparty/excanvas/AUTHORS diff --git a/pywrap/static/codebase/thirdparty/excanvas/COPYING b/pyserver/static/codebase/thirdparty/excanvas/COPYING index 75b5248..75b5248 100644 --- a/pywrap/static/codebase/thirdparty/excanvas/COPYING +++ b/pyserver/static/codebase/thirdparty/excanvas/COPYING diff --git a/pywrap/static/codebase/thirdparty/excanvas/README b/pyserver/static/codebase/thirdparty/excanvas/README index eb7c42f..eb7c42f 100644 --- a/pywrap/static/codebase/thirdparty/excanvas/README +++ b/pyserver/static/codebase/thirdparty/excanvas/README diff --git a/pywrap/static/codebase/thirdparty/excanvas/excanvas.js b/pyserver/static/codebase/thirdparty/excanvas/excanvas.js index 66310a8..66310a8 100644 --- a/pywrap/static/codebase/thirdparty/excanvas/excanvas.js +++ b/pyserver/static/codebase/thirdparty/excanvas/excanvas.js diff --git a/pywrap/static/jquery-2.2.1.js b/pyserver/static/jquery-2.2.1.js index b7c491f..b7c491f 100644 --- a/pywrap/static/jquery-2.2.1.js +++ b/pyserver/static/jquery-2.2.1.js diff --git a/pyserver/templates/base.html b/pyserver/templates/base.html new file mode 100644 index 0000000..a2df1e9 --- /dev/null +++ b/pyserver/templates/base.html @@ -0,0 +1,194 @@ +<!DOCTYPE html> +<html> +<head> + <title>{% block title %}Device {{ device }}{% endblock %}</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + <meta http-equiv="X-UA-Compatible" content="IE=edge"/> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='codebase/dhtmlx.css') }}"/> + <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='base.css') }}"/> + <script type=text/javascript src="{{ url_for('static', filename='jquery-2.2.1.js') }}"></script> + <script src="{{ url_for('static', filename='codebase/dhtmlx.js') }}"></script> + <script src="{{ url_for('static', filename='check_err.js') }}"></script> + <script> + var propsTree + function createPropertyTree(branch, id) { + + function getPropertyItemsOnLevel(branch, id) { + var pathToProperties = "{{ url_for('process_json_command', command = 'get_property_list') }}" + var completePath = pathToProperties + '?branch=' + branch + + $.getJSON(completePath, + function(json) { + checkError(json) + parsePropertyItems(json, branch, id) + }); + } + + function parsePropertyItems(json, branch, id) { + + checkError(json) + json = json.properties + + function loadPropertyInfo(branch) { + + var pathToProperties = "{{ url_for('get_property_list') }}" + var completePath = pathToProperties + '?branch=' + branch + + $("#prop_info_place").load(completePath) + } + + + function setPropertyField(id, name, branch) { + + var func = function(){loadPropertyInfo(branch)} + propsTree.insertNewItem(id, branch, + name, + func); + propsTree.closeAllItems() + } + + for(var i = 0; i < json.length; i++) { + + setPropertyField(id, json[i].name, json[i].path) + if(json[i].flags.indexOf("childs") != -1) + getPropertyItemsOnLevel(json[i].path, json[i].path) + } + } + + getPropertyItemsOnLevel(branch, id) + } + + var regTree + function createRegistersList() { + function parseJsonRegisterList(json) { + checkError(json) + json = json.registers + + function loadRegistersList(bank) { + var pathToGetRegisterList = "{{ url_for('get_registers_list') }}" + var completePath = pathToGetRegisterList + '?bank=' + bank + + $("#reg_info_place").load(completePath) + } + + function loadRegisterInfo(bank, name) { + var pathToGetRegister = "{{ url_for('get_register_info') }}" + var completePath = pathToGetRegister + '?bank=' + bank + + '&name=' + name + + $("#reg_info_place").load(completePath) + } + + function setRegisterField(id, bank, name) { + + var itemId = bank + "_" + name + var func = function(){loadRegisterInfo(bank, name)} + + regTree.insertNewItem(id, itemId, name, func) + regTree.closeAllItems() + } + + function setbankField(bank) { + + var func = function(){loadRegistersList(bank)} + regTree.insertNewItem(0, bank, bank, func); + regTree.closeAllItems() + } + + checkError(json) + if(json.lenght <= 0) + return + + //sort registers by bank + function compareRegistersByBank(a,b) { + if (a.bank < b.bank) + return -1; + else if (a.bank > b.bank) + return 1; + else + return 0; + } + json.sort(compareRegistersByBank) + + + //create bank dirs + var curBankName = json[0].bank + var created = 0 + for(var i = 0; i < json.length; i++) { + + //create new bank tab if it has not created already + if(json[i].bank != curBankName) { + curBankName = json[i].bank + created = 0 + } + + if(!created) { + setbankField(json[i].bank ) + created = 1 + } + + + //insert register info to bank + + setRegisterField(json[i].bank, json[i].bank, json[i].name) + } + } + + //get registers json list + var getRegistersListPath = "{{ url_for('process_json_command', command = 'get_registers_list') }}" + $.getJSON(getRegistersListPath, parseJsonRegisterList); + } + + function doOnLoad() + { + propsTree = new dhtmlXTreeObject("treeboxbox_tree","100%","100%",0); + propsTree.setImagePath("{{ url_for('static', filename='codebase/imgs/dhxtree_skyblue/') }}"); + //generating properties list + createPropertyTree('', 0) + + regTree = new dhtmlXTreeObject("treeboxbox_tree2","100%","100%",0,0,0,0,'SELECT') + regTree.setImagePath("{{ url_for('static', filename='codebase/imgs/dhxtree_skyblue/') }}"); + createRegistersList() + } + </script> +</head> +<body onload="doOnLoad()"> + {% block info %} + <div class="block1" > + <h2>Device {{ device }} model={{ model }} control page </h2> + </div> + {% endblock %} + + <div class="tabs"> + <input type="radio" name="current" checked="checked" id="props_id"/> + <label for="props_id">Properties</label> + <input type="radio" name="current" id="labels_id"/> + <label for="labels_id">Registers</label> + <div> + <table> + <tr> + <td valign="top"> + <div id="treeboxbox_tree" class = "tree"></div> + </td> + <td valign="top" id="prop_info_place" /> + </tr> + </table> + </div> + <div> + <table> + <tr> + <td valign="top"> + <div id="treeboxbox_tree2" class="tree"></div> + </td> + <td valign="top" id="reg_info_place" /> + </tr> + </table> + </div> + </div> + {% block content %} + {% endblock %} + <div class="block1" > + <a href="{{ url_for('process_json_command', command='help') }}">Json API usage</a> + </div> +</body> +</html> diff --git a/pyserver/templates/property_info.html b/pyserver/templates/property_info.html new file mode 100644 index 0000000..62ea1ba --- /dev/null +++ b/pyserver/templates/property_info.html @@ -0,0 +1,91 @@ +{% block content %} + +{% if standalone %} +<script src="{{ url_for('static', filename='codebase/dhtmlx.js') }}"></script> +<script src="{{ url_for('static', filename='check_err.js') }}"></script> +{% endif %} + +<script> + function updateProperty(prop) { + var pathToGetProperty = "{{ url_for('process_json_command', command = 'get_property') }}" + var completePath = pathToGetProperty + '?prop=' + prop + + $.getJSON(completePath, function(json){ + checkError(json) + var valFieldId = "#set_val_" + prop.split('/').join("_") + $(valFieldId).val(json.value) + }) + } + + function setProperty(prop) + { + var value = document.getElementById("set_val_" + prop.split('/').join("_")).value; + if(value == "") + return + + var pathToGetProperty = "{{ url_for('process_json_command', command = 'set_property') }}" + var completePath = pathToGetProperty + '?prop=' + prop + + '&value=' + value; + + $.getJSON(completePath, + function(json) { + checkError(json) + updateProperty(prop) + }) + }; +</script> + +<table class="infoTable"> + <tr class="infoTable"> + <td class="infoTable">Name</td> + <td class="infoTable">Description</td> + <td class="infoTable">Value</td> + <td class="infoTable">Mode</td> + <td class="infoTable">Type</td> + <td class="infoTable">Unit</td> + <td class="infoTable">Path</td> + </tr> + {% for property in properties %} + <tr class="infoTable"> + <td class="infoTable">{{ property.name }}</td> + <td class="infoTable"> + {% if 'description' in property %} + {{ property.description }} + {% endif %} + </td> + <td class="infoTable"> + <table> + {% if 'R' in property.mode %} + <tr> + <td> + <input type="text" + name="set_val_{{ property.path.replace('/', '_') }}" + id="set_val_{{ property.path.replace('/', '_') }}" + value="{{ value[property.path] }}" /> + </td> + {% if 'W' in property.mode %} + <td> + <input type="button" value="set" style="width:100%;height:100%" onclick="setProperty('{{ property.path }}')"> + </td> + {% endif %} + <td> + <input type="button" value="update" style="width:100%;height:100%" onclick="updateProperty('{{ property.path }}')"> + </td> + </tr> + {% endif %} + </table> + </td> + <td class="infoTable"> + <ul> + {% for m in property.mode %} + {{ m + '; '}} + {% endfor %} + </ul> + </td> + <td class="infoTable"> {{ property.type }} </td> + <td class="infoTable"> {{ property.unit }} </td> + <td class="infoTable"> {{ property.path }} </td> + </tr> + {% endfor %} +</table> +{% endblock %} diff --git a/pyserver/templates/register_info.html b/pyserver/templates/register_info.html new file mode 100644 index 0000000..3efebd7 --- /dev/null +++ b/pyserver/templates/register_info.html @@ -0,0 +1,9 @@ +{% block content %} + +{% include 'registers/table_scripts.html' %} + +<table class="infoTable"> + {% include 'registers/table_header.html' %} + {% include 'registers/table_cell.html' %} +</table> +{% endblock %} diff --git a/pyserver/templates/registers/table_cell.html b/pyserver/templates/registers/table_cell.html new file mode 100644 index 0000000..d394d42 --- /dev/null +++ b/pyserver/templates/registers/table_cell.html @@ -0,0 +1,100 @@ +<tr class="infoTable"> + <td class="infoTable"> {{ register.name }} </td> + {% if 'description' in register %} + <td class="infoTable"> {{ register.description }} </td> + {% else %} + <td class="infoTable"> </td> + {% endif %} + <td class="infoTable"> + <table> + {% if 'R' in register.mode %} + <tr class="infoTable"> + <td> + <input type="text" + name="set_val_box_{{ register.bank }}_{{ register.name }}" + id="set_val_box_{{ register.bank }}_{{ register.name }}" + value="{{ value[register.name] }}" /> + </td> + {% if 'W' in register.mode %} + <td> + <input type="button" value="set" + style="width:100%;height:100%" + onclick="writeRegister('{{ register.bank }}', '{{ register.name }}')"> + </td> + {% endif %} + <td> + <input type="button" value="update" + style="width:100%;height:100%" + onclick="updateRegister('{{ register.bank }}', '{{ register.name }}')"> + </td> + </tr> + {% endif %} + </table> + </td> + <td class="infoTable">{{ register.defvalue }}</td> + <td class="infoTable">{{ register.bank }}</td> + <td class="infoTable"> + <ul> + {% for m in register.mode %} + {{ m + '; '}} + {% endfor %} + </ul> + </td> + {% if 'range' in register %} + <td class="infoTable"> + <table> + <tr class="infoTable"> + <td class="infoTable"> min </td> + <td class="infoTable"> max </td> + </tr> + <tr class="infoTable"> + <td class="infoTable"> {{ register.range.min }} </td> + <td class="infoTable"> {{ register.range.max }} </td> + </tr> + </table> + </td> + {% else %} + <td class="infoTable"> </td> + {% endif %} + {% if 'values' in register %} + <td class="infoTable"> + <table> + <tr> + {% for v in register['values'] %} + <td> + <table> + {% if 'name' in v %} + <tr class="infoTable"> + <td class="infoTable"> Name </td> + <td class="infoTable"> {{v.name}} </td> + </tr> + {% endif %} + {% if 'description' in v %} + <tr class="infoTable"> + <td class="infoTable"> Description </td> + <td class="infoTable"> {{ v.description }} </td> + </tr> + {% endif %} + <tr class="infoTable"> + <td class="infoTable"> Min </td> + <td class="infoTable"> {{ v.min }} </td> + </tr> + <tr class="infoTable"> + <td class="infoTable"> Max </td> + <td class="infoTable"> {{ v.max }} </td> + </tr> + <tr class="infoTable"> + <td class="infoTable"> Value </td> + <td class="infoTable"> {{ v.value }} </td> + </tr> + </table> + </td> + {% endfor %} + </tr> + </table> + </td> + {% else %} + <td class="infoTable"> </td> + {% endif %} +</tr> + diff --git a/pyserver/templates/registers/table_header.html b/pyserver/templates/registers/table_header.html new file mode 100644 index 0000000..4c46713 --- /dev/null +++ b/pyserver/templates/registers/table_header.html @@ -0,0 +1,10 @@ +<tr class="infoTable"> + <td class="infoTable"> Name </td> + <td class="infoTable"> Description </td> + <td class="infoTable"> Value </td> + <td class="infoTable">Default value</td> + <td class="infoTable">Bank</td> + <td class="infoTable">Mode</td> + <td class="infoTable">Range</td> + <td class="infoTable">Values</td> +</tr> diff --git a/pyserver/templates/registers/table_scripts.html b/pyserver/templates/registers/table_scripts.html new file mode 100644 index 0000000..a772b9f --- /dev/null +++ b/pyserver/templates/registers/table_scripts.html @@ -0,0 +1,42 @@ +{% if standalone %} +<script src="{{ url_for('static', filename='codebase/dhtmlx.js') }}"></script> +<script src="{{ url_for('static', filename='check_err.js') }}"></script> +{% endif %} + +<script> + /* + $("#set_val_box").keyup(function(event){ + if(event.keyCode == 13){ + $("#set_val_button").click(); + } + }); + */ + + function updateRegister(bank, name) { + var pathToReadRegister = "{{ url_for('process_json_command', command = 'read_register') }}" + var completePath = pathToReadRegister + '?bank=' + bank + + '®=' + name + + $.getJSON(completePath, function(json){ + checkError(json) + $("#set_val_box_" + bank + "_" + name).val(json.value) + }) + } + + function writeRegister(bank, name) + { + var value = document.getElementById("set_val_box_" + bank + "_" + name).value; + if(value == "") + return + + var pathToReadRegister = "{{ url_for('process_json_command', command = 'write_register') }}" + var completePath = pathToReadRegister + '?bank=' + bank + + '®=' + name + '&value=' + value; + + $.getJSON(completePath, + function(json) { + checkError(json) + updateRegister(bank, name) + }) + }; +</script> diff --git a/pyserver/templates/registers_list.html b/pyserver/templates/registers_list.html new file mode 100644 index 0000000..26a6721 --- /dev/null +++ b/pyserver/templates/registers_list.html @@ -0,0 +1,12 @@ +{% block content %} +{% include 'registers/table_scripts.html' %} + +<table class="infoTable"> +{% include 'registers/table_header.html' %} +{% for register in registers %} + {% include 'registers/table_cell.html' %} +{% endfor %} +</table> +{% endblock %} + + diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index 75a9bed..033298e 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -17,15 +17,10 @@ set(CMAKE_SWIG_FLAGS "") swig_add_module(pcipywrap python pcipywrap.i pcipywrap.c) swig_link_libraries(pcipywrap ${PYTHON_LIBRARIES} pcilib) - install(TARGETS ${SWIG_MODULE_pcipywrap_REAL_NAME} DESTINATION ${PYTHON_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pcipywrap.py DESTINATION ${PYTHON_INSTALL_DIR}) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pcilib.py DESTINATION ${PYTHON_INSTALL_DIR}) if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/server.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_pcipywrap.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/templates DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/static DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/html_server.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_pcilib.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) diff --git a/pywrap/html_server.py b/pywrap/html_server.py deleted file mode 100644 index 76d132a..0000000 --- a/pywrap/html_server.py +++ /dev/null @@ -1,197 +0,0 @@ -import pcipywrap -import json -from optparse import OptionParser - -#import flask elements -from flask import render_template -from flask import Flask -from flask import request -from flask import url_for -from flask import redirect -from flask import send_from_directory - -app = Flask(__name__) -pcilib = 0; -device = '/dev/fpga0' -model = 'test_pywrap' - -# property json api -@app.route("/property_info_json") -def get_property_list_json(): - branch = request.args.get('branch') - if not branch is None: - branch = str(branch) - - prop_info = 0 - try: - prop_info = pcilib.get_property_list(branch) - return json.dumps(prop_info) - except Exception as e: - return json.dumps({'error': str(e)}) - -@app.route('/get_property_json') -def get_property_json(): - prop = request.args.get('prop') - - try: - val = pcilib.get_property(str(prop)) - return json.dumps({'value': val}) - except Exception as e: - return json.dumps({'error': str(e)}) - -@app.route('/set_property_json') -def set_property_json(): - val = request.args.get('val') - prop = request.args.get('prop') - - try: - pcilib.set_property(float(val), str(prop)) - return json.dumps({'status': 'ok'}) - except Exception as e: - return json.dumps({'error': str(e)}) - -# register json api -@app.route("/registers_list_json") -def get_registers_list_json(): - reg_list = 0 - try: - reg_list = pcilib.get_registers_list() - return json.dumps(reg_list) - except Exception as e: - return json.dumps({'error': str(e)}) - -@app.route('/read_register_json') -def read_register_json(): - name = request.args.get('name') - bank = request.args.get('bank') - - try: - value = pcilib.read_register(str(name), str(bank)) - return json.dumps({'value': value}) - except Exception as e: - return json.dumps({'error': str(e)}) - -@app.route('/write_register_json') -def write_register_json(): - val = request.args.get('val') - name = request.args.get('name') - bank = request.args.get('bank') - - try: - pcilib.write_register(float(val), str(name), str(bank)) - return json.dumps({'status': 'ok'}) - except Exception as e: - return json.dumps({'error': str(e)}) - -#html api -@app.route('/set_property') -def set_property(): - val = request.args.get('val') - prop = request.args.get('prop') - - try: - pcilib.set_property(float(val), str(prop)) - return redirect(url_for('get_property_list', branch=prop)) - except Exception as e: - return str(e) - -@app.route('/write_register') -def write_register(): - val = request.args.get('val') - name = request.args.get('name') - bank = request.args.get('bank') - - try: - pcilib.write_register(float(val), str(name), str(bank)) - return redirect(url_for('get_register_info', name=name, bank=bank)) - except Exception as e: - return str(e) - -@app.route('/register_info') -def get_register_info(): - name = request.args.get('name') - bank = request.args.get('bank') - - reg_info = 0 - value = 0 - try: - reg_info = pcilib.get_register_info(str(name), str(bank)) - value = pcilib.read_register(str(name), str(bank)) - except Exception as e: - return str(e) - return render_template('register_info.html', - register=reg_info, - value=value) - -@app.route("/registers_list") -def get_registers_list(): - reg_list = 0 - try: - reg_list = pcilib.get_registers_list() - except Exception as e: - return str(e) - - return render_template('registers_list.html', - registers=reg_list, - ) - -@app.route("/property_info") -def get_property_list(): - branch = request.args.get('branch') - if not branch is None: - branch = str(branch) - - prop_info = 0 - try: - prop_info = pcilib.get_property_list(branch) - except Exception as e: - return str(e) - - value = -1 - if (len(prop_info) == 1) and not ('childs' in (prop_info[0])['flags']): - try: - branch = (prop_info[0])['path'] - value = pcilib.get_property(branch) - except Exception as e: - return str(e) - - return render_template('property_info.html', - value = value, - branch = branch, - properties = prop_info, - json = json - ) - -@app.route("/") -def greet(): - return render_template('base.html', - device = device, - model = model) - -@app.route('/<path:path>') -def send_file(path): - return send_from_directory('static', path) - -if __name__ == "__main__": - #parce command line options - parser = OptionParser() - parser.add_option("-p", "--port", action="store", - type="int", dest="port", default=5000, - help="Set server port (5000)") - parser.add_option("-d", "--device", action="store", - type="string", dest="device", default=str('/dev/fpga0'), - help="FPGA device (/dev/fpga0)") - parser.add_option("-m", "--model", action="store", - type="string", dest="model", default=None, - help="Memory model (autodetected)") - opts = parser.parse_args()[0] - - HOST_NAME = '0.0.0.0' - PORT_NUMBER = opts.port - - device = opts.device - model = opts.model - - pcilib = pcipywrap.Pcipywrap(device, model) - pcipywrap.__redirect_logs_to_exeption() - app.run(host = HOST_NAME, port = PORT_NUMBER) diff --git a/pywrap/pcilib.py b/pywrap/pcilib.py new file mode 100644 index 0000000..f4976bf --- /dev/null +++ b/pywrap/pcilib.py @@ -0,0 +1,38 @@ +from pcipywrap import * +import os +import sys + +class pcilib(pcipywrap): + def __init__(s, *args): + pcipywrap.__init__(s, *args) + + #load scripts + scripts_dir = os.environ.get('PCILIB_SCRIPTS_DIR') + if scripts_dir: + scripts_dir_abs = os.path.abspath(scripts_dir) + if not scripts_dir_abs in sys.path: + sys.path.append(scripts_dir_abs) + + s.__scipts = dict() + for script in os.listdir(scripts_dir_abs): + if script.endswith('.py'): + script_module = os.path.splitext(script)[0] + __import__(script_module) + s.__scipts[script_module] = sys.modules[script_module] + + + def get_scripts_list(s): + scripts = [] + for script in s.__scipts: + curr_script = dict() + curr_script['name'] = script + if 'description' in dir(s.__scipts[script]): + curr_script['description'] = s.__scipts[script].description + scripts.append(curr_script) + return scripts + + + def run_script(s, name, input_value): + if not name in s.__scipts: + raise Exception('Script ' + name +' has not loaded') + return s.__scipts[name].run(s, input_value) diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index ceb0835..cb99ce2 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -94,7 +94,7 @@ void set_python_exception(const char* msg, ...) } -void __redirect_logs_to_exeption() +void redirect_logs_to_exeption() { pcilib_set_logger(pcilib_get_log_level(), pcilib_print_error_to_py, @@ -128,12 +128,12 @@ void add_pcilib_value_to_dict(pcilib_t* ctx, PyObject* dict, pcilib_value_t* val if(py_val) pcilib_pydict_set_item(dict, - PyString_FromString(name), + PyUnicode_FromString(name), py_val); else pcilib_pydict_set_item(dict, - PyString_FromString("defvalue"), - PyString_FromString("invalid")); + PyUnicode_FromString("defvalue"), + PyUnicode_FromString("invalid")); } PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_property_info_t listItem) @@ -142,18 +142,18 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper if(listItem.name) pcilib_pydict_set_item(pylistItem, - PyString_FromString("name"), - PyString_FromString(listItem.name)); + PyUnicode_FromString("name"), + PyUnicode_FromString(listItem.name)); if(listItem.description) pcilib_pydict_set_item(pylistItem, - PyString_FromString("description"), - PyString_FromString(listItem.description)); + PyUnicode_FromString("description"), + PyUnicode_FromString(listItem.description)); if(listItem.path) pcilib_pydict_set_item(pylistItem, - PyString_FromString("path"), - PyString_FromString(listItem.path)); + PyUnicode_FromString("path"), + PyUnicode_FromString(listItem.path)); //serialize types const char* type = "invalid"; @@ -175,40 +175,40 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper break; } pcilib_pydict_set_item(pylistItem, - PyString_FromString("type"), - PyString_FromString(type)); + PyUnicode_FromString("type"), + PyUnicode_FromString(type)); //serialize modes PyObject* modes = PyList_New(0); if((listItem.mode & PCILIB_ACCESS_R ) == PCILIB_REGISTER_R) - pcilib_pylist_append(modes, PyString_FromString("R")); + pcilib_pylist_append(modes, PyUnicode_FromString("R")); if((listItem.mode & PCILIB_ACCESS_W ) == PCILIB_REGISTER_W) - pcilib_pylist_append(modes, PyString_FromString("W")); + pcilib_pylist_append(modes, PyUnicode_FromString("W")); if((listItem.mode & PCILIB_ACCESS_RW ) == PCILIB_REGISTER_RW) - pcilib_pylist_append(modes, PyString_FromString("RW")); + pcilib_pylist_append(modes, PyUnicode_FromString("RW")); if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) - pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); + pcilib_pylist_append(modes, PyUnicode_FromString("NO_CHK")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("mode"), + PyUnicode_FromString("mode"), modes); //serialize flags PyObject* flags = PyList_New(0); if((listItem.flags & PCILIB_LIST_FLAG_CHILDS ) == PCILIB_LIST_FLAG_CHILDS) - pcilib_pylist_append(flags, PyString_FromString("childs")); + pcilib_pylist_append(flags, PyUnicode_FromString("childs")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("flags"), + PyUnicode_FromString("flags"), flags); if(listItem.unit) pcilib_pydict_set_item(pylistItem, - PyString_FromString("unit"), - PyString_FromString(listItem.unit)); + PyUnicode_FromString("unit"), + PyUnicode_FromString(listItem.unit)); return pylistItem; } @@ -219,42 +219,42 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist if(listItem.name) pcilib_pydict_set_item(pylistItem, - PyString_FromString("name"), - PyString_FromString(listItem.name)); + PyUnicode_FromString("name"), + PyUnicode_FromString(listItem.name)); if(listItem.description) pcilib_pydict_set_item(pylistItem, - PyString_FromString("description"), - PyString_FromString(listItem.description)); + PyUnicode_FromString("description"), + PyUnicode_FromString(listItem.description)); if(listItem.bank) pcilib_pydict_set_item(pylistItem, - PyString_FromString("bank"), - PyString_FromString(listItem.bank)); + PyUnicode_FromString("bank"), + PyUnicode_FromString(listItem.bank)); //serialize modes PyObject* modes = PyList_New(0); if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R) - pcilib_pylist_append(modes, PyString_FromString("R")); + pcilib_pylist_append(modes, PyUnicode_FromString("R")); if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W) - pcilib_pylist_append(modes, PyString_FromString("W")); + pcilib_pylist_append(modes, PyUnicode_FromString("W")); if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) - pcilib_pylist_append(modes, PyString_FromString("RW")); + pcilib_pylist_append(modes, PyUnicode_FromString("RW")); if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C) - pcilib_pylist_append(modes, PyString_FromString("W1C")); + pcilib_pylist_append(modes, PyUnicode_FromString("W1C")); if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C) - pcilib_pylist_append(modes, PyString_FromString("RW1C")); + pcilib_pylist_append(modes, PyUnicode_FromString("RW1C")); if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I) - pcilib_pylist_append(modes, PyString_FromString("W1I")); + pcilib_pylist_append(modes, PyUnicode_FromString("W1I")); if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I) - pcilib_pylist_append(modes, PyString_FromString("RW1I")); + pcilib_pylist_append(modes, PyUnicode_FromString("RW1I")); if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) - pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); + pcilib_pylist_append(modes, PyUnicode_FromString("NO_CHK")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("mode"), + PyUnicode_FromString("mode"), modes); pcilib_value_t defval = {0}; @@ -273,7 +273,7 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist add_pcilib_value_to_dict(ctx, range, &minval, "min"); add_pcilib_value_to_dict(ctx, range, &maxval, "max"); pcilib_pydict_set_item(pylistItem, - PyString_FromString("range"), + PyUnicode_FromString("range"), range); } @@ -301,20 +301,20 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist if(listItem.values[j].name) pcilib_pydict_set_item(valuesItem, - PyString_FromString("name"), - PyString_FromString(listItem.values[j].name)); + PyUnicode_FromString("name"), + PyUnicode_FromString(listItem.values[j].name)); if(listItem.values[j].description) { pcilib_pydict_set_item(valuesItem, - PyString_FromString("description"), - PyString_FromString(listItem.values[j].description)); + PyUnicode_FromString("description"), + PyUnicode_FromString(listItem.values[j].description)); } pcilib_pylist_append(values, valuesItem); } pcilib_pydict_set_item(pylistItem, - PyString_FromString("values"), + PyUnicode_FromString("values"), values); } @@ -322,7 +322,7 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist } -Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model) +pcipywrap *new_pcipywrap(const char* fpga_device, const char* model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); @@ -331,36 +331,37 @@ Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model) set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model); return NULL; } - Pcipywrap *self; - self = (Pcipywrap *) malloc(sizeof(Pcipywrap)); + pcipywrap *self; + self = (pcipywrap *) malloc(sizeof(pcipywrap)); self->shared = 0; self->ctx = ctx; return self; } -Pcipywrap *create_Pcipywrap(PyObject* ctx) +pcipywrap *create_pcipywrap(PyObject* ctx) { - if(!PyCObject_Check(ctx)) + if(!PyCapsule_CheckExact(ctx)) { - set_python_exception("Incorrect ctx type. Only PyCObject is allowed"); + set_python_exception("Incorrect ctx type. Only PyCapsule is allowed"); return NULL; } - Pcipywrap *self; - self = (Pcipywrap *) malloc(sizeof(Pcipywrap)); + pcipywrap *self; + self = (pcipywrap *) malloc(sizeof(pcipywrap)); self->shared = 1; - self->ctx = PyCObject_AsVoidPtr(ctx); + self->ctx = PyCapsule_GetPointer(ctx, PyCapsule_GetName(ctx)); + return self; } -void delete_Pcipywrap(Pcipywrap *self) { +void delete_pcipywrap(pcipywrap *self) { if(!self->shared) pcilib_close(self->ctx); free(self); } -PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const char *bank) +PyObject* pcipywrap_read_register(pcipywrap *self, const char *regname, const char *bank) { pcilib_value_t val = {0}; pcilib_register_value_t reg_value; @@ -384,7 +385,7 @@ PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const ch return pcilib_get_value_as_pyobject(self->ctx, &val, NULL); } -PyObject* Pcipywrap_write_register(Pcipywrap *self, PyObject* val, const char *regname, const char *bank) +PyObject* pcipywrap_write_register(pcipywrap *self, PyObject* val, const char *regname, const char *bank) { pcilib_value_t val_internal = {0}; pcilib_register_value_t reg_value; @@ -415,10 +416,10 @@ PyObject* Pcipywrap_write_register(Pcipywrap *self, PyObject* val, const char *r return NULL; } - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } -PyObject* Pcipywrap_get_property(Pcipywrap *self, const char *prop) +PyObject* pcipywrap_get_property(pcipywrap *self, const char *prop) { int err; pcilib_value_t val = {0}; @@ -434,7 +435,7 @@ PyObject* Pcipywrap_get_property(Pcipywrap *self, const char *prop) return pcilib_get_value_as_pyobject(self->ctx, &val, NULL); } -PyObject* Pcipywrap_set_property(Pcipywrap *self, PyObject* val, const char *prop) +PyObject* pcipywrap_set_property(pcipywrap *self, PyObject* val, const char *prop) { int err; @@ -453,25 +454,30 @@ PyObject* Pcipywrap_set_property(Pcipywrap *self, PyObject* val, const char *pro return NULL; } - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } -PyObject* Pcipywrap_get_registers_list(Pcipywrap *self, const char *bank) +PyObject* pcipywrap_get_registers_list(pcipywrap *self, const char *bank) { - pcilib_register_info_t *list = pcilib_get_register_list(self->ctx, bank, PCILIB_LIST_FLAGS_DEFAULT); - PyObject* pyList = PyList_New(0); - for(int i = 0; i < ((pcilib_t*)self->ctx)->num_reg; i++) - { - //serialize item attributes - PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(self->ctx, list[i]); - pcilib_pylist_append(pyList, pylistItem); - //Py_DECREF(pylistItem); - } - pcilib_free_register_info(self->ctx, list); - return pyList; + pcilib_register_info_t *list = pcilib_get_register_list(self->ctx, bank, PCILIB_LIST_FLAGS_DEFAULT); + + if(!list) { + set_python_exception("pcilib_get_register_list return NULL"); + return NULL; + } + + PyObject* pyList = PyList_New(0); + for(int i = 0; list[i].name; i++) + { + //serialize item attributes + PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(self->ctx, list[i]); + pcilib_pylist_append(pyList, pylistItem); + } + pcilib_free_register_info(self->ctx, list); + return pyList; } -PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const char *bank) +PyObject* pcipywrap_get_register_info(pcipywrap *self, const char* reg,const char *bank) { pcilib_register_info_t *info = pcilib_get_register_info(self->ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT); @@ -487,7 +493,7 @@ PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const cha return py_info; } -PyObject* Pcipywrap_get_property_list(Pcipywrap *self, const char* branch) +PyObject* pcipywrap_get_property_list(pcipywrap *self, const char* branch) { pcilib_property_info_t *list = pcilib_get_property_list(self->ctx, branch, PCILIB_LIST_FLAGS_DEFAULT); @@ -505,7 +511,7 @@ PyObject* Pcipywrap_get_property_list(Pcipywrap *self, const char* branch) return pyList; } -PyObject* Pcipywrap_read_dma(Pcipywrap *self, unsigned char dma, size_t size) +PyObject* pcipywrap_read_dma(pcipywrap *self, unsigned char dma, size_t size) { int err; void* buf = NULL; @@ -526,7 +532,7 @@ PyObject* Pcipywrap_read_dma(Pcipywrap *self, unsigned char dma, size_t size) return py_buf; } -PyObject* Pcipywrap_lock_global(Pcipywrap *self) +PyObject* pcipywrap_lock_global(pcipywrap *self) { int err; @@ -537,19 +543,19 @@ PyObject* Pcipywrap_lock_global(Pcipywrap *self) return NULL; } - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } -void Pcipywrap_unlock_global(Pcipywrap *self) +void pcipywrap_unlock_global(pcipywrap *self) { pcilib_unlock_global(self->ctx); return; } -PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id) +PyObject* pcipywrap_lock(pcipywrap *self, const char *lock_id) { pcilib_lock_t* lock = pcilib_get_lock(self->ctx, - PCILIB_LOCK_FLAGS_DEFAULT, + PCILIB_LOCK_FLAG_PERSISTENT, lock_id); if(!lock) { @@ -565,13 +571,13 @@ PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id) return NULL; } - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } -PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id) +PyObject* pcipywrap_try_lock(pcipywrap *self, const char *lock_id) { pcilib_lock_t* lock = pcilib_get_lock(self->ctx, - PCILIB_LOCK_FLAGS_DEFAULT, + PCILIB_LOCK_FLAG_PERSISTENT, lock_id); if(!lock) { @@ -586,13 +592,13 @@ PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id) return NULL; } - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } -PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id) +PyObject* pcipywrap_unlock(pcipywrap *self, const char *lock_id) { pcilib_lock_t* lock = pcilib_get_lock(self->ctx, - PCILIB_LOCK_FLAGS_DEFAULT, + PCILIB_LOCK_FLAG_PERSISTENT, lock_id); if(!lock) { @@ -601,7 +607,7 @@ PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id) } pcilib_unlock(lock); - return PyInt_FromLong((long)1); + return PyLong_FromLong((long)1); } diff --git a/pywrap/pcipywrap.h b/pywrap/pcipywrap.h index 5876a06..1b71a56 100644 --- a/pywrap/pcipywrap.h +++ b/pywrap/pcipywrap.h @@ -8,7 +8,7 @@ typedef struct { void* ctx; int shared; -} Pcipywrap; +} pcipywrap; /*! * \brief Redirect pcilib standart log stream to exeption text. @@ -16,7 +16,7 @@ typedef struct { * After that, logger will write last error, and all accumulated errors * to Python exeption text */ -void __redirect_logs_to_exeption(); +void redirect_logs_to_exeption(); /*! * \brief Wraps for pcilib_open function. @@ -26,9 +26,9 @@ void __redirect_logs_to_exeption(); */ PyObject* create_pcilib_instance(const char *fpga_device, const char *model); -Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model); -Pcipywrap *create_Pcipywrap(PyObject* ctx); -void delete_Pcipywrap(Pcipywrap *self); +pcipywrap *new_pcipywrap(const char* fpga_device, const char* model); +pcipywrap *create_pcipywrap(PyObject* ctx); +void delete_pcipywrap(pcipywrap *self); /*! * \brief Reads register value. Wrap for pcilib_read_register function. @@ -36,7 +36,7 @@ void delete_Pcipywrap(Pcipywrap *self); * \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* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const char *bank); +PyObject* pcipywrap_read_register(pcipywrap *self, const char *regname, const char *bank); /*! * \brief Writes value to register. Wrap for pcilib_write_register function. @@ -45,14 +45,14 @@ PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const ch * \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* Pcipywrap_write_register(Pcipywrap *self, PyObject* val, const char *regname, const char *bank); +PyObject* pcipywrap_write_register(pcipywrap *self, PyObject* val, const char *regname, const char *bank); /*! * \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* Pcipywrap_get_property(Pcipywrap *self, const char *prop); +PyObject* pcipywrap_get_property(pcipywrap *self, const char *prop); /*! * \brief Writes value to property. Wrap for pcilib_set_property function. @@ -60,27 +60,27 @@ PyObject* Pcipywrap_get_property(Pcipywrap *self, 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* Pcipywrap_set_property(Pcipywrap *self, PyObject* val, const char *prop); -PyObject* Pcipywrap_get_registers_list(Pcipywrap *self, const char *bank); -PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const char *bank); -PyObject* Pcipywrap_get_property_list(Pcipywrap *self, const char* branch); +PyObject* pcipywrap_set_property(pcipywrap *self, PyObject* val, const char *prop); +PyObject* pcipywrap_get_registers_list(pcipywrap *self, const char *bank); +PyObject* pcipywrap_get_register_info(pcipywrap *self, const char* reg,const char *bank); +PyObject* pcipywrap_get_property_list(pcipywrap *self, const char* branch); -PyObject* Pcipywrap_read_dma(Pcipywrap *self, unsigned char dma, size_t size); +PyObject* pcipywrap_read_dma(pcipywrap *self, unsigned char dma, size_t size); -PyObject* Pcipywrap_lock_global(Pcipywrap *self); -void Pcipywrap_unlock_global(Pcipywrap *self); +PyObject* pcipywrap_lock_global(pcipywrap *self); +void pcipywrap_unlock_global(pcipywrap *self); /*! * \brief Wrap for pcilib_lock * \param lock_id lock identificator * \warning This function should be called only under Python standart threading lock. - * Otherwise it will stuck with more than 1 threads. See /xml/test_pywrap/test_prop_mt.py + * Otherwise it will stuck with more than 1 threads. See /xml/test/test_prop4.py * for example. * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ -PyObject* Pcipywrap_lock(Pcipywrap *self, const char *lock_id); +PyObject* pcipywrap_lock(pcipywrap *self, const char *lock_id); -PyObject* Pcipywrap_try_lock(Pcipywrap *self, const char *lock_id); -PyObject* Pcipywrap_unlock(Pcipywrap *self, const char *lock_id); +PyObject* pcipywrap_try_lock(pcipywrap *self, const char *lock_id); +PyObject* pcipywrap_unlock(pcipywrap *self, const char *lock_id); #endif /* PCIPYWRAP_H */ diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index f08ceb7..5ee1bd1 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -4,13 +4,13 @@ #include "pcipywrap.h" %} -extern void __redirect_logs_to_exeption(); +extern void redirect_logs_to_exeption(); typedef struct { %extend { - Pcipywrap(const char* fpga_device = "/dev/fpga0", const char* model = NULL); - Pcipywrap(PyObject* ctx){return create_Pcipywrap(ctx);} - ~Pcipywrap(); + pcipywrap(const char* fpga_device = "/dev/fpga0", const char* model = NULL); + pcipywrap(PyObject* ctx){return create_pcipywrap(ctx);} + ~pcipywrap(); PyObject* read_register(const char *regname = NULL, const char *bank = NULL); PyObject* write_register(PyObject* val, const char *regname, const char *bank = NULL); @@ -30,4 +30,4 @@ typedef struct { PyObject* try_lock(const char *lock_id); PyObject* unlock(const char *lock_id); } -} Pcipywrap; +} pcipywrap; diff --git a/pywrap/templates/base.html b/pywrap/templates/base.html deleted file mode 100644 index fdb95e8..0000000 --- a/pywrap/templates/base.html +++ /dev/null @@ -1,347 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>{% block title %}Device {{ device }}{% endblock %}</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <meta http-equiv="X-UA-Compatible" content="IE=edge"/> - <link rel="stylesheet" type="text/css" href="codebase/dhtmlx.css"/> - <script type=text/javascript src="{{ url_for('static', filename='jquery-2.2.1.js') }}"></script> - <script src="codebase/dhtmlx.js"></script> - <script src="pcilib_tree.js"></script> - <script> - var propsTree - - function checkError(json) - { - if(json.error) - alert('Error:\n' + json.error) - } - - function createPropertyTree(branch, id) - { - function getPropertyItemsOnLevel(branch, id) - { - pathToProperties = "{{ url_for('get_property_list_json') }}" - completePath = pathToProperties + '?branch=' + branch - - $.getJSON(completePath, - function(json) { - checkError(json) - parsePropertyItems(json, branch, id) - }); - } - - function parsePropertyItems(json, branch, id) - { - function updatePropertyValue(id, path) - { - pathToGetProperty = "{{ url_for('get_property_json') }}" - completePath = pathToGetProperty + '?prop=' + path - - $.getJSON(completePath, function(json){ - checkError(json) - propsTree.updateItem(id, 'value: ' + json.value); - }) - } - - function writePropertyValue(id, path) - { - value = window.prompt("Enter new property value"); - - if(value != null) - { - pathToGetProperty = "{{ url_for('set_property_json') }}" - completePath = pathToGetProperty + '?prop=' + path +'&val=' + value - - $.getJSON(completePath, - function(json) { - checkError(json) - updatePropertyValue(id, path) - }) - } - else - updatePropertyValue(id, path) - } - - function setCurrentValueField(id, path, mode) - { - var propValId = id + 'CurrVal' - var func = 0 - - if(mode) - func = function(){writePropertyValue(propValId, path)} - else - func = function(){updatePropertyValue(propValId, path)} - - propsTree.insertNewItem(id, propValId, - 'value: ', - func); - - updatePropertyValue(propValId, path) - } - - for(var i = 0; i < json.length; i++) - { - propsTree.insertNewItem(id, json[i].path, json[i].name, 0); - - if(json[i].flags.indexOf("childs") != -1) - { - getPropertyItemsOnLevel(json[i].path, json[i].path) - } - else - { - if(json[i].mode.indexOf("R") != -1) - { - var mode = (json[i].mode.indexOf("W") != -1) - setCurrentValueField(json[i].path, json[i].path, mode) - } - } - - //show aviable info - if(json[i].description) - propsTree.insertNewItem(json[i].path, json[i].path + 'Desc', - 'description:\n' + json[i].description, 0); - if(json[i].type) - propsTree.insertNewItem(json[i].path, json[i].path + 'Type', - 'type: ' + json[i].type, 0); - if(json[i].unit) - propsTree.insertNewItem(json[i].path, json[i].path + 'Unit', - 'unit: ' + json[i].unit, 0); - - if(json[i].mode) - { - var modeId = json[i].path + 'Mode' - propsTree.insertNewItem(json[i].path, modeId, - 'mode', 0); - - for(var j = 0; j < json[i].mode.length; j++) - propsTree.insertNewItem(modeId, modeId + j, - json[i].mode[j], 0); - propsTree.closeItem(modeId) - } - - if(json[i].path) - propsTree.insertNewItem(json[i].path, json[i].path + 'Path', - 'path: ' + json[i].path, 0); - - propsTree.closeItem(json[i].path); - } - } - - getPropertyItemsOnLevel(branch, id) - } - - var regTree - function createRegistersList() - { - function parseJsonRegisterList(json) - { - checkError(json) - - function compareRegistersByBank(a,b) - { - if (a.bank < b.bank) - return -1; - else if (a.bank > b.bank) - return 1; - else - return 0; - } - - if(json.lenght <= 0) - return - - //sort registers by bank - json.sort(compareRegistersByBank) - - //create bank dirs - var curBankName = json[0].bank - var created = 0 - for(var i = 0; i < json.length; i++) - { - //create new bank tab if it has not created already - if(json[i].bank != curBankName) - { - curBankName = json[i].bank - created = 0 - } - if(!created) - { - regTree.insertNewItem(0, json[i].bank, json[i].bank, 0); - created = 1 - } - - //insert register info to bank - var itemId = json[i].bank + "_" + json[i].name - regTree.insertNewItem(json[i].bank, itemId, json[i].name) - - function updateRegisterValue(id, bank, name) - { - pathToGetProperty = "{{ url_for('read_register_json') }}" - completePath = pathToGetProperty + '?bank=' + bank + - '&name=' + name - - $.getJSON(completePath, function(json){ - checkError(json) - regTree.updateItem(id, 'value: ' + json.value); - }) - } - - - function writeRegisterValue(id, bank, name) - { - value = window.prompt("Enter new register value"); - - if(value != null) - { - pathToGetProperty = "{{ url_for('write_register_json') }}" - completePath = pathToGetProperty + '?bank=' + bank + - '&name=' + name + '&val=' + value; - - $.getJSON(completePath, - function(json) { - checkError(json) - updateRegisterValue(id, bank, name) - }) - } - else - updateRegisterValue(id, bank, name) - } - - function setCurrentValueField(id, bank, name, mode) - { - var regValId = id + 'CurrVal' - var func = 0 - - if(mode) - func = function(){writeRegisterValue(regValId, bank, name)} - else - func = function(){updateRegisterValue(regValId, bank, name)} - - regTree.insertNewItem(id, regValId, - 'value: ', - func); - updateRegisterValue(regValId, bank, name) - } - - if(json[i].mode.indexOf("R") != -1) - { - var mode = (json[i].mode.indexOf("W") != -1) - setCurrentValueField(itemId, json[i].bank, json[i].name, mode) - } - - //show aviable info - if(json[i].description) - regTree.insertNewItem(itemId, itemId + 'Desc', - 'description:\n' + json[i].description, 0); - if(json[i].defvalue) - regTree.insertNewItem(itemId, itemId + 'Defvalue', - 'defvalue: ' + json[i].defvalue, 0); - - if(json[i].mode) - { - var modeId = itemId + 'Mode' - regTree.insertNewItem(itemId, modeId, - 'mode', 0); - - for(var j = 0; j < json[i].mode.length; j++) - regTree.insertNewItem(modeId, modeId + j, - json[i].mode[j], 0); - regTree.closeItem(modeId) - } - - if(json[i].range) - { - var rangeId = itemId + 'Range' - regTree.insertNewItem(itemId, rangeId, - 'range', 0); - regTree.insertNewItem(rangeId, rangeId + 'Min', - 'min: ' + json[i].range.min, 0); - regTree.insertNewItem(rangeId, rangeId + 'Max', - 'max: ' + json[i].range.max, 0); - regTree.closeItem(rangeId) - } - - if(json[i].values) - { - var valuesId = itemId + 'Values' - regTree.insertNewItem(itemId, valuesId, - 'values', 0); - - function addValueInfo(valuesId, value) - { - var valueId = valuesId + value.name - regTree.insertNewItem(valuesId, valueId, value.name, 0); - - if(value.description) - regTree.insertNewItem(valueId, valueId + 'Desc', - 'description: ' + value.description, 0); - if(value.value) - regTree.insertNewItem(valueId, valueId + 'Value', - 'value: ' + value.value, 0); - if(value.min) - regTree.insertNewItem(valueId, valueId + 'Min', - 'min: ' + value.min, 0); - if(value.max) - regTree.insertNewItem(valueId, valueId + 'Max', - 'max: ' + value.max, 0); - } - - for(var j = 0; j < json[i].values.length; j++) - { - addValueInfo(valuesId, json[i].values[j]) - } - regTree.closeItem(valuesId) - } - - propsTree.closeItem(json[i].path); - - regTree.closeItem(itemId); - } - } - - //get registers json list - getRegistersListPath = "{{ url_for('get_registers_list_json') }}" - $.getJSON(getRegistersListPath, parseJsonRegisterList); - } - - function doOnLoad() - { - propsTree = new dhtmlXTreeObject("treeboxbox_tree","100%","100%",0); - propsTree.setImagePath("codebase/imgs/dhxtree_skyblue/"); - //generating properties list - createPropertyTree('', 0) - - regTree = new dhtmlXTreeObject("treeboxbox_tree2","100%","100%",0,0,0,0,'SELECT') - regTree.setImagePath("codebase/imgs/dhxtree_skyblue/"); - createRegistersList() - } - </script> -</head> -<body onload="doOnLoad()"> - {% block info %} - <h2>Device {{ device }} model={{ model }} control page </h2> - {% endblock %} - - {% block content %} - {% endblock %} - <table> - <tr> - <td> - <h3>Properties Tree</h3> - </td> - <td> - <h3>Registers Tree</h3> - </td> - </tr> - <tr> - <td valign="top"> - <div id="treeboxbox_tree" style="background-color:#f5f5f5;border :1px solid Silver; overflow:auto;"></div> - </td> - <td valign="top"> - <div id="treeboxbox_tree2" style="background-color:#f5f5f5;border :1px solid Silver; overflow:auto;"></div> - </td> - </tr> - </table> -</body> -</html> diff --git a/pywrap/templates/property_info.html b/pywrap/templates/property_info.html deleted file mode 100644 index 912d3d5..0000000 --- a/pywrap/templates/property_info.html +++ /dev/null @@ -1,91 +0,0 @@ -{% extends "base.html" %} -{% block title %}Property list{% endblock %} -{% block info %} -<h1>List of properties in branch {{ branch }}</h1> -{% endblock %} - -{% block content %} - - <script> - function set_property() - { - var value = document.getElementById("set_val_box").value; - window.location.href = "{{ url_for('set_property') }}?prop={{ branch }}&"+ - 'val='+value; - }; - </script> - -<table border="1" style="width:100%"> - <tr> - <th>Name</th> - <th>Description</th> - </tr> - {% for property in properties %} - <tr> - {% if ('childs' in property.flags) or (properties|length != 1) %} - <td><a href="{{ url_for('get_property_list', branch = property.path) }}">"{{ property.name }}"</td> - {% if 'description' in property %} - <script> - function set_property() - { - var value = document.getElementById("set_val_box").value; - window.location.href = "{{ url_for('set_property') }}?prop={{ branch }}&"+ - 'val='+value; - }; - </script> - <td>{{ property.description }}</td> - {% else %} - <td></td> - {% endif %} - {% else %} - <td>{{ property.name }}"</td> - <td> - <table border="1" style="width:100%"> - {% if 'description' in property %} - <tr> - <th> Description </th> - <td> {{ property.description }} </td> - </tr> - {% endif %} - <tr> - <th> Current value </th> - <td> {{ value }} </td> - </tr> - {% if 'W' in property.mode %} - <tr> - <th> Set value</th> - <td> - <input type="text" name="set_val_box" id="set_val_box" value="" /> - <input type="button" value="set" onclick="set_property()"> - </td> - </tr> - {% endif %} - <tr> - <th>Mode</th> - <td> - <ul> - {% for m in property.mode %} - <li>{{ m }}</li> - {% endfor %} - </ul> - </td> - </tr> - <tr> - <th>Type</th> - <td> {{ property.type }} </td> - </tr> - <tr> - <th>Unit</th> - <td> {{ property.unit }} </td> - </tr> - <tr> - <th>Path</th> - <td> {{ property.path }} </td> - </tr> - </table> - </td> - {% endif %} - </tr> - {% endfor %} - </table> -{% endblock %} diff --git a/pywrap/templates/register_info.html b/pywrap/templates/register_info.html deleted file mode 100644 index a7f11dc..0000000 --- a/pywrap/templates/register_info.html +++ /dev/null @@ -1,106 +0,0 @@ -{% extends "base.html" %} -{% block title %}Register info{% endblock %} -{% block info %} -<h1>Register '{{ register.name }}' info</h1> -{% endblock %} - -{% block content %} - <script> - function write_register() - { - var value = document.getElementById("set_val_box").value; - window.location.href = "{{ url_for('write_register') }}?name={{ register.name }}&"+ - 'bank={{ register.bank }}&val='+value; - }; - </script> - - <table border="1" style="width:100%"> - {% if 'description' in register %} - <tr> - <th> Description </th> - <td> {{ register.description }} </td> - </tr> - {% endif %} - <tr> - <th> Current value </th> - <td> {{ value }} </td> - </tr> - {% if 'W' in register.mode %} - <tr> - <th> Set value</th> - <td> - <input type="text" name="set_val_box" id="set_val_box" value="" /> - <input type="button" value="set" onclick="write_register()"> - </td> - </tr> - {% endif %} - <tr> - <th>Bank</th> - <td>{{ register.bank }}</td> - </tr> - <tr> - <th>Default value</th> - <td>{{ register.defvalue }}</td> - </tr> - <tr> - <th>Mode</th> - <td> - <ul> - {% for m in register.mode %} - <li>{{ m }}</li> - {% endfor %} - </ul> - </td> - </tr> - {% if 'range' in register %} - <tr> - <th> - Range - </th> - <td> - <table> - <tr> - <th> min </th> - <td> {{ register.range.min }} </td> - </tr> - <tr> - <th> max </th> - <td> {{ register.range.max }} </td> - </tr> - </table> - </td> - </tr> - {% endif %} - {% if 'values' in register %} - {% for v in register['values'] %} - <tr> - {% if 'name' in v %} - <th> {{v.name}} </th> - {% endif %} - <td> - <table> - {% if 'description' in v %} - <tr> - <th> description </th> - <td> {{ v.description }} </td> - </tr> - {% endif %} - <tr> - <th> min </th> - <td> {{ v.min }} </td> - </tr> - <tr> - <th> max </th> - <td> {{ v.max }} </td> - </tr> - <tr> - <th> value </th> - <td> {{ v.value }} </td> - </tr> - </table> - </td> - </tr> - {% endfor %} - {% endif %} - </table> -{% endblock %} diff --git a/pywrap/templates/registers_list.html b/pywrap/templates/registers_list.html deleted file mode 100644 index 199475b..0000000 --- a/pywrap/templates/registers_list.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "base.html" %} -{% block title %}Registers list{% endblock %} -{% block info %} -<h1>List of aviable registers</h1> -{% endblock %} - -{% block content %} -<table border="1" style="width:100%"> - <tr> - <th>Name</th> - <th>Description</th> - </tr> -{% for register in registers %} - <tr> - <td><a href="{{ url_for('get_register_info', bank=register.bank, name=register.name) }}">{{ register.name }}</td> - {% if 'description' in register %} - <td>{{ register.description }}</td> - {% else %} - <td></td> - {% endif %} - </tr> -{% endfor %} -</table> -{% endblock %} - - diff --git a/pywrap/test_pcipywrap.py b/pywrap/test_pcilib.py index 91780ec..398d975 100644 --- a/pywrap/test_pcipywrap.py +++ b/pywrap/test_pcilib.py @@ -1,5 +1,5 @@ import threading -import pcipywrap +import pcilib import random import os import json @@ -7,7 +7,7 @@ import requests import time from optparse import OptionParser, OptionGroup -class test_pcipywrap(): +class test_pcilib(): def __init__(self, device, model, @@ -35,7 +35,7 @@ class test_pcipywrap(): #create pcilib_instance self.device = device self.model = model - self.pcilib = pcipywrap.Pcipywrap(device, model) + self.pcilib = pcilib.pcilib(device, model) self.num_threads = num_threads self.write_percentage = write_percentage self.register = register @@ -55,17 +55,17 @@ class test_pcipywrap(): {'command': 'unlock_global'}, {'command': 'help'}] r = requests.get(url, data=json.dumps(payload[message]), headers=headers) - print json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': ')) + print(json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': '))) def testThreadSafeReadWrite(self): def threadFunc(): if random.randint(0, 100) >= (self.write_percentage * 100): ret = self.pcilib.get_property(self.prop) - print self.register, ':', ret + print(self.register, ':', ret) del ret else: val = random.randint(0, 65536) - print 'set value:', val + print('set value:', val) self.pcilib.set_property(val, self.prop) try: while(1): @@ -74,25 +74,25 @@ class test_pcipywrap(): thread_list[i].start() for i in range(0, self.num_threads): thread_list[i].join() - print 'cycle done' + print('cycle done') except KeyboardInterrupt: - print 'testing done' + print('testing done') pass def testMemoryLeak(self): try: while(1): - val = random.randint(0, 8096) - self.pcilib = pcipywrap.Pcipywrap(self.device, self.model) - print self.pcilib.get_property_list(self.branch) - print self.pcilib.get_register_info(self.register) - print self.pcilib.get_registers_list(); - print self.pcilib.read_register(self.register) - print self.pcilib.write_register(val, self.register) - print self.pcilib.get_property(self.prop) - print self.pcilib.set_property(val, self.prop) + val = long(random.randint(0, 8096)) + self.pcilib = pcilib.pcilib(self.device, self.model) + print(self.pcilib.get_property_list(self.branch)) + print(self.pcilib.get_register_info(self.register)) + print(self.pcilib.get_registers_list()) + print(self.pcilib.write_register(val, self.register)) + print(self.pcilib.read_register(self.register)) + print(self.pcilib.set_property(val, self.prop)) + print(self.pcilib.get_property(self.prop)) except KeyboardInterrupt: - print 'testing done' + print('testing done') pass def testServer(self): @@ -111,14 +111,19 @@ class test_pcipywrap(): def sendRandomMessage(): message_number = random.randint(1, len(payload) - 1) - print 'message number: ', message_number + print('message number: ', message_number) payload[message_number]['value'] = random.randint(0, 8096) r = requests.get(url, data=json.dumps(payload[message_number]), headers=headers) - print json.dumps(r.json(), sort_keys=True, indent=4, separators=(',', ': ')) - + if(r.headers['content-type'] == 'application/json'): + print(json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': '))) + else: + print(r.content) try: r = requests.get(url, data=json.dumps(payload[1]), headers=headers) - print json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': ')) + if(r.headers['content-type'] == 'application/json'): + print(json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': '))) + else: + print(r.content) while(1): time.sleep(self.server_message_delay) @@ -127,10 +132,10 @@ class test_pcipywrap(): thread_list[i].start() for i in range(0, self.num_threads): thread_list[i].join() - print 'cycle done' + print('cycle done') except KeyboardInterrupt: - print 'testing done' + print('testing done') pass if __name__ == '__main__': @@ -140,7 +145,7 @@ if __name__ == '__main__': type="string", dest="device", default=str('/dev/fpga0'), help="FPGA device (/dev/fpga0)") parser.add_option("-m", "--model", action="store", - type="string", dest="model", default=None, + type="string", dest="model", default=str('test'), help="Memory model (autodetected)") parser.add_option("-t", "--threads", action="store", type="int", dest="threads", default=150, @@ -232,7 +237,7 @@ if __name__ == '__main__': opts = parser.parse_args()[0] #create pcilib test instance - lib = test_pcipywrap(opts.device, + lib = test_pcilib(opts.device, opts.model, num_threads = opts.threads, write_percentage = opts.write_percentage, @@ -2,4 +2,4 @@ APP_PATH=`dirname $0` -PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $* +PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_SCRIPTS_DIR="$APP_PATH/pyserver/scripts" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $* diff --git a/xml/test/cmosis.xml b/xml/test/cmosis.xml deleted file mode 100644 index 45d2f6e..0000000 --- a/xml/test/cmosis.xml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <bank bar="0" size="128" protocol="software_registers" read_address="0x9010" write_address="0x9000" word_size="8" endianess="little" format="%lu" name="cmosis" description="CMOSIS CMV2000 Registers"> - <register address="1" offset="0" size="16" default="1088" rwmask="0" mode="RW" name="cmosis_number_lines" description="test"/> - <register address="3" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start1"/> - <register address="5" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start2"/> - <register address="7" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start3"/> - <register address="9" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start4"/> - <register address="11" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start5"/> - <register address="13" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start6"/> - <register address="15" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start7"/> - <register address="17" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start8"/> - <register address="19" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines1"/> - <register address="21" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines2"/> - <register address="23" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines3"/> - <register address="25" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines4"/> - <register address="27" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines5"/> - <register address="29" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines6"/> - <register address="31" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines7"/> - <register address="33" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines8"/> - <register address="35" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_s"/> - <register address="37" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_a"/> - <register address="39" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_color"/> - <register address="40" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_image_flipping"/> - <register address="41" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_exp_flags"/> - <register address="42" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time"><view view="formuu3"/><view view="enumm3"/></register> - <register address="45" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step"/> - <register address="48" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp1"/> - <register address="51" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp2"/> - <register address="54" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes"/> - <register address="55" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq"/> - <register address="56" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time2"/> - <register address="59" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step2"/> - <register address="68" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes2"/> - <register address="69" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq2"/> - <register address="70" offset="0" size="16" default="1" rwmask="0" mode="RW" name="cmosis_number_frames"/> - <register address="72" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_output_mode"/> - <register address="78" offset="0" size="12" default="85" rwmask="0" mode="RW" name="cmosis_training_pattern"/> - <register address="80" offset="0" size="18" default="0x3FFFF" rwmask="0" mode="RW" name="cmosis_channel_en"/> - <register address="82" offset="0" size="3" default="7" rwmask="0" mode="RW" name="cmosis_special_82"/> - <register address="89" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow2"/> - <register address="90" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow3"/> - <register address="100" offset="0" size="14" default="16260" rwmask="0" mode="RW" name="cmosis_offset"/> - <register address="102" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_pga"/> - <register address="103" offset="0" size="8" default="32" rwmask="0" mode="RW" name="cmosis_adc_gain"/> - <register address="111" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_bit_mode"/> - <register address="112" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_adc_resolution"/> - <register address="115" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_special_115"/> - </bank> -</model> diff --git a/xml/test/props.xml b/xml/test/props.xml index 57702e2..750881d 100644 --- a/xml/test/props.xml +++ b/xml/test/props.xml @@ -3,4 +3,5 @@ <transform path="/test/prop1" register="test_prop1" unit="C" read_from_register="(503975./1024000)*${/registers/fpga/sensor_temperature:C} - 27315./100" description="formula to get real fpga temperature from the fpga_temperature register in decimal"/> <transform path="/test/prop2" register="test_prop2" unit="C" script="test_prop2.py" description="test python script #1" write_verification="0" /> <transform path="/test/prop3" register="test_prop3" unit="C" script="test_prop3.py" description="test python script #2" /> + <transform path="/test/prop4" register="test_prop4" unit="C" script="test_prop4.py" description="Example of thread safe python property"/> </model> diff --git a/xml/test/test_prop2.py b/xml/test/test_prop2.py index d78dbea..8a3ebf6 100644 --- a/xml/test/test_prop2.py +++ b/xml/test/test_prop2.py @@ -1,6 +1,5 @@ def read_from_register(ctx, value): return ctx.get_property('/test/prop3') / 2 - + def write_to_register(ctx, value): ctx.set_property(value*2, '/test/prop3') - diff --git a/xml/test/test_prop4.py b/xml/test/test_prop4.py new file mode 100644 index 0000000..a7e0269 --- /dev/null +++ b/xml/test/test_prop4.py @@ -0,0 +1,24 @@ +import time +import threading +lock = threading.Lock() + +def read_from_register(ctx, value): + with lock: + ctx.lock('test_prop4') + + cur = read_from_register.counter + read_from_register.counter += 1 + for i in range (0, 5): + time.sleep(0.1) + print(cur) + out = ctx.get_property('/test/prop3') / 2 + + ctx.unlock('test_prop4') + + return out + +read_from_register.counter = 0 + +def write_to_register(ctx, value): + with lock: + ctx.set_property(value*2, '/test/prop3') |