Kaynağa Gözat

Merge script and transform view. Add get register and properties info to python wrap.

Vasilii Chernov 8 yıl önce
ebeveyn
işleme
d9a31945a9
11 değiştirilmiş dosya ile 579 ekleme ve 288 silme
  1. 1 1
      docs/Doxyfile.in
  2. 305 26
      pcilib/pcipywrap.c
  3. 10 2
      pcilib/pcipywrap.i
  4. 183 4
      pcilib/py.c
  5. 9 0
      pcilib/py.h
  6. 29 15
      pcilib/xml.c
  7. 2 2
      views/CMakeLists.txt
  8. 0 206
      views/script.c
  9. 0 18
      views/script.h
  10. 38 14
      views/transform.c
  11. 2 0
      views/transform.h

+ 1 - 1
docs/Doxyfile.in

@@ -1486,7 +1486,7 @@ MATHJAX_CODEFILE       =
 # The default value is: YES.
 # This tag requires that the tag GENERATE_HTML is set to YES.
 
-SEARCHENGINE           = NO
+SEARCHENGINE           = YES
 
 # When the SERVER_BASED_SEARCH tag is enabled the search engine will be
 # implemented using a web server instead of a web client using Javascript. There

+ 305 - 26
pcilib/pcipywrap.c

@@ -4,30 +4,18 @@
 
 /*!
  * \brief Global pointer to pcilib_t context.
- * Used by __setPcilib and read_register.
+ * Used by setPcilib and read_register.
  */
 pcilib_t* __ctx = 0;
 
-/*!
- * \brief Wraps for pcilib_open function.
- * \param[in] fpga_device path to the device file [/dev/fpga0]
- * \param[in] model specifies the model of hardware, autodetected if NULL is passed
- * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray
- */
-PyObject* __createPcilibInstance(const char *fpga_device, const char *model)
-{
-	//opening device
-    pcilib_t* ctx = pcilib_open(fpga_device, model);
-    
-    //serializing object
-    return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
-}
-
 /*!
  * \brief Sets python exeption text. Function interface same as printf.
  */
 void __setPyExeptionText(const char* msg, ...)
 {
+	if(!Py_IsInitialized())
+        Py_Initialize();
+	
 	char *buf;
 	size_t sz;
 	
@@ -52,17 +40,58 @@ void __setPyExeptionText(const char* msg, ...)
 	free(buf);
 }
 
+/*!
+ * \brief Wraps for pcilib_open function.
+ * \param[in] fpga_device path to the device file [/dev/fpga0]
+ * \param[in] model specifies the model of hardware, autodetected if NULL is passed
+ * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray; NULL with exeption text, if failed.
+ */
+PyObject* createPcilibInstance(const char *fpga_device, const char *model)
+{
+	//opening device
+    pcilib_t* ctx = pcilib_open(fpga_device, model);
+    if(!ctx)
+    {
+		__setPyExeptionText("Failed pcilib_open(%s, %s)", fpga_device, model);
+		return NULL;
+	}
+	
+    //serializing object
+    return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
+}
+
+/*!
+ * \brief Closes current pciliv instance, if its open.
+ */
+void closeCurrentPcilibInstance()
+{
+    if(__ctx)
+    {
+        pcilib_close(__ctx);
+        __ctx = NULL;
+    }
+}
+
+/*!
+ * \brief Returns current opened pcilib_t instatnce
+ * \return Pointer to pcilib_t, serialized to bytearray
+ */
+PyObject* getCurrentPcilibInstance()
+{
+    return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*));
+}
+
 /*!
  * \brief Sets pcilib context to wraper.
  * \param[in] addr Pointer to pcilib_t, serialized to bytearray
  * \return 1, serialized to PyObject or NULL with exeption text, if failed.
  */
