diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-10-19 20:31:56 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-10-19 20:31:56 +0200 |
commit | 6ae98bfdd390638c1b020cbc576a590504fe24cf (patch) | |
tree | 69836a90b3d48d4f31f1f779591ba7657cc81d7d | |
parent | 55255f2ce3a2234850249efcabd9ba32d0a89a9c (diff) | |
download | pcitool-6ae98bfdd390638c1b020cbc576a590504fe24cf.tar.gz pcitool-6ae98bfdd390638c1b020cbc576a590504fe24cf.tar.bz2 pcitool-6ae98bfdd390638c1b020cbc576a590504fe24cf.tar.xz pcitool-6ae98bfdd390638c1b020cbc576a590504fe24cf.zip |
Support multiple XML files per folder
-rw-r--r-- | docs/ToDo | 23 | ||||
-rw-r--r-- | pcilib/xml.c | 230 | ||||
-rw-r--r-- | pcilib/xml.h | 43 | ||||
-rw-r--r-- | xml/model.xsd | 2 | ||||
-rw-r--r-- | xml/references.xsd | 19 | ||||
-rw-r--r-- | xml/test/camera.xml | 97 | ||||
-rw-r--r-- | xml/test/cmosis.xml | 50 | ||||
-rw-r--r-- | xml/test/dma.xml | 4 | ||||
-rw-r--r-- | xml/test/names.xml | 16 | ||||
-rw-r--r-- | xml/test/props.xml | 4 | ||||
-rw-r--r-- | xml/test/units.xml | 35 | ||||
-rw-r--r-- | xml/test/views.xml | 6 |
12 files changed, 324 insertions, 205 deletions
@@ -1,23 +1,30 @@ High Priority (we would need it for IPE Camera) ============= - 1. Join multiple XML files and on error use simplified XSD scheme on all files to find the file causing error + 1. DMA without ring buffer, just send data in the newly configured buffers while there is the space... + * We need a way to add (remove?) pages into the same use. Some times in the middle of existing pages, i.e. tructuring seems complicated. + * vmsplice them out trough the device? + 2. Allow DMA into the user pages + * Dangerous as hardware accessed memory is only valid during life-time of one application. Instead the kernel pages can be re-assembled as big buffer using vmmngr_map_page (?) + 3. Use huge-pages + dynamicaly configure DMA page size + 4. DirectGMA/GPUDirect support + 5. High-speed interface to Infiniband Normal Priority (it would make just few things a bit easier) =============== - 1. Implement pcilib_configure_autotrigger - 2. Provide OR and AND operations on registers in cli - 3. Support writting a data from a binary file in cli - 4. Support Python-scripts in a views, we need to provide python function to read registers/properties... - 5. Really check the specified min, max values while setting registers + 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 Low Priority (only as generalization for other projects) ============ - 1. Shall we allow overriding of registers? + 1. We managed kmem performance using next kmem prediction, but it is still wise to provide additionally a binary tree for faster search 2. Support for Network Registers and Network DMA 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. We managed kmem performance using next kmem prediction, but it is still wise to provide additionally a binary tree for faster search Performance =========== diff --git a/pcilib/xml.c b/pcilib/xml.c index 1238ba8..bc48a34 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -78,6 +78,17 @@ static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr } */ +int pcilib_get_xml_attr(pcilib_t *ctx, pcilib_xml_node_t *node, const char *attr, pcilib_value_t *val) { + xmlAttr *prop; + xmlChar *str; + + prop = xmlHasProp(node, BAD_CAST attr); + if ((!prop)||(!prop->children)) return PCILIB_ERROR_NOTFOUND; + + str = prop->children->content; + return pcilib_set_value_from_static_string(ctx, val, (const char*)str); +} + static int pcilib_xml_parse_view_reference(pcilib_t *ctx, xmlDocPtr doc, xmlNodePtr node, pcilib_view_reference_t *desc) { xmlAttr *cur; char *value, *name; @@ -873,11 +884,14 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon return 0; } -static int pcilib_xml_load_xsd(pcilib_t *ctx, char *xsd_filename) { +static int pcilib_xml_load_xsd_file(pcilib_t *ctx, char *xsd_filename, xmlSchemaPtr *schema, xmlSchemaValidCtxtPtr *validator) { int err; xmlSchemaParserCtxtPtr ctxt; + *schema = NULL; + *validator = NULL; + /** we first parse the xsd file for AST with validation*/ ctxt = xmlSchemaNewParserCtxt(xsd_filename); if (!ctxt) { @@ -887,8 +901,8 @@ static int pcilib_xml_load_xsd(pcilib_t *ctx, char *xsd_filename) { return PCILIB_ERROR_FAILED; } - ctx->xml.schema = xmlSchemaParse(ctxt); - if (!ctx->xml.schema) { + *schema = xmlSchemaParse(ctxt); + if (!*schema) { xmlErrorPtr xmlerr = xmlGetLastError(); xmlSchemaFreeParserCtxt(ctxt); if (xmlerr) pcilib_error("Failed to parse XML schema, xmlSchemaParse reported error %d - %s", xmlerr->code, xmlerr->message); @@ -898,15 +912,15 @@ static int pcilib_xml_load_xsd(pcilib_t *ctx, char *xsd_filename) { xmlSchemaFreeParserCtxt(ctxt); - ctx->xml.validator = xmlSchemaNewValidCtxt(ctx->xml.schema); - if (!ctx->xml.validator) { + *validator = xmlSchemaNewValidCtxt(*schema); + if (!*validator) { xmlErrorPtr xmlerr = xmlGetLastError(); if (xmlerr) pcilib_error("xmlSchemaNewValidCtxt reported error %d - %s", xmlerr->code, xmlerr->message); else pcilib_error("Failed to create a validation context"); return PCILIB_ERROR_FAILED; } - err = xmlSchemaSetValidOptions(ctx->xml.validator, XML_SCHEMA_VAL_VC_I_CREATE); + err = xmlSchemaSetValidOptions(*validator, XML_SCHEMA_VAL_VC_I_CREATE); if (err) { xmlErrorPtr xmlerr = xmlGetLastError(); if (xmlerr) pcilib_error("xmlSchemaSetValidOptions reported error %d - %s", xmlerr->code, xmlerr->message); @@ -917,16 +931,45 @@ static int pcilib_xml_load_xsd(pcilib_t *ctx, char *xsd_filename) { return 0; } -static int pcilib_xml_load_file(pcilib_t *ctx, const char *path, const char *name) { + +static int pcilib_xml_load_xsd(pcilib_t *ctx, char *model_dir) { + int err; + + struct stat st; + char *xsd_path; + + xsd_path = (char*)alloca(strlen(model_dir) + 32); + if (!xsd_path) return PCILIB_ERROR_MEMORY; + + sprintf(xsd_path, "%s/model.xsd", model_dir); + if (stat(xsd_path, &st)) { + pcilib_info("XML models are not present, missing parts schema"); + return PCILIB_ERROR_NOTFOUND; + } + + err = pcilib_xml_load_xsd_file(ctx, xsd_path, &ctx->xml.parts_schema, &ctx->xml.parts_validator); + if (err) return err; + + sprintf(xsd_path, "%s/references.xsd", model_dir); + if (stat(xsd_path, &st)) { + pcilib_info("XML models are not present, missing schema"); + return PCILIB_ERROR_NOTFOUND; + } + + return pcilib_xml_load_xsd_file(ctx, xsd_path, &ctx->xml.schema, &ctx->xml.validator); +} + + + +static xmlDocPtr pcilib_xml_load_file(pcilib_t *ctx, const char *path, const char *name) { int err; char *full_name; xmlDocPtr doc; - xmlXPathContextPtr xpath; full_name = (char*)alloca(strlen(path) + strlen(name) + 2); if (!name) { pcilib_error("Error allocating %zu bytes of memory in stack to create a file name", strlen(path) + strlen(name) + 2); - return PCILIB_ERROR_MEMORY; + return NULL; } sprintf(full_name, "%s/%s", path, name); @@ -936,104 +979,139 @@ static int pcilib_xml_load_file(pcilib_t *ctx, const char *path, const char *nam xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); if (xmlerr) pcilib_error("Error parsing %s, xmlCtxtReadFile reported error %d - %s", full_name, xmlerr->code, xmlerr->message); else pcilib_error("Error parsing %s", full_name); - return PCILIB_ERROR_INVALID_DATA; + return NULL; } - err = xmlSchemaValidateDoc(ctx->xml.validator, doc); + err = xmlSchemaValidateDoc(ctx->xml.parts_validator, doc); if (err) { xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); xmlFreeDoc(doc); if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", full_name, xmlerr->code, xmlerr->message); else pcilib_error("Error validating %s", full_name); - return PCILIB_ERROR_VERIFY; - } - - xpath = xmlXPathNewContext(doc); - if (!xpath) { - xmlErrorPtr xmlerr = xmlGetLastError(); - xmlFreeDoc(doc); - if (xmlerr) pcilib_error("Document %s: xmlXpathNewContext reported error %d - %s for document %s", full_name, xmlerr->code, xmlerr->message); - else pcilib_error("Error creating XPath context for %s", full_name); - return PCILIB_ERROR_FAILED; - } - - // This can only partially fail... Therefore we need to keep XML and just return the error... - err = pcilib_xml_process_document(ctx, doc, xpath); - - if (ctx->xml.num_files == PCILIB_MAX_MODEL_FILES) { - xmlFreeDoc(doc); - xmlXPathFreeContext(xpath); - pcilib_error("Too many XML files for a model, only up to %zu are supported", PCILIB_MAX_MODEL_FILES); - return PCILIB_ERROR_TOOBIG; + return NULL; } - ctx->xml.docs[ctx->xml.num_files] = doc; - ctx->xml.xpath[ctx->xml.num_files] = xpath; - ctx->xml.num_files++; - - return err; + return doc; } - -int pcilib_process_xml(pcilib_t *ctx, const char *location) { +static int pcilib_process_xml_internal(pcilib_t *ctx, const char *model, const char *location) { int err; DIR *rep; struct dirent *file = NULL; char *model_dir, *model_path; + xmlDocPtr doc = NULL; + xmlNodePtr root = NULL; + xmlXPathContextPtr xpath; + + if (ctx->xml.num_files == PCILIB_MAX_MODEL_FILES) { + pcilib_error("Too many XML locations for a model, only up to %zu are supported", PCILIB_MAX_MODEL_FILES); + return PCILIB_ERROR_TOOBIG; + } + model_dir = getenv("PCILIB_MODEL_DIR"); if (!model_dir) model_dir = PCILIB_MODEL_DIR; - model_path = (char*)alloca(strlen(model_dir) + strlen(location) + 2); + if (!model) model = ctx->model; + if (!location) location = ""; + + model_path = (char*)alloca(strlen(model_dir) + strlen(model) + strlen(location) + 3); if (!model_path) return PCILIB_ERROR_MEMORY; - sprintf(model_path, "%s/%s", model_dir, location); + sprintf(model_path, "%s/%s/%s", model_dir, model, location); rep = opendir(model_path); if (!rep) return PCILIB_ERROR_NOTFOUND; while ((file = readdir(rep)) != NULL) { + xmlDocPtr newdoc; + size_t len = strlen(file->d_name); if ((len < 4)||(strcasecmp(file->d_name + len - 4, ".xml"))) continue; if (file->d_type != DT_REG) continue; - err = pcilib_xml_load_file(ctx, model_path, file->d_name); - if (err) pcilib_error("Error processing XML file %s", file->d_name); - } + newdoc = pcilib_xml_load_file(ctx, model_path, file->d_name); + if (!newdoc) { + pcilib_error("Error processing XML file %s", file->d_name); + continue; + } + + if (doc) { + xmlNodePtr node; + node = xmlDocGetRootElement(newdoc); + if (node) node = xmlFirstElementChild(node); + if (node) node = xmlDocCopyNodeList(doc, node); + xmlFreeDoc(newdoc); + + if ((!node)||(!xmlAddChildList(root, node))) { + xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); + if (node) xmlFreeNode(node); + if (xmlerr) pcilib_error("Error manipulating XML tree of %s, libXML2 reported error %d - %s", file->d_name, xmlerr->code, xmlerr->message); + else pcilib_error("Error manipulating XML tree of %s", file->d_name); + continue; + } + } else { + root = xmlDocGetRootElement(newdoc); + if (!root) { + xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); + xmlFreeDoc(newdoc); + if (xmlerr) pcilib_error("Error manipulating XML tree of %s, libXML2 reported error %d - %s", file->d_name, xmlerr->code, xmlerr->message); + else pcilib_error("Error manipulating XML tree of %s", file->d_name); + continue; + } + doc = newdoc; + // This is undocumented, but should be fine... + if (doc->URL) xmlFree((xmlChar*)doc->URL); + doc->URL = xmlStrdup(BAD_CAST model_path); + } + } closedir(rep); - return 0; + if (!doc) + return 0; + + err = xmlSchemaValidateDoc(ctx->xml.validator, doc); + if (err) { + xmlErrorPtr xmlerr = xmlCtxtGetLastError(ctx->xml.parser); + xmlFreeDoc(doc); + if (xmlerr) pcilib_error("Error validating %s, xmlSchemaValidateDoc reported error %d - %s", model_path, xmlerr->code, xmlerr->message); + else pcilib_error("Error validating %s", model_path); + return PCILIB_ERROR_VERIFY; + } + + xpath = xmlXPathNewContext(doc); + if (!xpath) { + xmlErrorPtr xmlerr = xmlGetLastError(); + xmlFreeDoc(doc); + if (xmlerr) pcilib_error("Document %s: xmlXpathNewContext reported error %d - %s for document %s", model_path, xmlerr->code, xmlerr->message); + else pcilib_error("Error creating XPath context for %s", model_path); + return PCILIB_ERROR_FAILED; + } + + // This can only partially fail... Therefore we need to keep XML and just return the error... + err = pcilib_xml_process_document(ctx, doc, xpath); + + ctx->xml.docs[ctx->xml.num_files] = doc; + ctx->xml.xpath[ctx->xml.num_files] = xpath; + ctx->xml.num_files++; + + return err; } +int pcilib_process_xml(pcilib_t *ctx, const char *location) { + return pcilib_process_xml_internal(ctx, NULL, location); +} -/** pcilib_init_xml - * this function will initialize the registers and banks from the xml files - * @param[in,out] ctx the pciilib_t running that gets filled with structures - * @param[in] model the current model of ctx - * @return an error code - */ int pcilib_init_xml(pcilib_t *ctx, const char *model) { int err; char *model_dir; - char *xsd_path; - - struct stat st; model_dir = getenv("PCILIB_MODEL_DIR"); if (!model_dir) model_dir = PCILIB_MODEL_DIR; - xsd_path = (char*)alloca(strlen(model_dir) + 16); - if (!xsd_path) return PCILIB_ERROR_MEMORY; - - sprintf(xsd_path, "%s/model.xsd", model_dir); - if (stat(xsd_path, &st)) { - pcilib_info("XML models are not present"); - return PCILIB_ERROR_NOTFOUND; - } - ctx->xml.parser = xmlNewParserCtxt(); if (!ctx->xml.parser) { xmlErrorPtr xmlerr = xmlGetLastError(); @@ -1042,16 +1120,12 @@ int pcilib_init_xml(pcilib_t *ctx, const char *model) { return PCILIB_ERROR_FAILED; } - err = pcilib_xml_load_xsd(ctx, xsd_path); + err = pcilib_xml_load_xsd(ctx, model_dir); if (err) return err; - return pcilib_process_xml(ctx, model); + return pcilib_process_xml_internal(ctx, model, NULL); } -/** pcilib_free_xml - * this function free the xml parts of the pcilib_t running, and some libxml ashes - * @param[in] pci the pcilib_t running -*/ void pcilib_free_xml(pcilib_t *ctx) { int i; @@ -1085,7 +1159,16 @@ void pcilib_free_xml(pcilib_t *ctx) { if (ctx->xml.schema) { xmlSchemaFree(ctx->xml.schema); ctx->xml.schema = NULL; + } + + if (ctx->xml.parts_validator) { + xmlSchemaFreeValidCtxt(ctx->xml.parts_validator); + ctx->xml.parts_validator = NULL; + } + if (ctx->xml.parts_schema) { + xmlSchemaFree(ctx->xml.parts_schema); + ctx->xml.parts_schema = NULL; } if (ctx->xml.parser) { @@ -1099,14 +1182,3 @@ void pcilib_free_xml(pcilib_t *ctx) { xmlMemoryDump(); */ } - -int pcilib_get_xml_attr(pcilib_t *ctx, pcilib_xml_node_t *node, const char *attr, pcilib_value_t *val) { - xmlAttr *prop; - xmlChar *str; - - prop = xmlHasProp(node, BAD_CAST attr); - if ((!prop)||(!prop->children)) return PCILIB_ERROR_NOTFOUND; - - str = prop->children->content; - return pcilib_set_value_from_static_string(ctx, val, (const char*)str); -} diff --git a/pcilib/xml.h b/pcilib/xml.h index 10bc154..e4a5744 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -28,8 +28,10 @@ struct pcilib_xml_s { xmlXPathContextPtr xpath[PCILIB_MAX_MODEL_FILES]; /**< Per-file XPath context */ xmlParserCtxtPtr parser; /**< Pointer to the XML parser context */ - xmlSchemaPtr schema; /**< Pointer to the parsed xsd schema */ + xmlSchemaPtr schema; /**< Pointer to the parsed xsd schema */ xmlSchemaValidCtxtPtr validator; /**< Pointer to the XML validation context */ + xmlSchemaPtr parts_schema; /**< Pointer to the parsed xsd schema capable of validating individual XML files - no check for cross-references */ + xmlSchemaValidCtxtPtr parts_validator; /**< Pointer to the XML validation context capable of validating individual XML files - no check for cross-references */ xmlNodePtr bank_nodes[PCILIB_MAX_REGISTER_BANKS]; /**< pointer to xml nodes of banks in the xml file */ }; @@ -38,27 +40,46 @@ struct pcilib_xml_s { extern "C" { #endif -/** - * this function gets the xml files and validates them, before filling the pcilib_t struct with the registers and banks of those files - *@param[in,out] ctx the pcilib_t struct running that gets filled with banks and registers - *@param[in] model the name of the model +/** pcilib_init_xml + * Initializes XML stack and loads a default set of XML files. The default location for model XML files is + * /usr/local/share/pcilib/models/<current_model>. This can be altered using CMake PCILIB_MODEL_DIR variable + * while building or using PCILIB_MODEL_DIR environmental variable dynamicly. More XML files can be added + * later using pcilib_process_xml call. + * @param[in,out] ctx - pcilib context + * @param[in] model - the name of the model + * @return - error or 0 on success */ int pcilib_init_xml(pcilib_t *ctx, const char *model); /** pcilib_free_xml * this function free the xml parts of the pcilib_t running, and some libxml ashes * @param[in] ctx the pcilib_t running -*/ + */ void pcilib_free_xml(pcilib_t *ctx); - /** pcilib_process_xml - * this function free the xml parts of the pcilib_t running, and some libxml ashes - * @param[in] ctx the pcilib_t running - * @param[in] location of XML files relative to the PCILIB_MODEL_DIR -*/ + * Processes a bunch of XML files in the specified directory. During the initialization, all XML files + * in the corresponding model directory will be loaded. This function allows to additionally load XML + * files from the specified subdirectories of the model directory. I.e. the XML files from the + * /usr/local/share/pcilib/models/<current_model>/<location> will be loaded. As with pcilib_init_xml, + * the directory can be adjusted using CMake build configuration or PCILIB_MODEL_DIR environmental + * variable. + * @param[in] ctx - pcilib context + * @param[in] location - Specifies sub-directory with XML files relative to the model directory. + * @return - error or 0 on success + */ int pcilib_process_xml(pcilib_t *ctx, const char *location); +/** pcilib_get_xml_attr + * This is an internal function which returns a specified node attribute in the pcilib_value_t structure. + * This function should not be used directly. Instead subsystem specific calls like pcilib_get_register_attr, + * pcilib_get_property_attr, ...have to be used. + * @param[in] ctx - pcilib context + * @param[in] node - LibXML2 node + * @param[in] attr - attribute name + * @param[out] val - the result will be returned in this variable. Prior to first usage pcilib_value_t variable should be initalized to 0. + * @return - error or 0 on success + */ int pcilib_get_xml_attr(pcilib_t *ctx, pcilib_xml_node_t *node, const char *attr, pcilib_value_t *val); diff --git a/xml/model.xsd b/xml/model.xsd index 1440032..164e887 100644 --- a/xml/model.xsd +++ b/xml/model.xsd @@ -4,7 +4,7 @@ <xsd:element name="model"> <xsd:complexType> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> <xsd:element name="bank" type="pcilib_bank_t" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="transform" type="pcilib_transform_view_t" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="enum" type="pcilib_enum_view_t" minOccurs="0" maxOccurs="unbounded" /> diff --git a/xml/references.xsd b/xml/references.xsd index f382840..4474141 100644 --- a/xml/references.xsd +++ b/xml/references.xsd @@ -1,9 +1,9 @@ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:include schemaLocation="types.xsd"/> - + <xsd:element name="model"> <xsd:complexType> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> + <xsd:choice minOccurs="1" maxOccurs="unbounded"> <xsd:element name="bank" type="pcilib_bank_t" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="transform" type="pcilib_transform_view_t" minOccurs="0" maxOccurs="unbounded" /> <xsd:element name="enum" type="pcilib_enum_view_t" minOccurs="0" maxOccurs="unbounded"> @@ -25,30 +25,31 @@ <xsd:selector xpath="bank" /> <xsd:field xpath="@name" /> </xsd:key> +<!-- Currently, we define all registers, banks, views, and units as xsd:ID which prevents them from sharing name anyway. +Currently it seems fine, but later it could turn out too be to strict. Then, we get problem also here as transform[@name] +is ID of view, not register. But how can we restrict transform field to @register only? --> <xsd:key name="pcilib_register_key"> - <xsd:selector xpath="bank/register|bank/register/field" /> - <xsd:field xpath="@name" /> + <xsd:selector xpath="bank/register|bank/register/field|transform" /> + <xsd:field xpath="@name|@register" /> </xsd:key> <xsd:key name="pcilib_view_key"> <xsd:selector xpath="transform|enum" /> - <xsd:field xpath="@name" /> + <xsd:field xpath="@name|@path" /> </xsd:key> <xsd:key name="pcilib_unit_key"> <xsd:selector xpath="unit" /> <xsd:field xpath="@name" /> </xsd:key> - <xsd:key name="pcilib_path_key"> - <xsd:selector xpath="transform" /> - <xsd:field xpath="@path" /> - </xsd:key> <xsd:keyref name="pcilib_register_view_ref" refer="pcilib_view_key"> <xsd:selector xpath="bank/register/view|bank/register/field/view" /> <xsd:field xpath="@view" /> </xsd:keyref> +<!-- Actually, it is no problem to reference non-existing unit just for informative purposes <xsd:keyref name="pcilib_unit_ref" refer="pcilib_unit_key"> <xsd:selector xpath="transform|enum" /> <xsd:field xpath="@unit" /> </xsd:keyref> +--> </xsd:element> </xsd:schema> diff --git a/xml/test/camera.xml b/xml/test/camera.xml index a84299a..6568f17 100644 --- a/xml/test/camera.xml +++ b/xml/test/camera.xml @@ -1,52 +1,5 @@ <?xml version="1.0"?> <model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <bank bar="0" size="128" protocol="software_registers" read_address="0x9010" write_address="0x9000" word_size="8" endianess="little" format="%lu" name="cmosis" description="CMOSIS CMV2000 Registers"> - <register address="1" offset="0" size="16" default="1088" rwmask="0" mode="RW" name="cmosis_number_lines" description="test"/> - <register address="3" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start1"/> - <register address="5" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start2"/> - <register address="7" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start3"/> - <register address="9" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start4"/> - <register address="11" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start5"/> - <register address="13" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start6"/> - <register address="15" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start7"/> - <register address="17" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start8"/> - <register address="19" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines1"/> - <register address="21" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines2"/> - <register address="23" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines3"/> - <register address="25" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines4"/> - <register address="27" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines5"/> - <register address="29" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines6"/> - <register address="31" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines7"/> - <register address="33" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines8"/> - <register address="35" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_s"/> - <register address="37" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_a"/> - <register address="39" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_color"/> - <register address="40" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_image_flipping"/> - <register address="41" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_exp_flags"/> - <register address="42" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time"><view view="formuu3"/><view view="enumm3"/></register> - <register address="45" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step"/> - <register address="48" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp1"/> - <register address="51" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp2"/> - <register address="54" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes"/> - <register address="55" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq"/> - <register address="56" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time2"/> - <register address="59" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step2"/> - <register address="68" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes2"/> - <register address="69" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq2"/> - <register address="70" offset="0" size="16" default="1" rwmask="0" mode="RW" name="cmosis_number_frames"/> - <register address="72" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_output_mode"/> - <register address="78" offset="0" size="12" default="85" rwmask="0" mode="RW" name="cmosis_training_pattern"/> - <register address="80" offset="0" size="18" default="0x3FFFF" rwmask="0" mode="RW" name="cmosis_channel_en"/> - <register address="82" offset="0" size="3" default="7" rwmask="0" mode="RW" name="cmosis_special_82"/> - <register address="89" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow2"/> - <register address="90" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow3"/> - <register address="100" offset="0" size="14" default="16260" rwmask="0" mode="RW" name="cmosis_offset"/> - <register address="102" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_pga"/> - <register address="103" offset="0" size="8" default="32" rwmask="0" mode="RW" name="cmosis_adc_gain"/> - <register address="111" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_bit_mode"/> - <register address="112" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_adc_resolution"/> - <register address="115" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_special_115"/> - </bank> <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="spi_conf_input"/> <register address="0x10" offset="0" size="32" default="0" rwmask="0" mode="R" name="spi_conf_output"/> @@ -105,54 +58,4 @@ <register address="0x1a0" offset="0" size="32" default="0x64" rwmask="0" mode="RW" name="ddr_max_frames"/> <register address="0x1b0" offset="0" size="32" default="0" rwmask="0" mode="R" name="ddr_num_frames"/> </bank> - <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x0" write_address="0x0" word_size="32" endianess="little" format="0x%lx" name="dma" description="DMA Registers"/> - <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 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"/> - <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> - <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/cmosis.xml b/xml/test/cmosis.xml new file mode 100644 index 0000000..45d2f6e --- /dev/null +++ b/xml/test/cmosis.xml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <bank bar="0" size="128" protocol="software_registers" read_address="0x9010" write_address="0x9000" word_size="8" endianess="little" format="%lu" name="cmosis" description="CMOSIS CMV2000 Registers"> + <register address="1" offset="0" size="16" default="1088" rwmask="0" mode="RW" name="cmosis_number_lines" description="test"/> + <register address="3" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start1"/> + <register address="5" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start2"/> + <register address="7" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start3"/> + <register address="9" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start4"/> + <register address="11" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start5"/> + <register address="13" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start6"/> + <register address="15" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start7"/> + <register address="17" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_start8"/> + <register address="19" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines1"/> + <register address="21" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines2"/> + <register address="23" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines3"/> + <register address="25" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines4"/> + <register address="27" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines5"/> + <register address="29" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines6"/> + <register address="31" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines7"/> + <register address="33" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_number_lines8"/> + <register address="35" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_s"/> + <register address="37" offset="0" size="16" default="0" rwmask="0" mode="RW" name="cmosis_sub_a"/> + <register address="39" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_color"/> + <register address="40" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_image_flipping"/> + <register address="41" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_exp_flags"/> + <register address="42" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time"><view view="formuu3"/><view view="enumm3"/></register> + <register address="45" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step"/> + <register address="48" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp1"/> + <register address="51" offset="0" size="24" default="1" rwmask="0" mode="RW" name="cmosis_exp_kp2"/> + <register address="54" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes"/> + <register address="55" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq"/> + <register address="56" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_time2"/> + <register address="59" offset="0" size="24" default="1088" rwmask="0" mode="RW" name="cmosis_exp_step2"/> + <register address="68" offset="0" size="2" default="1" rwmask="0" mode="RW" name="cmosis_nr_slopes2"/> + <register address="69" offset="0" size="8" default="1" rwmask="0" mode="RW" name="cmosis_exp_seq2"/> + <register address="70" offset="0" size="16" default="1" rwmask="0" mode="RW" name="cmosis_number_frames"/> + <register address="72" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_output_mode"/> + <register address="78" offset="0" size="12" default="85" rwmask="0" mode="RW" name="cmosis_training_pattern"/> + <register address="80" offset="0" size="18" default="0x3FFFF" rwmask="0" mode="RW" name="cmosis_channel_en"/> + <register address="82" offset="0" size="3" default="7" rwmask="0" mode="RW" name="cmosis_special_82"/> + <register address="89" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow2"/> + <register address="90" offset="0" size="8" default="96" rwmask="0" mode="RW" name="cmosis_vlow3"/> + <register address="100" offset="0" size="14" default="16260" rwmask="0" mode="RW" name="cmosis_offset"/> + <register address="102" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_pga"/> + <register address="103" offset="0" size="8" default="32" rwmask="0" mode="RW" name="cmosis_adc_gain"/> + <register address="111" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_bit_mode"/> + <register address="112" offset="0" size="2" default="0" rwmask="0" mode="RW" name="cmosis_adc_resolution"/> + <register address="115" offset="0" size="1" default="1" rwmask="0" mode="RW" name="cmosis_special_115"/> + </bank> +</model> diff --git a/xml/test/dma.xml b/xml/test/dma.xml new file mode 100644 index 0000000..1d20725 --- /dev/null +++ b/xml/test/dma.xml @@ -0,0 +1,4 @@ +<?xml version="1.0"?> +<model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <bank bar="0" size="0x0200" protocol="software_registers" read_address="0x0" write_address="0x0" word_size="32" endianess="little" format="0x%lx" name="dma" description="DMA Registers"/> +</model> diff --git a/xml/test/names.xml b/xml/test/names.xml new file mode 100644 index 0000000..f6ddbcc --- /dev/null +++ b/xml/test/names.xml @@ -0,0 +1,16 @@ +<?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/props.xml b/xml/test/props.xml new file mode 100644 index 0000000..cf163eb --- /dev/null +++ b/xml/test/props.xml @@ -0,0 +1,4 @@ +<?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"/> +</model> diff --git a/xml/test/units.xml b/xml/test/units.xml new file mode 100644 index 0000000..74ab9f7 --- /dev/null +++ b/xml/test/units.xml @@ -0,0 +1,35 @@ +<?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/views.xml b/xml/test/views.xml new file mode 100644 index 0000000..c40cd0f --- /dev/null +++ b/xml/test/views.xml @@ -0,0 +1,6 @@ +<?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> |