Procházet zdrojové kódy

new --enable-profile option, removed unneeded types

Julius Pfrommer před 9 roky
rodič
revize
3e98f7b505
7 změnil soubory, kde provedl 109 přidání a 73 odebrání
  1. 7 1
      Makefile.am
  2. 24 18
      configure.ac
  3. 4 10
      examples/src/Makefile.am
  4. 12 6
      src/Makefile.am
  5. 3 3
      src/ua_types.h
  6. 28 16
      tools/generate_builtin.py
  7. 31 19
      tools/generate_namespace.py

+ 7 - 1
Makefile.am

@@ -7,7 +7,6 @@ else
 AM_CFLAGS += -fPIC 
 endif
 
-
 if DEBUG
 AM_CFLAGS += -g3 -O0
 else
@@ -23,6 +22,13 @@ if MULTITHREADING
 AM_LDADD += -lpthread
 endif
 
+UA_ENCODING_AMOUNT = 1
+if UA_ENCODING_XML
+UA_ENCODING_AMOUNT := $$(echo $(UA_ENCODING_AMOUNT)+1 | bc)
+endif
+
+AM_CFLAGS += -D UA_ENCODING_AMOUNT=$(UA_ENCODING_AMOUNT)
+
 export GLOBAL_AM_CFLAGS = $(AM_CFLAGS)
 export GLOBAL_AM_LDADD = $(AM_LDADD)
 

+ 24 - 18
configure.ac

@@ -6,8 +6,7 @@ AC_INIT(Open62541, 1.0)
 AC_CANONICAL_SYSTEM
 AM_INIT_AUTOMAKE([subdir-objects])
 AC_PROG_MAKE_SET
-#default CFLAGS is -g -02
-#reset it just to -g and make optimization dependend on --enable-debug
+# Default CFLAGS is -g -02. Set depending on debug flag.
 if test -z $CFLAGS; then
    CFLAGS=''
 fi
@@ -16,9 +15,9 @@ AC_PROG_CC
 AC_PROG_LN_S
 AM_PROG_CC_C_O
 AC_CHECK_LIB([m],[exp],,AC_MSG_ERROR([Libm missing]))
-AC_CHECK_LIB([expat],[XML_Parse],,AC_MSG_ERROR([Libexpat missing]))
-PKG_CHECK_MODULES([CHECK], [check >= 0.9.12],[have_check="yes"],AC_MSG_WARN([Check not found or check version lower than 0.9.12; cannot run unit tests!])
-[have_check="no"])
+PKG_CHECK_MODULES([CHECK], [check >= 0.9.12],[have_check="yes"],
+                  AC_MSG_WARN([Check not found or check version lower than 0.9.12; cannot run unit tests!])
+				  [have_check="no"])
 AM_CONDITIONAL([HAVE_CHECK], [test x"$have_check" = "xyes"])
 AM_CONDITIONAL([TARGET_WIN],[test "${host_os}" = "mingw32"])
 AM_CONDITIONAL([TARGET_LINUX],[test "${host_os}" = "linux-gnu" || test "${host_os}" = "linux"]) 
@@ -47,6 +46,26 @@ AM_CONDITIONAL(VERBOSE, test x"$verbose" = x"true")
 AM_COND_IF([VERBOSE],
     AC_DEFINE([VERBOSE])) #define VERBOSE is accessible from pre-processor
 
