diff options
54 files changed, 1150 insertions, 932 deletions
@@ -31,4 +31,8 @@ pcitool/pci version.h Doxyfile html +pcilib/build.h +build.h build +pcipywrap.py +pcipywrapPYTHON_wrap.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bfff47..b77529e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ project(pcitool) -set(PCILIB_VERSION "0.2.5") +set(PCILIB_VERSION "0.2.6") set(PCILIB_ABI_VERSION "2") cmake_minimum_required(VERSION 2.8) @@ -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 TRUE CACHE BOOL "Build pcilib python modules") +set(DISABLE_PYTHON FALSE CACHE BOOL "Disable python scripting support") #list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -37,11 +37,11 @@ SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) -if (BUILD_PYTHON_MODULES) - find_package(PythonLibs 2.7 REQUIRED) - find_package(SWIG REQUIRED) - add_definitions(-DBUILD_PYTHON_MODULES) -endif (BUILD_PYTHON_MODULES) +if (NOT DISABLE_PYTHON) + find_package(PythonLibs 2.7 REQUIRED) + find_package(SWIG REQUIRED) + set(HAVE_PYTHON TRUE) +endif (NOT DISABLE_PYTHON) set(EXTRA_SYSTEM_LIBS -lrt) @@ -65,8 +65,17 @@ add_definitions("-fPIC --std=c99 -Wall -O2 -gdwarf-2 -g3 -fno-omit-frame-pointer #add_definitions("-fPIC --std=c99 -Wall -O2") include(cmake/version.cmake) + VERSION_TO_VARS(${PCILIB_VERSION} PCILIB_VERSION_MAJOR PCILIB_VERSION_MINOR PCILIB_VERSION_MICRO) +add_custom_target(build) +add_custom_command(TARGET build + COMMAND ${CMAKE_COMMAND} -DPCILIB_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DPCILIB_BINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_SOURCE_DIR}/cmake/build.cmake + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +set_source_files_properties(${CMAKE_BINARY_DIR}/pcilib/build.h PROPERTIES GENERATED TRUE) + + set(TARNAME "pcitool") set(PACKAGE_VERSION ${PCILIB_VERSION}) set(PACKAGE_NAME "${TARNAME}") @@ -88,27 +97,28 @@ add_subdirectory(pcitool) add_subdirectory(apps) add_subdirectory(xml) -if (BUILD_PYTHON_MODULES) - add_subdirectory(pywrap) -endif (BUILD_PYTHON_MODULES) +if (HAVE_PYTHON) + add_subdirectory(pywrap) +endif (HAVE_PYTHON) set_target_properties(pcilib PROPERTIES VERSION ${PCILIB_VERSION} 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) - +if (NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + file(COPY ${CMAKE_SOURCE_DIR}/xml DESTINATION ${CMAKE_BINARY_DIR}) + file(COPY ${CMAKE_SOURCE_DIR}/pci + DESTINATION ${CMAKE_BINARY_DIR} + FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) +endif(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/misc/pcitool.pc diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 2a1471c..45d627b 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -7,10 +7,6 @@ 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) @@ -21,3 +17,6 @@ add_executable(compare_to_value compare_to_value.c) add_executable(heb_strip_bad_values heb_strip_bad_values.c) add_executable(check_counter check_counter.c) + +add_executable(test_multithread test_multithread.c) +target_link_libraries (test_multithread pcilib ${CMAKE_THREAD_LIBS_INIT}) diff --git a/apps/test_multithread.c b/apps/test_multithread.c index cad4cd9..4d0e8f2 100644 --- a/apps/test_multithread.c +++ b/apps/test_multithread.c @@ -9,86 +9,84 @@ int stop = 0; void *get_prop(void *arg) { - pcilib_t *ctx = (pcilib_t*)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; + 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 = %li\n", value); + } + return NULL; } void *read_reg(void *arg) { - pcilib_t *ctx = (pcilib_t*)arg; + pcilib_t *ctx = (pcilib_t*)arg; + + while(!stop) + { + int err; + pcilib_register_value_t reg_val = {0}; + pcilib_value_t val = {0}; - 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; + 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 = %li\n", value); + } + return NULL; } int main(int argc, char *argv[]) { - if (argc < 5) { - printf("Usage:\n\t\t%s <device> <model> <register> <num_threads>\n", argv[0]); - exit(0); + if (argc < 5) { + printf("Usage:\n\t\t%s <device> <model> <register> <num_threads>\n", argv[0]); + exit(0); + } + + reg = argv[3]; + int threads = atoi( argv[4] ); + + pcilib_t *ctx = pcilib_open(argv[1], argv[2]); + + for(int i = 0; i < threads; i++) + { + pthread_t pth; + pthread_create(&pth, NULL, read_reg, ctx); } - 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; + getchar(); + stop = 1; + return 0; } diff --git a/cmake/FindBAZAAR.cmake b/cmake/FindBAZAAR.cmake new file mode 100644 index 0000000..ad7b76b --- /dev/null +++ b/cmake/FindBAZAAR.cmake @@ -0,0 +1,83 @@ +# +# This program source code file is part of KICAD, a free EDA CAD application. +# +# Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net> +# Copyright (C) 2010 Kicad Developers, see AUTHORS.txt for contributors. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, you may find one here: +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# or you may search the http://www.gnu.org website for the version 2 license, +# or you may write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +# +# This CMake script finds the BAZAAR version control system executable and +# and fetches the veresion string to valid that BAZAAR was found and executes +# properly. +# +# Usage: +# find_package( BAZAAR ) +# +# User definable. +# BAZAAR_EXECUTABLE Set this to use a version of BAZAAR that is not in +# current path. Defaults to bzr. +# +# Defines: +# BAZAAR_FOUND Set to TRUE if BAZAAR command line client is found +# and the bzr --version command executes properly. +# BAZAAR_VERSION Result of the bzr --version command. +# + +set( BAZAAR_FOUND FALSE ) + +find_program( BAZAAR_EXECUTABLE bzr + DOC "BAZAAR version control system command line client" ) +mark_as_advanced( BAZAAR_EXECUTABLE ) + +if( BAZAAR_EXECUTABLE ) + + # BAZAAR commands should be executed with the C locale, otherwise + # the message (which are parsed) may be translated causing the regular + # expressions to fail. + set( _BAZAAR_SAVED_LC_ALL "$ENV{LC_ALL}" ) + set( ENV{LC_ALL} C ) + + # Fetch the BAZAAR executable version. + execute_process( COMMAND ${BAZAAR_EXECUTABLE} --version + OUTPUT_VARIABLE _bzr_version_output + ERROR_VARIABLE _bzr_version_error + RESULT_VARIABLE _bzr_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE ) + + if( ${_bzr_version_result} EQUAL 0 ) + set( BAZAAR_FOUND TRUE ) + string( REGEX REPLACE "^[\n]*Bazaar \\(bzr\\) ([0-9.a-z]+).*" + "\\1" BAZAAR_VERSION "${_bzr_version_output}" ) + if( NOT BAZAAR_FIND_QUIETLY ) + message( STATUS "BAZAAR version control system version ${BAZAAR_VERSION} found." ) + endif() + endif() + + # restore the previous LC_ALL + set( ENV{LC_ALL} ${_BAZAAR_SAVED_LC_ALL} ) +endif() + +if( NOT BAZAAR_FOUND ) + if( NOT BAZAAR_FIND_QUIETLY ) + message( STATUS "BAZAAR version control command line client was not found." ) + else() + if( BAZAAR_FIND_REQUIRED ) + message( FATAL_ERROR "BAZAAR version control command line client was not found." ) + endif() + endif() +endif() diff --git a/cmake/build.cmake b/cmake/build.cmake new file mode 100644 index 0000000..b0d803a --- /dev/null +++ b/cmake/build.cmake @@ -0,0 +1,82 @@ +cmake_minimum_required(VERSION 2.6) + +list(APPEND CMAKE_MODULE_PATH "${PCILIB_SOURCE_DIR}/cmake/") + +find_package(BAZAAR QUIET) + +set(PCILIB_BUILD_DATE "") +set(PCILIB_LAST_MODIFICATION "") +set(PCILIB_REVISION "0") +set(PCILIB_REVISION_BRANCH "") +set(PCILIB_REVISION_AUTHOR "") +set(PCILIB_REVISION_MODIFICATIONS "") + +execute_process( + COMMAND date "+%Y/%m/%d %H:%M:%S" + RESULT_VARIABLE _retcode + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if (${_retcode} EQUAL 0) + set(PCILIB_BUILD_DATE ${_output}) +endif (${_retcode} EQUAL 0) + +execute_process( + COMMAND find ${PCILIB_SOURCE_DIR} -type f -name "*.[ch]" -printf "%TY/%Tm/%Td %TH:%TM:%TS %p\n" + COMMAND sort -n + COMMAND grep -E -v "build.h|config.h|CMakeFiles|./apps" + COMMAND tail -n 1 + COMMAND cut -d " " -f 1-2 + COMMAND cut -d "." -f 1 + RESULT_VARIABLE _retcode + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if (${_retcode} EQUAL 0) + set(PCILIB_LAST_MODIFICATION ${_output}) +endif (${_retcode} EQUAL 0) + +if (BAZAAR_FOUND) + execute_process( + COMMAND ${BAZAAR_EXECUTABLE} revno --tree ${PCILIB_SOURCE_DIR} + RESULT_VARIABLE _retcode + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (${_retcode} EQUAL 0) + set(PCILIB_REVISION ${_output}) + + execute_process( + COMMAND ${BAZAAR_EXECUTABLE} log -r${PCILIB_REVISION} ${PCILIB_SOURCE_DIR} + RESULT_VARIABLE _retcode + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (${_retcode} EQUAL 0) + string(REGEX REPLACE "^(.*\n)?committer: ([^\n]+).*" + "\\2" PCILIB_REVISION_AUTHOR "${_output}" ) + string(REGEX REPLACE "^(.*\n)?branch nick: ([^\n]+).*" + "\\2" PCILIB_REVISION_BRANCH "${_output}" ) + endif (${_retcode} EQUAL 0) + endif (${_retcode} EQUAL 0) + + execute_process( + COMMAND ${BAZAAR_EXECUTABLE} status -SV + COMMAND cut -c 5- + WORKING_DIRECTORY ${PCILIB_SOURCE_DIR} + RESULT_VARIABLE _retcode + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (${_retcode} EQUAL 0) + string(REGEX REPLACE "\n+" ";" PCILIB_REVISION_MODIFICATIONS "${_output}") +# set(PCILIB_REVISION_MODIFICATIONS ${_output}) + endif (${_retcode} EQUAL 0) +endif(BAZAAR_FOUND) + +configure_file(${PCILIB_SOURCE_DIR}/pcilib/build.h.in ${PCILIB_BINARY_DIR}/pcilib/build.h) @@ -5,10 +5,10 @@ #include "pcilib.h" #include "version.h" -#define IPEDMA_PAGE_SIZE 4096 /**< page size */ -#define IPEDMA_DMA_PAGES 1024 /**< number of DMA pages in the ring buffer to allocate */ +#define IPEDMA_PAGE_SIZE 4096l /**< page size */ +#define IPEDMA_DMA_PAGES 1024l /**< number of DMA pages in the ring buffer to allocate */ -#define IPEDMA_DMA_TIMEOUT 100000 /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */ +#define IPEDMA_DMA_TIMEOUT 100000l /**< us, overrides PCILIB_DMA_TIMEOUT (actual hardware timeout is 50ms according to Lorenzo) */ pcilib_dma_context_t *dma_ipe_init(pcilib_t *ctx, const char *model, const void *arg); void dma_ipe_free(pcilib_dma_context_t *vctx); @@ -11,12 +11,11 @@ High Priority (we would need it for IPE Camera) Normal Priority (it would make just few things a bit easier) =============== - 1. Support Python-scripts in the views (we need to provide python API to read registers/properties) - 2. Integrate base streaming model into the pcitool - 3. Implement pcilib_configure_autotrigger - 4. Really check the specified min, max values while setting registers - 5. Provide OR and AND operations on registers in cli - 6. Support writting a data from a binary file in cli + 1. Integrate base streaming model into the pcitool + 2. Implement pcilib_configure_autotrigger + 3. Really check the specified min, max values while setting registers + 4. Provide OR and AND operations on registers in cli + 5. Support writting a data from a binary file in cli Low Priority (only as generalization for other projects) ============ @@ -25,6 +24,8 @@ Low Priority (only as generalization for other projects) 3. Define a syntax for register dependencies / delays (?) 4. Use pthread_condition_t instead of polling 5. Support FIFO reads/writes from/to registers + 6. OPC UA interface to the registers + 7. Generate XML models from SystemRDL descriptions Performance =========== diff --git a/driver/Makefile b/driver/Makefile index 83a8c46..c26a84a 100644 --- a/driver/Makefile +++ b/driver/Makefile @@ -20,8 +20,8 @@ default: echo "No compiler of $$GCC_MAJOR series is installed" ;\ exit 1 ;\ fi ;\ - GCC_VERSION=`$$CC --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | head -n 1` ;\ - if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION ]; then \ + GCC_VERSION=`$$CC --version | head -n 1 | tr ' ' '\n' | grep -e "[0-9]\+\.[0-9]" | tail -n 1` ;\ + if [ $$KERNEL_GCC_VERSION != $$GCC_VERSION -a -z "$$RELAXED_GCC_CHECK" ]; then \ echo "The $$GCC_VERSION of $$GCC_MAJOR series is installed" ;\ exit 1 ;\ fi ;\ @@ -29,6 +29,17 @@ default: else \ CC=$(CC) ;\ fi ;\ + build_revision=`bzr revno` ;\ + build_author=`bzr log -r$$build_revision | grep committer | cut -c 12-` ;\ + build_path=`pwd` ;\ + build_branch=`bzr nick` ;\ + build_lastmod=`find . -type f -name '*.[ch]' -printf '%TY/%Tm/%Td %TH:%TM:%TS %p\n' | grep -E -v 'build.h|mod.c' | sort -n | tail -n 1 | cut -d ' ' -f 1-2 | cut -d '.' -f 1` ;\ + build_changes=`bzr status -SV | cut -c 5- | tr \\\n " "` ;\ + build_user=`whoami` ;\ + build_date=`date "+%Y/%m/%d %H:%M:%S"` ;\ + build="Built at $$build_date by $$build_user" ;\ + revision="Revision $$build_revision from $$build_branch by $$build_author at $$build_path, last modification from $$build_lastmod" ;\ + echo -e "#define PCIDRIVER_BUILD \"$$build\"\\n#define PCIDRIVER_REVISION \"$$revision\"\\n#define PCIDRIVER_CHANGES \"$$build_changes\"\\n" > build.h ;\ $(MAKE) $(CFLAGS) -C $(KERNELDIR) M=$(PWD) CC=$$CC modules install: diff --git a/driver/base.c b/driver/base.c index 2768f9e..bc9ab98 100644 --- a/driver/base.c +++ b/driver/base.c @@ -164,6 +164,8 @@ #include <linux/interrupt.h> #include <linux/wait.h> +#include "../pcilib/version.h" + /* Configuration for the driver (what should be compiled in, module name, etc...) */ #include "config.h" @@ -190,6 +192,8 @@ #include "ioctl.h" +#include "build.h" + /*************************************************************************/ /* Module device table associated with this driver */ MODULE_DEVICE_TABLE(pci, pcidriver_ids); @@ -240,7 +244,12 @@ static int __init pcidriver_init(void) goto init_pcireg_fail; } - mod_info("Module loaded\n"); + mod_info("pcidriver %u.%u.%u loaded\n", PCILIB_VERSION_GET_MAJOR(PCILIB_VERSION), PCILIB_VERSION_GET_MINOR(PCILIB_VERSION), PCILIB_VERSION_GET_MICRO(PCILIB_VERSION)); + mod_info("%s\n", PCIDRIVER_BUILD); + mod_info("%s\n", PCIDRIVER_REVISION); + if (strlen(PCIDRIVER_CHANGES)) { + mod_info("Extra changes - %s\n", PCIDRIVER_CHANGES); + } return 0; @@ -2,7 +2,4 @@ APP_PATH=`dirname $0` -PYTHONPATH="$PYTHONPATH:$APP_PATH/pywrap" \ -PCILIB_MODEL_DIR="$APP_PATH/xml" \ -LD_LIBRARY_PATH="$APP_PATH/pcilib" \ -$APP_PATH/pcitool/pci $* +PYTHONPATH="$APP_PATH/pywrap:$PYTHONPATH" PCILIB_MODEL_DIR="$APP_PATH/xml" LD_LIBRARY_PATH="$APP_PATH/pcilib" $APP_PATH/pcitool/pci $* diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index cdc9c3f..a7557b7 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -8,10 +8,10 @@ include_directories( ${UTHASH_INCLUDE_DIRS} ) -set(HEADERS pcilib.h pci.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h) -add_library(pcilib SHARED pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c ) +set(HEADERS pcilib.h pci.h datacpy.h memcpy.h pagecpy.h cpu.h timing.h export.h value.h bar.h fifo.h model.h bank.h register.h view.h property.h unit.h xml.h py.h kmem.h irq.h locking.h lock.h dma.h event.h plugin.h tools.h error.h debug.h env.h version.h config.h build.h) +add_library(pcilib SHARED pci.c datacpy.c memcpy.c pagecpy.c cpu.c timing.c export.c value.c bar.c fifo.c model.c bank.c register.c view.c unit.c property.c xml.c py.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c) target_link_libraries(pcilib dma protocols views ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) -add_dependencies(pcilib dma protocols views) +add_dependencies(pcilib build dma protocols views) install(TARGETS pcilib LIBRARY DESTINATION lib${LIB_SUFFIX} @@ -23,4 +23,4 @@ install(FILES pcilib.h install(FILES bar.h kmem.h locking.h lock.h bank.h register.h xml.h dma.h event.h model.h error.h debug.h env.h tools.h timing.h cpu.h datacpy.h pagecpy.h memcpy.h export.h version.h view.h unit.h DESTINATION include/pcilib -) +)
\ No newline at end of file diff --git a/pcilib/build.h.in b/pcilib/build.h.in new file mode 100644 index 0000000..1713378 --- /dev/null +++ b/pcilib/build.h.in @@ -0,0 +1,7 @@ +#define PCILIB_REVISION "${PCILIB_REVISION}" +#define PCILIB_REVISION_BRANCH "${PCILIB_REVISION_BRANCH}" +#define PCILIB_REVISION_AUTHOR "${PCILIB_REVISION_AUTHOR}" +#define PCILIB_REVISION_MODIFICATIONS "${PCILIB_REVISION_MODIFICATIONS}" +#define PCILIB_BUILD_DATE "${PCILIB_BUILD_DATE}" +#define PCILIB_BUILD_DIR "${CMAKE_SOURCE_DIR}" +#define PCILIB_LAST_MODIFICATION "${PCILIB_LAST_MODIFICATION}" diff --git a/pcilib/config.h.in b/pcilib/config.h.in index bdd9ec3..cd8033c 100644 --- a/pcilib/config.h.in +++ b/pcilib/config.h.in @@ -3,3 +3,4 @@ #cmakedefine PCILIB_MODEL_DIR "${PCILIB_MODEL_DIR}" #cmakedefine PCILIB_DEBUG_DIR "${PCILIB_DEBUG_DIR}" #cmakedefine HAVE_STDATOMIC_H @HAVE_STDATOMIC_H@ +#cmakedefine HAVE_PYTHON diff --git a/pcilib/error.c b/pcilib/error.c index a2e5a04..ae8bacb 100644 --- a/pcilib/error.c +++ b/pcilib/error.c @@ -80,10 +80,11 @@ 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_log_level() { - return pcilib_logger_min_prio; + return pcilib_logger_min_prio; } + void* pcilib_get_logger_context() { - return pcilib_logger_argument; + return pcilib_logger_argument; } - diff --git a/pcilib/pci.c b/pcilib/pci.c index 2b7b97b..19165ba 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -192,7 +192,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - err = pcilib_py_add_script_dir(ctx); + err = pcilib_py_add_script_dir(ctx, NULL); if (err) { pcilib_error("Error (%i) add script path to python path", err); pcilib_close(ctx); @@ -355,12 +355,11 @@ void pcilib_close(pcilib_t *ctx) { if (ctx->registers) free(ctx->registers); - pcilib_free_py(ctx); - if (ctx->model) free(ctx->model); pcilib_free_xml(ctx); + pcilib_free_py(ctx); if (ctx->handle >= 0) close(ctx->handle); diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h index c32d1fb..8ab8e9e 100644 --- a/pcilib/pcilib.h +++ b/pcilib/pcilib.h @@ -43,7 +43,8 @@ typedef enum { typedef enum { PCILIB_ACCESS_R = 1, /**< getting property is allowed */ PCILIB_ACCESS_W = 2, /**< setting property is allowed */ - PCILIB_ACCESS_RW = 3 + PCILIB_ACCESS_RW = 3, + PCILIB_ACCESS_INCONSISTENT = 0x10000 /**< inconsistent access, one will not read that one has written */ } pcilib_access_mode_t; typedef enum { @@ -54,7 +55,7 @@ typedef enum { PCILIB_REGISTER_RW1C = 5, PCILIB_REGISTER_W1I = 8, /**< writting 1 inversts the bit, writting 0 keeps the value */ PCILIB_REGISTER_RW1I = 9, - PCILIB_REGISTER_INCONSISTENT = 0x1000 /**< dont check register value after set*/ + PCILIB_REGISTER_INCONSISTENT = 0x10000 /**< inconsistent register, writting and reading does not match */ } pcilib_register_mode_t; typedef enum { @@ -1257,6 +1258,16 @@ int pcilib_set_value_from_register_value(pcilib_t *ctx, pcilib_value_t *val, pci int pcilib_set_value_from_static_string(pcilib_t *ctx, pcilib_value_t *val, const char *str); /** + * Initializes the polymorphic value from the string. The string is copied. + * If `val` already contains the value, cleans it first. Therefore, before first usage the value should be always initialized to 0. + * @param[in] ctx - pcilib context + * @param[in,out] val - initialized polymorphic value + * @param[in] str - initializer + * @return - 0 on success or memory error + */ +int pcilib_set_value_from_string(pcilib_t *ctx, pcilib_value_t *value, const char *str); + +/** * Get the floating point value from the polymorphic type. May inmply impliced type conversion, * for isntance parsing the number from the string. Will return 0. and report an error if * conversion failed. diff --git a/pcilib/property.c b/pcilib/property.c index 3a7ebb3..dfab9a6 100644 --- a/pcilib/property.c +++ b/pcilib/property.c @@ -225,11 +225,9 @@ 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_DEL(dir_hash, dir); + free(dir); } HASH_CLEAR(hh, dir_hash); diff --git a/pcilib/py.c b/pcilib/py.c index a288043..9254df7 100644 --- a/pcilib/py.c +++ b/pcilib/py.c @@ -1,151 +1,333 @@ -#ifdef BUILD_PYTHON_MODULES -#include <Python.h> -#endif - +#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> +#include <alloca.h> #include "pci.h" #include "debug.h" #include "pcilib.h" #include "py.h" #include "error.h" +#include "config.h" + +#ifdef HAVE_PYTHON +# include <Python.h> +#endif /* HAVE_PYTHON */ -#ifdef BUILD_PYTHON_MODULES -typedef struct pcilib_script_s { - const char* name; - PyObject *module; /**< PyModule object, contains script enviroment */ - UT_hash_handle hh; -} pcilib_script_s; +#ifdef HAVE_PYTHON +typedef struct pcilib_script_s pcilib_script_t; + +struct pcilib_script_s { + const char *name; /**< Script name */ + PyObject *module; /**< PyModule object, contains script enviroment */ + UT_hash_handle hh; /**< hash */ +}; 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; + int finalyze; /**< Indicates, that we are initialized from wrapper and should not destroy Python resources in destructor */ + PyObject *main_module; /**< Main interpreter */ + PyObject *global_dict; /**< Dictionary of main interpreter */ + PyObject *pcilib_pywrap; /**< pcilib wrapper module */ + pcilib_script_t *script_hash; /**< Hash with loaded scripts */ }; -#endif +#endif /* HAVE_PYTHON */ + +void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...) { + va_list va; + const char *type = NULL; + const char *val = NULL; + +#ifdef HAVE_PYTHON + PyObject *pytype = NULL; + PyObject *pyval = NULL; + PyObject *pytraceback = NULL; + + PyErr_Fetch(&pytype, &pyval, &pytraceback); + type = PyString_AsString(pytype); + val = PyString_AsString(pyval); +#endif /* HAVE_PYTHON */ + + va_start(va, msg); + if (type) { + char *str; + size_t len = 32; + + if (msg) len += strlen(msg); + if (type) len += strlen(type); + if (val) len += strlen(val); + + str = alloca(len * sizeof(char)); + if (str) { + if (msg&&val) + sprintf(str, "%s <%s: %s>", msg, type, val); + else if (msg) + sprintf(str, "%s <%s>", msg, type); + else if (val) + sprintf(str, "Python error %s: %s", type, val); + else + sprintf(str, "Python error %s", type); + + pcilib_log_vmessage(file, line, flags, prio, str, va); + } + } else { + pcilib_log_vmessage(file, line, flags, prio, msg, va); + } + va_end(va); + +#ifdef HAVE_PYTHON + Py_XDECREF(pytype); + Py_XDECREF(pyval); + Py_XDECREF(pytraceback); +#endif /* HAVE_PYTHON */ +} + + int pcilib_init_py(pcilib_t *ctx) { -#ifdef BUILD_PYTHON_MODULES +#ifdef HAVE_PYTHON ctx->py = (pcilib_py_t*)malloc(sizeof(pcilib_py_t)); if (!ctx->py) return PCILIB_ERROR_MEMORY; - if(!Py_IsInitialized()) - { + memset(ctx->py, 0, sizeof(pcilib_py_t)); + + if(Py_IsInitialized()) + ctx->py->finalyze = 1; + else { Py_Initialize(); - //Since python is being initializing from c programm, it needs - //to initialize threads to works properly with c threads + // Since python is being initializing from c programm, it needs to initialize threads to work properly with c threads PyEval_InitThreads(); PyEval_ReleaseLock(); - - 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) + if (!ctx->py->main_module) { + pcilib_python_error("Error importing python parser"); return PCILIB_ERROR_FAILED; + } ctx->py->global_dict = PyModule_GetDict(ctx->py->main_module); - if (!ctx->py->global_dict) + if (!ctx->py->global_dict) { + pcilib_python_error("Error locating global python dictionary"); 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 *pywrap = PyImport_ImportModule("pcipywrap"); + if (!pywrap) { + pcilib_python_error("Error importing pcilib python wrapper"); + 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); + PyObject *mod_name = PyString_FromString("Pcipywrap"); + ctx->py->pcilib_pywrap = PyObject_CallMethodObjArgs(pywrap, mod_name, PyCObject_FromVoidPtr(ctx, NULL), NULL); + Py_XDECREF(mod_name); - if(!ctx->py->pcilib_pywrap) - { - printf("Error in import python module: "); - PyErr_Print(); + if (!ctx->py->pcilib_pywrap) { + pcilib_python_error("Error initializing python wrapper"); return PCILIB_ERROR_FAILED; - } - - ctx->py->scripts = NULL; -#endif + } +#endif /* HAVE_PYTHON */ + 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) - { - 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; - } -#endif - return 0; +int pcilib_py_add_script_dir(pcilib_t *ctx, const char *dir) { +#ifdef HAVE_PYTHON + PyObject* pypath; + char *script_dir; + + const char *model_dir = getenv("PCILIB_MODEL_DIR"); + if (!model_dir) model_dir = PCILIB_MODEL_DIR; + + if (!dir) dir = ctx->model; + + if (*dir == '/') { + script_dir = (char*)dir; + } else { + script_dir = alloca(strlen(model_dir) + strlen(dir) + 2); + if (!script_dir) return PCILIB_ERROR_MEMORY; + sprintf(script_dir, "%s/%s", model_dir, dir); + } + + pypath = PySys_GetObject("path"); + if (!pypath) { + pcilib_python_error("Can't get python path"); + return PCILIB_ERROR_FAILED; + } + + // Shall we check if the directory already in the path? + if(PyList_Append(pypath, PyString_FromString(script_dir)) == -1) { + pcilib_python_error("Can't add directory (%s) to python path", script_dir); + return PCILIB_ERROR_FAILED; + } +#endif /* HAVE_PYTHON */ + + return 0; } void pcilib_free_py(pcilib_t *ctx) { -#ifdef BUILD_PYTHON_MODULES - int py_initialized_inside = 0; +#ifdef HAVE_PYTHON + int finalyze = 0; if (ctx->py) { - if(ctx->py->py_initialized_inside) - py_initialized_inside = 1; - - // Dict and module references are borrowed + if(ctx->py->finalyze) finalyze = 1; + + if (ctx->py->script_hash) { + pcilib_script_t *script, *script_tmp; + + HASH_ITER(hh, ctx->py->script_hash, script, script_tmp) { + HASH_DEL(ctx->py->script_hash, script); + free(script); + } + ctx->py->script_hash = NULL; + } + free(ctx->py); ctx->py = NULL; } - if(py_initialized_inside) - Py_Finalize(); -#endif + if (finalyze) + Py_Finalize(); +#endif /* HAVE_PYTHON */ } -/* -static int pcilib_py_realloc_string(pcilib_t *ctx, size_t required, size_t *size, char **str) { - char *ptr; - size_t cur = *size; +int pcilib_py_load_script(pcilib_t *ctx, const char *script_name) { +#ifdef HAVE_PYTHON + PyObject* pymodule; + pcilib_script_t *module = NULL; + + + char *module_name = strdupa(script_name); + if (!module_name) return PCILIB_ERROR_MEMORY; + + char *py = strrchr(module_name, '.'); + if ((!py)||(strcasecmp(py, ".py"))) { + pcilib_error("Invalid script name (%s) is specified", script_name); + return PCILIB_ERROR_INVALID_ARGUMENT; + } + *py = 0; + + HASH_FIND_STR(ctx->py->script_hash, script_name, module); + if (module) return 0; + + pymodule = PyImport_ImportModule(module_name); + if (!pymodule) { + pcilib_python_error("Error importing script (%s)", script_name); + return PCILIB_ERROR_FAILED; + } + + module = (pcilib_script_t*)malloc(sizeof(pcilib_script_t)); + if (!module) return PCILIB_ERROR_MEMORY; + + module->module = pymodule; + module->name = script_name; + HASH_ADD_KEYPTR(hh, ctx->py->script_hash, module->name, strlen(module->name), module); +#endif /* HAVE_PYTHON */ + return 0; +} + +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *script_name, pcilib_access_mode_t *mode_ret) { + pcilib_access_mode_t mode = 0; + +#ifdef HAVE_PYTHON + PyObject *dict; + PyObject *pystr; + pcilib_script_t *module; + + HASH_FIND_STR(ctx->py->script_hash, script_name, module); + + if(!module) { + pcilib_error("Script (%s) is not loaded yet", script_name); + return PCILIB_ERROR_NOTFOUND; + } + + dict = PyModule_GetDict(module->module); + if (!dict) { + pcilib_python_error("Error getting dictionary for script (%s)", script_name); + return PCILIB_ERROR_FAILED; + } - if ((required + 1) > cur) { - while (cur < required) cur *= 2; - ptr = (char*)realloc(*str, cur); - if (!ptr) return PCILIB_ERROR_MEMORY; - *size = cur; - *str = ptr; + pystr = PyString_FromString("read_from_register"); + if (pystr) { + if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_R; + Py_XDECREF(pystr); } - ] + + pystr = PyString_FromString("write_to_register"); + if (pystr) { + if (PyDict_Contains(dict, pystr)) mode |= PCILIB_ACCESS_W; + Py_XDECREF(pystr); + } +#endif /* HAVE_PYTHON */ + + if (mode_ret) *mode_ret = mode; return 0; } -*/ -#ifdef BUILD_PYTHON_MODULES + +pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *ret) { +#ifdef HAVE_PYTHON + int err = 0; + PyObject *res = NULL; + + long ival; + double fval; + + switch(val->type) { + case PCILIB_TYPE_LONG: + ival = pcilib_get_value_as_int(ctx, val, &err); + if (!err) res = (PyObject*)PyInt_FromLong(ival); + break; + case PCILIB_TYPE_DOUBLE: + fval = pcilib_get_value_as_float(ctx, val, &err); + if (!err) res = (PyObject*)PyFloat_FromDouble(fval); + break; + default: + err = PCILIB_ERROR_NOTSUPPORTED; + pcilib_error("Can't convert pcilib value of type (%lu) to PyObject", val->type); + } + + if (err) { + if (ret) *ret = err; + return NULL; + } else if (!res) { + if (ret) *ret = PCILIB_ERROR_MEMORY; + return res; + } + + if (ret) *ret = 0; + return res; +#else /* HAVE_PYTHON */ + pcilib_error("Python is not supported"); + return NULL; +#endif /* HAVE_PYTHON */ +} + +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object *pval) { +#ifdef HAVE_PYTHON + int err = 0; + PyObject *pyval = (PyObject*)pval; + + if (PyInt_Check(pyval)) { + err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyval)); + } else if (PyFloat_Check(pyval)) { + err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyval)); + } else if (PyString_Check(pyval)) { + err = pcilib_set_value_from_string(ctx, val, PyString_AsString(pyval)); + } else { + pcilib_error("Can't convert PyObject to polymorphic pcilib value"); + err = PCILIB_ERROR_NOTSUPPORTED; + } + + return err; +#else /* HAVE_PYTHON */ + pcilib_error("Python is not supported"); + return PCILIB_ERROR_NOTSUPPORTED; +#endif /* HAVE_PYTHON */ +} + +#ifdef HAVE_PYTHON static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { int i; int err = 0; @@ -251,10 +433,10 @@ static char *pcilib_py_parse_string(pcilib_t *ctx, const char *codestr, pcilib_v return dst; } -#endif +#endif /* HAVE_PYTHON */ int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *value) { -#ifdef BUILD_PYTHON_MODULES +#ifdef HAVE_PYTHON PyGILState_STATE gstate; char *code; PyObject* obj; @@ -276,248 +458,57 @@ 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 +#else /* HAVE_PYTHON */ pcilib_error("Current build not support python."); return PCILIB_ERROR_NOTAVAILABLE; -#endif +#endif /* HAVE_PYTHON */ } -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) - { - case 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_error("Invalid register output type (PCILIB_TYPE_STRING)"); - if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; - return NULL; - - case PCILIB_TYPE_LONG: - { - long ret_val; - ret_val = pcilib_get_value_as_int(ctx, val, &err); - - if(err) - { - if (ret) *ret = err; - return NULL; - } - - if (ret) *ret = 0; - return (PyObject*)PyInt_FromLong((long) ret_val); - } - - case PCILIB_TYPE_DOUBLE: - { - double ret_val; - ret_val = pcilib_get_value_as_float(ctx, val, &err); - - if(err) - { - if (ret) *ret = err; - return NULL; - } - - if (ret) *ret = 0; - return (PyObject*)PyFloat_FromDouble((double) ret_val); - } - - default: - if (ret) *ret = PCILIB_ERROR_NOTSUPPORTED; - 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_py_eval_func(pcilib_t *ctx, const char *script_name, const char *func_name, pcilib_value_t *val) { +#ifdef HAVE_PYTHON + int err = 0; + PyObject *pyfunc; + PyObject *pyval = NULL, *pyret; + pcilib_script_t *module = NULL; -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; - - PyGILState_STATE gstate = PyGILState_Ensure(); - if(PyInt_Check(pyVal)) - { - err = pcilib_set_value_from_int(ctx, val, PyInt_AsLong(pyVal)); + HASH_FIND_STR(ctx->py->script_hash, script_name, module); + + if (!module) { + pcilib_error("Script (%s) is not loaded", script_name); + return PCILIB_ERROR_NOTFOUND; + } + + if (val) { + pyval = pcilib_get_value_as_pyobject(ctx, val, &err); + if (err) return err; } - else - if(PyFloat_Check(pyVal)) - err = pcilib_set_value_from_float(ctx, val, PyFloat_AsDouble(pyVal)); - else - if(PyString_Check(pyVal)) - 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; - } + + pyfunc = PyUnicode_FromString(func_name); + if (!pyfunc) { + if (pyval) Py_XDECREF(pyval); + return PCILIB_ERROR_MEMORY; + } + + PyGILState_STATE gstate = PyGILState_Ensure(); + pyret = PyObject_CallMethodObjArgs(module->module, pyfunc, ctx->py->pcilib_pywrap, pyval, NULL); PyGILState_Release(gstate); - if(err) - 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, const char* module_name) -{ -#ifdef BUILD_PYTHON_MODULES - //extract module name from script 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)." - " Seems like name doesnt contains extension", module_name); - return PCILIB_ERROR_INVALID_DATA; - } - - pcilib_script_s* module = NULL; - 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); - return 0; - } - - //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); + Py_XDECREF(pyfunc); + Py_XDECREF(pyval); - //Success. Create struct and initialize values - module = malloc(sizeof(pcilib_script_s)); - if (!module) - return PCILIB_ERROR_MEMORY; - module->module = py_script_module; - module->name = module_name; - HASH_ADD_STR( ctx->py->scripts, name, module); -#endif - return 0; -} + if (!pyret) { + pcilib_python_error("Error executing function (%s) of python script (%s)", func_name, script_name); + return PCILIB_ERROR_FAILED; + } -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) - { - pcilib_error("Failed to find script module (%s) in hash", module_name); - return PCILIB_ERROR_NOTFOUND; - } - - 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; - return 0; -#else - mode[0] = PCILIB_ACCESS_RW; - return 0; -#endif -} + if ((val)&&(pyret != Py_None)) + err = pcilib_set_value_from_pyobject(ctx, val, pyret); -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) - { - pcilib_warning("Cant find Python module %s in hash. Seems it has already deleted.", module_name); - return 0; - } - - if(module->module) - { - module->module = NULL; - } - - HASH_DEL(ctx->py->scripts, module); - free(module); -#endif - return 0; -} + Py_XDECREF(pyret); -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); - if(!module) - { - pcilib_error("Failed to find script module (%s) in hash", module_name); - return PCILIB_ERROR_NOTFOUND; - } - - PyGILState_STATE gstate = PyGILState_Ensure(); - 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, - ctx->py->pcilib_pywrap, - input, - NULL); - - Py_XDECREF(py_func_name); - Py_XDECREF(input); - PyGILState_Release(gstate); - - if (!ret) - { - printf("Python script error: "); - PyErr_Print(); - return PCILIB_ERROR_FAILED; - } - - if(ret != Py_None) - { - err = pcilib_set_value_from_pyobject(ctx, val, ret); - Py_XDECREF(ret); - - if(err) - { - pcilib_error("Failed to convert python script return value to internal type: %i", err); - return err; - } - } - return 0; -#else - pcilib_error("Current build not support python."); - return PCILIB_ERROR_NOTAVAILABLE; -#endif + return err; +#else /* HAVE_PYTHON */ + pcilib_error("Python is not supported"); + return PCILIB_ERROR_NOTSUPPORTED; +#endif /* HAVE_PYTHON */ } diff --git a/pcilib/py.h b/pcilib/py.h index 04b4e8b..c372a09 100644 --- a/pcilib/py.h +++ b/pcilib/py.h @@ -1,7 +1,10 @@ #ifndef _PCILIB_PY_H #define _PCILIB_PY_H -#include "pcilib.h" +#include <pcilib.h> +#include <pcilib/error.h> + +#define pcilib_python_error(...) pcilib_log_python_error(__FILE__, __LINE__, PCILIB_LOG_DEFAULT, PCILIB_LOG_ERROR, __VA_ARGS__) typedef struct pcilib_py_s pcilib_py_t; typedef void pcilib_py_object; @@ -10,39 +13,110 @@ typedef void pcilib_py_object; extern "C" { #endif +void pcilib_log_python_error(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...); + +/** Initializes Python engine + * + * This function will return success if Python support is disabled. Only functions + * executing python call, like pcilib_py_eval_string(), return errors. Either way, + * no script directories are configured. The pcilib_add_script_dir() call is used + * for this purpose. + * + * @param[in,out] ctx - pcilib context + * @return - error or 0 on success + */ 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); + +/** Cleans up memory used by various python structures + * and finalyzes python environment if pcilib is not started from python script + * + * @param[in] ctx - the pcilib_t context + */ void pcilib_free_py(pcilib_t *ctx); +/** Add an additional path to look for python scripts + * + * The default location for python files is /usr/local/share/pcilib/models/@b{model}. + * This can be altered using CMake PCILIB_MODEL_DIR variable while building or using + * PCILIB_MODEL_DIR environmental variable dynamicly. The default location is added + * with @b{location} = NULL. Additional directories can be added as well either + * by specifying relative path from the default directory or absolute path in the + * system. + * + * @param[in,out] ctx - pcilib context + * @param[in] location - NULL or path to additional scripts + * @return - error or 0 on success + */ +int pcilib_py_add_script_dir(pcilib_t *ctx, const char *location); + +/** Loads the specified python script + * + * Once loaded the script is available until pcilib context is destryoed. + * + * @param[in,out] ctx - pcilib context + * @param[in] name - script name, the passed variable is referenced and, hence, should have static duration + * @return - error or 0 on success + */ +int pcilib_py_load_script(pcilib_t *ctx, const char *name); + +/** Check if the specified script can be used as transform view and detects transform configuration + * + * @param[in,out] ctx - pcilib context + * @param[in] name - script name + * @param[out] mode - supported access mode (read/write/read-write) + * @return - error or 0 on success + */ +int pcilib_py_get_transform_script_properties(pcilib_t *ctx, const char *name, pcilib_access_mode_t *mode); -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); +/** + * Get the PyObject from the polymorphic type. The returned value should be cleaned with Py_XDECREF() + * @param[in] ctx - pcilib context + * @param[in] val - initialized polymorphic value of arbitrary type + * @param[out] err - error code or 0 on sccuess + * @return - valid PyObject or NULL in the case of error + */ +pcilib_py_object *pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *err); -/*! - * \brief Converts pcilib_value_t to PyObject. - * \param ctx pointer to pcilib_t context - * \param val pointer to pcilib_value_t to convert - * \return PyObject, containing value. NULL with error message, sended to errstream. +/** + * Initializes the polymorphic value from PyObject. If `val` already contains the value, cleans it first. + * Therefore, before first usage the value should be always initialized to 0. + * @param[in] ctx - pcilib context + * @param[in,out] val - initialized polymorphic value + * @param[in] pyval - valid PyObject* containing PyInt, PyFloat, or PyString + * @return - 0 on success or memory error */ -pcilib_py_object* pcilib_get_value_as_pyobject(pcilib_t* ctx, pcilib_value_t *val, int *err); +int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object *pyval); +/** Evaluates the specified python code and returns result in @b{val} + * + * The python code may include special variables which will be substituted by pcitool before executing Python interpreter + * @b{$value} - will be replaced by the current value of the @b{val} parameter + * @b{$reg} - will be replaced by the current value of the specified register @b{reg} + * @b{${/prop/temp}} - will be replaced by the current value of the specified property @b{/prop/temp} + * @b{${/prop/temp:C}} - will be replaced by the current value of the specified property @b{/prop/temp} in the given units -/*! - * \brief Converts PyObject to pcilib_value_t. - * \param ctx pcilib context - * \param pyVal python object, containing value - * \param val initialized polymorphic value - * \return 0 on success or memory error + * @param[in,out] ctx - pcilib context + * @param[in] codestr - python code to evaluate + * @param[in,out] val - Should contain the value which will be substituted in place of @b{$value} and on + * successful execution will contain the computed value + * @return - error or 0 on success */ -int pcilib_set_value_from_pyobject(pcilib_t* ctx, pcilib_value_t *val, pcilib_py_object* pyObjVal); +int pcilib_py_eval_string(pcilib_t *ctx, const char *codestr, pcilib_value_t *val); +/** Execute the specified function in the Python script which was loaded with pcilib_py_load_script() call + * + * The function is expected to accept two paramters. The first parameter is pcipywrap context and the @b{val} + * is passed as the second parameter. The return value of the script will be returned in the @b{val} as well. + * If function returns Py_None, the value of @b{val} will be unchanged. + * + * @param[in,out] ctx - pcilib context + * @param[in] script - script name + * @param[in] func - function name + * @param[in,out] val - Should contain the value of second parameter of the function before call and on + * successful return will contain the returned value + * @return - error or 0 on success + */ +int pcilib_py_eval_func(pcilib_t *ctx, const char *script, const char *func, pcilib_value_t *val); #ifdef __cplusplus } diff --git a/pcilib/value.c b/pcilib/value.c index 6e65307..e8268e9 100644 --- a/pcilib/value.c +++ b/pcilib/value.c @@ -1,3 +1,4 @@ +#define _POSIX_C_SOURCE 200809L #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -71,6 +72,27 @@ int pcilib_set_value_from_static_string(pcilib_t *ctx, pcilib_value_t *value, co return 0; } +int pcilib_set_value_from_string(pcilib_t *ctx, pcilib_value_t *value, const char *str) { + size_t len; + + pcilib_clean_value(ctx, value); + + len = strlen(str) + 1; + if (len < sizeof(value->str)) { + memcpy(value->str, str, len); + value->sval = value->str; + } else { + value->data = (void*)strdup(str); + if (!value->data) return PCILIB_ERROR_MEMORY; + + value->size = strlen(str) + 1; + value->sval = value->data; + } + value->type = PCILIB_TYPE_STRING; + + return 0; +} + double pcilib_get_value_as_float(pcilib_t *ctx, const pcilib_value_t *val, int *ret) { int err; double res; diff --git a/pcilib/view.c b/pcilib/view.c index 797f4ae..985c1b2 100644 --- a/pcilib/view.c +++ b/pcilib/view.c @@ -69,8 +69,11 @@ int pcilib_add_views_custom(pcilib_t *ctx, size_t n, const pcilib_view_descripti return PCILIB_ERROR_MEMORY; } + memcpy(cur, v, v->api->description_size); + ctx->views[ctx->num_views + i] = cur; + if (v->api->init) - view_ctx = v->api->init(ctx, v); + view_ctx = v->api->init(ctx, ctx->num_views + i); 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)); @@ -83,14 +86,12 @@ int pcilib_add_views_custom(pcilib_t *ctx, size_t n, const pcilib_view_descripti return PCILIB_ERROR_FAILED; } - memcpy(cur, v, v->api->description_size); - view_ctx->view = ctx->num_views + i; + view_ctx->view = ctx->num_views + i; view_ctx->name = v->name; - if (refs) refs[i] = view_ctx; - HASH_ADD_KEYPTR(hh, ctx->view_hash, view_ctx->name, strlen(view_ctx->name), view_ctx); - ctx->views[ctx->num_views + i] = cur; + + if (refs) refs[i] = view_ctx; ptr += v->api->description_size; } diff --git a/pcilib/view.h b/pcilib/view.h index 1a1d277..8b1c07c 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, const pcilib_view_description_t *desc); /**< Optional function which should allocated context used by read/write functions */ + pcilib_view_context_t *(*init)(pcilib_t *ctx, pcilib_view_t view); /**< 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 35721aa..fd12636 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -40,9 +40,9 @@ #include "xml.h" #include "error.h" #include "view.h" +#include "py.h" #include "views/enum.h" #include "views/transform.h" -#include "py.h" #define BANKS_PATH ((xmlChar*)"/model/bank") /**< path to complete nodes of banks */ @@ -492,8 +492,8 @@ static int pcilib_xml_create_bank(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node, pcilib_view_description_t *desc) { xmlAttrPtr cur; const char *value, *name; - - int register_incosistent = 0; + + int inconsistent = (desc->mode & PCILIB_ACCESS_INCONSISTENT); for (cur = node->properties; cur != NULL; cur = cur->next) { if (!cur->children) continue; @@ -540,19 +540,14 @@ static int pcilib_xml_parse_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDoc pcilib_error("Invalid access mode (%s) is specified in the XML register description", value); return PCILIB_ERROR_INVALID_DATA; } - } - else if (!strcasecmp(name, "write_verification")) { - if (!strcasecmp(value, "0")) - { - register_incosistent = 1; - } - } + } else if (!strcasecmp(name, "write_verification")) { + if (strcmp(value, "0")) inconsistent = 0; + else inconsistent = 1; } + } - if(register_incosistent) - { - desc->mode |= PCILIB_REGISTER_INCONSISTENT; - } + if (inconsistent) desc->mode |= PCILIB_ACCESS_INCONSISTENT; + else desc->mode &= ~PCILIB_ACCESS_INCONSISTENT; return 0; } @@ -563,7 +558,7 @@ static int pcilib_xml_create_transform_view(pcilib_t *ctx, xmlXPathContextPtr xp const char *value, *name; pcilib_view_context_t *view_ctx; - pcilib_access_mode_t mode = PCILIB_REGISTER_INCONSISTENT; + pcilib_access_mode_t mode = 0; pcilib_transform_view_description_t desc = {{0}}; desc.base.api = &pcilib_transform_view_api; @@ -600,11 +595,11 @@ 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 = value; - break; + desc.script = value; + break; } } - desc.base.mode &= mode; + desc.base.mode &= (~PCILIB_ACCESS_RW)|mode; err = pcilib_add_views_custom(ctx, 1, (pcilib_view_description_t*)&desc, &view_ctx); if (err) return err; @@ -845,7 +840,6 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon if (bank_nodes) transform_nodes = xmlXPathEvalExpression(TRANSFORM_VIEWS_PATH, xpath); if (transform_nodes) enum_nodes = xmlXPathEvalExpression(ENUM_VIEWS_PATH, xpath); if (enum_nodes) unit_nodes = xmlXPathEvalExpression(UNITS_PATH, xpath); - if (!unit_nodes) { const unsigned char *expr = (enum_nodes?UNITS_PATH:(transform_nodes?ENUM_VIEWS_PATH:(bank_nodes?TRANSFORM_VIEWS_PATH:BANKS_PATH))); diff --git a/pcitool/CMakeLists.txt b/pcitool/CMakeLists.txt index 2f3639f..d8b5a6c 100644 --- a/pcitool/CMakeLists.txt +++ b/pcitool/CMakeLists.txt @@ -13,9 +13,9 @@ link_directories( ) if (NOT DISABLE_PCITOOL) - add_executable(pci cli.c sysinfo.c formaters.c) - set(HEADERS ${HEADERS} sysinfo.h formaters.h) - add_dependencies(pci pcilib) + set(HEADERS ${HEADERS} sysinfo.h formaters.h buildinfo.h) + add_executable(pci cli.c sysinfo.c formaters.c buildinfo.c) + add_dependencies(pci build pcilib) target_link_libraries(pci pcilib ${FASTWRITER_LIBRARIES}) set_target_properties(pci PROPERTIES LINK_FLAGS "${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}" diff --git a/pcitool/buildinfo.c b/pcitool/buildinfo.c new file mode 100644 index 0000000..624a934 --- /dev/null +++ b/pcitool/buildinfo.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include <string.h> +#include "pcilib/build.h" + +void BuildInfo() { + printf("\n"); + printf("Revision: %s built on %s in %s\n", PCILIB_REVISION, PCILIB_BUILD_DATE, PCILIB_BUILD_DIR); + printf("Branch: %s by %s\n", PCILIB_REVISION_BRANCH, PCILIB_REVISION_AUTHOR); + if (strlen(PCILIB_REVISION_MODIFICATIONS)) { + printf("Modifications: %s - %s\n", PCILIB_LAST_MODIFICATION, PCILIB_REVISION_MODIFICATIONS); + } +} diff --git a/pcitool/buildinfo.h b/pcitool/buildinfo.h new file mode 100644 index 0000000..5157a24 --- /dev/null +++ b/pcitool/buildinfo.h @@ -0,0 +1,6 @@ +#ifndef _PCITOOL_BUILDINFO_H +#define _PCITOOL_BUILDINFO_H + +void BuildInfo(); + +#endif /* _PCITOOL_BUILDINFO_H */
\ No newline at end of file diff --git a/pcitool/cli.c b/pcitool/cli.c index 0b0c98d..3f1af74 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -31,18 +31,19 @@ #include "pcitool/sysinfo.h" #include "pcitool/formaters.h" +#include "pcitool/buildinfo.h" #include "views/transform.h" #include "views/enum.h" -#include "pci.h" -#include "plugin.h" -#include "config.h" -#include "tools.h" -#include "kmem.h" -#include "error.h" -#include "debug.h" -#include "model.h" -#include "locking.h" +#include "pcilib/pci.h" +#include "pcilib/plugin.h" +#include "pcilib/config.h" +#include "pcilib/tools.h" +#include "pcilib/kmem.h" +#include "pcilib/error.h" +#include "pcilib/debug.h" +#include "pcilib/model.h" +#include "pcilib/locking.h" /* defines */ #define MAX_KBUF 14 @@ -895,6 +896,8 @@ void Version(pcilib_t *handle, const pcilib_model_description_t *model_info) { PCILIB_VERSION_GET_MICRO(version) ); } + + BuildInfo(); } void Info(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *target) { @@ -1385,7 +1388,7 @@ int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, const char *reg, const char *view, const char *unit, const char *attr) { int i; int err; - const char *format; + const char *format; pcilib_register_bank_t bank_id; pcilib_register_bank_addr_t bank_addr = 0; @@ -1699,23 +1702,19 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info err = pcilib_write_register(handle, bank, reg, value); if (err) Error("Error writting register %s\n", reg); - if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) { + if ((model_info->registers[regid].mode&(PCILIB_REGISTER_RW|PCILIB_REGISTER_INCONSISTENT)) == PCILIB_REGISTER_RW) { const char *format = (val.format?val.format:"%u"); - - 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"); - } - } + 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); } diff --git a/pywrap/CMakeLists.txt b/pywrap/CMakeLists.txt index 4592c9a..1693232 100644 --- a/pywrap/CMakeLists.txt +++ b/pywrap/CMakeLists.txt @@ -11,12 +11,12 @@ include_directories( set(HEADERS pcipywrap.h) #Creating python wrapping -INCLUDE(${SWIG_USE_FILE}) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) -SET(CMAKE_SWIG_FLAGS "") +include(${SWIG_USE_FILE}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_SWIG_FLAGS "") -SWIG_ADD_MODULE(pcipywrap python pcipywrap.i pcipywrap.c) -SWIG_LINK_LIBRARIES(pcipywrap ${PYTHON_LIBRARIES} pcilib) +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) +#configure_file(server.py server.py) +#configure_file(test_pcipywrap.py test_pcipywrap.py) diff --git a/pywrap/pcipywrap.c b/pywrap/pcipywrap.c index 11e3ce7..bcf4561 100644 --- a/pywrap/pcipywrap.c +++ b/pywrap/pcipywrap.c @@ -8,24 +8,24 @@ char* full_log = NULL; */ 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; + 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; } @@ -35,69 +35,69 @@ char* vmake_str(const char* msg, va_list vl) */ char* make_str(const char* msg, ...) { - va_list vl; + va_list vl; va_start(vl, msg); - char *buf = vmake_str(msg, vl); - va_end(vl); - return buf; + 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) { - //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(""); - - //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); - - free(buf_wrapped_message); - free(buf_raw_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) { + //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(""); + + //copy received message to log + char* buf = full_log; + full_log = make_str("%s%s", buf, buf_wrapped_message); + free(buf); + } + else + printf("%s", buf_wrapped_message); + + free(buf_wrapped_message); + free(buf_raw_msg); } void set_python_exception(const char* msg, ...) { - va_list vl; + 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); + 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_log_level(), - pcilib_print_error_to_py, - pcilib_get_logger_context()); + pcilib_set_logger(pcilib_get_log_level(), + pcilib_print_error_to_py, + pcilib_get_logger_context()); } /*! @@ -125,14 +125,14 @@ void add_pcilib_value_to_dict(pcilib_t* ctx, PyObject* dict, pcilib_value_t* val { PyObject *py_val = (PyObject*)pcilib_get_value_as_pyobject(ctx, val, NULL); - if(py_val) + if(py_val) pcilib_pydict_set_item(dict, - PyString_FromString(name), - py_val); - else + PyString_FromString(name), + py_val); + else pcilib_pydict_set_item(dict, - PyString_FromString("defvalue"), - PyString_FromString("invalid")); + PyString_FromString("defvalue"), + PyString_FromString("invalid")); } PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_property_info_t listItem) @@ -141,41 +141,41 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper if(listItem.name) pcilib_pydict_set_item(pylistItem, - PyString_FromString("name"), - PyString_FromString(listItem.name)); + PyString_FromString("name"), + PyString_FromString(listItem.name)); if(listItem.description) pcilib_pydict_set_item(pylistItem, - PyString_FromString("description"), - PyString_FromString(listItem.description)); + PyString_FromString("description"), + PyString_FromString(listItem.description)); - if(listItem.path) + if(listItem.path) pcilib_pydict_set_item(pylistItem, - PyString_FromString("path"), - PyString_FromString(listItem.path)); + 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; + 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; } pcilib_pydict_set_item(pylistItem, - PyString_FromString("type"), - PyString_FromString(type)); + PyString_FromString("type"), + PyString_FromString(type)); //serialize modes @@ -191,8 +191,8 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("mode"), - modes); + PyString_FromString("mode"), + modes); //serialize flags PyObject* flags = PyList_New(0); @@ -201,13 +201,13 @@ PyObject * pcilib_convert_property_info_to_pyobject(pcilib_t* ctx, pcilib_proper pcilib_pylist_append(flags, PyString_FromString("childs")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("flags"), - flags); + PyString_FromString("flags"), + flags); if(listItem.unit) - pcilib_pydict_set_item(pylistItem, - PyString_FromString("unit"), - PyString_FromString(listItem.unit)); + pcilib_pydict_set_item(pylistItem, + PyString_FromString("unit"), + PyString_FromString(listItem.unit)); return pylistItem; } @@ -218,18 +218,18 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist if(listItem.name) pcilib_pydict_set_item(pylistItem, - PyString_FromString("name"), - PyString_FromString(listItem.name)); + PyString_FromString("name"), + PyString_FromString(listItem.name)); if(listItem.description) pcilib_pydict_set_item(pylistItem, - PyString_FromString("description"), - PyString_FromString(listItem.description)); + PyString_FromString("description"), + PyString_FromString(listItem.description)); - if(listItem.bank) + if(listItem.bank) pcilib_pydict_set_item(pylistItem, - PyString_FromString("bank"), - PyString_FromString(listItem.bank)); + PyString_FromString("bank"), + PyString_FromString(listItem.bank)); //serialize modes PyObject* modes = PyList_New(0); @@ -252,27 +252,27 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist pcilib_pylist_append(modes, PyString_FromString("NO_CHK")); pcilib_pydict_set_item(pylistItem, - PyString_FromString("mode"), - modes); - + PyString_FromString("mode"), + modes); + pcilib_value_t defval = {0}; 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_value_t maxval = {0}; - pcilib_set_value_from_register_value(ctx, &maxval, listItem.range->max); - + 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(ctx, range, &minval, "min"); add_pcilib_value_to_dict(ctx, range, &maxval, "max"); pcilib_pydict_set_item(pylistItem, - PyString_FromString("range"), - range); + PyString_FromString("range"), + range); } if(listItem.values) @@ -282,36 +282,36 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist 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); - + 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(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, - PyString_FromString("name"), - PyString_FromString(listItem.values[j].name)); + PyString_FromString("name"), + PyString_FromString(listItem.values[j].name)); if(listItem.values[j].description) pcilib_pydict_set_item(valuesItem, - PyString_FromString("name"), - PyString_FromString(listItem.values[j].description)); + PyString_FromString("name"), + PyString_FromString(listItem.values[j].description)); pcilib_pylist_append(values, valuesItem); } pcilib_pydict_set_item(pylistItem, - PyString_FromString("values"), - values); + PyString_FromString("values"), + values); } return pylistItem; @@ -319,163 +319,163 @@ PyObject * pcilib_convert_register_info_to_pyobject(pcilib_t* ctx, pcilib_regist Pcipywrap *new_Pcipywrap(const char* fpga_device, const char* model) { - //opening device + //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; + 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)) - { + if(!PyCObject_Check(ctx)) + { set_python_exception("Incorrect ctx type. Only PyCObject is allowed"); - return NULL; - } - - Pcipywrap *self; - self = (Pcipywrap *) malloc(sizeof(Pcipywrap)); - self->shared = 1; - self->ctx = PyCObject_AsVoidPtr(ctx); - return self; + return NULL; + } + + 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); +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_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; - } + + 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_value_t val_internal = {0}; pcilib_register_value_t reg_value; - - int err; - + + 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; - } - + + 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; - } - +{ + 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}; + 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); + 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); + pcilib_register_info_t *list = pcilib_get_register_list(self->ctx, bank, PCILIB_LIST_FLAGS_DEFAULT); + + PyObject* pyList = PyList_New(0); for(int i = 0; i < ((pcilib_t*)self->ctx)->num_reg; i++) { - //serialize item attributes + //serialize item attributes PyObject* pylistItem = pcilib_convert_register_info_to_pyobject(self->ctx, list[i]); pcilib_pylist_append(pyList, pylistItem); } - + pcilib_free_register_info(self->ctx, list); - - return pyList; + + return pyList; } PyObject* Pcipywrap_get_register_info(Pcipywrap *self, const char* reg,const char *bank) { pcilib_register_info_t *info = pcilib_get_register_info(self->ctx, bank, reg, PCILIB_LIST_FLAGS_DEFAULT); - if(!info) - { + if(!info) + { return NULL; - } + } PyObject* py_info = pcilib_convert_register_info_to_pyobject(self->ctx, info[0]); diff --git a/pywrap/pcipywrap.h b/pywrap/pcipywrap.h index 8389445..99cebd7 100644 --- a/pywrap/pcipywrap.h +++ b/pywrap/pcipywrap.h @@ -6,8 +6,8 @@ #include <Python.h> typedef struct { - void* ctx; - int shared; + void* ctx; + int shared; } Pcipywrap; /*! diff --git a/pywrap/test_pcipywrap.py b/pywrap/test_pcipywrap.py index 257b4a5..257b4a5 100755..100644 --- a/pywrap/test_pcipywrap.py +++ b/pywrap/test_pcipywrap.py diff --git a/tests/device_info.sh b/tests/device_info.sh index 21e59db..21e59db 100644..100755 --- a/tests/device_info.sh +++ b/tests/device_info.sh diff --git a/tests/dump_file.sh b/tests/dump_file.sh index 6773a19..6773a19 100644..100755 --- a/tests/dump_file.sh +++ b/tests/dump_file.sh diff --git a/tests/grab.sh b/tests/grab.sh index daa08c1..daa08c1 100644..100755 --- a/tests/grab.sh +++ b/tests/grab.sh diff --git a/tests/ipedma/ipecamera-frame.sh b/tests/ipedma/ipecamera-frame.sh index 5e72c6c..5e72c6c 100644..100755 --- a/tests/ipedma/ipecamera-frame.sh +++ b/tests/ipedma/ipecamera-frame.sh diff --git a/tests/ipedma/ipecamera-test.sh b/tests/ipedma/ipecamera-test.sh index cd21391..cd21391 100644..100755 --- a/tests/ipedma/ipecamera-test.sh +++ b/tests/ipedma/ipecamera-test.sh diff --git a/tests/ipedma/test.sh b/tests/ipedma/test.sh index 48f9184..48f9184 100644..100755 --- a/tests/ipedma/test.sh +++ b/tests/ipedma/test.sh diff --git a/tests/nwldma/bench.sh b/tests/nwldma/bench.sh index d0bf323..d0bf323 100644..100755 --- a/tests/nwldma/bench.sh +++ b/tests/nwldma/bench.sh diff --git a/tests/nwldma/cleanup.sh b/tests/nwldma/cleanup.sh index 87e1517..87e1517 100644..100755 --- a/tests/nwldma/cleanup.sh +++ b/tests/nwldma/cleanup.sh diff --git a/tests/reload.sh b/tests/reload.sh index 62c6e22..62c6e22 100644..100755 --- a/tests/reload.sh +++ b/tests/reload.sh diff --git a/tests/test-iommu.sh b/tests/test-iommu.sh index 5a5924b..5a5924b 100644..100755 --- a/tests/test-iommu.sh +++ b/tests/test-iommu.sh diff --git a/tests/xilinxdma/xilinx_dma.sh b/tests/xilinxdma/xilinx_dma.sh index 4fedac3..4fedac3 100644..100755 --- a/tests/xilinxdma/xilinx_dma.sh +++ b/tests/xilinxdma/xilinx_dma.sh diff --git a/tests/xilinxdma/xilinx_dma_static_mem.sh b/tests/xilinxdma/xilinx_dma_static_mem.sh index 23ee5c9..23ee5c9 100644..100755 --- a/tests/xilinxdma/xilinx_dma_static_mem.sh +++ b/tests/xilinxdma/xilinx_dma_static_mem.sh diff --git a/views/transform.c b/views/transform.c index eb3572a..f2d4b4a 100644 --- a/views/transform.c +++ b/views/transform.c @@ -11,90 +11,79 @@ #include "py.h" #include "error.h" +static pcilib_view_context_t * pcilib_transform_view_init(pcilib_t *ctx, pcilib_view_t view) { + int err; -static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) { + pcilib_view_context_t *view_ctx; 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]); + pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view]); - int err; + if(v->script) { + pcilib_access_mode_t mode = 0; + + err = pcilib_py_load_script(ctx, v->script); + if(err) { + pcilib_error("Error (%i), loading script %s", err, v->script); + return NULL; + } + + err = pcilib_py_get_transform_script_properties(ctx, v->script, &mode); + if(err) { + pcilib_error("Error (%i) obtaining properties of transform script %s", err, v->script); + return NULL; + } - err = pcilib_set_value_from_register_value(ctx, val, regval); - if (err) return err; + if ((v->base.mode&PCILIB_REGISTER_RW) == 0) + v->base.mode |= PCILIB_REGISTER_RW; + v->base.mode &= (~PCILIB_REGISTER_RW)|mode; - if(v->module) - 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); + if (!v->read_from_reg) v->read_from_reg = "read_from_register"; + if (!v->write_to_reg) v->write_to_reg = "write_to_register"; + } + + 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; } -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) { - +static int pcilib_transform_view_read(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t regval, pcilib_value_t *val) { + int err; + const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); - int err = 0; - - pcilib_value_t val_copy = {0}; - err = pcilib_copy_value(ctx, &val_copy, val); - if (err) return err; + err = pcilib_set_value_from_register_value(ctx, val, regval); + if (err) return err; + if (v->script) + err = pcilib_py_eval_func(ctx, v->script, v->read_from_reg, val); + else + err = pcilib_py_eval_string(ctx, v->read_from_reg, val); - if(v->module) - 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); - - if (err) return err; - - *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); - return 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->module) - pcilib_py_free_script(ctx, v->module); -} +static int pcilib_transform_view_write(pcilib_t *ctx, pcilib_view_context_t *view_ctx, pcilib_register_value_t *regval, const pcilib_value_t *val) { + int err = 0; + pcilib_value_t val_copy = {0}; -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); - if(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; - } + const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); + pcilib_transform_view_description_t *v = (pcilib_transform_view_description_t*)(model_info->views[view_ctx->view]); + + err = pcilib_copy_value(ctx, &val_copy, val); + if (err) return err; + + if (v->script) + err = pcilib_py_eval_func(ctx, v->script, v->write_to_reg, &val_copy); + else + err = pcilib_py_eval_string(ctx, v->write_to_reg, &val_copy); - v_desc->base.mode |= PCILIB_REGISTER_RW; - mode |= PCILIB_REGISTER_INCONSISTENT; - v_desc->base.mode &= mode; - } + if (err) return err; - 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; + *regval = pcilib_get_value_as_register_value(ctx, &val_copy, &err); + return err; } 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 }; + { PCILIB_VERSION, sizeof(pcilib_transform_view_description_t), pcilib_transform_view_init, NULL, NULL, pcilib_transform_view_read, pcilib_transform_view_write }; diff --git a/views/transform.h b/views/transform.h index 8c9321d..774a019 100644 --- a/views/transform.h +++ b/views/transform.h @@ -3,13 +3,12 @@ #include <pcilib.h> #include <pcilib/view.h> -#include <py.h> typedef struct { pcilib_view_description_t base; + const char *script; /**< Python script module name */ 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 */ - const char *module; /**< Python script module name (without extension) */ } pcilib_transform_view_description_t; #ifndef _PCILIB_VIEW_TRANSFORM_C diff --git a/xml/test/props.xml b/xml/test/props.xml index cf163eb..57702e2 100644 --- a/xml/test/props.xml +++ b/xml/test/props.xml @@ -1,4 +1,6 @@ <?xml version="1.0"?> <model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <transform path="/test/prop1" register="test_prop1" unit="C" read_from_register="(503975./1024000)*${/registers/fpga/sensor_temperature:C} - 27315./100" description="formula to get real fpga temperature from the fpga_temperature register in decimal"/> + <transform path="/test/prop2" register="test_prop2" unit="C" script="test_prop2.py" description="test python script #1" write_verification="0" /> + <transform path="/test/prop3" register="test_prop3" unit="C" script="test_prop3.py" description="test python script #2" /> </model> diff --git a/xml/test_pywrap/test_prop2.py b/xml/test/test_prop2.py index d78dbea..d78dbea 100644 --- a/xml/test_pywrap/test_prop2.py +++ b/xml/test/test_prop2.py diff --git a/xml/test_pywrap/test_prop3.py b/xml/test/test_prop3.py index a082096..a082096 100644 --- a/xml/test_pywrap/test_prop3.py +++ b/xml/test/test_prop3.py diff --git a/xml/test_pywrap/camera.xml b/xml/test_pywrap/camera.xml deleted file mode 100644 index 4b31209..0000000 --- a/xml/test_pywrap/camera.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x9000" write_address="0x9000" word_size="32" endianess="little" format="0x%lx" name="fpga" description="IPECamera Registers"> - <register address="0x00" offset="0" size="32" default="0" rwmask="0" mode="RW" name="reg1"/> - </bank> -</model> diff --git a/xml/test_pywrap/names.xml b/xml/test_pywrap/names.xml deleted file mode 100644 index f6ddbcc..0000000 --- a/xml/test_pywrap/names.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <enum name="enumm1" description="enum towards temperatures register"> - <name name="high" value="0x100" min="0x2" max="0x300"/> - <name name="low" value="0x010"/> - </enum> - <enum name="enumm2" description="enum towards sensor_temperature register"> - <name name="high" value="0x120"/> - <name name="low" value="0x010" min="0x00" max="0x020"/> - </enum> - <enum name="enumm3" description="enum towards cmosis_exp_register register"> - <name name="short" value="0x000"/> - <name name="mid" value="0x010"/> - <name name="long" value="0x100" min="0x0F0"/> - </enum> -</model> diff --git a/xml/test_pywrap/props.xml b/xml/test_pywrap/props.xml deleted file mode 100644 index 0d0078b..0000000 --- a/xml/test_pywrap/props.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <transform path="/test/prop1" - register="test_prop1" - unit="C" - read_from_register="(503975./1024000)*${/registers/fpga/reg1} + 28715./100" - description="formula to get real fpga temperature from the fpga_temperature register in decimal"/> - <transform path="/test/prop2" - register="test_prop2" - unit="C" - script="test_prop2.py" - description="test python script #1" - write_verification="0"/> - <transform path="/test/prop3" - register="test_prop3" - unit="C" - script="test_prop3.py" - description="test python script #2"/> -</model> diff --git a/xml/test_pywrap/units.xml b/xml/test_pywrap/units.xml deleted file mode 100644 index 74ab9f7..0000000 --- a/xml/test_pywrap/units.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <unit name="C"> - <transform unit="K" transform="$value+273.15"/> - <transform unit="F" transform="$value*(9./5)+32"/> - </unit> - <unit name="K"> - <transform unit="C" transform="$value-273.15"/> - <transform unit="F" transform="($value-273.15)*(9./5)+32"/> - </unit> - <unit name="F"> - <transform unit="C" transform="($value-32)*5./9"/> - <transform unit="K" transform="($value+273.15-32)*5./9"/> - </unit> - <unit name="s"> - <transform unit="ms" transform="$value*1000"/> - <transform unit="us" transform="$value*1000000"/> - <transform unit="ns" transform="$value*1000000000"/> - </unit> - <unit name="ms"> - <transform unit="s" transform="$value/1000"/> - <transform unit="us" transform="$value*1000"/> - <transform unit="ns" transform="$value*1000000"/> - </unit> - <unit name="us"> - <transform unit="s" transform="$value/1000000"/> - <transform unit="ms" transform="$value/1000"/> - <transform unit="ns" transform="$value*1000"/> - </unit> - <unit name="ns"> - <transform unit="s" transform="$value/1000000000"/> - <transform unit="ms" transform="$value/1000000"/> - <transform unit="us" transform="$value/1000"/> - </unit> -</model> diff --git a/xml/test_pywrap/views.xml b/xml/test_pywrap/views.xml deleted file mode 100644 index c40cd0f..0000000 --- a/xml/test_pywrap/views.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <transform name="formuu1" unit="C" read_from_register="(503975./1024000)*$value - 27315./100" write_to_register="($value + 27315./100)*(1024000./503975)" description="formula to get real fpga temperature from the fpga_temperature register in decimal"/> - <transform name="formuu2" unit="C1" read_from_register="((1./4)*($value - 1200)) if $freq==0 else ((3./10)*($value - 1000))" write_to_register="4*$value + 1200 if $freq==0 else (10./3)*$value + 1000" description="formula to get real sensor temperature from the sensor_temperature register in decimal"/> - <transform name="formuu3" unit="us" read_from_register="($value+(43./100))*129./(40*1000000)if $freq==0 else ($value+(43./100))*129./(48*1000000)" write_to_register="$value/129.*(40*1000000) - 43./100 if $freq==0 else $value/129.*(48*1000000) - 43./100" description="formula to get real exposure time from the cmosis_exp_time register in decimal"/> -</model> |