-PyObject* __setPcilib(PyObject* addr)
+PyObject* setPcilib(PyObject* addr)
 {
 	if(!PyByteArray_Check(addr))
 	{
-        __setPyExeptionText(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed");
-		return;
+        __setPyExeptionText("Incorrect addr type. Only bytearray is allowed");
+		return NULL;
 	}
 	
 	//deserializing adress
@@ -71,8 +100,6 @@ PyObject* __setPcilib(PyObject* addr)
 	//hard copy context adress
 	for(int i = 0; i < sizeof(pcilib_t*) + 10; i++)
 		((char*)&__ctx)[i] = pAddr[i];
-
-	free(pAddr);
 	
 	return PyInt_FromLong((long)1);
 }
@@ -84,11 +111,13 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
 	switch(val->type)
 	{
 		case PCILIB_TYPE_INVALID:
-            errstream("Invalid register output type (PCILIB_TYPE_INVALID)");
+			if(errstream)
+				errstream("Invalid register output type (PCILIB_TYPE_INVALID)");
 			return NULL;
 			
 		case PCILIB_TYPE_STRING:
-            errstream("Invalid register output type (PCILIB_TYPE_STRING)");
+			if(errstream)
+				errstream("Invalid register output type (PCILIB_TYPE_STRING)");
 			return NULL;
 		
 		case PCILIB_TYPE_LONG:
@@ -98,7 +127,8 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
 			
 			if(err)
 			{
-                errstream("Failed: pcilib_get_value_as_int (%i)", err);
+				if(errstream)
+					errstream("Failed: pcilib_get_value_as_int (%i)", err);
 				return NULL;
 			}
 			return PyInt_FromLong((long) ret);
@@ -111,14 +141,16 @@ PyObject* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val, voi
 			
 			if(err)
 			{
-                errstream("Failed: pcilib_get_value_as_int (%i)", err);
+				if(errstream)
+					errstream("Failed: pcilib_get_value_as_int (%i)", err);
 				return NULL;
 			}
 			return PyFloat_FromDouble((double) ret);
 		}
 		
 		default:
-            errstream("Invalid register output type (unknown)");
+			if(errstream)
+				errstream("Invalid register output type (unknown)");
 			return NULL;
 	}
 }
@@ -289,3 +321,250 @@ PyObject* set_property(const char *prop, PyObject* val)
 	return PyInt_FromLong((long)1);
 }
 
