summaryrefslogtreecommitdiffstats
path: root/pcilib
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-02-05 12:33:48 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-02-05 12:33:48 +0100
commit5349163e93a107fdfea2ad58760f6149a8d749b0 (patch)
tree84afe1008bac52a00785ba71f415ae51b1b9c768 /pcilib
parent99c165c078222c789d5fc90a79c756c8fffdafea (diff)
downloadpcitool-5349163e93a107fdfea2ad58760f6149a8d749b0.tar.gz
pcitool-5349163e93a107fdfea2ad58760f6149a8d749b0.tar.bz2
pcitool-5349163e93a107fdfea2ad58760f6149a8d749b0.tar.xz
pcitool-5349163e93a107fdfea2ad58760f6149a8d749b0.zip
Add support for python script properties. Correct pcilib python wrapping. Update examples. Update cmakelists for work in shadow build mode.
Diffstat (limited to 'pcilib')
-rw-r--r--pcilib/CMakeLists.txt1
-rw-r--r--pcilib/pcipywrap.c271
-rw-r--r--pcilib/pcipywrap.i9
-rw-r--r--pcilib/py.c1
-rw-r--r--pcilib/xml.c65
5 files changed, 168 insertions, 179 deletions
diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt
index ea275a3..db74775 100644
--- a/pcilib/CMakeLists.txt
+++ b/pcilib/CMakeLists.txt
@@ -24,7 +24,6 @@ SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c)
SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES})
-#wrapping end
install(TARGETS pcilib
LIBRARY DESTINATION lib${LIB_SUFFIX}
diff --git a/pcilib/pcipywrap.c b/pcilib/pcipywrap.c
index 5abd56c..efce909 100644
--- a/pcilib/pcipywrap.c
+++ b/pcilib/pcipywrap.c
@@ -1,190 +1,125 @@
#include "pcilib.h"
-
-//Remove unused headers
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <alloca.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <pthread.h>
-#include <signal.h>
-#include <dlfcn.h>
-
-#include <getopt.h>
-
-#include <fastwriter.h>
-
-#include "pcitool/sysinfo.h"
-#include "pcitool/formaters.h"
-
-#include "views/transform.h"
-#include "views/enum.h"
+#include <Python.h>
#include "pci.h"
-#include "plugin.h"
-#include "config.h"
-#include "tools.h"
-#include "kmem.h"
#include "error.h"
-#include "debug.h"
-#include "model.h"
-#include "locking.h"
+/*!
+ * \brief Global pointer to pcilib_t context.
+ * Used by __setPcilib and read_register.
+ */
pcilib_t* __ctx = 0;
-pcilib_model_description_t *model_info = 0;
/*!
- * \brief присваивание указателя на устройство. Закрытая функция. Будет проходить при парсинге xml.
- * \param ctx
+ * \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
*/
-void __initCtx(void* ctx)
+PyObject* __createPcilibInstance(const char *fpga_device, const char *model)
{
- __ctx = ctx;
+ //opening device
+ pcilib_t* ctx = pcilib_open(fpga_device, model);
+
+ //serializing object
+ return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*));
}
/*!
- * \brief создание хэндлера устройства, для тестирования скрипта не из программы.
- * \return
+ * \brief Sets pcilib context to wraper.
+ * \param[in] addr Pointer to pcilib_t, serialized to bytearray
*/
-void __createCtxInstance(const char *fpga_device, const char *model)
+void __setPcilib(PyObject* addr)
{
- __ctx = pcilib_open(fpga_device, model);
- model_info = pcilib_get_model_description(__ctx);
-}
-
-int read_register(const char *bank, const char *regname, void *value)
-{
- int ret = pcilib_read_register(__ctx, bank, regname, (pcilib_register_value_t*)value);
- return ret;
-}
-
-void Error(const char *message, const char *attr, ...)
-{
- printf("Catch error: %s, %s\n", message, attr);
+ if(!PyByteArray_Check(addr))
+ {
+ PyErr_SetString(PyExc_Exception, "Incorrect addr type. Only bytearray is allowed");
+ return NULL;
+ }
+
+ //deserializing adress
+ char* pAddr = PyByteArray_AsString(addr);
+
+ //hard copy context adress
+ for(int i = 0; i < sizeof(pcilib_t*) + 10; i++)
+ ((char*)&__ctx)[i] = pAddr[i];
+
+ free(pAddr);
}
-int ReadRegister(const char *bank, const char *reg) {
+/*!
+ * \brief Reads register value.
+ * \param[in] regname the name of the register
+ * \param[in] bank should specify the bank name if register with the same name may occur in multiple banks, NULL otherwise
+ * \return register value, can be integer or float type
+ */
+PyObject* read_register(const char *regname, const char *bank)
+{
+ if(!__ctx)
+ {
+ PyErr_SetString(PyExc_Exception, "pcilib_t handler not initialized");
+ return NULL;
+ }
- const char *view = NULL;
- const char *unit = NULL;
- const char *attr = NULL;
- pcilib_t *handle = __ctx;
- int i;
- int err;
- const char *format;
-
- pcilib_register_bank_t bank_id;
- pcilib_register_bank_addr_t bank_addr = 0;
-
- pcilib_register_value_t value;
-
- // Adding DMA registers
- pcilib_get_dma_description(handle);
-
- if (reg||view||attr) {
- pcilib_value_t val = {0};
- if (attr) {
- if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val);
- else if (view) err = pcilib_get_property_attr(handle, view, attr, &val);
- else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val);
- else err = PCILIB_ERROR_INVALID_ARGUMENT;
-
- if (err) {
- if (err == PCILIB_ERROR_NOTFOUND)
- Error("Attribute %s is not found", attr);
- else
- Error("Error (%i) reading attribute %s", err, attr);
- }
-
- err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
- if (err) Error("Error converting attribute %s to string", attr);
-
- printf("%s = %s", attr, val.sval);
- if ((val.unit)&&(strcasecmp(val.unit, "name")))
- printf(" %s", val.unit);
- printf(" (for %s)\n", (reg?reg:(view?view:bank)));
- } else if (view) {
- if (reg) {
- err = pcilib_read_register_view(handle, bank, reg, view, &val);
- if (err) Error("Error reading view %s of register %s", view, reg);
- } else {
- err = pcilib_get_property(handle, view, &val);
- if (err) Error("Error reading property %s", view);
- }
-
- if (unit) {
- err = pcilib_convert_value_unit(handle, &val, unit);
- if (err) {
- if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit);
- else Error("Error converting property %s to unit %s", view, unit);
- }
- }
-
- err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
- if (err) {
- if (reg) Error("Error converting view %s of register %s to string", view);
- else Error("Error converting property %s to string", view);
- }
-
- printf("%s = %s", (reg?reg:view), val.sval);
- if ((val.unit)&&(strcasecmp(val.unit, "name")))
- printf(" %s", val.unit);
- printf("\n");
- } else {
- pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
- bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank);
- format = model_info->banks[bank_id].format;
- if (!format) format = "%lu";
- err = pcilib_read_register_by_id(handle, regid, &value);
- if (err) Error("Error reading register %s", reg);
-
- printf("%s = ", reg);
- printf(format, value);
- printf("\n");
+ pcilib_get_dma_description(__ctx);
+
+ pcilib_value_t val = {0};
+ pcilib_register_value_t reg_value;
+
+ int err;
+
+ err = pcilib_read_register(__ctx, bank, regname, &reg_value);
+ if(err)
+ {
+ PyErr_SetString(PyExc_Exception, "Failed: read_register");
+ return NULL;
+ }
+
+ err = pcilib_set_value_from_register_value(__ctx, &val, reg_value);
+
+ if(err)
+ {
+ PyErr_SetString(PyExc_Exception, "Failed: pcilib_set_value_from_register_value");
+ return NULL;
}
- } else {
- if (model_info->registers) {
- if (bank) {
- bank_id = pcilib_find_register_bank(handle, bank);
- bank_addr = model_info->banks[bank_id].addr;
- }
-
- printf("Registers:\n");
- for (i = 0; model_info->registers[i].bits; i++) {
- if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) {
- bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank);
- format = model_info->banks[bank_id].format;
- if (!format) format = "%lu";
-
- err = pcilib_read_register_by_id(handle, i, &value);
- if (err) printf(" %s = error reading value", model_info->registers[i].name);
- else {
- printf(" %s = ", model_info->registers[i].name);
- printf(format, value);
- }
- printf(" [");
- printf(format, model_info->registers[i].defvalue);
- printf("]");
- printf("\n");
+ switch(val.type)
+ {
+ case PCILIB_TYPE_INVALID:
+ PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_INVALID)");
+ return NULL;
+
+ case PCILIB_TYPE_STRING:
+ PyErr_SetString(PyExc_Exception, "Invalid register output type (PCILIB_TYPE_STRING)");
+ return NULL;
+
+ case PCILIB_TYPE_LONG:
+ {
+ long ret;
+ ret = pcilib_get_value_as_int(__ctx, &val, &err);
+
+ if(err)
+ {
+ PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int");
+ return NULL;
+ }
+ return PyInt_FromLong((long) ret);
}
- }
- } else {
- printf("No registers");
+
+ case PCILIB_TYPE_DOUBLE:
+ {
+ double ret;
+ ret = pcilib_get_value_as_float(__ctx, &val, &err);
+
+ if(err)
+ {
+ PyErr_SetString(PyExc_Exception, "Failed: pcilib_get_value_as_int");
+ return NULL;
+ }
+ return PyFloat_FromDouble((double) ret);
+ }
+
+ default:
+ PyErr_SetString(PyExc_Exception, "Invalid register output type (unknown)");
+ return NULL;
}
- printf("\n");
- }
-
- return 0;
}
diff --git a/pcilib/pcipywrap.i b/pcilib/pcipywrap.i
index fc7f4ef..ed5ca62 100644
--- a/pcilib/pcipywrap.i
+++ b/pcilib/pcipywrap.i
@@ -1,6 +1,5 @@
%module pcipywrap
-/*extern void* __ctx;*/
-extern void __initCtx(void* ctx);
-extern void __createCtxInstance(const char *fpga_device, const char *model);
-extern int read_register(const char *bank, const char *regname, void *value);
-extern int ReadRegister(const char *reg);
+
+extern PyObject* read_register(const char *regname, const char *bank = NULL);
+extern PyObject* __createPcilibInstance(const char *fpga_device, const char *model = NULL);
+extern void __setPcilib(PyObject* addr);
diff --git a/pcilib/py.c b/pcilib/py.c
index 4256afc..13113d7 100644
--- a/pcilib/py.c
+++ b/pcilib/py.c
@@ -5,7 +5,6 @@
#include <string.h>
#include <strings.h>
-
#include "pci.h"
#include "debug.h"
#include "pcilib.h"
diff --git a/pcilib/xml.c b/pcilib/xml.c
index 50aaa35..76ed38c 100644
--- a/pcilib/xml.c
+++ b/pcilib/xml.c
@@ -42,17 +42,19 @@
#include "view.h"
#include "views/enum.h"
#include "views/transform.h"
+#include "views/script.h"
#define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */
#define REGISTERS_PATH ((xmlChar*)"./register") /**< all standard registers nodes */
#define BIT_REGISTERS_PATH ((xmlChar*)"./field") /**< all bits registers nodes */
#define REGISTER_VIEWS_PATH ((xmlChar*)"./view") /**< supported register & field views */
-#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */
+#define TRANSFORM_VIEWS_PATH ((xmlChar*)"/model/transform") /**< path to complete nodes of views */
+#define SCRIPT_VIEWS_PATH ((xmlChar*)"/model/script") /**< path to complete nodes of views */
#define ENUM_VIEWS_PATH ((xmlChar*)"/model/enum") /**< path to complete nodes of views */
#define ENUM_ELEMENTS_PATH ((xmlChar*)"./name") /**< all elements in the enum */
#define UNITS_PATH ((xmlChar*)"/model/unit") /**< path to complete nodes of units */
-#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */
+#define UNIT_TRANSFORMS_PATH ((xmlChar*)"./transform") /**< all transforms of the unit */
@@ -543,6 +545,51 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc
return 0;
}
+static int pcilib_xml_create_script_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
+ int err;
+ xmlAttrPtr cur;
+ const char *value, *name;
+ pcilib_view_context_t *view_ctx;
+
+ pcilib_access_mode_t mode = 0;
+ pcilib_script_view_description_t desc = {{0}};
+
+ desc.base.api = &pcilib_script_view_api;
+ desc.base.type = PCILIB_TYPE_DOUBLE;
+ desc.base.mode = PCILIB_ACCESS_RW;
+ desc.py_script_module = NULL;
+ desc.script_name = NULL;
+
+ err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc);
+ if (err) return err;
+
+ for (cur = node->properties; cur != NULL; cur = cur->next) {
+ if (!cur->children) continue;
+ if (!xmlNodeIsText(cur->children)) continue;
+
+ name = (char*)cur->name;
+ value = (char*)cur->children->content;
+ if (!value) continue;
+
+ if (!strcasecmp(name, "script")) {
+ //write script name to struct
+ desc.script_name = malloc(strlen(value));
+ sprintf(desc.script_name, "%s", value);
+ //set read access
+ mode |= PCILIB_ACCESS_R;
+ }
+ }
+
+ desc.base.mode &= mode;
+
+ err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx);
+ if (err) return err;
+
+ view_ctx->xml = node;
+ return 0;
+}
+
+
static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {
int err;
xmlAttrPtr cur;
@@ -822,14 +869,16 @@ static int pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo
*/
static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathContextPtr xpath) {
int err;
- xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL;
+ xmlXPathObjectPtr bank_nodes = NULL, transform_nodes = NULL, enum_nodes = NULL, unit_nodes = NULL, script_nodes = NULL;
xmlNodeSetPtr nodeset;
int i;
bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath);
if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath);
- if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath);
+ if (transform_nodes) script_nodes = xmlXPathEvalExpression(SCRIPT_VIEWS_PATH, xpath);
+ if (script_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath);
if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath);
+
if (!unit_nodes) {
const unsigned char *expr = (enum_nodes?UNITS_PATH:(transform_nodes?ENUM_VIEWS_PATH:(bank_nodes?TRANSFORM_VIEWS_PATH:BANKS_PATH)));
@@ -850,6 +899,14 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon
if (err) pcilib_error("Error (%i) creating unit", err);
}
}
+
+ nodeset = script_nodes->nodesetval;
+ if(!xmlXPathNodeSetIsEmpty(nodeset)) {
+ for(i=0; i < nodeset->nodeNr; i++) {
+ err = pcilib_xml_create_script_view(ctx, xpath, doc, nodeset->nodeTab[i]);
+ if (err) pcilib_error("Error (%i) creating script transform", err);
+ }
+ }
nodeset = transform_nodes->nodesetval;
if (!xmlXPathNodeSetIsEmpty(nodeset)) {