From 9bcd0b7b98dfb10d054913dad34313391f6029f2 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Thu, 10 Sep 2015 16:09:02 +0200 Subject: compilation ok --- CMakeLists.txt | 1 + pcilib/CMakeLists.txt | 13 +- pcilib/register.h | 1 + pcilib/views.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++++ pcilib/views.h | 39 ++++++ views.c | 302 --------------------------------------------- views.h | 15 --- 7 files changed, 381 insertions(+), 321 deletions(-) create mode 100644 pcilib/views.c create mode 100644 pcilib/views.h delete mode 100644 views.c delete mode 100644 views.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 10742fd..d9e637f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ SET(ENV{PKG_CONFIG_PATH} "${LIB_INSTALL_DIR}/pkgconfig:$ENV{PKG_CONFIG_PATH}") find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) +find_package(PythonLibs REQUIRED) set(EXTRA_SYSTEM_LIBS -lrt) diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index 8b11d60..f75d7de 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -4,11 +4,16 @@ include_directories( ${CMAKE_SOURCE_DIR}/pcilib ${CMAKE_BINARY_DIR}/pcilib ${LIBXML2_INCLUDE_DIRS} + ${PYTHON_INCLUDE_DIRS} ) -set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h xml.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 export.c bar.c fifo.c model.c bank.c register.c xml.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 ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} ${LIBXML2_LIBRARIES}) +set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h +xml.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 views.h) +add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c xml.c kmem.c irq.c locking.c lock.c dma.c event.c plugin.c tools.c error.c debug.c env.c views.c) +target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT} +${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS} ${EXTRA_SYSTEM_LIBS} +${LIBXML2_LIBRARIES} ${PYTHON_LIBRARIES}) add_dependencies(pcilib dma protocols) install(TARGETS pcilib @@ -19,6 +24,6 @@ install(FILES pcilib.h DESTINATION include ) -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 export.h version.h +install(FILES bar.h kmem.h locking.h lock.h bank.h register.h views.h xml.h dma.h event.h model.h error.h debug.h env.h tools.h export.h version.h DESTINATION include/pcilib ) diff --git a/pcilib/register.h b/pcilib/register.h index 9126e9f..5669237 100644 --- a/pcilib/register.h +++ b/pcilib/register.h @@ -3,6 +3,7 @@ #include #include +#include #define PCILIB_REGISTER_NO_BITS 0 #define PCILIB_REGISTER_ALL_BITS ((pcilib_register_value_t)-1) diff --git a/pcilib/views.c b/pcilib/views.c new file mode 100644 index 0000000..38ce102 --- /dev/null +++ b/pcilib/views.c @@ -0,0 +1,331 @@ +#include +#include "pci.h" +#include "pcilib.h" +#include +#include "views.h" +#include "error.h" +#include +#include + +/** + * + * replace a substring within a string by another + * @param[in] txt - the string to be modified + *@param[in] before - the substring in the string that will be replaced + *@param[in] after - the new value of before substring + *@return the modified txt string + */ +static char* +pcilib_view_formula_replace (const char *txt, const char *before, const char *after) +{ + const char *pos; + char *return_txt; + size_t pos_return_txt; + size_t len; + size_t allocated_size; + + /*get the first occurence of before. then we need one time to be out of the loop to correctly set the diverses varaibles (malloc instead of realloc notably)*/ + pos = strstr (txt, before); + + if (pos == NULL) + { + pcilib_warning("problem with a formula"); + } + + /* get the position of this occurence*/ + len = (size_t)pos - (size_t)txt; + allocated_size = len + strlen (after) + 1; + return_txt = malloc (allocated_size); + pos_return_txt = 0; + + /* we copy there the in a newly allocated string the start of txt before the "before" occurence, and then we copy after instead*/ + strncpy (return_txt + pos_return_txt, txt, len); + pos_return_txt += len; + txt = pos + strlen (before); + + len = strlen (after); + strncpy (return_txt + pos_return_txt, after, len); + pos_return_txt += len; + + /* we then iterate with the same principle to all occurences of before*/ + pos = strstr (txt, before); + while (pos != NULL) + { + len = (size_t)pos - (size_t)txt; + allocated_size += len + strlen (after); + return_txt = (char *)realloc (return_txt, allocated_size); + + strncpy (return_txt + pos_return_txt, txt, len); + pos_return_txt += len; + + txt = pos + strlen (before); + + len = strlen (after); + strncpy (return_txt + pos_return_txt, after, len); + pos_return_txt += len; + pos = strstr (txt, before); + } + /* put the rest of txt string at the end*/ + len = strlen (txt) + 1; + allocated_size += len; + return_txt = realloc (return_txt, allocated_size); + strncpy (return_txt + pos_return_txt, txt, len); + + return return_txt; +} + +/** + * function used to get the substring of a string s, from the starting and ending indexes + * @param[in] s string containing the substring we want to extract. + * @param[in] start the start index of the substring. + * @param[in] end the ending index of the substring. + * @return the extracted substring. + */ +static char* +pcilib_view_str_sub (const char *s, unsigned int start, unsigned int end) +{ + char *new_s = NULL; + + if (s != NULL && start < end) + { + new_s = malloc (sizeof (*new_s) * (end - start + 2)); + if (new_s != NULL) + { + int i; + + for (i = start; i <= end; i++) + { + new_s[i-start] = s[i]; + } + new_s[i-start] = '\0'; + } + else + { + pcilib_error("insufficient memory for string manipulation\n"); + return NULL; + } + } + return new_s; +} + +/** + * get the bank name associated with a register name + */ +static const char* +pcilib_view_get_bank_from_reg_name(pcilib_t* ctx,char* reg_name){ + int k; + for(k=0;ctx->registers[k].bits;k++){ + if(!(strcasecmp(reg_name,ctx->registers[k].name))){ + return ctx->banks[pcilib_find_register_bank_by_addr(ctx,ctx->registers[k].bank)].name; + } + } + return NULL; +} + +/** + * replace plain registers name in a formula by their value + */ +static char* +pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){ + int j,k; + char *substr, *substr2; + char temp[66]; + pcilib_register_value_t value; + + /*we get recursively all registers of string , and if they are not equel to '@reg', then we get their value and put it in formula*/ + for(j=0;j>> import re + >>> m = re.search('(?<=@)\w+', formula) + >>> m.group(0) + */ + + char reg_value_string[66]; /* to register reg_value as a string, need to check the length*/ + sprintf(reg_value_string,"%u",reg_value); + + /*computation of plain registers in the formula*/ + formula=pcilib_view_compute_plain_registers(ctx,formula); + /* computation of @reg with register value*/ + formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string); + + /* evaluation of the formula*/ + *out_value= pcilib_view_eval_formula(formula); + +} + +int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value) +{ + int i,j,err=0; + pcilib_register_value_t temp_value; + char* formula; + + /* we get the index of the register to find the corresponding register context*/ + if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){ + pcilib_error("can't get the index of the register %s", regname); + return PCILIB_ERROR_INVALID_REQUEST; + } + + /* we get the value of the register, as we will apply the view on it*/ + if((err==pcilib_read_register_by_id(ctx,i,&temp_value))>0){ + pcilib_error("can't read the register %s value before applying views",regname); + } + /*in the case we don't ask for a view's name, we know it will be for views of type enum. Especially, it's faster to search directly on the values of those views instead of a given name. + we iterate so through the views of type enum to verify if the value we have corresponds to an enum command*/ + if(!(view)){ + for(j=0; ctx->register_ctx[i].enums[j].value;j++){ + if((temp_value >= ctx->register_ctx[i].enums[j].min) && (temp_value <= ctx->register_ctx[i].enums[j].max)){ + value_size=strlen(ctx->register_ctx[i].enums[j].name)*sizeof(char); + value=malloc(sizeof(value_size)); + if(!(value)){ + pcilib_error("can't allocate memory for the returning value of the view %s",view); + return PCILIB_ERROR_MEMORY; + } + /* in the case the value of register is between min and max, then we return the correponding enum command*/ + strncpy((char*)value,ctx->register_ctx[i].enums[j].name, strlen(ctx->register_ctx[i].enums[j].name)); + return 0; + } + } + pcilib_warning("the value of the register asked do not correspond to any enum views"); + return PCILIB_ERROR_NOTAVAILABLE; + } + + /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views*/ + j=0; + while((ctx->register_ctx[i].formulas[j].name)){ + if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name,view))){ + /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/ + formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[j].read_formula)); + strncpy(formula,ctx->register_ctx[i].formulas[j].read_formula,strlen(ctx->register_ctx[i].formulas[j].read_formula)); + // pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].read_formula,temp_value,value); + pcilib_view_apply_formula(ctx, formula,temp_value,value); + value_size=sizeof(int); + return 0; + } + j++; + } + + pcilib_warning("the view asked and the register do not correspond"); + return PCILIB_ERROR_NOTAVAILABLE; +} + + +/** + * function to write to a register using a view + */ +int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view, size_t value_size,void* value/*, const char *unit*/){ + int i,j; + pcilib_register_value_t temp_value; + char *formula; + + /* we get the index of the register to find the corresponding register context*/ + if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){ + pcilib_error("can't get the index of the register %s", regname); + return PCILIB_ERROR_INVALID_REQUEST; + } + + /*here, in the case of views of type enum, view will correspond to the enum command. + we iterate so through the views of type enum to get the value corresponding to the enum command*/ + for(j=0; ctx->register_ctx[i].enums[j].value;j++){ + if(!(strcasecmp(ctx->register_ctx[i].enums[j].name,view))){ + pcilib_write_register(ctx,bank,regname,ctx->register_ctx[i].enums[j].value); + return 0; + } + } + + /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views in view, and the value we want to write in value*/ + j=0; + while((ctx->register_ctx[i].formulas[j].name)){ + if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name,view))){ + /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/ + formula=malloc(sizeof(char)*strlen(ctx->register_ctx[i].formulas[j].write_formula)); + strncpy(formula,ctx->register_ctx[i].formulas[j].write_formula,strlen(ctx->register_ctx[i].formulas[j].write_formula)); + // pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].write_formula,(pcilib_register_value_t*)value,temp_value); + pcilib_view_apply_formula(ctx,formula,*(pcilib_register_value_t*)value,&temp_value); + pcilib_write_register(ctx,bank,regname,temp_value); + return 0; + } + j++; + } + pcilib_warning("the view asked and the register do not correspond"); + return PCILIB_ERROR_NOTAVAILABLE; + } diff --git a/pcilib/views.h b/pcilib/views.h new file mode 100644 index 0000000..bdae9f4 --- /dev/null +++ b/pcilib/views.h @@ -0,0 +1,39 @@ +#ifndef _PCILIB_VIEWS_H +#define _PCILIB_VIEWS_H + +#include "pcilib.h" + +typedef struct pcilib_view_enum_s pcilib_view_enum_t; + +typedef struct pcilib_view_formula_s pcilib_view_formula_t; + +/** + * new type to define an enum view + */ +struct pcilib_view_enum_s { + const char *name; /** -#include "pci.h" - - -/** - * new type to define an enum view - */ -pcilib_value_enum_s { - const char *name; /**registers[k].bits;k++){ - if(!(strcasecmp(reg_name,ctx->registers[k].name))){ - return ctx->banks[pcilib_find_register_bank_by_addr(ctx,ctx->registers[k].bank)].name; - } - } -} - -/** - * replace plain registers name in a formula by their value - */ -static int -pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula){ - int j,k; - char* substr,substr2; - char temp[66]; - pcilib_register_value_t value; - - /*we get recursively all registers of string , and if they are not equel to '@reg', then we get their value and put it in formula*/ - for(j=0;j>> import re - >>> m = re.search('(?<=@)\w+', formula) - >>> m.group(0) - */ - - char reg_value_string[66]; /* to register reg_value as a string, need to check the length*/ - sprintf(reg_value_string,"%lu",reg_value); - - /*computation of plain registers in the formula*/ - formula=pcilib_view_formula_compute_plain_registers(formula,ctx); - /* computation of @reg with register value*/ - formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string); - - /* evaluation of the formula*/ - *out_value=*(pcilib_register_value_t*) pcilib_view_eval_formula(formula); - -} - -int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value) -{ - int i,j,err; - pcilib_register_value_t temp_value; - - /* we get the index of the register to find the corresponding register context*/ - if((i=pcilib_find_register(ctx,bank,regname))==PCILIB_REGISTER_INVALID){ - pcilib_error("can't get the index of the register %s", regname); - return PCILIB_ERROR_INVALID_REQUEST; - } - - /* we get the value of the register, as we will apply the view on it*/ - if((err==pcilib_read_register_by_id(ctx,i,&temp_value))>0){ - pcilib_error("can't read the register %s value before applying views",regname); - } - /*in the case we don't ask for a view's name, we know it will be for views of type enum. Especially, it's faster to search directly on the values of those views instead of a given name. - we iterate so through the views of type enum to verify if the value we have corresponds to an enum command*/ - if(!(view)){ - for(j=0; ctx->register_ctx[i].enums[j].value;j++){ - if((temp_value >= ctx->register_ctx[i].enums[j].min) && (temp_value <= ctx->register_ctx[i].enums[j].max)){ - value_size=strlen(ctx->register_ctx[i].enums[j].name)*sizeof(char); - value=malloc(sizeof(value_size)); - if(!(value)){ - pcilib_error("can't allocate memory for the returning value of the view %s",view); - return PCILIB_ERROR_MEMORY; - } - /* in the case the value of register is between min and max, then we return the correponding enum command*/ - value=*(char*)ctx->register_ctx[i].enums[j].name; - return 0; - } - } - pcilib_warning("the value of the register asked do not correspond to any enum views"); - return PCILIB_ERROR_NOTAVAILABLE; - } - - /** in the other case we ask for a view of type formula. Indeed, wa can't directly ask for a formula, so we have to provide a name for those views*/ - j=0; - while((ctx->register_ctx[i].formulas[j].name)){ - if(!(strcasecmp(ctx->register_ctx[i].formulas[j].name))){ - /* when we have found the correct view of type formula, we apply the formula, that get the good value for return*/ - pcilib_view_apply_formula(ctx, ctx->register_ctx[i].formulas[j].read_formula,temp_value,value); - value_size=sizeof(int); - return 0; - } - j++; - } - - pcilib_warning("the view asked and the register do not correspond"); - return PCILIB_ERROR_NOTAVAILABLE; -} - - int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value){ - diff --git a/views.h b/views.h deleted file mode 100644 index 988e376..0000000 --- a/views.h +++ /dev/null @@ -1,15 +0,0 @@ -typedef struct pcilib_view_enum_s pcilib_view_enum_t; - -typedef struct pcilib_view_formula_s pcilib_view_formula_t; - - -/** - * function to read a register using a view - */ -int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value); - -/** - * function to write to a register using a view - */ -int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value); - -- cgit v1.2.3