+void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name)
+{
+	PyObject *py_val = pcilib_convert_val_to_pyobject(__ctx, val, NULL);
+
+	if(py_val)
+		PyDict_SetItem(dict,
+                       PyString_FromString(name),
+                       val);
+	else
+		PyDict_SetItem(dict,
+                       PyString_FromString("defvalue"),
+                       PyString_FromString("invalid"));
+}
+
+PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listItem)
+{
+    PyObject* pylistItem = PyDict_New();
+
+    if(listItem.name)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("name"),
+                   PyString_FromString(listItem.name));
+
+    if(listItem.description)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("description"),
+                   PyString_FromString(listItem.description));
+
+   if(listItem.path)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("path"),
+                   PyString_FromString(listItem.path));
+
+    //serialize types
+    const char* type = "invalid";
+    switch(listItem.type)
+    {
+        case PCILIB_TYPE_INVALID:
+            type = "invalid";
+            break;
+        case PCILIB_TYPE_STRING:
+             type = "string";
+             break;
+        case PCILIB_TYPE_DOUBLE:
+             type = "double";
+             break;
+        case PCILIB_TYPE_LONG :
+             type = "long";
+             break;
+        default:
+             break;
+    }
+    PyDict_SetItem(pylistItem,
+               PyString_FromString("type"),
+               PyString_FromString(type));
+
+
+    //serialize modes
+    PyObject* modes = PyList_New(0);
+
+    if((listItem.mode & PCILIB_ACCESS_R ) == PCILIB_REGISTER_R)
+        PyList_Append(modes, PyString_FromString("R"));
+    if((listItem.mode & PCILIB_ACCESS_W ) == PCILIB_REGISTER_W)
+        PyList_Append(modes, PyString_FromString("W"));
+    if((listItem.mode & PCILIB_ACCESS_RW ) == PCILIB_REGISTER_RW)
+        PyList_Append(modes, PyString_FromString("RW"));
+    if((listItem.mode & PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK)
+        PyList_Append(modes, PyString_FromString("NO_CHK"));
+
+    PyDict_SetItem(pylistItem,
+                   PyString_FromString("mode"),
+                   modes);
+
+    //serialize flags
+    PyObject* flags = PyList_New(0);
+
+    if((listItem.flags & PCILIB_LIST_FLAG_CHILDS ) == PCILIB_LIST_FLAG_CHILDS)
+        PyList_Append(flags, PyString_FromString("childs"));
+
+    PyDict_SetItem(pylistItem,
+                   PyString_FromString("flags"),
+                   flags);
+
+    if(listItem.unit)
+         PyDict_SetItem(pylistItem,
+                    PyString_FromString("unit"),
+                    PyString_FromString(listItem.unit));
+
+    return pylistItem;
+}
+
+PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listItem)
+{
+    PyObject* pylistItem = PyDict_New();
+
+    if(listItem.name)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("name"),
+                   PyString_FromString(listItem.name));
+
+    if(listItem.description)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("description"),
+                   PyString_FromString(listItem.description));
+
+   if(listItem.bank)
+        PyDict_SetItem(pylistItem,
+                   PyString_FromString("bank"),
+                   PyString_FromString(listItem.bank));
+
+    //serialize modes
+    PyObject* modes = PyList_New(0);
+
+    if((listItem.mode & PCILIB_REGISTER_R) == PCILIB_REGISTER_R)
+        PyList_Append(modes, PyString_FromString("R"));
+    if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W)
+        PyList_Append(modes, PyString_FromString("W"));
+    if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW)
+        PyList_Append(modes, PyString_FromString("RW"));
+    if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C)
+        PyList_Append(modes, PyString_FromString("W1C"));
+    if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C)
+        PyList_Append(modes, PyString_FromString("RW1C"));
+    if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I)
+        PyList_Append(modes, PyString_FromString("W1I"));
+    if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I)
+        PyList_Append(modes, PyString_FromString("RW1I"));
+    if((listItem.mode & PCILIB_REGISTER_NO_CHK) == PCILIB_REGISTER_NO_CHK)
+        PyList_Append(modes, PyString_FromString("NO_CHK"));
+
+    PyDict_SetItem(pylistItem,
+                   PyString_FromString("mode"),
+                   modes);
+    add_pcilib_value_to_dict(pylistItem, &listItem.defvalue, "defvalue");
+
+    if(listItem.range)
+    {
+        PyObject* range = PyDict_New();
+        add_pcilib_value_to_dict(range, &(listItem.range->min), "min");
+        add_pcilib_value_to_dict(range, &(listItem.range->max), "max");
+        PyDict_SetItem(pylistItem,
+                       PyString_FromString("range"),
+                       range);
+    }
+
+    if(listItem.values)
+    {
+        PyObject* values = PyList_New(0);
+
+        for (int j = 0; listItem.values[j].name; j++)
+        {
+            PyObject* valuesItem = PyDict_New();
+
+            add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].value), "value");
+            add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].min), "min");
+            add_pcilib_value_to_dict(valuesItem, &(listItem.values[j].max), "max");
+
+            if(listItem.values[j].name)
+                PyDict_SetItem(valuesItem,
+                           PyString_FromString("name"),
+                           PyString_FromString(listItem.values[j].name));
+
+            if(listItem.values[j].description)
+                PyDict_SetItem(valuesItem,
+                           PyString_FromString("name"),
+                           PyString_FromString(listItem.values[j].description));
+
+            PyList_Append(values, valuesItem);
+        }
+
+        PyDict_SetItem(pylistItem,
+                       PyString_FromString("values"),
+                       values);
+    }
+
+    return pylistItem;
+}
+
+PyObject* get_register_list(const char *bank)
+{
+	if(!__ctx)
+	{
+        __setPyExeptionText("pcilib_t handler not initialized");
+		return NULL;
+	}
+	
+	pcilib_register_info_t *list = pcilib_get_register_list(__ctx, bank, PCILIB_LIST_FLAGS_DEFAULT);
+	
+	PyObject* pyList = PyList_New(0);
+    for(int i = 0; i < __ctx->num_reg; i++)
+    {
+		//serialize item attributes
+        PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(list[i]);
+        PyList_Append(pyList, pylistItem);
+    }
+    
+    pcilib_free_register_info(__ctx, list);
+	
+	return pyList;
+}
+
+PyObject* get_register_info(const char* reg,const char *bank)
+{
+    if(!__ctx)
+    {
+        __setPyExeptionText("pcilib_t handler not initialized");
+        return NULL;
+    }
+
+    pcilib_register_info_t *info = pcilib_get_register_info(__ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT);
+
+	if(!info)
+	{
+		__setPyExeptionText("Failed pcilib_get_register_info");
+        return NULL;
+	}
+
+    PyObject* py_info = pcilib_convert_register_info_to_pyobject(info[0]);
+
+    pcilib_free_register_info(__ctx, info);
+
+    return py_info;
+}
+
+PyObject* get_property_info(const char* branch)
+{
+    if(!__ctx)
+    {
+        __setPyExeptionText("pcilib_t handler not initialized");
+        return NULL;
+    }
+
+    pcilib_property_info_t *list = pcilib_get_property_list(__ctx, branch, PCILIB_LIST_FLAGS_DEFAULT);
+
+    PyObject* pyList = PyList_New(0);
+
+    for(int i = 0; i < list[i].path; i++)
+    {
+        //serialize item attributes
+        PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(list[i]);
+        PyList_Append(pyList, pylistItem);
+    }
+
+    pcilib_free_property_info(__ctx, list);
+
+    return pyList;
+}

