From d7fc669bf0dbe37f46d2efec4940feb8504017c2 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Thu, 11 Feb 2016 14:24:01 +0100 Subject: Change no_set_check parameter name. Move Python wrap to separate directory. --- pywrap/CMakeLists.txt | 22 ++ pywrap/pcipywrap.c | 542 ++++++++++++++++++++++++++++++++++++++++++++++++++ pywrap/pcipywrap.i | 21 ++ pywrap/server.py | 184 +++++++++++++++++ 4 files changed, 769 insertions(+) create mode 100644 pywrap/CMakeLists.txt create mode 100644 pywrap/pcipywrap.c create mode 100644 pywrap/pcipywrap.i create mode 100644 pywrap/server.py (limited to 'pywrap') diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt new file mode 100644 index 0000000..e5f7ea7 --- /dev/null +++ b/pywrap/CMakeLists.txt @@ -0,0 +1,22 @@ +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/pcilib + ${CMAKE_BINARY_DIR}/pcilib + ${LIBXML2_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIR} + ${UTHASH_INCLUDE_DIRS} +) + +#Creating python wrapping +INCLUDE(${SWIG_USE_FILE}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) + +SET(CMAKE_SWIG_FLAGS "") + +SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") +SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c) +SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) + +configure_file(server.py server.py) diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c new file mode 100644 index 0000000..c5164a8 --- /dev/null +++ b/pywrap/pcipywrap.c @@ -0,0 +1,542 @@ +#include "pci.h" +#include "error.h" +#include + +/*! + * \brief Global pointer to pcilib_t context. + * Used by setPcilib and read_register. + */ +pcilib_t* __ctx = 0; + +/*! + * \brief Wraping for vsnprintf function, that saves string to char* + * \return saved from vsnprintf string + */ +char* vmake_str(const char* msg, va_list vl) +{ + char *buf; + size_t sz; + + va_list vl_copy; + va_copy(vl_copy, vl); + + sz = vsnprintf(NULL, 0, msg, vl); + buf = (char *)malloc(sz + 1); + + if(!buf) + { + return NULL; + } + + vsnprintf(buf, sz+1, msg, vl_copy); + va_end(vl_copy); + + return buf; +} + +/*! + * \brief Wraping for vsnprintf function, that saves string to char* + * \return saved from vsnprintf string + */ +char* make_str(const char* msg, ...) +{ + va_list vl; + va_start(vl, msg); + char *buf = vmake_str(msg, vl); + va_end(vl); + return buf; +} + +/*! + * \brief Version of pcilib_logger_t, that saves error text to Python exeption + */ +void pcilib_print_error_to_py(void *arg, const char *file, int line, + pcilib_log_priority_t prio, const char *msg, + va_list va) { + char* buf_raw_msg = vmake_str(msg, va); + char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); + + printf("%s", buf_wrapped_message); + PyErr_SetString(PyExc_Exception, buf_wrapped_message); + + free(buf_wrapped_message); + free(buf_raw_msg); +} + +/*! + * \brief Inits pcipywrap module at importing + */ +void init_pcipywrap_module() +{ + pcilib_set_logger(pcilib_get_logger_min_prio(), + pcilib_print_error_to_py, + pcilib_get_logger_argument()); +} + +/*! + * \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) + 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) +{ + if(!PyByteArray_Check(addr)) + { + pcilib_error("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]; + + return PyInt_FromLong((long)1); +} + + +/*! + * \brief Reads register value. Wrap for pcilib_read_register function. + * \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; NULL with exeption text, if failed. + */ +PyObject* read_register(const char *regname, const char *bank) +{ + if(!__ctx) + { + pcilib_error("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val = {0}; + pcilib_register_value_t reg_value; + + int err; + + err = pcilib_read_register(__ctx, bank, regname, ®_value); + if(err) + { + pcilib_error("Failed: pcilib_read_register (%i)", err); + return NULL; + } + + err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); + if(err) + { + pcilib_error("Failed: pcilib_set_value_from_register_value (%i)", err); + return NULL; + } + + return pcilib_convert_val_to_pyobject(__ctx, &val); +} + +/*! + * \brief Writes value to register. Wrap for pcilib_write_register function. + * \param[in] val Register value, that needs to be set. Can be int, float or string. + * \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 1, serialized to PyObject or NULL with exeption text, if failed. + */ +PyObject* write_register(PyObject* val, const char *regname, const char *bank) +{ + if(!__ctx) + { + pcilib_error("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val_internal = {0}; + pcilib_register_value_t reg_value; + + int err; + err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + if(err) + { + pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); + return NULL; + } + + reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); + if(err) + { + pcilib_error("Failed: pcilib_get_value_as_register_value (%i)", err); + return NULL; + } + + err = pcilib_write_register(__ctx, bank, regname, reg_value); + if(err) + { + pcilib_error("Failed: pcilib_write_register (%i)", err); + return NULL; + } + return PyInt_FromLong((long)1); +} + +/*! + * \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* get_property(const char *prop) +{ + if(!__ctx) + { + pcilib_error("pcilib_t handler not initialized"); + return NULL; + } + + int err; + pcilib_value_t val = {0}; + + err = pcilib_get_property(__ctx, prop, &val); + + if(err) + { + pcilib_error("Failed pcilib_get_property (%i)", err); + return NULL; + } + + return pcilib_convert_val_to_pyobject(__ctx, &val); +} + +/*! + * \brief Writes value to property. Wrap for pcilib_set_property function. + * \param[in] prop property name (full name including path) + * \param[in] val Property value, that needs to be set. Can be int, float or string. + * \return 1, serialized to PyObject or NULL with exeption text, if failed. + */ +PyObject* set_property(const char *prop, PyObject* val) +{ + int err; + + if(!__ctx) + { + pcilib_error("pcilib_t handler not initialized"); + return NULL; + } + + pcilib_value_t val_internal = {0}; + err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + if(err) + { + pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); + return NULL; + } + + err = pcilib_set_property(__ctx, prop, &val_internal); + + if(err) + { + pcilib_error("Failed pcilib_get_property (%i)", err); + return NULL; + } + + return PyInt_FromLong((long)1); +} + +void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) +{ + PyObject *py_val = (PyObject*)pcilib_convert_val_to_pyobject(__ctx, val); + + if(py_val) + PyDict_SetItem(dict, + PyString_FromString(name), + py_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_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) + 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_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) + PyList_Append(modes, PyString_FromString("NO_CHK")); + + PyDict_SetItem(pylistItem, + PyString_FromString("mode"), + modes); + + pcilib_value_t defval = {0}; + pcilib_set_value_from_register_value(__ctx, &defval, listItem.defvalue); + add_pcilib_value_to_dict(pylistItem, &defval, "defvalue"); + + if(listItem.range) + { + pcilib_value_t minval = {0}; + pcilib_set_value_from_register_value(__ctx, &minval, listItem.range->min); + + pcilib_value_t maxval = {0}; + pcilib_set_value_from_register_value(__ctx, &maxval, listItem.range->max); + + PyObject* range = PyDict_New(); + add_pcilib_value_to_dict(range, &minval, "min"); + add_pcilib_value_to_dict(range, &maxval, "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(); + + pcilib_value_t val = {0}; + pcilib_set_value_from_register_value(__ctx, &val, listItem.values[j].value); + + pcilib_value_t min = {0}; + pcilib_set_value_from_register_value(__ctx, &min, listItem.values[j].min); + + pcilib_value_t max = {0}; + pcilib_set_value_from_register_value(__ctx, &max, listItem.values[j].max); + + add_pcilib_value_to_dict(valuesItem, &val, "value"); + add_pcilib_value_to_dict(valuesItem, &min, "min"); + add_pcilib_value_to_dict(valuesItem, &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_registers_list(const char *bank) +{ + if(!__ctx) + { + pcilib_error("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) + { + pcilib_error("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) + { + pcilib_error("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) + { + pcilib_error("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; 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; +} diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i new file mode 100644 index 0000000..3ff23a9 --- /dev/null +++ b/pywrap/pcipywrap.i @@ -0,0 +1,21 @@ +%module pcipywrap + +%init %{ + init_pcipywrap_module(); +%} + +extern PyObject* createPcilibInstance(const char *fpga_device, const char *model = NULL); +extern PyObject* setPcilib(PyObject* addr); +extern void closeCurrentPcilibInstance(); +extern PyObject* getCurrentPcilibInstance(); + +extern PyObject* 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_registers_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); diff --git a/pywrap/server.py b/pywrap/server.py new file mode 100644 index 0000000..d308867 --- /dev/null +++ b/pywrap/server.py @@ -0,0 +1,184 @@ +import time +import os #delete later +import pcipywrap +import json +import BaseHTTPServer + +class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): + + def do_HEAD(s): + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + + def do_GET(s): + length = int(s.headers['Content-Length']) + + #deserialize input data + data = json.loads(s.rfile.read(length).decode('utf-8')) + + if 'command' in data: + command = data['command'] + if(command == 'help'): + s.help(data) + + elif(command == 'open'): + #check required arguments + if not 'device' in data: + s.error('message doesnt contains "device" field, ' + 'which is required for "open" command', data) + return + #parse command arguments and convert them to string + device = str(data.get('device', None)) + model = data.get('model', None) + if not model is None: + model = str(model) + + try: + s.openPcilibInstance(device, model) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + + elif(command == 'get_registers_list'): + #parse command arguments and convert them to string + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + registers = dict() + try: + registers = pcipywrap.get_registers_list(bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['registers'] = registers + s.wrapMessageAndSend(out, data) + + elif(command == 'get_register_info'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "get_register_info" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + register = dict() + try: + register = pcipywrap.get_register_info(reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['register'] = register + s.wrapMessageAndSend(out, data) + + elif(command == 'get_property_info'): + #parse command arguments and convert them to string + branch = data.get('branch', None) + if not branch is None: + branch = str(bank) + + properties = dict() + try: + properties = pcipywrap.get_property_info(branch) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['properties'] = properties + s.wrapMessageAndSend(out, data) + + else: + 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'] + + """open device context """ + def openPcilibInstance(s, device, model): + pcipywrap.closeCurrentPcilibInstance() + + lib = pcipywrap.createPcilibInstance(device, model) + pcipywrap.setPcilib(lib) + + """Send help message""" + def help(s, received_message = None): + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = {'status': 'ok', 'help' : 'under construction'} + s.wrapMessageAndSend(out, received_message) + + """Send error message with text description""" + def error(s, info, received_message = None): + s.send_response(400) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + + out['status'] = 'error' + out['description'] = info + out['note'] = 'send {"command" : "help"} to get help' + s.wrapMessageAndSend(out, received_message) + + def wrapMessageAndSend(s, message, received_message = None): + if not received_message is None: + message['received_message'] = received_message + s.wfile.write(json.dumps(message)) + +HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! +PORT_NUMBER = 12412 # Maybe set this to 9000. + +if __name__ == '__main__': + #initialize variables test (to remove) + os.environ["APP_PATH"] = '/home/vchernov/1215N/pcitool' + os.environ["PCILIB_MODEL_DIR"] = os.environ["APP_PATH"] + "/xml" + os.environ["LD_LIBRARY_PATH"] = os.environ["APP_PATH"] + "/pcilib" + + pcilib_server = BaseHTTPServer.HTTPServer + httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) + print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) + try: + httpd.serve_forever() + except KeyboardInterrupt: + pass + httpd.server_close() + print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER) -- cgit v1.2.3 From 55eab7196d0104c71e40136b3b22e9501d234e17 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 14:43:20 +0100 Subject: 1. Cmakelists - move copy xml folder command to root file 2. - Move set python paths code to python module init funtction - pci.c move python module init block code after checking model to get paths before it runs. - Fix set python path code to work with PYTHONPATH - Update pci run script to work with PYTHONPATH - Fix python finalize code 3. Change pcilib_script_s interacting method. Now it stores in hash. 4. Change names of some fucntions to more unified ones 5. Remove old unused function pcilib_xml_create_script_or_transform_view 6. cli - disable reading register after set if write_verification flag is off 7. Remove uninformative error messages fro Python wrap. 8. - Server.py - add read/write property/register command handling - Add help message - Correcting paths --- CMakeLists.txt | 6 +- pci | 5 +- pcilib/pci.c | 14 +-- pcilib/py.c | 194 +++++++++++++++++++++-------------- pcilib/py.h | 13 ++- pcilib/xml.c | 53 +--------- pcitool/cli.c | 26 +++-- pywrap/pcipywrap.c | 50 +++------ pywrap/pcipywrap.i | 10 +- pywrap/server.py | 230 +++++++++++++++++++++++++++++++++++++++--- views/transform.c | 53 +++++----- views/transform.h | 2 +- xml/CMakeLists.txt | 27 ----- xml/test_pywrap/test_prop2.py | 2 +- 14 files changed, 416 insertions(+), 269 deletions(-) (limited to 'pywrap') diff --git a/CMakeLists.txt b/CMakeLists.txt index 204fe6d..e5c8b82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ project(pcitool) set(PCILIB_VERSION "0.2.5") set(PCILIB_ABI_VERSION "2") -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8) #set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH true) #set(CMAKE_PREFIX_PATH ${CMAKE_SYSTEM_PREFIX_PATH}) @@ -89,14 +89,18 @@ set_target_properties(pcilib PROPERTIES SOVERSION ${PCILIB_ABI_VERSION} ) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/xml DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/misc/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/version.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/docs/Doxyfile) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/pci DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc diff --git a/pci b/pci index a07d93d..6992ae8 100644 --- a/pci +++ b/pci @@ -2,4 +2,7 @@ APP_PATH=`dirname $0` -PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $APP_PATH/pcitool/pci $* +PYTHONPATH="$PYTHONPATH:$APP_PATH/pywrap" \ +PCILIB_MODEL_DIR="$APP_PATH/xml" \ +LD_LIBRARY_PATH="$APP_PATH/pcilib" \ +$APP_PATH/pcitool/pci $* diff --git a/pcilib/pci.c b/pcilib/pci.c index eaf41ac..cc2a67a 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -144,13 +144,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } - - err = pcilib_init_py(ctx); - if (err) { - pcilib_error("Error (%i) initializing python subsystem", err); - pcilib_close(ctx); - return NULL; - } ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE; ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE; @@ -191,6 +184,13 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); + + err = pcilib_init_py(ctx); + if (err) { + pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_close(ctx); + return NULL; + } xmlerr = pcilib_init_xml(ctx, ctx->model); if ((xmlerr)&&(xmlerr != PCILIB_ERROR_NOTFOUND)) { diff --git a/pcilib/py.c b/pcilib/py.c index 664e170..7b1ae79 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,37 @@ #include "py.h" #include "error.h" + + struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class }; -struct pcilib_script_s { +typedef struct pcilib_script_s { + char* script_name; PyObject *py_script_module; /**< PyModule object, contains script enviroment */ PyObject *dict; - char* script_name; -}; + pcilib_access_mode_t mode; + + UT_hash_handle hh; +} pcilib_script_s; + +struct pcilib_script_s *scripts = NULL; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; if(!Py_IsInitialized()) + { Py_Initialize(); - + ctx->py->py_initialized_inside = 1; + } + else + ctx->py->py_initialized_inside = 0; + ctx->py->main_module = PyImport_AddModule("__parser__"); if (!ctx->py->main_module) return PCILIB_ERROR_FAILED; @@ -36,17 +49,45 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; - + + + //create path string, where the model scripts should be + static int model_dir_added = 0; + if(!model_dir_added) + { + char* model_dir = getenv("PCILIB_MODEL_DIR"); + char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); + if (!model_path) return PCILIB_ERROR_MEMORY; + sprintf(model_path, "%s/%s", model_dir, ctx->model); + //add path to python + PyObject* path = PySys_GetObject("path"); + if(PyList_Append(path, PyString_FromString(model_path)) == -1) + { + pcilib_error("Cant set PCILIB_MODEL_DIR library path to python."); + free(model_path); + return PCILIB_ERROR_FAILED; + } + free(model_path); + model_dir_added = 1; + } return 0; } void pcilib_free_py(pcilib_t *ctx) { - if (ctx->py) { + + int py_initialized_inside = 0; + + if (ctx->py) { + if(ctx->py->py_initialized_inside) + py_initialized_inside = 1; + // Dict and module references are borrowed free(ctx->py); ctx->py = NULL; } - //Py_Finalize(); + + if(py_initialized_inside) + Py_Finalize(); } /* @@ -196,7 +237,7 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) +void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) { int err; @@ -242,7 +283,7 @@ void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val) } } -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) { PyObject* pyVal = pyObjVal; int err; @@ -268,61 +309,30 @@ int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyObjVal, pcilib_value_t return 0; } -int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode) +int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) { - //Initialize python script, if it has not initialized already. - if(!module_name) + //extract module name from script name + char* py_module_name = strtok(module_name, "."); + if(!py_module_name) { - pcilib_error("Invalid script name specified in XML property (NULL)"); + pcilib_error("Invalid script name specified in XML property (%s)." + " Seems like name doesnt contains extension", module_name); return PCILIB_ERROR_INVALID_DATA; } - //create path string to scripts - char* model_dir = getenv("PCILIB_MODEL_DIR"); - char* model_path = malloc(strlen(model_dir) + strlen(ctx->model) + 2); - if (!model_path) return PCILIB_ERROR_MEMORY; - sprintf(model_path, "%s/%s", model_dir, ctx->model); - - //set model path to python - PySys_SetPath(model_path); - free(model_path); - model_path = NULL; - - //create path string to pcipywrap library - char* app_dir = getenv("APP_PATH"); - char* pcipywrap_path; - if(app_dir) - { - pcipywrap_path = malloc(strlen(app_dir) + strlen("/pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s/%s", "/pywrap", ctx->model); - } - else - { - pcipywrap_path = malloc(strlen("./pywrap")); - if (!pcipywrap_path) return PCILIB_ERROR_MEMORY; - sprintf(pcipywrap_path, "%s", "./pywrap"); - - } - - //set pcipywrap library path to python - PyObject* path = PySys_GetObject("path"); - if(PyList_Append(path, PyString_FromString(pcipywrap_path)) == -1) + pcilib_script_s* module = NULL; + HASH_FIND_STR( scripts, module_name, module); + if(module) { - pcilib_error("Cant set pcipywrap library path to python."); - return PCILIB_ERROR_FAILED; + pcilib_warning("Python module %s is already in hash. Skip init step", module_name); + mode[0] = module->mode; + return 0; } - free(pcipywrap_path); - pcipywrap_path = NULL; - - - //extract module name from script name - char* py_module_name = strtok(module_name, "."); - if(!py_module_name) + //Initialize python module + if(!module_name) { - pcilib_error("Invalid script name specified in XML property (%s)." - " Seems like name doesnt contains extension", module_name); + pcilib_error("Invalid script name specified in XML property (NULL)"); return PCILIB_ERROR_INVALID_DATA; } @@ -336,7 +346,6 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo return PCILIB_ERROR_INVALID_DATA; } - //Initializing pcipywrap module if script use it PyObject* dict = PyModule_GetDict(py_script_module); if(PyDict_Contains(dict, PyString_FromString("pcipywrap"))) @@ -350,16 +359,18 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, - PyUnicode_FromString("setPcilib"), + PyUnicode_FromString("set_pcilib"), PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), NULL); } //Success. Create struct and initialize values - module[0] = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); - module[0]->py_script_module = py_script_module; - module[0]->script_name = module_name; - module[0]->dict = dict; + module = malloc(sizeof(pcilib_script_s)); + module->py_script_module = py_script_module; + module->script_name = malloc(strlen(module_name)); + sprintf(module->script_name, "%s", module_name); + module->dict = dict; + //Setting correct mode mode[0] = 0; @@ -367,32 +378,52 @@ int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **mo mode[0] |= PCILIB_ACCESS_R; if(PyDict_Contains(dict, PyString_FromString("write_to_register"))) mode[0] |= PCILIB_ACCESS_W; + + module->mode = mode[0]; + HASH_ADD_STR( scripts, script_name, module); return 0; } -int pcilib_free_py_script(pcilib_script_t *module) +int pcilib_py_free_script(char* module_name) { - if(module) + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) { - if(module->script_name) - { - free(module->script_name); - module->script_name = NULL; - } + //For some reason it will crash if uncomment. printf same warning is ok + //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + return 0; + } + + if(module->script_name) + { + free(module->script_name); + module->script_name = NULL; + } - if(module->py_script_module) - { - //PyObject_Free(module->py_script_module); - module->py_script_module = NULL; - } + if(module->py_script_module) + { + //PyObject_Free(module->py_script_module); + module->py_script_module = NULL; } + HASH_DEL(scripts, module); + free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } int err; @@ -404,7 +435,7 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return PCILIB_ERROR_FAILED; } - err = pcilib_convert_pyobject_to_val(ctx, ret, val); + err = pcilib_set_value_from_pyobject(ctx, ret, val); if(err) { @@ -414,9 +445,18 @@ int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *v return 0; } -int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val) +int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) { - PyObject *input = pcilib_convert_val_to_pyobject(ctx, val); + pcilib_script_s *module; + HASH_FIND_STR(scripts, module_name, module); + + if(!module) + { + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; + } + + PyObject *input = pcilib_get_value_as_pyobject(ctx, val); if(!input) { printf("Failed to convert input value to Python object"); diff --git a/pcilib/py.h b/pcilib/py.h index d0f1328..09e2b87 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -4,7 +4,6 @@ #include "pcilib.h" typedef struct pcilib_py_s pcilib_py_t; -typedef struct pcilib_script_s pcilib_script_t; #ifdef __cplusplus extern "C" { @@ -15,10 +14,10 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va void pcilib_free_py(pcilib_t *ctx); -int pcilib_init_py_script(pcilib_t *ctx, char* module_name, pcilib_script_t **module, pcilib_access_mode_t *mode); -int pcilib_free_py_script(pcilib_script_t *module); -int pcilib_script_read(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val); -int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t *val); +int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); +int pcilib_py_free_script(char* module_name); +int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val); +int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); /*! @@ -27,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, pcilib_script_t *module, pcilib_value_t * * \param val pointer to pcilib_value_t to convert * \return PyObject, containing value. NULL with error message, sended to errstream. */ -void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val); +void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); /*! @@ -37,7 +36,7 @@ void* pcilib_convert_val_to_pyobject(pcilib_t* ctx, pcilib_value_t *val); * \param val initialized polymorphic value * \return 0 on success or memory error */ -int pcilib_convert_pyobject_to_val(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); +int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); #ifdef __cplusplus diff --git a/pcilib/xml.c b/pcilib/xml.c index ca07ad3..f118491 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -569,7 +569,6 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp desc.base.api = &pcilib_transform_view_api; desc.base.type = PCILIB_TYPE_DOUBLE; desc.base.mode = PCILIB_ACCESS_RW; - desc.script = NULL; err = pcilib_xml_parse_view(ctx, xpath, doc, node, (pcilib_view_description_t*)&desc); if (err) return err; @@ -601,10 +600,10 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp desc.write_to_reg = value; if ((value)&&(*value)) mode |= PCILIB_ACCESS_W; } else if (!strcasecmp(name, "script")) { - char* script_name = malloc(strlen(value)); - sprintf(script_name, "%s", value); + desc.module = malloc(strlen(value)); + sprintf(desc.module, "%s", value); - err = pcilib_init_py_script(ctx, script_name, &(desc.script), &mode); + err = pcilib_py_init_script(ctx, desc.module, &mode); if(err) return err; mode |= PCILIB_REGISTER_INCONSISTENT; break; @@ -620,50 +619,6 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp return 0; } -static int pcilib_xml_create_script_or_transform_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) { - /* - int err; - xmlAttrPtr cur; - const char *name; - - int has_read_from_register = 0; - int has_write_to_register = 0; - int has_script = 0; - - //getting transform name in case of error - pcilib_view_description_t desc = {0}; - err = pcilib_xml_parse_view(ctx, xpath, doc, node, &desc); - - for (cur = node->properties; cur != NULL; cur = cur->next) { - if (!cur->children) continue; - if (!xmlNodeIsText(cur->children)) continue; - - name = (char*)cur->name; - - if (!strcasecmp(name, "read_from_register")) - has_read_from_register = 1; - if (!strcasecmp(name, "write_to_register")) - has_write_to_register = 1; - if (!strcasecmp(name, "script")) - has_script = 1; - } - - if (has_script && (has_read_from_register || has_write_to_register)) { - pcilib_error("Invalid transform group attributes specified in XML property (%s)." - "Transform could not contains both script and read_from_register" - " or write_to_register attributes at same time.", desc.name); - return PCILIB_ERROR_INVALID_DATA; - } - - if(has_script) - - return pcilib_xml_create_script_view(ctx, xpath, doc, node); - else - */ - return pcilib_xml_create_transform_view(ctx, xpath, doc, node); -} - - static int pcilib_xml_parse_value_name(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_register_value_name_t *desc) { xmlAttr *cur; char *value, *name; @@ -921,7 +876,7 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon nodeset = transform_nodes->nodesetval; if (!xmlXPathNodeSetIsEmpty(nodeset)) { for(i=0; i < nodeset->nodeNr; i++) { - err = pcilib_xml_create_script_or_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); + err = pcilib_xml_create_transform_view(ctx, xpath, doc, nodeset->nodeTab[i]); if (err) pcilib_error("Error (%i) creating register transform", err); } } diff --git a/pcitool/cli.c b/pcitool/cli.c index 3e69aac..3676a56 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1703,17 +1703,21 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info const char *format = (val.format?val.format:"%u"); - err = pcilib_read_register(handle, bank, reg, &verify); - if (err) Error("Error reading back register %s for verification\n", reg); - - if (!((model_info->registers[regid].mode&PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) && - verify != value) { - Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); - } else { - printf("%s = ", reg); - printf(format, verify); - printf("\n"); - } + if(!((model_info->registers[regid].mode&PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT)) + { + err = pcilib_read_register(handle, bank, reg, &verify); + if (err) Error("Error reading back register %s for verification\n", reg); + + if ( verify != value) { + Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify); + } else { + printf("%s = ", reg); + printf(format, verify); + printf("\n"); + } + } + else + printf("%s is written\n ", reg); } else { printf("%s is written\n ", reg); } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index c5164a8..fc0add1 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -4,7 +4,7 @@ /*! * \brief Global pointer to pcilib_t context. - * Used by setPcilib and read_register. + * Used by set_pcilib and read_register. */ pcilib_t* __ctx = 0; @@ -68,6 +68,7 @@ void pcilib_print_error_to_py(void *arg, const char *file, int line, */ void init_pcipywrap_module() { + printf("init_pcipywrap_module\n"); pcilib_set_logger(pcilib_get_logger_min_prio(), pcilib_print_error_to_py, pcilib_get_logger_argument()); @@ -79,7 +80,7 @@ void init_pcipywrap_module() * \param[in] model specifies the model of hardware, autodetected if NULL is passed * \return Pointer to pcilib_t, created by pcilib_open, serialized to bytearray; NULL with exeption text, if failed. */ -PyObject* createPcilibInstance(const char *fpga_device, const char *model) +PyObject* create_pcilib_instance(const char *fpga_device, const char *model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); @@ -93,7 +94,7 @@ PyObject* createPcilibInstance(const char *fpga_device, const char *model) /*! * \brief Closes current pciliv instance, if its open. */ -void closeCurrentPcilibInstance() +void close_curr_pcilib_instance() { if(__ctx) { @@ -106,7 +107,7 @@ void closeCurrentPcilibInstance() * \brief Returns current opened pcilib_t instatnce * \return Pointer to pcilib_t, serialized to bytearray */ -PyObject* getCurrentPcilibInstance() +PyObject* get_curr_pcilib_instance() { return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*)); } @@ -116,7 +117,7 @@ PyObject* getCurrentPcilibInstance() * \param[in] addr Pointer to pcilib_t, serialized to bytearray * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ -PyObject* setPcilib(PyObject* addr) +PyObject* set_pcilib(PyObject* addr) { if(!PyByteArray_Check(addr)) { @@ -156,19 +157,13 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) - { - pcilib_error("Failed: pcilib_read_register (%i)", err); return NULL; - } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) - { - pcilib_error("Failed: pcilib_set_value_from_register_value (%i)", err); return NULL; - } - return pcilib_convert_val_to_pyobject(__ctx, &val); + return pcilib_get_value_as_pyobject(__ctx, &val); } /*! @@ -190,26 +185,17 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) pcilib_register_value_t reg_value; int err; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) - { - pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); return NULL; - } reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) - { - pcilib_error("Failed: pcilib_get_value_as_register_value (%i)", err); return NULL; - } err = pcilib_write_register(__ctx, bank, regname, reg_value); if(err) - { - pcilib_error("Failed: pcilib_write_register (%i)", err); return NULL; - } return PyInt_FromLong((long)1); } @@ -232,12 +218,9 @@ PyObject* get_property(const char *prop) err = pcilib_get_property(__ctx, prop, &val); if(err) - { - pcilib_error("Failed pcilib_get_property (%i)", err); - return NULL; - } + return NULL; - return pcilib_convert_val_to_pyobject(__ctx, &val); + return pcilib_get_value_as_pyobject(__ctx, &val); } /*! @@ -246,7 +229,7 @@ PyObject* get_property(const char *prop) * \param[in] val Property value, that needs to be set. Can be int, float or string. * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ -PyObject* set_property(const char *prop, PyObject* val) +PyObject* set_property(PyObject* val, const char *prop) { int err; @@ -257,27 +240,21 @@ PyObject* set_property(const char *prop, PyObject* val) } pcilib_value_t val_internal = {0}; - err = pcilib_convert_pyobject_to_val(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) - { - pcilib_error("Failed pcilib_convert_pyobject_to_val (%i)", err); return NULL; - } err = pcilib_set_property(__ctx, prop, &val_internal); if(err) - { - pcilib_error("Failed pcilib_get_property (%i)", err); return NULL; - } return PyInt_FromLong((long)1); } void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) { - PyObject *py_val = (PyObject*)pcilib_convert_val_to_pyobject(__ctx, val); + PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val); if(py_val) PyDict_SetItem(dict, @@ -506,7 +483,6 @@ PyObject* get_register_info(const char* reg,const char *bank) if(!info) { - pcilib_error("Failed pcilib_get_register_info"); return NULL; } diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 3ff23a9..95045f3 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -4,16 +4,16 @@ init_pcipywrap_module(); %} -extern PyObject* createPcilibInstance(const char *fpga_device, const char *model = NULL); -extern PyObject* setPcilib(PyObject* addr); -extern void closeCurrentPcilibInstance(); -extern PyObject* getCurrentPcilibInstance(); +extern PyObject* create_pcilib_instance(const char *fpga_device, const char *model = NULL); +extern PyObject* set_pcilib(PyObject* addr); +extern void close_curr_pcilib_instance(); +extern PyObject* get_curr_pcilib_instance(); extern PyObject* read_register(const char *regname, const char *bank = NULL); extern PyObject* write_register(PyObject* val, const char *regname, const char *bank = NULL); extern PyObject* get_property(const char *prop); -extern PyObject* set_property(const char *prop, PyObject* val); +extern PyObject* set_property(PyObject* val, const char *prop); extern PyObject* get_registers_list(const char *bank = NULL); extern PyObject* get_register_info(const char* reg,const char *bank = NULL); diff --git a/pywrap/server.py b/pywrap/server.py index d308867..0da6bc8 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -1,8 +1,10 @@ import time -import os #delete later +import os import pcipywrap import json import BaseHTTPServer +import sys +import getopt class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): @@ -70,8 +72,8 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): out['registers'] = registers s.wrapMessageAndSend(out, data) - elif(command == 'get_register_info'): - #check required arguments + elif(command == 'get_register_info'): + #check required arguments if not 'reg' in data: s.error('message doesnt contains "reg" field, ' 'which is required for "get_register_info" command', data) @@ -81,7 +83,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): reg = str(data.get('reg', None)) bank = data.get('bank', None) if not bank is None: - bank = str(bank) + bank = str(bank) register = dict() try: @@ -120,6 +122,125 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): out['status'] = 'ok' out['properties'] = properties s.wrapMessageAndSend(out, data) + + elif(command == 'read_register'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "read_register" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + value = 0 + try: + value = pcipywrap.read_register(reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['value'] = value + s.wrapMessageAndSend(out, data) + + elif(command == 'write_register'): + #check required arguments + if not 'reg' in data: + s.error('message doesnt contains "reg" field, ' + 'which is required for "write_register" command', data) + return + + if not 'value' in data: + s.error('message doesnt contains "value" field, ' + 'which is required for "write_register" command', data) + return + + #parse command arguments and convert them to string + reg = str(data.get('reg', None)) + value = str(data.get('value', None)) + bank = data.get('bank', None) + if not bank is None: + bank = str(bank) + + try: + pcipywrap.write_register(value, reg, bank) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + + elif(command == 'get_property'): + #check required arguments + if not 'prop' in data: + s.error('message doesnt contains "prop" field, ' + 'which is required for "get_property" command', data) + return + + #parse command arguments and convert them to string + prop = str(data.get('prop', None)) + + value = 0 + try: + value = pcipywrap.get_property(prop) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + out['value'] = value + s.wrapMessageAndSend(out, data) + + elif(command == 'set_property'): + #check required arguments + if not 'prop' in data: + s.error('message doesnt contains "prop" field, ' + 'which is required for "set_property" command', data) + return + + if not 'value' in data: + s.error('message doesnt contains "value" field, ' + 'which is required for "set_property" command', data) + return + + #parse command arguments and convert them to string + prop = str(data.get('prop', None)) + value = str(data.get('value', None)) + + try: + pcipywrap.set_property(value, prop) + except Exception as e: + s.error(str(e), data) + return + + #Success! Create and send reply + s.send_response(200) + s.send_header('content-type', 'application/json') + s.end_headers() + out = dict() + out['status'] = 'ok' + s.wrapMessageAndSend(out, data) + else: s.error('command "' + command + '" undefined', data) @@ -134,19 +255,78 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): """open device context """ def openPcilibInstance(s, device, model): - pcipywrap.closeCurrentPcilibInstance() + pcipywrap.close_curr_pcilib_instance() - lib = pcipywrap.createPcilibInstance(device, model) - pcipywrap.setPcilib(lib) + lib = pcipywrap.create_pcilib_instance(device, model) + pcipywrap.set_pcilib(lib) """Send help message""" def help(s, received_message = None): s.send_response(200) s.send_header('content-type', 'application/json') s.end_headers() - out = {'status': 'ok', 'help' : 'under construction'} + usage = str('Usage:\n' + ' Server receive commands via http GET with json packet.\n' + ' content-type should have value "application/json"\n' + ' Server could handle only commands. to set command, you\n' + ' should specify field "command" in packet with command name\n' + ' List of commands:\n' + '\n' + ' command: help - Get help. This will return usage\n' + '\n' + + ' command: open - Opens context of device. It will be reopened if already open.\n' + ' required fields\n' + ' device: - path to the device file [/dev/fpga0]\n' + ' optional fields\n' + ' model: - specifies the model of hardware, autodetected if doesnt exists\n' + '\n' + + ' command: get_registers_list - Returns the list of registers provided by the hardware model.\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be returned\n' + '\n' + + ' command: get_register_info - Returns the information about the specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be returned\n' + '\n' + + ' command: get_property_info - Returns the list of properties available under the specified path.\n' + ' optional fields\n' + ' branch: - Path. If not set, will return the top-level properties\n' + '\n' + + ' command: read_register - Reads the specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be processed\n' + '\n' + + ' command: write_register - Writes to specified register.\n' + ' required fields\n' + ' reg: - the name of the register\n' + ' value: - the register value to write. Should be int, float or string (with number)\n' + ' optional fields\n' + ' bank: - if set, only register within the specified bank will be processed\n' + '\n' + + ' command: get_property - Reads / computes the property value.\n' + ' required fields\n' + ' prop: - full name including path\n' + '\n' + + ' command: set_property - Writes the property value or executes the code associated with property.\n' + ' required fields\n' + ' prop: - full name including path\n' + ' value: - the property value to write. Should be int, float or string (with number)\n' + '\n') + out = {'status': 'ok', 'usage' : usage} s.wrapMessageAndSend(out, received_message) - + """Send error message with text description""" def error(s, info, received_message = None): s.send_response(400) @@ -164,14 +344,34 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): message['received_message'] = received_message s.wfile.write(json.dumps(message)) -HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! -PORT_NUMBER = 12412 # Maybe set this to 9000. if __name__ == '__main__': - #initialize variables test (to remove) - os.environ["APP_PATH"] = '/home/vchernov/1215N/pcitool' - os.environ["PCILIB_MODEL_DIR"] = os.environ["APP_PATH"] + "/xml" - os.environ["LD_LIBRARY_PATH"] = os.environ["APP_PATH"] + "/pcilib" + + HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! + PORT_NUMBER = 12412 # Maybe set this to 9000. + + try: + opts, args = getopt.getopt(sys.argv[1:], "", []) + #opts, args = getopt.getopt(sys.argv[1:], "hop:v", ["help", "output="]) + #print opts, args + except getopt.GetoptError as err: + # print help information and exit: + print str(err) # will print something like "option -a not recognized" + #usage() + sys.exit(2) + + #Set enviroment variables, if it not setted already + if not 'APP_PATH' in os.environ: + APP_PATH = '' + file_dir = os.path.dirname(os.path.abspath(__file__)) + APP_PATH = str(os.path.abspath(file_dir + '/../..')) + os.environ["APP_PATH"] = APP_PATH + + if not 'PCILIB_MODEL_DIR' in os.environ: + os.environ['PCILIB_MODEL_DIR'] = os.environ["APP_PATH"] + "/xml" + + if not 'LD_LIBRARY_PATH' in os.environ: + os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" pcilib_server = BaseHTTPServer.HTTPServer httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) diff --git a/views/transform.c b/views/transform.c index 986cfd7..ba2f48f 100644 --- a/views/transform.c +++ b/views/transform.c @@ -15,53 +15,46 @@ static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); - if(v->script) - { - return pcilib_script_read(ctx, v->script, val); - } - else - { - int err; - - err = pcilib_set_value_from_register_value(ctx, val, regval); - if (err) return err; + int err; + err = pcilib_set_value_from_register_value(ctx, val, regval); + if (err) return err; + + if(v->module) + return pcilib_script_read(ctx, v->module, val); + else return pcilib_py_eval_string(ctx, v->read_from_reg, val); - } } static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, const pcilib_value_t *val) { - - - + const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); + int err = 0; + + pcilib_value_t val_copy = {0}; + err = pcilib_copy_value(ctx, &val_copy, val); + if (err) return err; - if(!v->script) - { - int err = 0; - - pcilib_value_t val_copy = {0}; - err = pcilib_copy_value(ctx, &val_copy, val); - if (err) return err; - - err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); - if (err) return err; - *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); - return err; - } + if(v->module) + err = pcilib_script_write(ctx, v->module, &val_copy); else - return pcilib_script_write(ctx, v->script, (pcilib_value_t *)val); + err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); + + if (err) return err; + + *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); + return err; } void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_description_t *view) { pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view); - if(v->script) - pcilib_free_py_script(v->script); + if(v->module) + pcilib_py_free_script(v->module); } diff --git a/views/transform.h b/views/transform.h index 8ab4f4f..c2f0a98 100644 --- a/views/transform.h +++ b/views/transform.h @@ -9,7 +9,7 @@ typedef struct { pcilib_view_description_t base; const char *read_from_reg; /**< Formula explaining how to convert the register value to the view value */ const char *write_to_reg; /**< Formula explaining how to convert from the view value to the register value */ - pcilib_script_t *script; + char *module; /**< Python script module name (without extension) */ } pcilib_transform_view_description_t; #ifndef _PCILIB_VIEW_TRANSFORM_C diff --git a/xml/CMakeLists.txt b/xml/CMakeLists.txt index 0b12d87..a7ac800 100644 --- a/xml/CMakeLists.txt +++ b/xml/CMakeLists.txt @@ -1,30 +1,3 @@ install(FILES model.xsd references.xsd types.xsd DESTINATION ${PCILIB_MODEL_DIR} ) - -# Copy files from source directory to destination directory, substituting any -# variables. Create destination directory if it does not exist. - -macro(configure_files srcDir destDir) - message(STATUS "Configuring directory ${destDir}") - make_directory(${destDir}) - - file(GLOB templateFiles RELATIVE ${srcDir} ${srcDir}/*) - foreach(templateFile ${templateFiles}) - set(srcTemplatePath ${srcDir}/${templateFile}) - if(NOT IS_DIRECTORY ${srcTemplatePath}) - message(STATUS "Configuring file ${templateFile}") - configure_file( - ${srcTemplatePath} - ${destDir}/${templateFile} - @ONLY) - endif(NOT IS_DIRECTORY ${srcTemplatePath}) - endforeach(templateFile) -endmacro(configure_files) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/model.xsd ${CMAKE_CURRENT_BINARY_DIR}/model.xsd) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/references.xsd ${CMAKE_CURRENT_BINARY_DIR}/references.xsd) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/types.xsd ${CMAKE_CURRENT_BINARY_DIR}/types.xsd) - -configure_files(${CMAKE_CURRENT_SOURCE_DIR}/test ${CMAKE_CURRENT_BINARY_DIR}/test) -configure_files(${CMAKE_CURRENT_SOURCE_DIR}/test_pywrap ${CMAKE_CURRENT_BINARY_DIR}/test_pywrap) diff --git a/xml/test_pywrap/test_prop2.py b/xml/test_pywrap/test_prop2.py index a831fdd..69a2190 100644 --- a/xml/test_pywrap/test_prop2.py +++ b/xml/test_pywrap/test_prop2.py @@ -4,5 +4,5 @@ def read_from_register(): return pcipywrap.get_property('/registers/fpga/reg1') / 2 def write_to_register(value): - pcipywrap.set_property('/registers/fpga/reg1', value*3) + pcipywrap.set_property(value*3, '/registers/fpga/reg1') -- cgit v1.2.3 From 1b3342649294c6ce99aeb82664a29eac47687ee5 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 17:50:57 +0100 Subject: Move python module init code to transfom view constructor Update python logger and python exeption messages Change serialization method in create_pcilib_instance set_pcilib functions --- pcilib/pci.c | 3 +- pcilib/py.c | 12 +++--- pcilib/view.c | 2 +- pcilib/view.h | 2 +- pcilib/xml.c | 5 --- pcitool/cli.c | 2 - pywrap/pcipywrap.c | 110 ++++++++++++++++++++++++++++++++++++++--------------- pywrap/pcipywrap.i | 4 +- pywrap/server.py | 3 ++ views/transform.c | 31 ++++++++++++++- 10 files changed, 124 insertions(+), 50 deletions(-) (limited to 'pywrap') diff --git a/pcilib/pci.c b/pcilib/pci.c index cc2a67a..c38097f 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -192,12 +192,14 @@ pcilib_t *pcilib_open(const char *device, const char *model) { return NULL; } + xmlerr = pcilib_init_xml(ctx, ctx->model); if ((xmlerr)&&(xmlerr != PCILIB_ERROR_NOTFOUND)) { pcilib_error("Error (%i) initializing XML subsystem for model %s", xmlerr, ctx->model); pcilib_close(ctx); return NULL; } + // We have found neither standard model nor XML if ((err)&&(xmlerr)) { @@ -219,7 +221,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } - err = pcilib_init_event_engine(ctx); if (err) { pcilib_error("Error (%i) initializing event engine\n", err); diff --git a/pcilib/py.c b/pcilib/py.c index 7b1ae79..e448d21 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -244,11 +244,11 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); return NULL; case PCILIB_TYPE_STRING: - pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); return NULL; case PCILIB_TYPE_LONG: @@ -258,7 +258,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyInt_FromLong((long) ret); @@ -271,14 +271,14 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); return NULL; } return (PyObject*)PyFloat_FromDouble((double) ret); } default: - pcilib_error("Invalid register output type (unknown)"); + pcilib_warning("Invalid register output type (unknown)"); return NULL; } } @@ -360,7 +360,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //setting pcilib_t instance PyObject_CallMethodObjArgs(pcipywrap_module, PyUnicode_FromString("set_pcilib"), - PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)), + PyCObject_FromVoidPtr(ctx, NULL), NULL); } diff --git a/pcilib/view.c b/pcilib/view.c index e31fdba..797f4ae 100644 --- a/pcilib/view.c +++ b/pcilib/view.c @@ -70,7 +70,7 @@ int pcilib_add_views_custom(pcilib_t *ctx, size_t n, const pcilib_view_descripti } if (v->api->init) - view_ctx = v->api->init(ctx); + view_ctx = v->api->init(ctx, v); else { view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t)); if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t)); diff --git a/pcilib/view.h b/pcilib/view.h index 33d4d96..1a1d277 100644 --- a/pcilib/view.h +++ b/pcilib/view.h @@ -19,7 +19,7 @@ typedef enum { typedef struct { pcilib_version_t version; /**< Version */ size_t description_size; /**< The actual size of the description */ - pcilib_view_context_t *(*init)(pcilib_t *ctx); /**< Optional function which should allocated context used by read/write functions */ + pcilib_view_context_t *(*init)(pcilib_t *ctx, const pcilib_view_description_t *desc); /**< Optional function which should allocated context used by read/write functions */ void (*free)(pcilib_t *ctx, pcilib_view_context_t *view); /**< Optional function which should clean context */ void (*free_description)(pcilib_t *ctx, pcilib_view_description_t *view); /**< Optional function which shoud clean required parts of the extended description if non-static memory was used to initialize it */ int (*read_from_reg)(pcilib_t *ctx, pcilib_view_context_t *view, pcilib_register_value_t regval, pcilib_value_t *val); /**< Function which computes view value based on the passed the register value (view-based properties should not use register value) */ diff --git a/pcilib/xml.c b/pcilib/xml.c index f118491..4e95437 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -602,14 +602,9 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp } else if (!strcasecmp(name, "script")) { desc.module = malloc(strlen(value)); sprintf(desc.module, "%s", value); - - err = pcilib_py_init_script(ctx, desc.module, &mode); - if(err) return err; - mode |= PCILIB_REGISTER_INCONSISTENT; break; } } - desc.base.mode &= mode; err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); diff --git a/pcitool/cli.c b/pcitool/cli.c index 3676a56..0b0c98d 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1716,8 +1716,6 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info printf("\n"); } } - else - printf("%s is written\n ", reg); } else { printf("%s is written\n ", reg); } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index fc0add1..8ef1dc0 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -8,6 +8,8 @@ */ pcilib_t* __ctx = 0; +char* full_log = NULL; + /*! * \brief Wraping for vsnprintf function, that saves string to char* * \return saved from vsnprintf string @@ -52,23 +54,51 @@ char* make_str(const char* msg, ...) */ void pcilib_print_error_to_py(void *arg, const char *file, int line, pcilib_log_priority_t prio, const char *msg, - va_list va) { - char* buf_raw_msg = vmake_str(msg, va); - char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); - - printf("%s", buf_wrapped_message); - PyErr_SetString(PyExc_Exception, buf_wrapped_message); + va_list va) { + //wrap error message with file and line number + char* buf_raw_msg = vmake_str(msg, va); + char* buf_wrapped_message = make_str("%s [%s:%d]\n", buf_raw_msg, file, line); + + if(prio == PCILIB_LOG_ERROR) + { + if(!full_log) + full_log = make_str(""); - free(buf_wrapped_message); - free(buf_raw_msg); + if(strlen(buf_wrapped_message) >= 2 && + buf_wrapped_message[0] == '#' && + buf_wrapped_message[1] == 'E') + { + char* wrapped_exeption = make_str("%sprogramm error log:\n%s", &(buf_wrapped_message[2]), full_log); + free(full_log); + full_log = NULL; + + PyErr_SetString(PyExc_Exception, wrapped_exeption); + free(wrapped_exeption); + } + else + { + //copy received message to log + char* buf = full_log; + char* buf_start = buf; + full_log = make_str("%s%s", buf, buf_wrapped_message); + free(buf); + } + } + else + printf(buf_wrapped_message); + + free(buf_wrapped_message); + free(buf_raw_msg); } /*! - * \brief Inits pcipywrap module at importing + * \brief Redirect pcilib standart log stream to exeption text. + * Logger will accumulate errors untill get message, starts with "#E". + * After that, logger will write last error, and all accumulated errors + * to Python exeption text */ -void init_pcipywrap_module() +void __redirect_logs_to_exeption() { - printf("init_pcipywrap_module\n"); pcilib_set_logger(pcilib_get_logger_min_prio(), pcilib_print_error_to_py, pcilib_get_logger_argument()); @@ -78,17 +108,19 @@ void init_pcipywrap_module() * \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. + * \return Pointer to pcilib_t, created by pcilib_open; NULL with exeption text, if failed. */ PyObject* create_pcilib_instance(const char *fpga_device, const char *model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); if(!ctx) + { + pcilib_error("#E Failed pcilib_open(%s, %s)", fpga_device, model); return NULL; + } - //serializing object - return PyByteArray_FromStringAndSize((const char*)&ctx, sizeof(pcilib_t*)); + return PyCObject_FromVoidPtr((void*)ctx, NULL); } /*! @@ -114,23 +146,18 @@ PyObject* get_curr_pcilib_instance() /*! * \brief Sets pcilib context to wraper. - * \param[in] addr Pointer to pcilib_t, serialized to bytearray + * \param[in] addr Pointer to pcilib_t, serialized to PyCObject * \return 1, serialized to PyObject or NULL with exeption text, if failed. */ PyObject* set_pcilib(PyObject* addr) { - if(!PyByteArray_Check(addr)) + if(!PyCObject_Check(addr)) { - pcilib_error("Incorrect addr type. Only bytearray is allowed"); + pcilib_error("#E Incorrect addr type. Only PyCObject 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]; + __ctx = (pcilib_t*)PyCObject_AsVoidPtr(addr); return PyInt_FromLong((long)1); } @@ -146,7 +173,7 @@ PyObject* read_register(const char *regname, const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -157,11 +184,17 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) + { + pcilib_error("#E Failed pcilib_read_register"); return NULL; + } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_register_value"); return NULL; + } return pcilib_get_value_as_pyobject(__ctx, &val); } @@ -187,15 +220,24 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) int err; err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject"); return NULL; + } reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } err = pcilib_write_register(__ctx, bank, regname, reg_value); if(err) + { + pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } return PyInt_FromLong((long)1); } @@ -208,7 +250,7 @@ PyObject* get_property(const char *prop) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -218,7 +260,10 @@ PyObject* get_property(const char *prop) err = pcilib_get_property(__ctx, prop, &val); if(err) + { + pcilib_error("#E Failed pcilib_get_property, (error %i)", err); return NULL; + } return pcilib_get_value_as_pyobject(__ctx, &val); } @@ -235,19 +280,24 @@ PyObject* set_property(PyObject* val, const char *prop) if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } pcilib_value_t val_internal = {0}; err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); if(err) + { + pcilib_error("#E pcilib_set_value_from_pyobject, (error %i)", err); return NULL; + } err = pcilib_set_property(__ctx, prop, &val_internal); - if(err) + { + pcilib_error("#E pcilib_set_property, (error %i)", err); return NULL; + } return PyInt_FromLong((long)1); } @@ -452,7 +502,7 @@ PyObject* get_registers_list(const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -475,7 +525,7 @@ PyObject* get_register_info(const char* reg,const char *bank) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } @@ -497,7 +547,7 @@ PyObject* get_property_info(const char* branch) { if(!__ctx) { - pcilib_error("pcilib_t handler not initialized"); + pcilib_error("#E pcilib_t handler not initialized"); return NULL; } diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 95045f3..4b735d2 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -1,8 +1,6 @@ %module pcipywrap -%init %{ - init_pcipywrap_module(); -%} +extern void __redirect_logs_to_exeption(); extern PyObject* create_pcilib_instance(const char *fpga_device, const char *model = NULL); extern PyObject* set_pcilib(PyObject* addr); diff --git a/pywrap/server.py b/pywrap/server.py index 0da6bc8..d2927fb 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -373,6 +373,9 @@ if __name__ == '__main__': 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() + pcilib_server = BaseHTTPServer.HTTPServer httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) diff --git a/views/transform.c b/views/transform.c index ba2f48f..75b95b2 100644 --- a/views/transform.c +++ b/views/transform.c @@ -9,6 +9,7 @@ #include "model.h" #include "transform.h" #include "py.h" +#include "error.h" static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) { @@ -57,6 +58,34 @@ void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_descript pcilib_py_free_script(v->module); } +pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_view_description_t *desc) +{ + pcilib_transform_view_description_t *v_desc = (pcilib_transform_view_description_t*)desc; + + if(v_desc->module) + { + pcilib_access_mode_t mode = 0; + + int err = pcilib_py_init_script(ctx, v_desc->module, &mode); + if(err) + { + pcilib_error("Failed init script module (%s) - error %i", v_desc->module, err); + return NULL; + } + + v_desc->base.mode |= PCILIB_REGISTER_RW; + mode |= PCILIB_REGISTER_INCONSISTENT; + v_desc->base.mode &= mode; + } + + pcilib_view_context_t *view_ctx; + view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t)); + if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t)); + + return view_ctx; +} + + const pcilib_view_api_description_t pcilib_transform_view_api = - { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), NULL, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write }; + { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), pcilib_transform_view_init, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write }; -- cgit v1.2.3 From a4f3ac0b00694287e791cd7d753b420976d9f22a Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Fri, 12 Feb 2016 18:12:08 +0100 Subject: Add destructor for returning PyCObject in create_pcilib_instance function --- pywrap/pcipywrap.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'pywrap') diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index 8ef1dc0..a33566a 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -79,7 +79,6 @@ void pcilib_print_error_to_py(void *arg, const char *file, int line, { //copy received message to log char* buf = full_log; - char* buf_start = buf; full_log = make_str("%s%s", buf, buf_wrapped_message); free(buf); } @@ -104,6 +103,16 @@ void __redirect_logs_to_exeption() pcilib_get_logger_argument()); } +/*! + * Destructor for pcilib_t + */ +void close_pcilib_instance(void *ctx) +{ + if(ctx == __ctx) + __ctx = NULL; + pcilib_close(ctx); +} + /*! * \brief Wraps for pcilib_open function. * \param[in] fpga_device path to the device file [/dev/fpga0] @@ -120,7 +129,7 @@ PyObject* create_pcilib_instance(const char *fpga_device, const char *model) return NULL; } - return PyCObject_FromVoidPtr((void*)ctx, NULL); + return PyCObject_FromVoidPtr((void*)ctx, close_pcilib_instance); } /*! -- cgit v1.2.3 From 398e756263502a98a0c1887dcf38f7ef1fafa84b Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 15 Feb 2016 13:41:25 +0100 Subject: Fix memory leaks Add GIL states for int pcilib_script_read and pcilib_script_write functions Correct desctructor for create_pcilib_instance return object --- pcilib/property.c | 7 ++- pcilib/py.c | 16 +++++- pywrap/pcipywrap.c | 140 +++++++++++++++++++++++++++++++---------------------- pywrap/server.py | 2 +- 4 files changed, 104 insertions(+), 61 deletions(-) (limited to 'pywrap') diff --git a/pcilib/property.c b/pcilib/property.c index a7d1a61..3a7ebb3 100644 --- a/pcilib/property.c +++ b/pcilib/property.c @@ -165,7 +165,6 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran continue; } - dir = (struct dir_hash_s*)malloc(sizeof(struct dir_hash_s)); if (!dir) { err = PCILIB_ERROR_MEMORY; @@ -226,6 +225,12 @@ pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *bran }; } + + + HASH_ITER(hh, dir_hash, dir, dir_tmp) { + HASH_DEL(dir_hash, dir); + free(dir); + } HASH_CLEAR(hh, dir_hash); memset(&info[pos], 0, sizeof(pcilib_property_info_t)); diff --git a/pcilib/py.c b/pcilib/py.c index e448d21..20fa546 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -427,7 +427,9 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) int err; + PyGILState_STATE gstate = PyGILState_Ensure(); PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyGILState_Release(gstate); if (!ret) { printf("Python script error: "); @@ -436,6 +438,7 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) } err = pcilib_set_value_from_pyobject(ctx, ret, val); + Py_XDECREF(ret); if(err) { @@ -463,17 +466,26 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val) PyErr_Print(); return PCILIB_ERROR_FAILED; } + PyObject *func_name = PyUnicode_FromString("write_to_register"); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - PyUnicode_FromString("write_to_register"), + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, + func_name, input, NULL); + PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); PyErr_Print(); return PCILIB_ERROR_FAILED; } + + //release objects + Py_XDECREF(func_name); + Py_XDECREF(ret); + Py_XDECREF(input); return 0; } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index a33566a..77da195 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -108,9 +108,8 @@ void __redirect_logs_to_exeption() */ void close_pcilib_instance(void *ctx) { - if(ctx == __ctx) - __ctx = NULL; - pcilib_close(ctx); + if(ctx != __ctx) + pcilib_close(ctx); } /*! @@ -223,17 +222,21 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) return NULL; } + pcilib_value_t val_internal = {0}; pcilib_register_value_t reg_value; int err; + err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); + if(err) { pcilib_error("#E Failed pcilib_set_value_from_pyobject"); return NULL; } + reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) { @@ -242,11 +245,13 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) } err = pcilib_write_register(__ctx, bank, regname, reg_value); + if(err) { pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; } + return PyInt_FromLong((long)1); } @@ -311,18 +316,39 @@ PyObject* set_property(PyObject* val, const char *prop) return PyInt_FromLong((long)1); } +/*! + * \brief Wrap for PyDict_SetItem, with decrease reference counting after set. + */ +void pcilib_pydict_set_item(PyObject* dict, PyObject* name, PyObject* value) +{ + PyDict_SetItem(dict, + name, + value); + Py_XDECREF(name); + Py_XDECREF(value); +} + +/*! + * \brief Wrap for PyList_Append, with decrease reference counting after append. + */ +void pcilib_pylist_append(PyObject* list, PyObject* value) +{ + PyList_Append(list, value); + Py_XDECREF(value); +} + void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) { PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val); if(py_val) - PyDict_SetItem(dict, - PyString_FromString(name), - py_val); + pcilib_pydict_set_item(dict, + PyString_FromString(name), + py_val); else - PyDict_SetItem(dict, - PyString_FromString("defvalue"), - PyString_FromString("invalid")); + pcilib_pydict_set_item(dict, + PyString_FromString("defvalue"), + PyString_FromString("invalid")); } PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listItem) @@ -330,17 +356,17 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listI PyObject* pylistItem = PyDict_New(); if(listItem.name) - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("name"), PyString_FromString(listItem.name)); if(listItem.description) - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("description"), PyString_FromString(listItem.description)); if(listItem.path) - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("path"), PyString_FromString(listItem.path)); @@ -363,7 +389,7 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listI default: break; } - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("type"), PyString_FromString(type)); @@ -372,15 +398,15 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listI PyObject* modes = PyList_New(0); if((listItem.mode & PCILIB_ACCESS_R ) == PCILIB_REGISTER_R) - PyList_Append(modes, PyString_FromString("R")); + pcilib_pylist_append(modes, PyString_FromString("R")); if((listItem.mode & PCILIB_ACCESS_W ) == PCILIB_REGISTER_W) - PyList_Append(modes, PyString_FromString("W")); + pcilib_pylist_append(modes, PyString_FromString("W")); if((listItem.mode & PCILIB_ACCESS_RW ) == PCILIB_REGISTER_RW) - PyList_Append(modes, PyString_FromString("RW")); + pcilib_pylist_append(modes, PyString_FromString("RW")); if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) - PyList_Append(modes, PyString_FromString("NO_CHK")); + pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("mode"), modes); @@ -388,14 +414,14 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listI PyObject* flags = PyList_New(0); if((listItem.flags & PCILIB_LIST_FLAG_CHILDS ) == PCILIB_LIST_FLAG_CHILDS) - PyList_Append(flags, PyString_FromString("childs")); + pcilib_pylist_append(flags, PyString_FromString("childs")); - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("flags"), flags); if(listItem.unit) - PyDict_SetItem(pylistItem, + pcilib_pydict_set_item(pylistItem, PyString_FromString("unit"), PyString_FromString(listItem.unit)); @@ -407,44 +433,44 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI PyObject* pylistItem = PyDict_New(); if(listItem.name) - PyDict_SetItem(pylistItem, - PyString_FromString("name"), - PyString_FromString(listItem.name)); + pcilib_pydict_set_item(pylistItem, + PyString_FromString("name"), + PyString_FromString(listItem.name)); if(listItem.description) - PyDict_SetItem(pylistItem, - PyString_FromString("description"), - PyString_FromString(listItem.description)); + pcilib_pydict_set_item(pylistItem, + PyString_FromString("description"), + PyString_FromString(listItem.description)); if(listItem.bank) - PyDict_SetItem(pylistItem, - PyString_FromString("bank"), - PyString_FromString(listItem.bank)); + pcilib_pydict_set_item(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")); + pcilib_pylist_append(modes, PyString_FromString("R")); if((listItem.mode & PCILIB_REGISTER_W) == PCILIB_REGISTER_W) - PyList_Append(modes, PyString_FromString("W")); + pcilib_pylist_append(modes, PyString_FromString("W")); if((listItem.mode & PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) - PyList_Append(modes, PyString_FromString("RW")); + pcilib_pylist_append(modes, PyString_FromString("RW")); if((listItem.mode & PCILIB_REGISTER_W1C) == PCILIB_REGISTER_W1C) - PyList_Append(modes, PyString_FromString("W1C")); + pcilib_pylist_append(modes, PyString_FromString("W1C")); if((listItem.mode & PCILIB_REGISTER_RW1C) == PCILIB_REGISTER_RW1C) - PyList_Append(modes, PyString_FromString("RW1C")); + pcilib_pylist_append(modes, PyString_FromString("RW1C")); if((listItem.mode & PCILIB_REGISTER_W1I) == PCILIB_REGISTER_W1I) - PyList_Append(modes, PyString_FromString("W1I")); + pcilib_pylist_append(modes, PyString_FromString("W1I")); if((listItem.mode & PCILIB_REGISTER_RW1I) == PCILIB_REGISTER_RW1I) - PyList_Append(modes, PyString_FromString("RW1I")); + pcilib_pylist_append(modes, PyString_FromString("RW1I")); if((listItem.mode & PCILIB_REGISTER_INCONSISTENT) == PCILIB_REGISTER_INCONSISTENT) - PyList_Append(modes, PyString_FromString("NO_CHK")); + pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); - PyDict_SetItem(pylistItem, - PyString_FromString("mode"), - modes); - + pcilib_pydict_set_item(pylistItem, + PyString_FromString("mode"), + modes); + pcilib_value_t defval = {0}; pcilib_set_value_from_register_value(__ctx, &defval, listItem.defvalue); add_pcilib_value_to_dict(pylistItem, &defval, "defvalue"); @@ -460,9 +486,9 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI PyObject* range = PyDict_New(); add_pcilib_value_to_dict(range, &minval, "min"); add_pcilib_value_to_dict(range, &maxval, "max"); - PyDict_SetItem(pylistItem, - PyString_FromString("range"), - range); + pcilib_pydict_set_item(pylistItem, + PyString_FromString("range"), + range); } if(listItem.values) @@ -487,21 +513,21 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI add_pcilib_value_to_dict(valuesItem, &max, "max"); if(listItem.values[j].name) - PyDict_SetItem(valuesItem, - PyString_FromString("name"), - PyString_FromString(listItem.values[j].name)); + pcilib_pydict_set_item(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)); + pcilib_pydict_set_item(valuesItem, + PyString_FromString("name"), + PyString_FromString(listItem.values[j].description)); - PyList_Append(values, valuesItem); + pcilib_pylist_append(values, valuesItem); } - PyDict_SetItem(pylistItem, - PyString_FromString("values"), - values); + pcilib_pydict_set_item(pylistItem, + PyString_FromString("values"), + values); } return pylistItem; @@ -522,7 +548,7 @@ PyObject* get_registers_list(const char *bank) { //serialize item attributes PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(list[i]); - PyList_Append(pyList, pylistItem); + pcilib_pylist_append(pyList, pylistItem); } pcilib_free_register_info(__ctx, list); @@ -568,7 +594,7 @@ PyObject* get_property_info(const char* branch) { //serialize item attributes PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(list[i]); - PyList_Append(pyList, pylistItem); + pcilib_pylist_append(pyList, pylistItem); } pcilib_free_property_info(__ctx, list); diff --git a/pywrap/server.py b/pywrap/server.py index d2927fb..f55d43a 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -105,7 +105,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): #parse command arguments and convert them to string branch = data.get('branch', None) if not branch is None: - branch = str(bank) + branch = str(branch) properties = dict() try: -- cgit v1.2.3 From fc80d8b64672785b4d9c7127e852ca9bf19c9194 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Mon, 15 Feb 2016 16:09:37 +0100 Subject: Add options parsing to server\n Rename get_property_info for get_property_list --- pywrap/pcipywrap.c | 2 +- pywrap/pcipywrap.i | 2 +- pywrap/server.py | 93 +++++++++++++++++++++++++++++------------------------- 3 files changed, 52 insertions(+), 45 deletions(-) (limited to 'pywrap') diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index 77da195..b1ee630 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -578,7 +578,7 @@ PyObject* get_register_info(const char* reg,const char *bank) return py_info; } -PyObject* get_property_info(const char* branch) +PyObject* get_property_list(const char* branch) { if(!__ctx) { diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 4b735d2..86b6f36 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -16,4 +16,4 @@ extern PyObject* set_property(PyObject* val, const char *prop); extern PyObject* get_registers_list(const char *bank = NULL); extern PyObject* get_register_info(const char* reg,const char *bank = NULL); -extern PyObject* get_property_info(const char* branch = NULL); +extern PyObject* get_property_list(const char* branch = NULL); diff --git a/pywrap/server.py b/pywrap/server.py index f55d43a..acba791 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -4,7 +4,7 @@ import pcipywrap import json import BaseHTTPServer import sys -import getopt +from optparse import OptionParser class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): @@ -23,33 +23,33 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): command = data['command'] if(command == 'help'): s.help(data) - - elif(command == 'open'): - #check required arguments - if not 'device' in data: - s.error('message doesnt contains "device" field, ' - 'which is required for "open" command', data) - return - #parse command arguments and convert them to string - device = str(data.get('device', None)) - model = data.get('model', None) - if not model is None: - model = str(model) - try: - s.openPcilibInstance(device, model) - except Exception as e: - s.error(str(e), data) - return - - #Success! Create and send reply - s.send_response(200) - s.send_header('content-type', 'application/json') - s.end_headers() - out = dict() - out['status'] = 'ok' - s.wrapMessageAndSend(out, data) - + #elif(command == 'open'): + # #check required arguments + # if not 'device' in data: + # s.error('message doesnt contains "device" field, ' + # 'which is required for "open" command', data) + # return + # #parse command arguments and convert them to string + # device = str(data.get('device', None)) + # model = data.get('model', None) + # if not model is None: + # model = str(model) + # + # try: + # s.openPcilibInstance(device, model) + # except Exception as e: + # s.error(str(e), data) + # return + # + # #Success! Create and send reply + # s.send_response(200) + # s.send_header('content-type', 'application/json') + # s.end_headers() + # out = dict() + # out['status'] = 'ok' + # s.wrapMessageAndSend(out, data) + elif(command == 'get_registers_list'): #parse command arguments and convert them to string bank = data.get('bank', None) @@ -101,7 +101,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): out['register'] = register s.wrapMessageAndSend(out, data) - elif(command == 'get_property_info'): + elif(command == 'get_property_list'): #parse command arguments and convert them to string branch = data.get('branch', None) if not branch is None: @@ -109,7 +109,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): properties = dict() try: - properties = pcipywrap.get_property_info(branch) + properties = pcipywrap.get_property_list(branch) except Exception as e: s.error(str(e), data) return @@ -294,7 +294,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): ' bank: - if set, only register within the specified bank will be returned\n' '\n' - ' command: get_property_info - Returns the list of properties available under the specified path.\n' + ' command: get_property_list - Returns the list of properties available under the specified path.\n' ' optional fields\n' ' branch: - Path. If not set, will return the top-level properties\n' '\n' @@ -344,21 +344,25 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): message['received_message'] = received_message s.wfile.write(json.dumps(message)) - if __name__ == '__main__': - HOST_NAME = '' # !!!REMEMBER TO CHANGE THIS!!! - PORT_NUMBER = 12412 # Maybe set this to 9000. + #parce command line options + parser = OptionParser() + parser.add_option("-p", "--port", action="store", + type="int", dest="port", default=9000, + help="Set server port (8888)") + 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] - try: - opts, args = getopt.getopt(sys.argv[1:], "", []) - #opts, args = getopt.getopt(sys.argv[1:], "hop:v", ["help", "output="]) - #print opts, args - except getopt.GetoptError as err: - # print help information and exit: - print str(err) # will print something like "option -a not recognized" - #usage() - sys.exit(2) + HOST_NAME = '' + 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: @@ -373,9 +377,12 @@ if __name__ == '__main__': if not 'LD_LIBRARY_PATH' in os.environ: os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" - #redirect logs to exeption + #create pcilib instance and redirect logs to exeption + lib = pcipywrap.create_pcilib_instance(opts.device, opts.model) + pcipywrap.set_pcilib(lib) pcipywrap.__redirect_logs_to_exeption() + #start server pcilib_server = BaseHTTPServer.HTTPServer httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) -- cgit v1.2.3 From ed9d8f285f4d81e1ce8bb5e7a5b9e471a73c1590 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Tue, 16 Feb 2016 16:30:40 +0100 Subject: 1. Add python thread initialization to pcilib_init_py() -Fix pcilib_script_run_func() work in multithread mode 2. pcilib_close() - Move free_py() code after free views to make view destructors work properly 3. Move script hash to pcilib_py_s 4. Move pcilib_get_logger() pcilib_get_logger_min_prio() and pcilib_get_logger_argument() declarations to error.h 5. Refactor pcilib_get_value_as_pyobject pcilib_set_value_from_pyobject to more unified form 6. Add more memory checks. Fix some string memory allocations. 7. Refactor pcilib_py_s member names. 8. Merge pcilib_script_read() and pcilib_script_write() to pcilib_script_run_func() 9. Update test_pywrap views scripts --- pcilib/error.h | 14 ++++ pcilib/pci.c | 4 +- pcilib/pcilib.h | 15 ---- pcilib/py.c | 180 ++++++++++++++++++++---------------------- pcilib/py.h | 12 +-- pcilib/xml.c | 2 +- pywrap/pcipywrap.c | 11 ++- views/transform.c | 8 +- xml/test_pywrap/test_prop2.py | 10 +-- xml/test_pywrap/test_prop3.py | 9 ++- 10 files changed, 129 insertions(+), 136 deletions(-) (limited to 'pywrap') diff --git a/pcilib/error.h b/pcilib/error.h index a9f4c0b..95774e9 100644 --- a/pcilib/error.h +++ b/pcilib/error.h @@ -40,6 +40,20 @@ extern "C" { void pcilib_log_message(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...); void pcilib_log_vmessage(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, va_list va); +/** + * Gets current logger function. + */ +pcilib_logger_t pcilib_get_logger(); + +/** + * Gets current logger min priority. + */ +pcilib_log_priority_t pcilib_get_logger_min_prio(); + +/** + * Gets current logger argument. + */ +void* pcilib_get_logger_argument(); #ifdef __cplusplus } diff --git a/pcilib/pci.c b/pcilib/pci.c index c38097f..58ee4b0 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -306,8 +306,6 @@ void pcilib_close(pcilib_t *ctx) { if (ctx->event_plugin) pcilib_plugin_close(ctx->event_plugin); - - pcilib_free_py(ctx); if (ctx->locks.kmem) pcilib_free_locking(ctx); @@ -349,6 +347,8 @@ void pcilib_close(pcilib_t *ctx) { if (ctx->registers) free(ctx->registers); + + pcilib_free_py(ctx); if (ctx->model) free(ctx->model); diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index 2458320..c32d1fb 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -263,21 +263,6 @@ extern "C" { */ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg); -/** - * Gets current logger function. - */ -pcilib_logger_t pcilib_get_logger(); - -/** - * Gets current logger min priority. - */ -pcilib_log_priority_t pcilib_get_logger_min_prio(); - -/** - * Gets current logger argument. - */ -void* pcilib_get_logger_argument(); - /** public_api_global * @} */ diff --git a/pcilib/py.c b/pcilib/py.c index 20fa546..038dba6 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -11,24 +11,20 @@ #include "py.h" #include "error.h" - - -struct pcilib_py_s { - PyObject *main_module; - PyObject *global_dict; - int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class -}; - typedef struct pcilib_script_s { - char* script_name; - PyObject *py_script_module; /**< PyModule object, contains script enviroment */ - PyObject *dict; + char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ pcilib_access_mode_t mode; UT_hash_handle hh; } pcilib_script_s; -struct pcilib_script_s *scripts = NULL; +struct pcilib_py_s { + PyObject *main_module; + PyObject *global_dict; + int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class + struct pcilib_script_s *scripts; +}; int pcilib_init_py(pcilib_t *ctx) { ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); @@ -37,6 +33,12 @@ int pcilib_init_py(pcilib_t *ctx) { if(!Py_IsInitialized()) { Py_Initialize(); + + //Since python is being initializing from c programm, it needs + //to initialize threads to works properly with c threads + PyEval_InitThreads(); + PyEval_ReleaseLock(); + ctx->py->py_initialized_inside = 1; } else @@ -70,6 +72,8 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } + + ctx->py->scripts = NULL; return 0; } @@ -237,53 +241,60 @@ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *va return pcilib_set_value_from_float(ctx, value, PyFloat_AsDouble(obj)); } -void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val) -{ +pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) +{ int err; switch(val->type) { case PCILIB_TYPE_INVALID: - pcilib_warning("Invalid register output type (PCILIB_TYPE_INVALID)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_INVALID)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_STRING: - pcilib_warning("Invalid register output type (PCILIB_TYPE_STRING)"); + pcilib_error("Invalid register output type (PCILIB_TYPE_STRING)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; return NULL; case PCILIB_TYPE_LONG: { - long ret; - ret = pcilib_get_value_as_int(ctx, val, &err); + long ret_val; + ret_val = pcilib_get_value_as_int(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyInt_FromLong((long) ret); + + if (ret) *ret = 0; + return (PyObject*)PyInt_FromLong((long) ret_val); } case PCILIB_TYPE_DOUBLE: { - double ret; - ret = pcilib_get_value_as_float(ctx, val, &err); + double ret_val; + ret_val = pcilib_get_value_as_float(ctx, val, &err); if(err) { - pcilib_error("Failed: pcilib_get_value_as_int (%i)", err); + if (ret) *ret = err; return NULL; } - return (PyObject*)PyFloat_FromDouble((double) ret); + + if (ret) *ret = 0; + return (PyObject*)PyFloat_FromDouble((double) ret_val); } default: - pcilib_warning("Invalid register output type (unknown)"); + if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; + pcilib_error("Invalid register output type (unknown)"); return NULL; } } -int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyObjVal, pcilib_value_t *val) +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { PyObject* pyVal = pyObjVal; int err; @@ -321,7 +332,7 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t } pcilib_script_s* module = NULL; - HASH_FIND_STR( scripts, module_name, module); + HASH_FIND_STR( ctx->py->scripts, module_name, module); if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); @@ -366,10 +377,16 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); - module->py_script_module = py_script_module; - module->script_name = malloc(strlen(module_name)); - sprintf(module->script_name, "%s", module_name); - module->dict = dict; + if (!module) + return PCILIB_ERROR_MEMORY; + module->module = py_script_module; + module->name = strdup(module_name); + if(!(module->name)) + { + free(module); + return PCILIB_ERROR_MEMORY; + } + sprintf(module->name, "%s", module_name); //Setting correct mode @@ -380,15 +397,15 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t mode[0] |= PCILIB_ACCESS_W; module->mode = mode[0]; - HASH_ADD_STR( scripts, script_name, module); + HASH_ADD_STR( ctx->py->scripts, name, module); return 0; } -int pcilib_py_free_script(char* module_name) +int pcilib_py_free_script(pcilib_t *ctx,char* module_name) { pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { @@ -397,39 +414,51 @@ int pcilib_py_free_script(char* module_name) return 0; } - if(module->script_name) + if(module->name) { - free(module->script_name); - module->script_name = NULL; + free(module->name); + module->name = NULL; } - if(module->py_script_module) + if(module->module) { - //PyObject_Free(module->py_script_module); - module->py_script_module = NULL; + module->module = NULL; } - HASH_DEL(scripts, module); + HASH_DEL(ctx->py->scripts, module); free(module); return 0; } -int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) -{ +int pcilib_script_run_func(pcilib_t *ctx, char* module_name, + const char* func_name, pcilib_value_t *val) +{ + int err; pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - + HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { pcilib_error("Failed to find script module (%s) in hash", module_name); return PCILIB_ERROR_NOTFOUND; } - int err; - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethod(module->py_script_module, "read_from_register", "()"); + PyObject *input = pcilib_get_value_as_pyobject(ctx, val, &err); + if(err) + return err; + + PyObject *py_func_name = PyUnicode_FromString(func_name); + PyObject *ret = PyObject_CallMethodObjArgs(module->module, + py_func_name, + input, + NULL); + + + + Py_XDECREF(py_func_name); + Py_XDECREF(input); PyGILState_Release(gstate); + if (!ret) { printf("Python script error: "); @@ -437,55 +466,16 @@ int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val) return PCILIB_ERROR_FAILED; } - err = pcilib_set_value_from_pyobject(ctx, ret, val); - Py_XDECREF(ret); - - 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, char* module_name, pcilib_value_t *val) -{ - pcilib_script_s *module; - HASH_FIND_STR(scripts, module_name, module); - - if(!module) - { - pcilib_error("Failed to find script module (%s) in hash", module_name); - return PCILIB_ERROR_NOTFOUND; - } - - PyObject *input = pcilib_get_value_as_pyobject(ctx, val); - if(!input) + if(ret != Py_None) { - printf("Failed to convert input value to Python object"); - PyErr_Print(); - return PCILIB_ERROR_FAILED; - } - PyObject *func_name = PyUnicode_FromString("write_to_register"); + err = pcilib_set_value_from_pyobject(ctx, val, ret); + Py_XDECREF(ret); - PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject *ret = PyObject_CallMethodObjArgs(module->py_script_module, - func_name, - input, - NULL); - PyGILState_Release(gstate); - - if (!ret) - { - printf("Python script error: "); - PyErr_Print(); - return PCILIB_ERROR_FAILED; + if(err) + { + pcilib_error("Failed to convert python script return value to internal type: %i", err); + return err; + } } - - //release objects - Py_XDECREF(func_name); - Py_XDECREF(ret); - Py_XDECREF(input); - return 0; } diff --git a/pcilib/py.h b/pcilib/py.h index 09e2b87..9703706 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -4,6 +4,7 @@ #include "pcilib.h" typedef struct pcilib_py_s pcilib_py_t; +typedef void pcilib_py_object; #ifdef __cplusplus extern "C" { @@ -15,10 +16,9 @@ void pcilib_free_py(pcilib_t *ctx); int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); -int pcilib_py_free_script(char* module_name); -int pcilib_script_read(pcilib_t *ctx, char* module_name, pcilib_value_t *val); -int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); - +int pcilib_py_free_script(pcilib_t *ctx,char* module_name); +int pcilib_script_run_func(pcilib_t *ctx, char* module_name, + const char* func_name, pcilib_value_t *val); /*! * \brief Converts pcilib_value_t to PyObject. @@ -26,7 +26,7 @@ int pcilib_script_write(pcilib_t *ctx, char* module_name, pcilib_value_t *val); * \param val pointer to pcilib_value_t to convert * \return PyObject, containing value. NULL with error message, sended to errstream. */ -void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); +pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *err); /*! @@ -36,7 +36,7 @@ void* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val); * \param val initialized polymorphic value * \return 0 on success or memory error */ -int pcilib_set_value_from_pyobject(pcilib_t* ctx, void* pyVal, pcilib_value_t *val); +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal); #ifdef __cplusplus diff --git a/pcilib/xml.c b/pcilib/xml.c index 4e95437..adca34e 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -600,7 +600,7 @@ 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")) { - desc.module = malloc(strlen(value)); + desc.module = strdup(value); sprintf(desc.module, "%s", value); break; } diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index b1ee630..40dbdfc 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -127,7 +127,6 @@ PyObject* create_pcilib_instance(const char *fpga_device, const char *model) pcilib_error("#E Failed pcilib_open(%s, %s)", fpga_device, model); return NULL; } - return PyCObject_FromVoidPtr((void*)ctx, close_pcilib_instance); } @@ -204,7 +203,7 @@ PyObject* read_register(const char *regname, const char *bank) return NULL; } - return pcilib_get_value_as_pyobject(__ctx, &val); + return pcilib_get_value_as_pyobject(__ctx, &val, NULL); } /*! @@ -228,7 +227,7 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) int err; - err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val); if(err) { @@ -279,7 +278,7 @@ PyObject* get_property(const char *prop) return NULL; } - return pcilib_get_value_as_pyobject(__ctx, &val); + return pcilib_get_value_as_pyobject(__ctx, &val, NULL); } /*! @@ -299,7 +298,7 @@ PyObject* set_property(PyObject* val, const char *prop) } pcilib_value_t val_internal = {0}; - err = pcilib_set_value_from_pyobject(__ctx, val, &val_internal); + err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val); if(err) { pcilib_error("#E pcilib_set_value_from_pyobject, (error %i)", err); @@ -339,7 +338,7 @@ void pcilib_pylist_append(PyObject* list, PyObject* value) void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) { - PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val); + PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val, NULL); if(py_val) pcilib_pydict_set_item(dict, diff --git a/views/transform.c b/views/transform.c index 75b95b2..24434e3 100644 --- a/views/transform.c +++ b/views/transform.c @@ -22,7 +22,8 @@ static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view if (err) return err; if(v->module) - return pcilib_script_read(ctx, v->module, val); + return err = pcilib_script_run_func(ctx, v->module, + "read_from_register", val); else return pcilib_py_eval_string(ctx, v->read_from_reg, val); } @@ -40,7 +41,8 @@ static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *vie if(v->module) - err = pcilib_script_write(ctx, v->module, &val_copy); + err = pcilib_script_run_func(ctx, v->module, + "write_to_register", &val_copy); else err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); @@ -55,7 +57,7 @@ void pcilib_transform_view_free_description (pcilib_t *ctx, pcilib_view_descript pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(view); if(v->module) - pcilib_py_free_script(v->module); + pcilib_py_free_script(ctx, v->module); } pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_view_description_t *desc) diff --git a/xml/test_pywrap/test_prop2.py b/xml/test_pywrap/test_prop2.py index 69a2190..d7e10bc 100644 --- a/xml/test_pywrap/test_prop2.py +++ b/xml/test_pywrap/test_prop2.py @@ -1,8 +1,8 @@ import pcipywrap + +def read_from_register(value): + return pcipywrap.get_property('/test/prop3') / 2 -def read_from_register(): - return pcipywrap.get_property('/registers/fpga/reg1') / 2 - -def write_to_register(value): - pcipywrap.set_property(value*3, '/registers/fpga/reg1') +def write_to_register(value): + pcipywrap.set_property(value*2, '/test/prop3') diff --git a/xml/test_pywrap/test_prop3.py b/xml/test_pywrap/test_prop3.py index c1300b3..9d33b63 100644 --- a/xml/test_pywrap/test_prop3.py +++ b/xml/test_pywrap/test_prop3.py @@ -1,4 +1,7 @@ -import os +import pcipywrap + +def read_from_register(value): + return pcipywrap.get_property('/registers/fpga/reg1') -def read_from_register(): - return 10; +def write_to_register(value): + pcipywrap.set_property(value, '/registers/fpga/reg1') -- cgit v1.2.3 From 3269dce32883e14b45cc490a0cc0037b4c808a68 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 11:01:22 +0100 Subject: 1. Add cmake BUILD_PYTHON_MODULES option. 2. Rename log options getting functions. 3. py: - pcilib_init_py() - extract pcilib_py_add_script_dir() - pcilib_py_init_script() - extract view-specialized code to pcilib_py_get_transform_script_properties() 3. pcilib_open(): - move pcilib_init_py() to previous position. - add extract pcilib_py_add_script_dir() 4. pcilib_script_s - change hash key. Now it is (const char*) and contains script file name with extension 5. pcipywrap: - Add pcipywrap.h to remove swig generated file complile warnings - remove -includeall swig flag to prevent crash in multi-thread scripts - change set python expetion mechanic --- CMakeLists.txt | 16 ++++-- pcilib/error.c | 4 +- pcilib/error.h | 4 +- pcilib/pci.c | 11 +++- pcilib/py.c | 124 ++++++++++++++++++++++++++++++---------------- pcilib/py.h | 11 ++-- pcilib/xml.c | 3 +- pywrap/CMakeLists.txt | 5 +- pywrap/pcipywrap.c | 135 ++++++++++++++++++-------------------------------- pywrap/pcipywrap.i | 4 ++ views/transform.c | 17 +++++-- views/transform.h | 2 +- 12 files changed, 180 insertions(+), 156 deletions(-) (limited to 'pywrap') diff --git a/CMakeLists.txt b/CMakeLists.txt index e5c8b82..846623f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,8 @@ cmake_minimum_required(VERSION 2.8) #set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH true) #set(CMAKE_PREFIX_PATH ${CMAKE_SYSTEM_PREFIX_PATH}) -set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") +set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") +set(BUILD_PYTHON_MODULES FALSE CACHE BOOL "Build pcilib python modules") #list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -35,8 +36,12 @@ SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) -find_package(PythonLibs 2.7 REQUIRED) -find_package(SWIG REQUIRED) + +if (BUILD_PYTHON_MODULES) + find_package(PythonLibs 2.7 REQUIRED) + find_package(SWIG REQUIRED) + add_definitions(-DBUILD_PYTHON_MODULES) +endif (BUILD_PYTHON_MODULES) set(EXTRA_SYSTEM_LIBS -lrt) @@ -79,11 +84,14 @@ add_subdirectory(dma) add_subdirectory(protocols) add_subdirectory(views) add_subdirectory(pcilib) -add_subdirectory(pywrap) add_subdirectory(pcitool) add_subdirectory(apps) add_subdirectory(xml) +if (BUILD_PYTHON_MODULES) + add_subdirectory(pywrap) +endif (BUILD_PYTHON_MODULES) + set_target_properties(pcilib PROPERTIES VERSION ${PCILIB_VERSION} SOVERSION ${PCILIB_ABI_VERSION} diff --git a/pcilib/error.c b/pcilib/error.c index 87380e7..a2e5a04 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -80,10 +80,10 @@ int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, vo pcilib_logger_t pcilib_get_logger() { return pcilib_logger; } -pcilib_log_priority_t pcilib_get_logger_min_prio() { +pcilib_log_priority_t pcilib_get_log_level() { return pcilib_logger_min_prio; } -void* pcilib_get_logger_argument() { +void* pcilib_get_logger_context() { return pcilib_logger_argument; } diff --git a/pcilib/error.h b/pcilib/error.h index 95774e9..051ecd8 100644 --- a/pcilib/error.h +++ b/pcilib/error.h @@ -48,12 +48,12 @@ pcilib_logger_t pcilib_get_logger(); /** * Gets current logger min priority. */ -pcilib_log_priority_t pcilib_get_logger_min_prio(); +pcilib_log_priority_t pcilib_get_log_level(); /** * Gets current logger argument. */ -void* pcilib_get_logger_argument(); +void* pcilib_get_logger_context(); #ifdef __cplusplus } diff --git a/pcilib/pci.c b/pcilib/pci.c index 58ee4b0..2b7b97b 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -144,6 +144,13 @@ pcilib_t *pcilib_open(const char *device, const char *model) { pcilib_close(ctx); return NULL; } + + err = pcilib_init_py(ctx); + if (err) { + pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_close(ctx); + return NULL; + } ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE; ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE; @@ -185,9 +192,9 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - err = pcilib_init_py(ctx); + err = pcilib_py_add_script_dir(ctx); if (err) { - pcilib_error("Error (%i) initializing python subsystem", err); + pcilib_error("Error (%i) add script path to python path", err); pcilib_close(ctx); return NULL; } diff --git a/pcilib/py.c b/pcilib/py.c index 038dba6..8f8040e 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -1,4 +1,6 @@ +#ifdef BUILD_PYTHON_MODULES #include +#endif #include #include @@ -11,11 +13,10 @@ #include "py.h" #include "error.h" +#ifdef BUILD_PYTHON_MODULES typedef struct pcilib_script_s { - char* name; - PyObject *module; /**< PyModule object, contains script enviroment */ - pcilib_access_mode_t mode; - + const char* name; + PyObject *module; /**< PyModule object, contains script enviroment */ UT_hash_handle hh; } pcilib_script_s; @@ -25,8 +26,10 @@ struct pcilib_py_s { int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; +#endif int pcilib_init_py(pcilib_t *ctx) { +#ifdef BUILD_PYTHON_MODULES ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; @@ -53,6 +56,16 @@ int pcilib_init_py(pcilib_t *ctx) { return PCILIB_ERROR_FAILED; + + + ctx->py->scripts = NULL; +#endif + return 0; +} + +int pcilib_py_add_script_dir(pcilib_t *ctx) +{ +#ifdef BUILD_PYTHON_MODULES //create path string, where the model scripts should be static int model_dir_added = 0; if(!model_dir_added) @@ -72,13 +85,12 @@ int pcilib_init_py(pcilib_t *ctx) { free(model_path); model_dir_added = 1; } - - ctx->py->scripts = NULL; - return 0; +#endif + return 0; } void pcilib_free_py(pcilib_t *ctx) { - +#ifdef BUILD_PYTHON_MODULES int py_initialized_inside = 0; if (ctx->py) { @@ -92,6 +104,7 @@ void pcilib_free_py(pcilib_t *ctx) { if(py_initialized_inside) Py_Finalize(); +#endif } /* @@ -110,7 +123,7 @@ static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size return 0; } */ - +#ifdef BUILD_PYTHON_MODULES static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { int i; int err = 0; @@ -216,8 +229,10 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v return dst; } +#endif int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { +#ifdef BUILD_PYTHON_MODULES PyGILState_STATE gstate; char *code; PyObject* obj; @@ -239,10 +254,15 @@ 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)); +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; switch(val->type) @@ -292,10 +312,16 @@ pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *va pcilib_error("Invalid register output type (unknown)"); return NULL; } +#else + pcilib_error("Current build not support python."); + if (ret) *ret = PCILIB_ERROR_NOTAVAILABLE; + return NULL; +#endif } int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal) { +#ifdef BUILD_PYTHON_MODULES PyObject* pyVal = pyObjVal; int err; @@ -318,12 +344,18 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py return err; return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } -int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode) -{ +int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) +{ +#ifdef BUILD_PYTHON_MODULES //extract module name from script name - char* py_module_name = strtok(module_name, "."); + char* py_module_name = strdup(module_name); + py_module_name = strtok(py_module_name, "."); if(!py_module_name) { pcilib_error("Invalid script name specified in XML property (%s)." @@ -336,26 +368,19 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if(module) { pcilib_warning("Python module %s is already in hash. Skip init step", module_name); - mode[0] = module->mode; return 0; } - //Initialize python module - if(!module_name) - { - pcilib_error("Invalid script name specified in XML property (NULL)"); - 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(); + free(py_module_name); return PCILIB_ERROR_INVALID_DATA; } + free(py_module_name); //Initializing pcipywrap module if script use it PyObject* dict = PyModule_GetDict(py_script_module); @@ -380,45 +405,50 @@ int pcilib_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t if (!module) return PCILIB_ERROR_MEMORY; module->module = py_script_module; - module->name = strdup(module_name); - if(!(module->name)) + module->name = module_name; + HASH_ADD_STR( ctx->py->scripts, name, module); +#endif + return 0; +} + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char* module_name, +pcilib_access_mode_t *mode) +{ +#ifdef BUILD_PYTHON_MODULES + pcilib_script_s *module; + + HASH_FIND_STR(ctx->py->scripts, module_name, module); + if(!module) { - free(module); - return PCILIB_ERROR_MEMORY; + pcilib_error("Failed to find script module (%s) in hash", module_name); + return PCILIB_ERROR_NOTFOUND; } - sprintf(module->name, "%s", module_name); - + PyObject* dict = PyModule_GetDict(module->module); //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; - - module->mode = mode[0]; - HASH_ADD_STR( ctx->py->scripts, name, module); - + mode[0] |= PCILIB_ACCESS_W; return 0; +#else + mode[0] = PCILIB_ACCESS_RW; + return 0; +#endif } -int pcilib_py_free_script(pcilib_t *ctx,char* module_name) +int pcilib_py_free_script(pcilib_t *ctx, const char* module_name) { +#ifdef BUILD_PYTHON_MODULES pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); if(!module) { - //For some reason it will crash if uncomment. printf same warning is ok - //pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); + pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); return 0; } - - if(module->name) - { - free(module->name); - module->name = NULL; - } if(module->module) { @@ -427,12 +457,14 @@ int pcilib_py_free_script(pcilib_t *ctx,char* module_name) HASH_DEL(ctx->py->scripts, module); free(module); +#endif return 0; } -int pcilib_script_run_func(pcilib_t *ctx, char* module_name, +int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, const char* func_name, pcilib_value_t *val) -{ +{ +#ifdef BUILD_PYTHON_MODULES int err; pcilib_script_s *module; HASH_FIND_STR(ctx->py->scripts, module_name, module); @@ -478,4 +510,8 @@ int pcilib_script_run_func(pcilib_t *ctx, char* module_name, } } return 0; +#else + pcilib_error("Current build not support python."); + return PCILIB_ERROR_NOTAVAILABLE; +#endif } diff --git a/pcilib/py.h b/pcilib/py.h index 9703706..04b4e8b 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -11,14 +11,19 @@ extern "C" { #endif int pcilib_init_py(pcilib_t *ctx); +int pcilib_py_add_script_dir(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_py_init_script(pcilib_t *ctx, char* module_name, pcilib_access_mode_t *mode); -int pcilib_py_free_script(pcilib_t *ctx,char* module_name); -int pcilib_script_run_func(pcilib_t *ctx, char* module_name, +int pcilib_py_init_script(pcilib_t *ctx, const char* module_name); +int pcilib_py_free_script(pcilib_t *ctx, const char* module_name); +int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, const char* func_name, pcilib_value_t *val); + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, + const char* module_name, + pcilib_access_mode_t *mode); /*! * \brief Converts pcilib_value_t to PyObject. diff --git a/pcilib/xml.c b/pcilib/xml.c index adca34e..35721aa 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -600,8 +600,7 @@ 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")) { - desc.module = strdup(value); - sprintf(desc.module, "%s", value); + desc.module = value; break; } } diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index e5f7ea7..d4d75d1 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -8,14 +8,13 @@ include_directories( ${UTHASH_INCLUDE_DIRS} ) +set(HEADERS pcipywrap.h) + #Creating python wrapping INCLUDE(${SWIG_USE_FILE}) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) - SET(CMAKE_SWIG_FLAGS "") -SET_SOURCE_FILES_PROPERTIES(pcipywrap.i PROPERTIES SWIG_FLAGS "-includeall") SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c) SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index 40dbdfc..639fa15 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -1,6 +1,4 @@ -#include "pci.h" -#include "error.h" -#include +#include "pcipywrap.h" /*! * \brief Global pointer to pcilib_t context. @@ -63,25 +61,11 @@ void pcilib_print_error_to_py(void *arg, const char *file, int line, { if(!full_log) full_log = make_str(""); - - if(strlen(buf_wrapped_message) >= 2 && - buf_wrapped_message[0] == '#' && - buf_wrapped_message[1] == 'E') - { - char* wrapped_exeption = make_str("%sprogramm error log:\n%s", &(buf_wrapped_message[2]), full_log); - free(full_log); - full_log = NULL; - PyErr_SetString(PyExc_Exception, wrapped_exeption); - free(wrapped_exeption); - } - else - { - //copy received message to log - char* buf = full_log; - full_log = make_str("%s%s", buf, buf_wrapped_message); - free(buf); - } + //copy received message to log + char* buf = full_log; + full_log = make_str("%s%s", buf, buf_wrapped_message); + free(buf); } else printf(buf_wrapped_message); @@ -90,17 +74,35 @@ void pcilib_print_error_to_py(void *arg, const char *file, int line, free(buf_raw_msg); } -/*! - * \brief Redirect pcilib standart log stream to exeption text. - * Logger will accumulate errors untill get message, starts with "#E". - * After that, logger will write last error, and all accumulated errors - * to Python exeption text - */ +void set_python_exception(const char* msg, ...) +{ + va_list vl; + va_start(vl, msg); + char *buf = vmake_str(msg, vl); + + char* wrapped_exeption; + if(full_log) + wrapped_exeption = make_str("%s\nprogramm error log:\n%s", buf, full_log); + else + wrapped_exeption = buf; + + free(full_log); + full_log = NULL; + + PyErr_SetString(PyExc_Exception, wrapped_exeption); + + free(buf); + if(full_log) + free(wrapped_exeption); + va_end(vl); +} + + void __redirect_logs_to_exeption() { - pcilib_set_logger(pcilib_get_logger_min_prio(), + pcilib_set_logger(pcilib_get_log_level(), pcilib_print_error_to_py, - pcilib_get_logger_argument()); + pcilib_get_logger_context()); } /*! @@ -112,27 +114,18 @@ void close_pcilib_instance(void *ctx) pcilib_close(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; NULL with exeption text, if failed. - */ PyObject* create_pcilib_instance(const char *fpga_device, const char *model) { //opening device pcilib_t* ctx = pcilib_open(fpga_device, model); if(!ctx) { - pcilib_error("#E Failed pcilib_open(%s, %s)", fpga_device, model); + set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model); return NULL; } return PyCObject_FromVoidPtr((void*)ctx, close_pcilib_instance); } -/*! - * \brief Closes current pciliv instance, if its open. - */ void close_curr_pcilib_instance() { if(__ctx) @@ -142,25 +135,16 @@ void close_curr_pcilib_instance() } } -/*! - * \brief Returns current opened pcilib_t instatnce - * \return Pointer to pcilib_t, serialized to bytearray - */ PyObject* get_curr_pcilib_instance() { return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*)); } -/*! - * \brief Sets pcilib context to wraper. - * \param[in] addr Pointer to pcilib_t, serialized to PyCObject - * \return 1, serialized to PyObject or NULL with exeption text, if failed. - */ PyObject* set_pcilib(PyObject* addr) { if(!PyCObject_Check(addr)) { - pcilib_error("#E Incorrect addr type. Only PyCObject is allowed"); + set_python_exception("Incorrect addr type. Only PyCObject is allowed"); return NULL; } @@ -169,18 +153,11 @@ PyObject* set_pcilib(PyObject* addr) return PyInt_FromLong((long)1); } - -/*! - * \brief Reads register value. Wrap for pcilib_read_register function. - * \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; NULL with exeption text, if failed. - */ PyObject* read_register(const char *regname, const char *bank) { if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } @@ -192,27 +169,20 @@ PyObject* read_register(const char *regname, const char *bank) err = pcilib_read_register(__ctx, bank, regname, ®_value); if(err) { - pcilib_error("#E Failed pcilib_read_register"); + set_python_exception("Failed pcilib_read_register"); return NULL; } err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); if(err) { - pcilib_error("#E Failed pcilib_set_value_from_register_value"); + set_python_exception("Failed pcilib_set_value_from_register_value"); return NULL; } return pcilib_get_value_as_pyobject(__ctx, &val, NULL); } -/*! - * \brief Writes value to register. Wrap for pcilib_write_register function. - * \param[in] val Register value, that needs to be set. Can be int, float or string. - * \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 1, serialized to PyObject or NULL with exeption text, if failed. - */ PyObject* write_register(PyObject* val, const char *regname, const char *bank) { if(!__ctx) @@ -231,7 +201,7 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) if(err) { - pcilib_error("#E Failed pcilib_set_value_from_pyobject"); + set_python_exception("Failed pcilib_set_value_from_pyobject"); return NULL; } @@ -239,7 +209,7 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); if(err) { - pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); + set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; } @@ -247,23 +217,18 @@ PyObject* write_register(PyObject* val, const char *regname, const char *bank) if(err) { - pcilib_error("#E Failed pcilib_set_value_from_pyobject, (error %i)", err); + set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); return NULL; } return PyInt_FromLong((long)1); } -/*! - * \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* get_property(const char *prop) { if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } @@ -274,26 +239,20 @@ PyObject* get_property(const char *prop) if(err) { - pcilib_error("#E Failed pcilib_get_property, (error %i)", err); + set_python_exception("Failed pcilib_get_property, (error %i)", err); return NULL; } return pcilib_get_value_as_pyobject(__ctx, &val, NULL); } -/*! - * \brief Writes value to property. Wrap for pcilib_set_property function. - * \param[in] prop property name (full name including path) - * \param[in] val Property value, that needs to be set. Can be int, float or string. - * \return 1, serialized to PyObject or NULL with exeption text, if failed. - */ PyObject* set_property(PyObject* val, const char *prop) { int err; if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } @@ -301,14 +260,14 @@ PyObject* set_property(PyObject* val, const char *prop) err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val); if(err) { - pcilib_error("#E pcilib_set_value_from_pyobject, (error %i)", err); + set_python_exception("pcilib_set_value_from_pyobject, (error %i)", err); return NULL; } err = pcilib_set_property(__ctx, prop, &val_internal); if(err) { - pcilib_error("#E pcilib_set_property, (error %i)", err); + set_python_exception("pcilib_set_property, (error %i)", err); return NULL; } @@ -536,7 +495,7 @@ PyObject* get_registers_list(const char *bank) { if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } @@ -559,7 +518,7 @@ PyObject* get_register_info(const char* reg,const char *bank) { if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } @@ -581,7 +540,7 @@ PyObject* get_property_list(const char* branch) { if(!__ctx) { - pcilib_error("#E pcilib_t handler not initialized"); + set_python_exception("pcilib_t handler not initialized"); return NULL; } diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 86b6f36..952e145 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -1,5 +1,9 @@ %module pcipywrap +%{ +#include "pcipywrap.h" +%} + extern void __redirect_logs_to_exeption(); extern PyObject* create_pcilib_instance(const char *fpga_device, const char *model = NULL); diff --git a/views/transform.c b/views/transform.c index 24434e3..eb3572a 100644 --- a/views/transform.c +++ b/views/transform.c @@ -68,12 +68,21 @@ pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_v { pcilib_access_mode_t mode = 0; - int err = pcilib_py_init_script(ctx, v_desc->module, &mode); + int err = pcilib_py_init_script(ctx, v_desc->module); if(err) { - pcilib_error("Failed init script module (%s) - error %i", v_desc->module, err); + pcilib_error("Failed init script module (%s) - error %i", + v_desc->module, err); return NULL; - } + } + err = pcilib_py_get_transform_script_properties(ctx, v_desc->module, + &mode); + if(err) + { + pcilib_error("Failed get transform script properties (%s) - error %i", + v_desc->module, err); + return NULL; + } v_desc->base.mode |= PCILIB_REGISTER_RW; mode |= PCILIB_REGISTER_INCONSISTENT; @@ -87,7 +96,5 @@ pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, const pcilib_v return view_ctx; } - - const pcilib_view_api_description_t pcilib_transform_view_api = { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), pcilib_transform_view_init, NULL, pcilib_transform_view_free_description, pcilib_transform_view_read, pcilib_transform_view_write }; diff --git a/views/transform.h b/views/transform.h index c2f0a98..8c9321d 100644 --- a/views/transform.h +++ b/views/transform.h @@ -9,7 +9,7 @@ typedef struct { pcilib_view_description_t base; const char *read_from_reg; /**< Formula explaining how to convert the register value to the view value */ const char *write_to_reg; /**< Formula explaining how to convert from the view value to the register value */ - char *module; /**< Python script module name (without extension) */ + const char *module; /**< Python script module name (without extension) */ } pcilib_transform_view_description_t; #ifndef _PCILIB_VIEW_TRANSFORM_C -- cgit v1.2.3 From 9a9ffd5594a5d27bbecf6160de2c33d44870f5bd Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 17:20:25 +0100 Subject: Refactor pcipywrap to object --- CMakeLists.txt | 2 +- pcilib/py.c | 45 ++--- pywrap/pcipywrap.c | 380 ++++++++++++++++++------------------------ pywrap/pcipywrap.h | 68 ++++++++ pywrap/pcipywrap.i | 32 ++-- pywrap/server.py | 39 +++-- xml/test_pywrap/test_prop2.py | 10 +- xml/test_pywrap/test_prop3.py | 10 +- 8 files changed, 301 insertions(+), 285 deletions(-) create mode 100644 pywrap/pcipywrap.h (limited to 'pywrap') diff --git a/CMakeLists.txt b/CMakeLists.txt index 846623f..5bfff47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 2.8) #set(CMAKE_PREFIX_PATH ${CMAKE_SYSTEM_PREFIX_PATH}) set(DISABLE_PCITOOL FALSE CACHE BOOL "Build only the library") -set(BUILD_PYTHON_MODULES FALSE CACHE BOOL "Build pcilib python modules") +set(BUILD_PYTHON_MODULES TRUE CACHE BOOL "Build pcilib python modules") #list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") diff --git a/pcilib/py.c b/pcilib/py.c index 8f8040e..372d475 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -23,6 +23,7 @@ typedef struct pcilib_script_s { struct pcilib_py_s { PyObject *main_module; PyObject *global_dict; + PyObject *pcilib_pywrap; int py_initialized_inside; ///< Flag, shows that Py_Initialize has been called inside class struct pcilib_script_s *scripts; }; @@ -54,9 +55,30 @@ int pcilib_init_py(pcilib_t *ctx) { ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); if (!ctx->py->global_dict) return PCILIB_ERROR_FAILED; + + + + PyObject* py_script_module = PyImport_ImportModule("pcipywrap"); + if(!py_script_module) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } + PyObject* mod_name = PyString_FromString("Pcipywrap"); + ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(py_script_module, + mod_name, + PyCObject_FromVoidPtr(ctx, NULL), + NULL); + Py_XDECREF(mod_name); - + if(!ctx->py->pcilib_pywrap) + { + printf("Error in import python module: "); + PyErr_Print(); + return PCILIB_ERROR_FAILED; + } ctx->py->scripts = NULL; #endif @@ -381,24 +403,6 @@ int pcilib_py_init_script(pcilib_t *ctx, const char* module_name) return PCILIB_ERROR_INVALID_DATA; } free(py_module_name); - - //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("set_pcilib"), - PyCObject_FromVoidPtr(ctx, NULL), - NULL); - } //Success. Create struct and initialize values module = malloc(sizeof(pcilib_script_s)); @@ -482,10 +486,9 @@ int pcilib_script_run_func(pcilib_t *ctx, const char* module_name, PyObject *py_func_name = PyUnicode_FromString(func_name); PyObject *ret = PyObject_CallMethodObjArgs(module->module, py_func_name, + ctx->py->pcilib_pywrap, input, NULL); - - Py_XDECREF(py_func_name); Py_XDECREF(input); diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index 639fa15..11e3ce7 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -1,11 +1,5 @@ #include "pcipywrap.h" -/*! - * \brief Global pointer to pcilib_t context. - * Used by set_pcilib and read_register. - */ -pcilib_t* __ctx = 0; - char* full_log = NULL; /*! @@ -34,6 +28,7 @@ char* vmake_str(const char* msg, va_list vl) return buf; } + /*! * \brief Wraping for vsnprintf function, that saves string to char* * \return saved from vsnprintf string @@ -105,175 +100,6 @@ void __redirect_logs_to_exeption() pcilib_get_logger_context()); } -/*! - * Destructor for pcilib_t - */ -void close_pcilib_instance(void *ctx) -{ - if(ctx != __ctx) - pcilib_close(ctx); -} - -PyObject* create_pcilib_instance(const char *fpga_device, const char *model) -{ - //opening device - pcilib_t* ctx = pcilib_open(fpga_device, model); - if(!ctx) - { - set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model); - return NULL; - } - return PyCObject_FromVoidPtr((void*)ctx, close_pcilib_instance); -} - -void close_curr_pcilib_instance() -{ - if(__ctx) - { - pcilib_close(__ctx); - __ctx = NULL; - } -} - -PyObject* get_curr_pcilib_instance() -{ - return PyByteArray_FromStringAndSize((const char*)&__ctx, sizeof(pcilib_t*)); -} - -PyObject* set_pcilib(PyObject* addr) -{ - if(!PyCObject_Check(addr)) - { - set_python_exception("Incorrect addr type. Only PyCObject is allowed"); - return NULL; - } - - __ctx = (pcilib_t*)PyCObject_AsVoidPtr(addr); - - return PyInt_FromLong((long)1); -} - -PyObject* read_register(const char *regname, const char *bank) -{ - if(!__ctx) - { - set_python_exception("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_value_t val = {0}; - pcilib_register_value_t reg_value; - - int err; - - err = pcilib_read_register(__ctx, bank, regname, ®_value); - if(err) - { - set_python_exception("Failed pcilib_read_register"); - return NULL; - } - - err = pcilib_set_value_from_register_value(__ctx, &val, reg_value); - if(err) - { - set_python_exception("Failed pcilib_set_value_from_register_value"); - return NULL; - } - - return pcilib_get_value_as_pyobject(__ctx, &val, NULL); -} - -PyObject* write_register(PyObject* val, const char *regname, const char *bank) -{ - if(!__ctx) - { - pcilib_error("pcilib_t handler not initialized"); - return NULL; - } - - - pcilib_value_t val_internal = {0}; - pcilib_register_value_t reg_value; - - int err; - - err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val); - - if(err) - { - set_python_exception("Failed pcilib_set_value_from_pyobject"); - return NULL; - } - - - reg_value = pcilib_get_value_as_register_value(__ctx, &val_internal, &err); - if(err) - { - set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); - return NULL; - } - - err = pcilib_write_register(__ctx, bank, regname, reg_value); - - if(err) - { - set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); - return NULL; - } - - return PyInt_FromLong((long)1); -} - -PyObject* get_property(const char *prop) -{ - if(!__ctx) - { - set_python_exception("pcilib_t handler not initialized"); - return NULL; - } - - int err; - pcilib_value_t val = {0}; - - err = pcilib_get_property(__ctx, prop, &val); - - if(err) - { - set_python_exception("Failed pcilib_get_property, (error %i)", err); - return NULL; - } - - return pcilib_get_value_as_pyobject(__ctx, &val, NULL); -} - -PyObject* set_property(PyObject* val, const char *prop) -{ - int err; - - if(!__ctx) - { - set_python_exception("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_value_t val_internal = {0}; - err = pcilib_set_value_from_pyobject(__ctx, &val_internal, val); - if(err) - { - set_python_exception("pcilib_set_value_from_pyobject, (error %i)", err); - return NULL; - } - - err = pcilib_set_property(__ctx, prop, &val_internal); - if(err) - { - set_python_exception("pcilib_set_property, (error %i)", err); - return NULL; - } - - return PyInt_FromLong((long)1); -} - /*! * \brief Wrap for PyDict_SetItem, with decrease reference counting after set. */ @@ -295,9 +121,9 @@ void pcilib_pylist_append(PyObject* list, PyObject* value) Py_XDECREF(value); } -void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *name) +void add_pcilib_value_to_dict(pcilib_t* ctx, PyObject* dict, pcilib_value_t* val, const char *name) { - PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(__ctx, val, NULL); + PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(ctx, val, NULL); if(py_val) pcilib_pydict_set_item(dict, @@ -309,7 +135,7 @@ void add_pcilib_value_to_dict(PyObject* dict, pcilib_value_t* val, const char *n PyString_FromString("invalid")); } -PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listItem) +PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_property_info_t listItem) { PyObject* pylistItem = PyDict_New(); @@ -386,7 +212,7 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_property_info_t listI return pylistItem; } -PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listItem) +PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_register_info_t listItem) { PyObject* pylistItem = PyDict_New(); @@ -430,20 +256,20 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI modes); pcilib_value_t defval = {0}; - pcilib_set_value_from_register_value(__ctx, &defval, listItem.defvalue); - add_pcilib_value_to_dict(pylistItem, &defval, "defvalue"); + pcilib_set_value_from_register_value(ctx, &defval, listItem.defvalue); + add_pcilib_value_to_dict(ctx, pylistItem, &defval, "defvalue"); if(listItem.range) { pcilib_value_t minval = {0}; - pcilib_set_value_from_register_value(__ctx, &minval, listItem.range->min); - + pcilib_set_value_from_register_value(ctx, &minval, listItem.range->min); + pcilib_value_t maxval = {0}; - pcilib_set_value_from_register_value(__ctx, &maxval, listItem.range->max); + pcilib_set_value_from_register_value(ctx, &maxval, listItem.range->max); PyObject* range = PyDict_New(); - add_pcilib_value_to_dict(range, &minval, "min"); - add_pcilib_value_to_dict(range, &maxval, "max"); + 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"), range); @@ -458,17 +284,17 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI PyObject* valuesItem = PyDict_New(); pcilib_value_t val = {0}; - pcilib_set_value_from_register_value(__ctx, &val, listItem.values[j].value); + pcilib_set_value_from_register_value(ctx, &val, listItem.values[j].value); pcilib_value_t min = {0}; - pcilib_set_value_from_register_value(__ctx, &min, listItem.values[j].min); + pcilib_set_value_from_register_value(ctx, &min, listItem.values[j].min); pcilib_value_t max = {0}; - pcilib_set_value_from_register_value(__ctx, &max, listItem.values[j].max); + pcilib_set_value_from_register_value(ctx, &max, listItem.values[j].max); - add_pcilib_value_to_dict(valuesItem, &val, "value"); - add_pcilib_value_to_dict(valuesItem, &min, "min"); - add_pcilib_value_to_dict(valuesItem, &max, "max"); + add_pcilib_value_to_dict(ctx, valuesItem, &val, "value"); + add_pcilib_value_to_dict(ctx, valuesItem, &min, "min"); + add_pcilib_value_to_dict(ctx, valuesItem, &max, "max"); if(listItem.values[j].name) pcilib_pydict_set_item(valuesItem, @@ -491,71 +317,187 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_register_info_t listI return pylistItem; } -PyObject* get_registers_list(const char *bank) +Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model) { - if(!__ctx) + //opening device + pcilib_t* ctx = pcilib_open(fpga_device, model); + if(!ctx) + { + set_python_exception("Failed pcilib_open(%s, %s)", fpga_device, model); + return NULL; + } + Pcipywrap *self; + self = (Pcipywrap *) malloc(sizeof(Pcipywrap)); + self->shared = 0; + self->ctx = ctx; + return self; +} + +Pcipywrap *create_Pcipywrap(PyObject* ctx) +{ + if(!PyCObject_Check(ctx)) { - set_python_exception("pcilib_t handler not initialized"); + set_python_exception("Incorrect ctx type. Only PyCObject is allowed"); return NULL; } - pcilib_register_info_t *list = pcilib_get_register_list(__ctx, bank, PCILIB_LIST_FLAGS_DEFAULT); + Pcipywrap *self; + self = (Pcipywrap *) malloc(sizeof(Pcipywrap)); + self->shared = 1; + self->ctx = PyCObject_AsVoidPtr(ctx); + return 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) +{ + pcilib_value_t val = {0}; + pcilib_register_value_t reg_value; + + int err; + + err = pcilib_read_register(self->ctx, bank, regname, ®_value); + if(err) + { + set_python_exception("Failed pcilib_read_register"); + return NULL; + } + + err = pcilib_set_value_from_register_value(self->ctx, &val, reg_value); + if(err) + { + set_python_exception("Failed pcilib_set_value_from_register_value"); + return NULL; + } + + return pcilib_get_value_as_pyobject(self->ctx, &val, NULL); +} + +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; + + int err; + + err = pcilib_set_value_from_pyobject(self->ctx, &val_internal, val); + + if(err) + { + set_python_exception("Failed pcilib_set_value_from_pyobject"); + return NULL; + } + + + reg_value = pcilib_get_value_as_register_value(self->ctx, &val_internal, &err); + if(err) + { + set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); + return NULL; + } + + err = pcilib_write_register(self->ctx, bank, regname, reg_value); + + if(err) + { + set_python_exception("Failed pcilib_set_value_from_pyobject, (error %i)", err); + return NULL; + } + + return PyInt_FromLong((long)1); +} + +PyObject* Pcipywrap_get_property(Pcipywrap *self, const char *prop) +{ + int err; + pcilib_value_t val = {0}; + + err = pcilib_get_property(self->ctx, prop, &val); + + if(err) + { + set_python_exception("Failed pcilib_get_property, (error %i)", err); + return NULL; + } + + return pcilib_get_value_as_pyobject(self->ctx, &val, NULL); +} + +PyObject* Pcipywrap_set_property(Pcipywrap *self, PyObject* val, const char *prop) +{ + int err; + + pcilib_value_t val_internal = {0}; + err = pcilib_set_value_from_pyobject(self->ctx, &val_internal, val); + if(err) + { + set_python_exception("pcilib_set_value_from_pyobject, (error %i)", err); + return NULL; + } + + err = pcilib_set_property(self->ctx, prop, &val_internal); + if(err) + { + set_python_exception("pcilib_set_property, (error %i)", err); + return NULL; + } + + return PyInt_FromLong((long)1); +} + +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 < __ctx->num_reg; i++) + for(int i = 0; i < ((pcilib_t*)self->ctx)->num_reg; i++) { //serialize item attributes - PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(list[i]); + PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(self->ctx, list[i]); pcilib_pylist_append(pyList, pylistItem); } - pcilib_free_register_info(__ctx, list); + pcilib_free_register_info(self->ctx, list); return pyList; } -PyObject* get_register_info(const char* reg,const char *bank) +PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const char *bank) { - if(!__ctx) - { - set_python_exception("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_register_info_t *info = pcilib_get_register_info(__ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT); + pcilib_register_info_t *info = pcilib_get_register_info(self->ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT); if(!info) { return NULL; } - PyObject* py_info = pcilib_convert_register_info_to_pyobject(info[0]); + PyObject* py_info = pcilib_convert_register_info_to_pyobject(self->ctx, info[0]); - pcilib_free_register_info(__ctx, info); + pcilib_free_register_info(self->ctx, info); return py_info; } -PyObject* get_property_list(const char* branch) +PyObject* Pcipywrap_get_property_list(Pcipywrap *self, const char* branch) { - if(!__ctx) - { - set_python_exception("pcilib_t handler not initialized"); - return NULL; - } - - pcilib_property_info_t *list = pcilib_get_property_list(__ctx, branch, PCILIB_LIST_FLAGS_DEFAULT); + pcilib_property_info_t *list = pcilib_get_property_list(self->ctx, branch, PCILIB_LIST_FLAGS_DEFAULT); PyObject* pyList = PyList_New(0); for(int i = 0; list[i].path; i++) { //serialize item attributes - PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(list[i]); + PyObject* pylistItem = pcilib_convert_property_info_to_pyobject(self->ctx, list[i]); pcilib_pylist_append(pyList, pylistItem); } - pcilib_free_property_info(__ctx, list); + pcilib_free_property_info(self->ctx, list); return pyList; } diff --git a/pywrap/pcipywrap.h b/pywrap/pcipywrap.h new file mode 100644 index 0000000..8389445 --- /dev/null +++ b/pywrap/pcipywrap.h @@ -0,0 +1,68 @@ +#ifndef PCIPYWRAP_H +#define PCIPYWRAP_H + +#include "pci.h" +#include "error.h" +#include + +typedef struct { + void* ctx; + int shared; +} Pcipywrap; + +/*! + * \brief Redirect pcilib standart log stream to exeption text. + * Logger will accumulate errors untill get message, starts with "#E". + * After that, logger will write last error, and all accumulated errors + * to Python exeption text + */ +void __redirect_logs_to_exeption(); + +/*! + * \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; NULL with exeption text, if failed. + */ +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); + +/*! + * \brief Reads register value. Wrap for pcilib_read_register function. + * \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; NULL with exeption text, if failed. + */ +PyObject* Pcipywrap_read_register(Pcipywrap *self, const char *regname, const char *bank); + +/*! + * \brief Writes value to register. Wrap for pcilib_write_register function. + * \param[in] val Register value, that needs to be set. Can be int, float or string. + * \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 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); + +/*! + * \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); + +/*! + * \brief Writes value to property. Wrap for pcilib_set_property function. + * \param[in] prop property name (full name including path) + * \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); + +#endif /* PCIPYWRAP_H */ diff --git a/pywrap/pcipywrap.i b/pywrap/pcipywrap.i index 952e145..88a746f 100644 --- a/pywrap/pcipywrap.i +++ b/pywrap/pcipywrap.i @@ -6,18 +6,20 @@ extern void __redirect_logs_to_exeption(); -extern PyObject* create_pcilib_instance(const char *fpga_device, const char *model = NULL); -extern PyObject* set_pcilib(PyObject* addr); -extern void close_curr_pcilib_instance(); -extern PyObject* get_curr_pcilib_instance(); - -extern PyObject* read_register(const char *regname, const char *bank = NULL); -extern PyObject* write_register(PyObject* val, const char *regname, const char *bank = NULL); - -extern PyObject* get_property(const char *prop); -extern PyObject* set_property(PyObject* val, const char *prop); - -extern PyObject* get_registers_list(const char *bank = NULL); -extern PyObject* get_register_info(const char* reg,const char *bank = NULL); - -extern PyObject* get_property_list(const char* branch = NULL); +typedef struct { + %extend { + Pcipywrap(const char* fpga_device = NULL, 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); + + PyObject* get_property(const char *prop); + PyObject* set_property(PyObject* val, const char *prop); + + PyObject* get_registers_list(const char *bank = NULL); + PyObject* get_register_info(const char* reg,const char *bank = NULL); + PyObject* get_property_list(const char* branch = NULL); + } +} Pcipywrap; diff --git a/pywrap/server.py b/pywrap/server.py index acba791..03302a2 100644 --- a/pywrap/server.py +++ b/pywrap/server.py @@ -7,7 +7,10 @@ import sys from optparse import OptionParser class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): - + def __init__(s, pcilib, *args): + s.pcilib = pcilib + BaseHTTPServer.BaseHTTPRequestHandler.__init__(s, *args) + def do_HEAD(s): s.send_response(200) s.send_header('content-type', 'application/json') @@ -58,7 +61,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): registers = dict() try: - registers = pcipywrap.get_registers_list(bank) + registers = s.pcilib.get_registers_list(bank) except Exception as e: s.error(str(e), data) return @@ -87,7 +90,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): register = dict() try: - register = pcipywrap.get_register_info(reg, bank) + register = s.pcilib.get_register_info(reg, bank) except Exception as e: s.error(str(e), data) return @@ -109,7 +112,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): properties = dict() try: - properties = pcipywrap.get_property_list(branch) + properties = s.pcilib.get_property_list(branch) except Exception as e: s.error(str(e), data) return @@ -138,7 +141,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): value = 0 try: - value = pcipywrap.read_register(reg, bank) + value = s.pcilib.read_register(reg, bank) except Exception as e: s.error(str(e), data) return @@ -172,7 +175,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): bank = str(bank) try: - pcipywrap.write_register(value, reg, bank) + s.pcilib.write_register(value, reg, bank) except Exception as e: s.error(str(e), data) return @@ -197,7 +200,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): value = 0 try: - value = pcipywrap.get_property(prop) + value = s.pcilib.get_property(prop) except Exception as e: s.error(str(e), data) return @@ -228,7 +231,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): value = str(data.get('value', None)) try: - pcipywrap.set_property(value, prop) + s.pcilib.set_property(value, prop) except Exception as e: s.error(str(e), data) return @@ -255,10 +258,7 @@ class PcilibServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): """open device context """ def openPcilibInstance(s, device, model): - pcipywrap.close_curr_pcilib_instance() - - lib = pcipywrap.create_pcilib_instance(device, model) - pcipywrap.set_pcilib(lib) + s.pcilib = pcipywrap.create_pcilib_instance(device, model) """Send help message""" def help(s, received_message = None): @@ -350,7 +350,7 @@ if __name__ == '__main__': parser = OptionParser() parser.add_option("-p", "--port", action="store", type="int", dest="port", default=9000, - help="Set server port (8888)") + help="Set server port (9000)") parser.add_option("-d", "--device", action="store", type="string", dest="device", default=str('/dev/fpga0'), help="FPGA device (/dev/fpga0)") @@ -377,14 +377,19 @@ if __name__ == '__main__': if not 'LD_LIBRARY_PATH' in os.environ: os.environ['LD_LIBRARY_PATH'] = os.environ["APP_PATH"] + "/pcilib" - #create pcilib instance and redirect logs to exeption - lib = pcipywrap.create_pcilib_instance(opts.device, opts.model) - pcipywrap.set_pcilib(lib) + #redirect logs to exeption pcipywrap.__redirect_logs_to_exeption() #start server pcilib_server = BaseHTTPServer.HTTPServer - httpd = pcilib_server((HOST_NAME, PORT_NUMBER), PcilibServerHandler) + + #pass Pcipywrap to to server handler + lib = pcipywrap.Pcipywrap(DEVICE, MODEL) + def handler(*args): + PcilibServerHandler(lib, *args) + + httpd = pcilib_server((HOST_NAME, PORT_NUMBER), handler) + print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) try: httpd.serve_forever() diff --git a/xml/test_pywrap/test_prop2.py b/xml/test_pywrap/test_prop2.py index d7e10bc..d78dbea 100644 --- a/xml/test_pywrap/test_prop2.py +++ b/xml/test_pywrap/test_prop2.py @@ -1,8 +1,6 @@ -import pcipywrap - -def read_from_register(value): - return pcipywrap.get_property('/test/prop3') / 2 +def read_from_register(ctx, value): + return ctx.get_property('/test/prop3') / 2 -def write_to_register(value): - pcipywrap.set_property(value*2, '/test/prop3') +def write_to_register(ctx, value): + ctx.set_property(value*2, '/test/prop3') diff --git a/xml/test_pywrap/test_prop3.py b/xml/test_pywrap/test_prop3.py index 9d33b63..a082096 100644 --- a/xml/test_pywrap/test_prop3.py +++ b/xml/test_pywrap/test_prop3.py @@ -1,7 +1,5 @@ -import pcipywrap - -def read_from_register(value): - return pcipywrap.get_property('/registers/fpga/reg1') +def read_from_register(ctx, value): + return ctx.get_property('/registers/fpga/reg1') -def write_to_register(value): - pcipywrap.set_property(value, '/registers/fpga/reg1') +def write_to_register(ctx, value): + ctx.set_property(value, '/registers/fpga/reg1') -- cgit v1.2.3 From 52eb7f4fb76ddf99dedf44332aae7af4df76ab36 Mon Sep 17 00:00:00 2001 From: Vasilii Chernov Date: Wed, 17 Feb 2016 18:13:36 +0100 Subject: Add test to repository. Add GIL states to pcilib_set_value_from_pyobject --- apps/CMakeLists.txt | 4 ++ apps/test_multithread.c | 94 +++++++++++++++++++++++++++++++++++++ pcilib/py.c | 3 ++ pywrap/CMakeLists.txt | 1 + pywrap/test_pcipywrap.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 221 insertions(+) create mode 100644 apps/test_multithread.c create mode 100755 pywrap/test_pcipywrap.py (limited to 'pywrap') diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 4524db4..2a1471c 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -7,6 +7,10 @@ link_directories( ${CMAKE_BINARY_DIR}/pcilib ) +find_package (Threads) +add_executable(test_multithread test_multithread.c) +target_link_libraries (test_multithread pcilib ${CMAKE_THREAD_LIBS_INIT}) + add_executable(xilinx xilinx.c) target_link_libraries(xilinx pcilib rt) diff --git a/apps/test_multithread.c b/apps/test_multithread.c new file mode 100644 index 0000000..cad4cd9 --- /dev/null +++ b/apps/test_multithread.c @@ -0,0 +1,94 @@ +#include +#include +#include "pcilib.h" +#include + +const char* prop = "/registers/fpga/reg1"; +char* reg; +int stop = 0; + +void *get_prop(void *arg) +{ + pcilib_t *ctx = (pcilib_t*)arg; + + while(!stop) + { + int err; + pcilib_value_t val = {0}; + err = pcilib_get_property(ctx, prop, &val); + if(err) + { + printf("err pcilib_read_register\n"); + 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"); + return NULL; + } + printf("reg = %i\n", value); + } + return NULL; +} + +void *read_reg(void *arg) +{ + pcilib_t *ctx = (pcilib_t*)arg; + + while(!stop) + { + int err; + pcilib_register_value_t reg_val = {0}; + pcilib_value_t val = {0}; + + err = pcilib_read_register(ctx, NULL, reg, ®_val); + + if(err) + { + printf("err pcilib_read_register\n"); + return NULL; + } + err = pcilib_set_value_from_register_value(ctx, &val, reg_val); + if(err) + { + printf("err pcilib_set_value_from_register_value\n"); + 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"); + return NULL; + } + printf("reg = %i\n", value); + } + return NULL; +} + +int main(int argc, char *argv[]) +{ + if (argc < 5) { + printf("Usage:\n\t\t%s \n", argv[0]); + exit(0); + } + + reg = argv[3]; + int threads = atoi( argv[4] ); + + pcilib_t *ctx = pcilib_open(argv[1], argv[2]); + int err; + pcilib_value_t val = {0}; + + for(int i = 0; i < threads; i++) + { + pthread_t pth; + pthread_create(&pth, NULL, read_reg, ctx); + } + + getchar(); + stop = 1; + return 0; +} diff --git a/pcilib/py.c b/pcilib/py.c index 372d475..a288043 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -347,6 +347,7 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py PyObject* pyVal = pyObjVal; int err; + PyGILState_STATE gstate = PyGILState_Ensure(); if(PyInt_Check(pyVal)) { err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); @@ -359,9 +360,11 @@ int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py err = pcilib_set_value_from_static_string(ctx, val, PyString_AsString(pyVal)); else { + PyGILState_Release(gstate); pcilib_error("Invalid input. Input type should be int, float or string."); return PCILIB_ERROR_NOTSUPPORTED; } + PyGILState_Release(gstate); if(err) return err; diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index d4d75d1..4592c9a 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -19,3 +19,4 @@ SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c) SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) configure_file(server.py server.py) +configure_file(test_pcipywrap.py test_pcipywrap.py) diff --git a/pywrap/test_pcipywrap.py b/pywrap/test_pcipywrap.py new file mode 100755 index 0000000..257b4a5 --- /dev/null +++ b/pywrap/test_pcipywrap.py @@ -0,0 +1,119 @@ +import threading +import pcipywrap +import random +import os +import json +import requests +import time + +class test_pcipywrap(): + def __init__(self, device, model, num_threads = 150, + write_percentage = 0.1, register = 'test_prop2', + server_host = 'http://localhost', server_port = 12412, + server_message_delay = 0): + #initialize enviroment variables + 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" + + random.seed() + #create pcilib_instance + self.pcilib = pcipywrap.Pcipywrap(device, model) + self.num_threads = num_threads + self.write_percentage = write_percentage + self.register = register + self.server_message_delay = server_message_delay + self.server_port = server_port + self.server_host = server_host + + def testThreadSafeReadWrite(self): + def threadFunc(): + if random.randint(0, 100) >= (self.write_percentage * 100): + ret = self.pcilib.get_property('/test/prop2') + print self.register, ':', ret + del ret + else: + val = random.randint(0, 65536) + print 'set value:', val + self.pcilib.write_register(val, self.register) + try: + while(1): + thread_list = [threading.Thread(target=threadFunc) for i in range(0, self.num_threads)] + for i in range(0, self.num_threads): + thread_list[i].start() + for i in range(0, self.num_threads): + thread_list[i].join() + print 'cycle done' + except KeyboardInterrupt: + print 'testing done' + pass + + def testMemoryLeak(self): + try: + while(1): + #print self.pcilib.create_pcilib_instance('/dev/fpga0','test_pywrap') + + print self.pcilib.get_property_list('/test') + print self.pcilib.get_register_info('test_prop1') + #print self.pcilib.get_registers_list(); + + #print self.pcilib.read_register('reg1') + #print self.pcilib.write_register(12, 'reg1') + + #print self.pcilib.get_property('/test/prop2') + #print self.pcilib.set_property(12, '/test/prop2') + except KeyboardInterrupt: + print 'testing done' + pass + + def testServer(self): + url = str(self.server_host + ':' + str(self.server_port)) + headers = {'content-type': 'application/json'} + payload =[{'com': 'open', 'data2' : '12341'}, + #{'command': 'open', 'device' : '/dev/fpga0', 'model': 'test_pywrap'}, + {'command': 'help'}, + {'command': 'get_registers_list'}, + {'command': 'get_register_info', 'reg': 'reg1'}, + {'command': 'get_property_list'}, + {'command': 'read_register', 'reg': 'reg1'}, + {'command': 'write_register', 'reg': 'reg1'}, + {'command': 'get_property', 'prop': '/test/prop2'}, + {'command': 'set_property', 'prop': '/test/prop2'}] + + def sendRandomMessage(): + message_number = random.randint(1, len(payload) - 1) + print 'message number: ', message_number + payload[message_number]['value'] = random.randint(0, 65535) + r = requests.get(url, data=json.dumps(payload[message_number]), headers=headers) + print json.dumps(r.json(), sort_keys=True, indent=4, separators=(',', ': ')) + + try: + r = requests.get(url, data=json.dumps(payload[1]), headers=headers) + print json.dumps(r.json(), sort_keys=True, indent=3, separators=(',', ': ')) + + while(1): + time.sleep(self.server_message_delay) + thread_list = [threading.Thread(target=sendRandomMessage) for i in range(0, self.num_threads)] + for i in range(0, self.num_threads): + thread_list[i].start() + for i in range(0, self.num_threads): + thread_list[i].join() + print 'cycle done' + + except KeyboardInterrupt: + print 'testing done' + pass + +if __name__ == '__main__': + lib = test_pcipywrap('/dev/fpga0','test_pywrap', num_threads = 150, + write_percentage = 0.1, register = 'test_prop2',server_host = 'http://localhost', server_port = 12412, + server_message_delay = 0) + lib.testThreadSafeReadWrite() + -- cgit v1.2.3