+#profile
+# 100: nano
+# 200: embedded
+# 900: all available features
+AC_ARG_ENABLE(profile,
+AS_HELP_STRING([--enable-profile], [select supported features, default: all]),
+	[case "${enableval}" in
+        	nano) profile=100;;
+            embedded) profile=200;;
+            all) profile=900;;
+            *) AC_MSG_ERROR([bad value ${enableval} for --enable-profile]);; 
+	esac],[profile=900])
+AC_DEFINE([PROFILE], [x"$profile"])
+
+#xml encoding
+AM_CONDITIONAL(UA_ENCODING_XML, test x"$profile" -ge 200)
+AM_COND_IF([UA_ENCODING_XML],
+    AC_DEFINE([UA_ENCODING_XML], [1])
+    AC_CHECK_LIB([expat],[XML_Parse],,AC_MSG_ERROR([Libexpat missing])))
+
 #multithreading
 AC_ARG_ENABLE(multithreading,
 AS_HELP_STRING([--enable-multithreading],
@@ -72,19 +91,6 @@ AS_HELP_STRING([--enable-coverage],
 AM_CONDITIONAL(COVERAGE, test x"$coverage" = x"true")
 AM_COND_IF([COVERAGE],
     AC_DEFINE([COVERAGE])) #define MULTITHREADING is accessible from pre-processor
-    
-#raspberry pi
-AC_ARG_ENABLE(raspi,
-AS_HELP_STRING([--enable-raspi],
-               [enable raspi, default: no]),
-	[case "${enableval}" in
-		yes) raspi=true ;;
-		no)  raspi=false ;;
-		*)   AC_MSG_ERROR([bad value ${enableval} for --enable-raspi]) ;; 
-	esac],[raspi=false])
-AM_CONDITIONAL(RASPI, test x"$raspi" = x"true")
-AM_COND_IF([RASPI],
-    AC_DEFINE([RASPI]))
 
 #doxygen start
 AC_ARG_ENABLE(doxygen,

+ 4 - 10
examples/src/Makefile.am

@@ -1,36 +1,30 @@
-bin_PROGRAMS = $(top_builddir)/bin/xml2ns0 
+bin_PROGRAMS =
 
+if UA_ENCODING_XML
+bin_PROGRAMS += $(top_builddir)/bin/xml2ns0 
 __top_builddir__bin_xml2ns0_SOURCES = xml2ns0.c
 __top_builddir__bin_xml2ns0_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_xml2ns0_LDADD = $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
 __top_builddir__bin_xml2ns0_LDFLAGS = -lexpat
 
 bin_PROGRAMS += $(top_builddir)/bin/generateSam 
-
 __top_builddir__bin_generateSam_SOURCES = generateSam.c
 __top_builddir__bin_generateSam_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_generateSam_LDADD = $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
 __top_builddir__bin_generateSam_LDFLAGS = -lexpat
-
-
+endif
 
 if MULTITHREADING
 bin_PROGRAMS += $(top_builddir)/bin/exampleServerMT 
-
 __top_builddir__bin_exampleServerMT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServerMT_SOURCES = opcuaServerMT.c networklayer.c
 __top_builddir__bin_exampleServerMT_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
-
 else
 bin_PROGRAMS += $(top_builddir)/bin/exampleServer $(top_builddir)/bin/exampleServerACPLT $(top_builddir)/bin/exampleServerMini
 
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServer_SOURCES = opcuaServer.c networklayer.c
 __top_builddir__bin_exampleServer_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
-if RASPI
-__top_builddir__bin_exampleServer_LDFLAGS = -lwiringPi
-__top_builddir__bin_exampleServer_SOURCES += raspberrypi_io.c
-endif
 
 __top_builddir__bin_exampleServerACPLT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServerACPLT_SOURCES = opcuaServerACPLT.c networklayer.c

+ 12 - 6
src/Makefile.am

@@ -7,7 +7,6 @@ libopen62541_la_LDFLAGS = -avoid-version -no-undefined
 libopen62541_la_SOURCES = ua_types.c \
 						  ua_types_encoding_binary.c \
 						  ua_types_generated.c \
-						  ua_types_encoding_xml.c \
 						  ua_namespace_0.c \
 						  util/ua_util.c \
 						  util/ua_list.c \
@@ -17,7 +16,6 @@ libopen62541_la_SOURCES = ua_types.c \
 						  ua_transport_binary.c \
 						  ua_transport_binary_secure.c \
 						  ua_namespace.c \
-						  ua_namespace_xml.c \
 						  ua_services_attribute.c \
 						  ua_services_session.c \
 						  ua_services_discovery.c \
@@ -26,16 +24,24 @@ libopen62541_la_SOURCES = ua_types.c \
 						  ua_services_view.c \
 						  ua_services_subscription.c\
 						  ua_services_monitoreditems.c\
-						  ua_application.c \
-						  ua_xml.c
+						  ua_application.c
+
+WITH_XML =
+if UA_ENCODING_XML
+libopen62541_la_SOURCES += ua_types_encoding_xml.c \
+						   ua_namespace_xml.c \
+						   ua_xml.c
+WITH_XML = --with-xml
+endif
+
 ua_types.c: ua_namespace_0.h
 ua_namespace_0.h: ua_types_generated.h
 
 ua_types_generated.c ua_types_generated.h: $(SCHEMA_DIR)/Opc.Ua.Types.bsd $(TOOL_DIR)/generate_builtin.py
-	python $(TOOL_DIR)/generate_builtin.py $(SCHEMA_DIR)/Opc.Ua.Types.bsd ua_types_generated
+	python $(TOOL_DIR)/generate_builtin.py $(SCHEMA_DIR)/Opc.Ua.Types.bsd ua_types_generated $(WITH_XML)
 
 ua_namespace_0.c ua_namespace_0.h: $(SCHEMA_DIR)/NodeIds.csv $(TOOL_DIR)/generate_namespace.py
-	python $(TOOL_DIR)/generate_namespace.py $(SCHEMA_DIR)/NodeIds.csv ua_namespace_0
+	python $(TOOL_DIR)/generate_namespace.py $(SCHEMA_DIR)/NodeIds.csv ua_namespace_0 $(WITH_XML)
 
 .PHONY: convenience-link clean-convenience-link
 

+ 3 - 3
src/ua_types.h

@@ -391,8 +391,8 @@ typedef struct UA_Encoding {
 	UA_decode   decode;
 } UA_Encoding;
 
-#define UA_ENCODING_BINARY 0
-#define UA_ENCODING_XML 1
+#define UA_ENCODING_BINARY 0 // Binary encoding is always available
+// #define UA_ENCODING_XML 1 // This is set by the build script.
 
 struct UA_VTable_Entry {
 	UA_NodeId  typeId;
@@ -409,7 +409,7 @@ struct UA_VTable_Entry {
 	UA_Boolean dynMembers;    // does the type contain members that are dynamically
 	                          // allocated (strings, ..)? Otherwise, the size on
 	                          // the wire == size in memory.
-	UA_Encoding encodings[2]; // binary, xml, ...
+	UA_Encoding encodings[UA_ENCODING_AMOUNT]; // binary, xml, ... UA_ENCODING_AMOUNT is set by the build script
 };
 
 typedef UA_Int32 (*UA_nodeIdToVTableIndex)(const UA_NodeId *id);

+ 28 - 16
tools/generate_builtin.py

@@ -7,17 +7,21 @@ from collections import OrderedDict
 import re
 from lxml import etree
 import inspect
-
-if len(sys.argv) != 3:
-	print("Usage: python generate_builtin.py <path/to/Opc.Ua.Types.bsd> <outfile w/o extension>", file=sys.stdout)
-	exit(0)
-
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument('types', help='path/to/Opc.Ua.Types.bsd')
+parser.add_argument('outfile', help='outfile w/o extension')
+parser.add_argument('--with-xml', action='store_true', help='generate xml encoding')
+parser.add_argument('--only-nano', action='store_true', help='generate only the types for the nano profile')
+args = parser.parse_args()
+        
 ns = {"opc": "http://opcfoundation.org/BinarySchema/"}
-tree = etree.parse(sys.argv[1])
+tree = etree.parse(args.types)
 types = tree.xpath("/opc:TypeDictionary/*[not(self::opc:Import)]", namespaces=ns)
 
-fh = open(sys.argv[2] + ".h",'w')
-fc = open(sys.argv[2] + ".c",'w')
+fh = open(args.outfile + ".h",'w')
+fc = open(args.outfile + ".c",'w')
 
 # dirty hack. we go up the call frames to access local variables of the calling
 # function. this allows to shorten code and get %()s replaces with less clutter.
@@ -42,6 +46,10 @@ fixed_size = set(["UA_Boolean", "UA_SByte", "UA_Byte", "UA_Int16", "UA_UInt16",
 def skipType(name):
     if name in existing_types:
         return True
+    if "Test" in name:
+        return True
+    if re.search("Attributes$", name) != None:
+        return True
     if re.search("NodeId$", name) != None:
         return True
     return False
@@ -79,10 +87,11 @@ def createEnumerated(element):
            "\n};")
     printh("UA_TYPE_PROTOTYPES (" + name + ")")
     printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
-    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
     printc("UA_TYPE_AS(" + name + ", UA_Int32)")
     printc("UA_TYPE_BINARY_ENCODING_AS(" + name + ", UA_Int32)")
-    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+    if args.with_xml:
+        printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+        printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
 UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
 UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s\n)''')
 
@@ -94,10 +103,11 @@ def createOpaque(element):
     printh("typedef UA_ByteString %(name)s;")
     printh("UA_TYPE_PROTOTYPES(%(name)s)")
     printh("UA_TYPE_BINARY_ENCODING(%(name)s)")
-    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
     printc("UA_TYPE_AS(%(name)s, UA_ByteString)")
     printc("UA_TYPE_BINARY_ENCODING_AS(%(name)s, UA_ByteString)")
-    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+    if args.with_xml:
+        printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+        printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
 UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
 UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)\n''')
 
@@ -140,7 +150,8 @@ def createStructured(element):
     # 3) function prototypes
     printh("UA_TYPE_PROTOTYPES(" + name + ")")
     printh("UA_TYPE_BINARY_ENCODING(" + name + ")")
-    printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
+    if args.with_xml:
+        printh("UA_TYPE_XML_ENCODING(" + name + ")\n")
 
     # 4) CalcSizeBinary
     printc('''UA_Int32 %(name)s_calcSizeBinary(%(name)s const * ptr) {
@@ -188,9 +199,10 @@ def createStructured(element):
     printc("\treturn retval;\n}\n")
 
     # 7) Xml
-    printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
-    UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
-    UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
+    if args.with_xml:
+        printc('''UA_TYPE_METHOD_CALCSIZEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_ENCODEXML_NOTIMPL(%(name)s)
+UA_TYPE_METHOD_DECODEXML_NOTIMPL(%(name)s)''')
     
     # 8) Delete
     printc('''UA_Int32 %(name)s_delete(%(name)s *p) {

+ 31 - 19
tools/generate_namespace.py

@@ -4,11 +4,14 @@ import sys
 import platform
 import getpass
 import time
+import re
+import argparse
 
-if len(sys.argv) != 3:
-    print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>",
-          file=sys.stdout)
-    exit(0)
+parser = argparse.ArgumentParser()
+parser.add_argument('nodeids', help='path/to/NodeIds.csv')
+parser.add_argument('outfile', help='outfile w/o extension')
+parser.add_argument('--with-xml', action='store_true', help='generate xml encoding')
+args = parser.parse_args()
 
 # types that are to be excluded
 exclude_kinds = set(["Object","ObjectType","Variable","Method","ReferenceType"])
@@ -52,14 +55,23 @@ fixed_size = ['UA_DeadbandType', 'UA_DataChangeTrigger', 'UA_Guid', 'UA_Applicat
               'UA_ExceptionDeviationFormat', 'UA_ComplianceLevel', 'UA_DateTime', 'UA_Int64',
               'UA_Double']
 
-f = open(sys.argv[1])
+def skipType(row):
+    if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
+        return True
+    if "Test" in row[0]:
+        return True
+    if re.search("Attributes$", row[0]) != None:
+        return True
+    return False
+
+f = open(args.nodeids)
 input_str = f.read() + "\nInvalidType,0,DataType"
 input_str = input_str.replace('\r','')
 rows = map(lambda x:tuple(x.split(',')), input_str.split('\n'))
 f.close()
 
-fh = open(sys.argv[2] + ".h",'w')
-fc = open(sys.argv[2] + ".c",'w')
+fh = open(args.outfile + ".h",'w')
+fc = open(args.outfile + ".c",'w')
 def printh(string):
     print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fh)
 
@@ -67,14 +79,14 @@ def printc(string):
     print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fc)
 
 printh('''/**********************************************************
- * '''+sys.argv[2]+'''.hgen -- do not modify
+ * '''+args.outfile+'''.hgen -- do not modify
  **********************************************************
- * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
+ * Generated from '''+args.nodeids+''' with script '''+sys.argv[0]+'''
  * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+
        time.strftime("%Y-%m-%d %I:%M:%S")+'''
  **********************************************************/\n 
-#ifndef ''' + sys.argv[2].upper() + '''_H_
-#define ''' + sys.argv[2].upper() + '''_H_\n
+#ifndef ''' + args.outfile.upper() + '''_H_
+#define ''' + args.outfile.upper() + '''_H_\n
 #include "util/ua_util.h"
 #include "ua_types.h"  // definition of UA_VTable and basic UA_Types
 #include "ua_types_generated.h"\n
@@ -98,13 +110,13 @@ extern const UA_VTable UA_borrowed_;\n
 enum UA_VTableIndex_enum {''')
 
 printc('''/**********************************************************
- * '''+sys.argv[2]+'''.cgen -- do not modify
+ * '''+args.outfile+'''.cgen -- do not modify
  **********************************************************
- * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
+ * Generated from '''+args.nodeids+''' with script '''+sys.argv[0]+'''
  * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser() +
        ''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  **********************************************************/\n
-#include "''' + sys.argv[2] + '''.h"\n
+#include "''' + args.outfile + '''.h"\n
 UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
 	UA_Int32 retval = 0; // InvalidType
         if(id->namespace != 0) return retval;
@@ -112,7 +124,7 @@ UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
 
 i = 0
 for row in rows:
-    if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
+    if skipType(row):
         continue
     if row[0] == "BaseDataType":
     	name = "UA_Variant"
@@ -134,7 +146,7 @@ printc('''const UA_VTable UA_ = {
 
 i = 0
 for row in rows:
-    if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
+    if skipType(row):
         continue
     if row[0] == "BaseDataType":
         name = "UA_Variant"
@@ -160,9 +172,9 @@ for row in rows:
           ",\n.encodings={{.calcSize=(UA_calcSize)%(name)s_calcSizeBinary" +
           ",\n.encode=(UA_encode)%(name)s_encodeBinary" +
           ",\n.decode=(UA_decode)%(name)s_decodeBinary}" +
-          ",\n{.calcSize=(UA_calcSize)%(name)s_calcSizeXml" +
-          ",\n.encode=(UA_encode)%(name)s_encodeXml" +
-          ",\n.decode=(UA_decode)%(name)s_decodeXml}" +
+           (",\n{.calcSize=(UA_calcSize)%(name)s_calcSizeXml" +
+            ",\n.encode=(UA_encode)%(name)s_encodeXml" +
+            ",\n.decode=(UA_decode)%(name)s_decodeXml}" if (args.with_xml) else "") +
           "}},")
 
 printc('''}};''')