+ 10 - 2
pcilib/pcipywrap.i

@@ -1,10 +1,18 @@
 %module pcipywrap
 
-extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL);
-extern PyObject* __setPcilib(PyObject* addr);
+
+extern PyObject* createPcilibInstance(const char *fpga_device, const char *model = NULL);
+extern PyObject* setPcilib(PyObject* addr);
+extern void closeCurrentPcilibInstance();
+extern PyObject* getCurrentPcilibInstance();
 
 extern PyObject* read_register(const char *regname, const char *bank = NULL);
 extern PyObject* write_register(PyObject* val, const char *regname, const char *bank = NULL);
 
 extern PyObject* get_property(const char *prop);
 extern PyObject* set_property(const char *prop, PyObject* val);
+
+extern PyObject* get_register_list(const char *bank = NULL);
+extern PyObject* get_register_info(const char* reg,const char *bank = NULL);
+
+extern PyObject* get_property_info(const char* branch = NULL);

+ 183 - 4
pcilib/py.c

@@ -16,11 +16,18 @@ struct pcilib_py_s {
     PyObject *global_dict;
 };
 
+struct pcilib_script_s {
+    PyObject *py_script_module;	/**< PyModule object, contains script enviroment */
+	PyObject *dict;
+	char* script_name;
+};
+
 int pcilib_init_py(pcilib_t *ctx) {
     ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t));
     if (!ctx->py) return PCILIB_ERROR_MEMORY;
 
-    Py_Initialize();
+    if(!Py_IsInitialized())
+        Py_Initialize();
 
     ctx->py->main_module = PyImport_AddModule("__parser__");
     if (!ctx->py->main_module)
