summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2016-03-02 23:36:19 +0100
committerSuren A. Chilingaryan <csa@suren.me>2016-03-02 23:36:19 +0100
commitf7636162ba124c0d6b5accaa72c842033f3e2309 (patch)
tree9ae5ceddde46e7c511bba899b869f54c6fef6283
parent7e39a6c8ae5c3f95b3b2895c4ce8d858c7ad3b79 (diff)
parent02d0026e2df2ba5c68c0c1a67aec4437c9e8e8f3 (diff)
downloadpcitool-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.txt10
-rw-r--r--apps/test_multithread.c14
-rw-r--r--pcilib/error.c13
-rw-r--r--pcilib/py.c69
-rw-r--r--pyserver/api_server.py (renamed from pywrap/server.py)270
-rw-r--r--pyserver/html_server.py231
-rw-r--r--pyserver/scripts/test_script.py10
-rw-r--r--pyserver/scripts/test_script2.py4
-rw-r--r--pyserver/static/base.css46
-rw-r--r--pyserver/static/check_err.js4
-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)bin23436 -> 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)bin3646 -> 3646 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif)bin56 -> 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)bin87 -> 87 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif)bin579 -> 579 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif)bin571 -> 571 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif)bin155 -> 155 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif)bin155 -> 155 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif)bin155 -> 155 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif)bin92 -> 92 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif)bin878 -> 878 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif)bin361 -> 361 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif)bin79 -> 79 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif)bin79 -> 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)bin79 -> 79 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif)bin74 -> 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)bin76 -> 76 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif)bin81 -> 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)bin81 -> 81 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif)bin67 -> 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)bin69 -> 69 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif)bin208 -> 208 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif)bin107 -> 107 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif)bin107 -> 107 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif)bin119 -> 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)bin121 -> 121 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif)bin125 -> 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)bin125 -> 125 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif)bin117 -> 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)bin117 -> 117 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif)bin111 -> 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)bin111 -> 111 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif)bin111 -> 111 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif)bin111 -> 111 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif)bin123 -> 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)bin124 -> 124 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif)bin128 -> 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)bin128 -> 128 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif)bin120 -> 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)bin119 -> 119 bytes
-rw-r--r--pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif (renamed from pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif)bin114 -> 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)bin113 -> 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)bin213 -> 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)bin223 -> 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.html194
-rw-r--r--pyserver/templates/property_info.html91
-rw-r--r--pyserver/templates/register_info.html9
-rw-r--r--pyserver/templates/registers/table_cell.html100
-rw-r--r--pyserver/templates/registers/table_header.html10
-rw-r--r--pyserver/templates/registers/table_scripts.html42
-rw-r--r--pyserver/templates/registers_list.html12
-rw-r--r--pywrap/CMakeLists.txt9
-rw-r--r--pywrap/html_server.py197
-rw-r--r--pywrap/pcilib.py38
-rw-r--r--pywrap/pcipywrap.c176
-rw-r--r--pywrap/pcipywrap.h38
-rw-r--r--pywrap/pcipywrap.i10
-rw-r--r--pywrap/templates/base.html347
-rw-r--r--pywrap/templates/property_info.html91
-rw-r--r--pywrap/templates/register_info.html106
-rw-r--r--pywrap/templates/registers_list.html26
-rw-r--r--pywrap/test_pcilib.py (renamed from pywrap/test_pcipywrap.py)57
-rwxr-xr-xrun2
-rw-r--r--xml/test/cmosis.xml50
-rw-r--r--xml/test/props.xml1
-rw-r--r--xml/test/test_prop2.py3
-rw-r--r--xml/test/test_prop4.py24
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
index f2deecd..f2deecd 100644
--- a/pywrap/static/codebase/ext/dhxupload.xap
+++ b/pyserver/static/codebase/ext/dhxupload.xap
Binary files differ
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
index 2fa8674..2fa8674 100644
--- a/pywrap/static/codebase/ext/uploader.swf
+++ b/pyserver/static/codebase/ext/uploader.swf
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif
index d7ae406..d7ae406 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/blank.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/blank.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/but_cut.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/but_cut.gif
index 942bd18..942bd18 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/but_cut.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/but_cut.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif
index e0a88ce..e0a88ce 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderClosed.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif
index 1680dbc..1680dbc 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/folderOpen.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif
index a61302a..a61302a 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckAll.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif
index 42447b8..42447b8 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckDis.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif
index 0350b2a..0350b2a 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconCheckGray.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif
index 9f3fe50..9f3fe50 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckAll.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif
index f15d9f7..f15d9f7 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/iconUncheckDis.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif
index 9c3e531..9c3e531 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/leaf.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/leaf.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif
index b4f560c..b4f560c 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif
index b4f560c..b4f560c 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif
index bf32db2..bf32db2 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line1_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif
index 23b2ce3..23b2ce3 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif
index 6ec17b5..6ec17b5 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line2_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif
index 43152c5..43152c5 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif
index 74a874c..74a874c 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line3_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif
index 907fe7a..907fe7a 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif
index 5c7e162..5c7e162 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/line4_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif
index 67456b1..67456b1 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/lock.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/lock.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif
index caa3f57..caa3f57 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif
index 2ab1070..2ab1070 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus1.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus1.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif
index 036e5b3..036e5b3 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif
index b4672bf..b4672bf 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus2_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif
index 3242cca..3242cca 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif
index 8c279e0..8c279e0 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus3_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif
index 1c7c0a7..1c7c0a7 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif
index 70992fe..70992fe 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus4_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif
index 031c160..031c160 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif
index 47e25cd..47e25cd 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/minus5_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif
index 019cfbd..019cfbd 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif
index 34dee94..34dee94 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus1.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus1.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif
index d57afa9..d57afa9 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif
index fde3a58..fde3a58 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus2_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif
index 2b6546b..2b6546b 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif
index 863d34c..863d34c 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus3_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif
index a4fe8c0..a4fe8c0 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif
index 635e6f6..635e6f6 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus4_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif
index 88c35a4..88c35a4 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif
index 2ae5444..2ae5444 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/plus5_rtl.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_off.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_off.gif
index a050afd..a050afd 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_off.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_off.gif
Binary files differ
diff --git a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_on.gif b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_on.gif
index 4d594b5..4d594b5 100644
--- a/pywrap/static/codebase/imgs/dhxtree_skyblue/radio_on.gif
+++ b/pyserver/static/codebase/imgs/dhxtree_skyblue/radio_on.gif
Binary files differ
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 +
+ '&reg=' + 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 +
+ '&reg=' + 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,
diff --git a/run b/run
index 42160f2..ebc558b 100755
--- a/run
+++ b/run
@@ -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')