@@ -35,12 +42,11 @@ int pcilib_init_py(pcilib_t *ctx) {
 
 void pcilib_free_py(pcilib_t *ctx) {
     if (ctx->py) {
-	    // Dict and module references are borrowed
+        // Dict and module references are borrowed
         free(ctx->py);
         ctx->py = NULL;
     }
-
-    Py_Finalize();
+    //Py_Finalize();
 }
 
 /*
@@ -189,3 +195,176 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va
     pcilib_debug(VIEWS, "Evaluating a Python string \'%s\' to %lf=\'%s\'", codestr, PyFloat_AsDouble(obj), code);
     return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj));
 }
+
+
+int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode)
+{
+	int err;
+	
+	//Initialize python script, if it has not initialized already.
+	if(!module_name)
+	{
+		pcilib_error("Invalid script name specified in XML property (NULL)");
+		return PCILIB_ERROR_INVALID_DATA;
+	}
+	
+	//create path string to scripts
+	char* model_dir = getenv("PCILIB_MODEL_DIR");
+	char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2);
+	if (!model_path) return PCILIB_ERROR_MEMORY;
+	sprintf(model_path, "%s/%s", model_dir, ctx->model);
+	
+	//set model path to python
+	PySys_SetPath(model_path);
+	free(model_path);
+	model_path = NULL;
+	
+	//create path string to pcipywrap library
+	char* app_dir = getenv("APP_PATH");
+	char* pcipywrap_path;
+	if(app_dir)
+	{
+		pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib"));
+		if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
+		sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model);
+	}
+	else
+	{
+		pcipywrap_path = malloc(strlen("./pcilib"));
+		if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
+		sprintf(pcipywrap_path, "%s", "./pcilib");
+
+	}
+	
+	//set pcipywrap library path to python
+	PyObject* path = PySys_GetObject("path");
+	if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1)
+	{
+		pcilib_error("Cant set pcipywrap library path to python.");
+		return PCILIB_ERROR_FAILED;
+	}
+	free(pcipywrap_path);
+	pcipywrap_path = NULL;
+	
+	
+	//extract module name from script name
+	char* py_module_name = strtok(module_name, ".");
+	
+	if(!py_module_name)
+	{
+		pcilib_error("Invalid script name specified in XML property (%s)."
+					 " Seems like name doesnt contains extension", module_name);
+		return PCILIB_ERROR_INVALID_DATA;
+	}
+	
+	//import python script
+	PyObject* py_script_module = PyImport_ImportModule(py_module_name);
+	
+	if(!py_script_module)
+	{
+		printf("Error in import python module: ");
+		PyErr_Print();
+		return PCILIB_ERROR_INVALID_DATA;
+	}
+
+
+	//Initializing pcipywrap module if script use it
+	PyObject* dict = PyModule_GetDict(py_script_module);
+	if(PyDict_Contains(dict, PyString_FromString("pcipywrap")))
+	{
+		PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap");
+		if(!pcipywrap_module)
+		{
+			pcilib_error("Cant extract pcipywrap module from script dictionary");
+			return PCILIB_ERROR_FAILED;
+		}
+	   
+	   //setting pcilib_t instance                 
+	   PyObject_CallMethodObjArgs(pcipywrap_module,
+							   PyUnicode_FromString("setPcilib"),
+							   PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)),
+							   NULL);
+	}
+	
+	//Success. Create struct and initialize values
+	module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t));
+	module[0]->py_script_module = py_script_module;
+	module[0]->script_name = module_name;
+	module[0]->dict = dict;
+	
+	//Setting correct mode
+	mode[0] = 0;
+	if(PyDict_Contains(dict, PyString_FromString("read_from_register")))
+		mode[0] |= PCILIB_ACCESS_R;	
+	if(PyDict_Contains(dict, PyString_FromString("write_to_register")))
+		mode[0] |= PCILIB_ACCESS_W;
+	
+	return 0;
+}
+
+int pcilib_free_py_script(pcilib_script_t *module)
+{
+	if(module)
+	{
+		if(module->script_name)
+		{
+			free(module->script_name);
+			module->script_name = NULL;
+		}
+		
+		if(module->py_script_module)
+		{
+			//PyObject_Free(module->py_script_module);
+			module->py_script_module = NULL;
+		}
+	}
+}
+
+int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val)
+{
+	
+	int err;
+	
+	PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()");
+	if (!ret) 
+	{
+	   printf("Python script error: ");
+	   PyErr_Print();
+	   return PCILIB_ERROR_FAILED;
+	}
+	
+	err = pcilib_convert_pyobject_to_val(ctx, ret, val);
+	
+	if(err)
+	{
+		pcilib_error("Failed to convert python script return value to internal type: %i", err);
+		return err;
+	}
+    return 0;
+}
+
+int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val)
+{
+	int err;
+		
+	PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf);
+	if(!input)
+	{
+	   printf("Failed to convert input value to Python object");
+	   PyErr_Print();
+	   return PCILIB_ERROR_FAILED;
+	}
+	
+	PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module,
+											   PyUnicode_FromString("write_to_register"),
+											   input,
+											   NULL);
+	if (!ret) 
+	{
+	   printf("Python script error: ");
+	   PyErr_Print();
+	   return PCILIB_ERROR_FAILED;
+	}
+
+    return 0;
+}

+ 9 - 0
pcilib/py.h

@@ -1,7 +1,10 @@
 #ifndef _PCILIB_PY_H
 #define _PCILIB_PY_H
 
+#include "pcilib.h"
+
 typedef struct pcilib_py_s pcilib_py_t;
+typedef struct pcilib_script_s pcilib_script_t;
 
 #ifdef __cplusplus
 extern "C" {
@@ -11,6 +14,12 @@ int pcilib_init_py(pcilib_t *ctx);
 int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value);
 void pcilib_free_py(pcilib_t *ctx);
 
+
+int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode);
+int pcilib_free_py_script(pcilib_script_t *module);
+int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val);
+int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val);
+
 #ifdef __cplusplus
 }
 #endif

+ 29 - 15
pcilib/xml.c

@@ -42,7 +42,7 @@
 #include "view.h"
 #include "views/enum.h"
 #include "views/transform.h"
-#include "views/script.h"
+#include "py.h"
 
 
 #define BANKS_PATH ((xmlChar*)"/model/bank")					/**< path to complete nodes of banks */
@@ -559,15 +559,15 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath
     xmlAttrPtr cur;
     const char *value, *name;
     pcilib_view_context_t *view_ctx;
+    
 
-    pcilib_access_mode_t mode = PCILIB_REGISTER_NO_CHK;
-    pcilib_script_view_description_t desc = {{0}};
+    pcilib_access_mode_t mode = 0;
+    pcilib_transform_view_description_t desc = {{0}};
 
-    desc.base.api = &pcilib_script_view_api;
+    desc.base.api = &pcilib_transform_view_api;
     desc.base.type = PCILIB_TYPE_DOUBLE;
     desc.base.mode = PCILIB_ACCESS_RW;
-    desc.py_script_module = NULL;
-    desc.script_name = NULL;
+    desc.script = NULL;
 
     err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
     if (err) return err;
@@ -580,14 +580,16 @@ static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath
         value = (char*)cur->children->content;
         if (!value) continue;
 
-        if (!strcasecmp(name, "script")) {
+        if (!strcasecmp(name, "script")) 
+        {
 			//write script name to struct
-			desc.script_name = malloc(strlen(value));
-			sprintf(desc.script_name, "%s", value);
-			//set read write access
-			mode |= PCILIB_ACCESS_R;
-			mode |= PCILIB_ACCESS_W;
-            }
+			char* script_name = malloc(strlen(value));
+			sprintf(script_name, "%s", value);
+			
+			err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode);
+			if(err) return err;
+			mode |= PCILIB_REGISTER_NO_CHK;
+        }
     }
     
     desc.base.mode &= mode;
@@ -611,6 +613,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
     desc.base.api = &pcilib_transform_view_api;
     desc.base.type = PCILIB_TYPE_DOUBLE;
     desc.base.mode = PCILIB_ACCESS_RW;
+    desc.script = NULL;
 
     err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
     if (err) return err;
@@ -641,7 +644,15 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
             }
             desc.write_to_reg = value;
             if ((value)&&(*value)) mode |= PCILIB_ACCESS_W;
-        } 
+        } else if (!strcasecmp(name, "script")) {
+			char* script_name = malloc(strlen(value));
+			sprintf(script_name, "%s", value);
+			
+			err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode);
+			if(err) return err;
+			mode |= PCILIB_REGISTER_NO_CHK;
+			break;
+        }
     }
 
     desc.base.mode &= mode;
@@ -654,6 +665,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp
 }
 
 static int pcilib_xml_create_script_or_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+    /*
     int err;
     xmlAttrPtr cur;
     const char *name;
@@ -688,9 +700,11 @@ static int pcilib_xml_create_script_or_transform_view(pcilib_t *ctx, xmlXPathCon
     }
 
     if(has_script)
+    
         return pcilib_xml_create_script_view(ctx, xpath, doc, node);
     else
-        return pcilib_xml_create_transform_view(ctx, xpath, doc, node);
+    */
+       return pcilib_xml_create_transform_view(ctx, xpath, doc, node);
 }
 
 

+ 2 - 2
views/CMakeLists.txt

@@ -8,6 +8,6 @@ include_directories(
     ${UTHASH_INCLUDE_DIRS}
 )
 
-set(HEADERS ${HEADERS} enum.h transform.h register.h script.h)
+set(HEADERS ${HEADERS} enum.h transform.h register.h)
 
-add_library(views STATIC enum.c transform.c register.c script.c)
+add_library(views STATIC enum.c transform.c register.c)

+ 0 - 206
views/script.c

@@ -1,206 +0,0 @@
-#define _PCILIB_VIEW_TRANSFORM_C
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pci.h"
-#include "pcipywrap.h"
-#include "error.h"
-
-#include "model.h"
-#include "script.h"
-
-static int pcilib_script_view_module_init(pcilib_t *ctx, pcilib_script_view_description_t *v)
-{
-	int err;
-	
-	//Initialize python script, if it has not initialized already.
-	if(!v->py_script_module)
-	{
-		if(!v->script_name)
-		{
-			pcilib_error("Invalid script name specified in XML property (NULL)");
-			return PCILIB_ERROR_INVALID_DATA;
-		}
-		
-		//create path string to scripts
-		char* model_dir = getenv("PCILIB_MODEL_DIR");
-		char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2);
-		if (!model_path) return PCILIB_ERROR_MEMORY;
-		sprintf(model_path, "%s/%s", model_dir, ctx->model);
-		
-		//set model path to python
-		PySys_SetPath(model_path);
-		free(model_path);
-		model_path = NULL;
-		
-		//create path string to pcipywrap library
-		char* app_dir = getenv("APP_PATH");
-		char* pcipywrap_path;
-		if(app_dir)
-		{
-			pcipywrap_path = malloc(strlen(app_dir) + strlen("/pcilib"));
-			if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
-			sprintf(pcipywrap_path, "%s/%s", "/pcilib", ctx->model);
-		}
-		else
-		{
-			pcipywrap_path = malloc(strlen("./pcilib"));
-			if (!pcipywrap_path) return PCILIB_ERROR_MEMORY;
-			sprintf(pcipywrap_path, "%s", "./pcilib");
-	
-		}
-		
-		//set pcipywrap library path to python
-		PyObject* path = PySys_GetObject("path");
-		if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1)
-		{
-			pcilib_error("Cant set pcipywrap library path to python.");
-			return PCILIB_ERROR_FAILED;
-		}
-		free(pcipywrap_path);
-		pcipywrap_path = NULL;
-		
-		
-		//extract module name from script name
-		char* py_module_name = strtok(v->script_name, ".");
-		
-		if(!py_module_name)
-		{
-			pcilib_error("Invalid script name specified in XML property (%s)."
-						 " Seems like name doesnt contains extension", v->script_name);
-			return PCILIB_ERROR_INVALID_DATA;
-		}
-		
-		//import python script
-		v->py_script_module = PyImport_ImportModule(py_module_name);
-		
-		if(!v->py_script_module)
-		{
-			printf("Error in import python module: ");
-			PyErr_Print();
-			return PCILIB_ERROR_INVALID_DATA;
-		}
-	}
-	
-	//Initializing pcipywrap module if script use it
-	PyObject* dict = PyModule_GetDict(v->py_script_module);
-	if(PyDict_Contains(dict, PyString_FromString("pcipywrap")))
-	{
-		PyObject* pcipywrap_module = PyDict_GetItemString(dict, "pcipywrap");
-		if(!pcipywrap_module)
-		{
-			pcilib_error("Cant extract pcipywrap module from script dictionary");
-			return PCILIB_ERROR_FAILED;
-		}
-       
-       //setting pcilib_t instance                 
-	   PyObject_CallMethodObjArgs(pcipywrap_module,
-                               PyUnicode_FromString("__setPcilib"),
-                               PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)),
-                               NULL);
-	}
-	
-	return 0;
-}
-
-static int pcilib_script_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) {
-	
-	int err;
-
-    const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(model_info->views[view_ctx->view]);
-	
-	err = pcilib_script_view_module_init(ctx, v);
-	if(err)
-		return err;
-	
-	PyObject *ret = PyObject_CallMethod(v->py_script_module, "read_from_register", "()");
-	if (!ret) 
-	{
-	   printf("Python script error: ");
-	   PyErr_Print();
-	   return PCILIB_ERROR_FAILED;
-	}
-	
-	err = pcilib_convert_pyobject_to_val(ctx, ret, val);
-	
-	if(err)
-	{
-		pcilib_error("Failed to convert python script return value to internal type: %i", err);
-		return err;
-	}
-    return 0;
-}
-
-static int pcilib_script_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, pcilib_value_t *val) {
-	
-	int err;
-
-    const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
-    pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(model_info->views[view_ctx->view]);
-	
-	err = pcilib_script_view_module_init(ctx, v);
-	if(err)
-		return err;
-		
-	PyObject *input = pcilib_convert_val_to_pyobject(ctx, val, printf);
-	if(!input)
-	{
-	   printf("Failed to convert input value to Python object");
-	   PyErr_Print();
-	   return PCILIB_ERROR_FAILED;
-	}
-	
-	PyObject *ret = PyObject_CallMethodObjArgs(v->py_script_module,
-											   PyUnicode_FromString("write_to_register"),
-											   input,
-											   NULL);
-	if (!ret) 
-	{
-	   printf("Python script error: ");
-	   PyErr_Print();
-	   return PCILIB_ERROR_FAILED;
-	}
-	
-	//convert output value back to pcilib_value_t
-	//no need because it wont be used later, and the script return could be none
-	/*
-	err = pcilib_convert_pyobject_to_val(ctx, ret, val);
-	if(err)
-	{
-		pcilib_error("failed to convert script write_to_register function return value to internal type: %i", err);
-		return err;
-	}
-	
-	uint64_t output = pcilib_get_value_as_register_value(ctx, val, &err);
-	if(err)
-	{
-		pcilib_error("failed to convert value to register value (%i)", err);
-		return err;
-	}
-	regval[0] = output;
-	*/
-
-    return 0;
-}
-
-void pcilib_script_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view)
-{
-	pcilib_script_view_description_t *v = (pcilib_script_view_description_t*)(view);
-	
-	if(v->script_name)
-	{
-		free(v->script_name);
-		v->script_name = NULL;
-	}
-	
-	if(v->py_script_module)
-	{
-		PyObject_Free(v->py_script_module);
-		v->py_script_module = NULL;
-	}
-}
-
-const pcilib_view_api_description_t pcilib_script_view_api =
-  { PCILIB_VERSION, sizeof(pcilib_script_view_description_t), NULL, NULL, pcilib_script_view_free_description, pcilib_script_view_read, pcilib_script_view_write};

+ 0 - 18
views/script.h

@@ -1,18 +0,0 @@
-#ifndef _PCILIB_VIEW_SCRIPT_H
-#define _PCILIB_VIEW_SCRIPT_H
-
-#include <pcilib.h>
-#include <pcilib/view.h>
-#include <Python.h>
-
-typedef struct {
-    pcilib_view_description_t base;
-    PyObject *py_script_module;	/**< PyModule object, contains script enviroment */
-	char* script_name;
-} pcilib_script_view_description_t;
-
-#ifndef _PCILIB_VIEW_SCRIPT_C
-const pcilib_view_api_description_t pcilib_script_view_api;
-#endif /* _PCILIB_VIEW_SCRIPT_C */
-
-#endif /* _PCILIB_VIEW_SCRIPT_H */

+ 38 - 14
views/transform.c

@@ -12,34 +12,58 @@
 
 
 static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) {
-    int err;
-
     const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
     pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]);
 
-    err = pcilib_set_value_from_register_value(ctx, val, regval);
-    if (err) return err;
+	if(v->script)
+	{
+		return pcilib_script_read(ctx, v->script, val);
+	}
+	else
+	{
+		int err;
+		
+		err = pcilib_set_value_from_register_value(ctx, val, regval);
+		if (err) return err;
 
-    return  pcilib_py_eval_string(ctx, v->read_from_reg, val);
+		return  pcilib_py_eval_string(ctx, v->read_from_reg, val);
+	}
 }
 
 static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, const pcilib_value_t *val) {
-    int err = 0;
-    pcilib_value_t val_copy = {0};
+    
+    
 
     const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
     pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]);
 
-    err = pcilib_copy_value(ctx, &val_copy, val);
-    if (err) return err;
 
-    err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
-    if (err) return err;
+	if(!v->script)
+	{
+		int err = 0;
+		
+		pcilib_value_t val_copy = {0};
+		err = pcilib_copy_value(ctx, &val_copy, val);
+		if (err) return err;
+
+		err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy);
+		if (err) return err;
+
+		*regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err);
+		return err;
+	}
+	else
+		pcilib_script_write(ctx, v->script, val);
+}
 
-    *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err);
-    return err;
+void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view)
+{
+	pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view);
+	
+	if(v->script)
+		pcilib_free_py_script(v->script);
 }
 
 
 const pcilib_view_api_description_t pcilib_transform_view_api =
-  { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, NULL, pcilib_transform_view_read,  pcilib_transform_view_write };
+  { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read,  pcilib_transform_view_write };

+ 2 - 0
views/transform.h

@@ -3,11 +3,13 @@
 
 #include <pcilib.h>
 #include <pcilib/view.h>
+#include <py.h>
 
 typedef struct {
     pcilib_view_description_t base;
     const char *read_from_reg;			/**< Formula explaining how to convert the register value to the view value */
     const char *write_to_reg;			/**< Formula explaining how to convert from the view value to the register value */
+	pcilib_script_t *script;
 } pcilib_transform_view_description_t;
 
 #ifndef _PCILIB_VIEW_TRANSFORM_C