objdictgen/gen_cfile.py
changeset 0 4472ee7c6c3e
child 5 e4365e7d47f0
equal deleted inserted replaced
-1:000000000000 0:4472ee7c6c3e
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 copyright_notice="""/*
       
     4 This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     5 
       
     6 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     7 
       
     8 See COPYING file for copyrights details.
       
     9 
       
    10 This library is free software; you can redistribute it and/or
       
    11 modify it under the terms of the GNU Lesser General Public
       
    12 License as published by the Free Software Foundation; either
       
    13 version 2.1 of the License, or (at your option) any later version.
       
    14 
       
    15 This library is distributed in the hope that it will be useful,
       
    16 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    18 Lesser General Public License for more details.
       
    19 
       
    20 You should have received a copy of the GNU Lesser General Public
       
    21 License along with this library; if not, write to the Free Software
       
    22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    23 */
       
    24 """
       
    25 
       
    26 from node import *
       
    27 from types import *
       
    28 
       
    29 import re, os
       
    30 
       
    31 word_model = re.compile('([a-zA-Z_0-9]*)')
       
    32 type_model = re.compile('([\_A-Z]*)([0-9]*)')
       
    33 range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]')
       
    34 
       
    35 categories = [("SDO_SVR", 0x1200, 0x127F), ("SDO_CLT", 0x1280, 0x12FF),
       
    36               ("PDO_RCV", 0x1400, 0x15FF), ("PDO_RCV_MAP", 0x1600, 0x17FF),
       
    37               ("PDO_TRS", 0x1800, 0x19FF), ("PDO_TRS_MAP", 0x1A00, 0x1BFF)]
       
    38 index_categories = ["firstIndex", "lastIndex"]
       
    39 
       
    40 generated_tag = """\n/* File generated by gen_cfile.py. Should not be modified. */\n"""
       
    41 
       
    42 # Format a string for making a C++ variable
       
    43 def FormatName(name):
       
    44     wordlist = [word for word in word_model.findall(name) if word != '']
       
    45     result = ''
       
    46     sep = ''
       
    47     for word in wordlist:
       
    48         result += "%s%s"%(sep,word)
       
    49         sep = '_'
       
    50     return result
       
    51 
       
    52 # Extract the informations from a given type name
       
    53 def GetValidTypeInfos(typename):
       
    54     result = type_model.match(typename)
       
    55     if result:
       
    56         values = result.groups()
       
    57         if values[0] in ("UNSIGNED", "INTEGER") and eval(values[1]) in [i * 8 for i in xrange(1, 9)]:
       
    58             return "UNS%s"%values[1], "", "uint%s"%values[1]
       
    59         elif values[0] == "REAL" and eval(values[1]) in (32, 64):
       
    60             return "%s%s"%(values[0], values[1]), "", "real%s"%values[1]
       
    61         elif values[0] == "VISIBLE_STRING":
       
    62             if values[1] == "":
       
    63                 return "UNS8", "[10]", "visible_string"
       
    64             else:
       
    65                 return "UNS8", "[%s]"%values[1], "visible_string"
       
    66     return None
       
    67 
       
    68 def WriteFile(filepath, content):
       
    69     cfile = open(filepath,"w")
       
    70     cfile.write(content)
       
    71     cfile.close()
       
    72 
       
    73 def GenerateFileContent(Manager, headerfilepath):
       
    74     global type
       
    75     texts = {}
       
    76     texts["maxPDOtransmit"] = 0
       
    77     texts["NodeName"], texts["NodeID"], texts["NodeType"] = Manager.GetCurrentNodeInfos()
       
    78     internal_types = {}
       
    79     texts["iam_a_slave"] = 0
       
    80     if (texts["NodeType"] == "slave"):
       
    81         texts["iam_a_slave"] = 1
       
    82     
       
    83     # Compiling lists of indexes
       
    84     rangelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0, 0x260)]
       
    85     listIndex = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0xFFFF)]
       
    86     communicationlist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0x11FF)]
       
    87     sdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1200, 0x12FF)]
       
    88     pdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1400, 0x1BFF)]
       
    89     variablelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x2000, 0xBFFF)]
       
    90 
       
    91 #-------------------------------------------------------------------------------
       
    92 #                       Declaration of the value range types
       
    93 #-------------------------------------------------------------------------------    
       
    94     
       
    95     valueRangeContent = ""
       
    96     strDefine = ""
       
    97     strSwitch = ""
       
    98     num = 0
       
    99     for index in rangelist:
       
   100         rangename = Manager.GetEntryName(index)
       
   101         result = range_model.match(rangename)
       
   102         if result:
       
   103             num += 1
       
   104             internal_types[rangename] = "valueRange_%d"%num
       
   105             typeindex = Manager.GetCurrentEntry(index, 1)
       
   106             typename = Manager.GetTypeName(typeindex)
       
   107             typeinfos = GetValidTypeInfos(typename)
       
   108             if typeinfos == None:
       
   109                 raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
       
   110             typename = typeinfos[0]
       
   111             minvalue = str(Manager.GetCurrentEntry(index, 2))
       
   112             maxvalue = str(Manager.GetCurrentEntry(index, 3))
       
   113             strDefine += "\n#define valueRange_%d 0x%02X /* Type %s, %s < value < %s */"%(num,index,typename,minvalue,maxvalue)
       
   114             strSwitch += """    case valueRange_%d:
       
   115       if (*(%s*)Value < (%s)%s) return OD_VALUE_TOO_LOW;
       
   116       if (*(%s*)Value > (%s)%s) return OD_VALUE_TOO_HIGH;
       
   117       break;\n"""%(num,typename,typename,minvalue,typename,typename,maxvalue)
       
   118 
       
   119     valueRangeContent += strDefine
       
   120     valueRangeContent += "\nUNS32 %(NodeName)s_valueRangeTest (UNS8 typeValue, void * value)\n{"%texts
       
   121     valueRangeContent += "\n  switch (typeValue) {\n"
       
   122     valueRangeContent += strSwitch
       
   123     valueRangeContent += "  }\n  return 0;\n}\n"
       
   124 
       
   125 #-------------------------------------------------------------------------------
       
   126 #            Creation of the mapped variables and object dictionary
       
   127 #-------------------------------------------------------------------------------
       
   128 
       
   129     mappedVariableContent = ""
       
   130     strDeclareHeader = ""
       
   131     strDeclareCallback = ""
       
   132     indexContents = {}
       
   133     indexCallbacks = {}
       
   134     for index in listIndex:
       
   135         texts["index"] = index
       
   136         strIndex = ""
       
   137         entry_infos = Manager.GetEntryInfos(index)
       
   138         texts["EntryName"] = entry_infos["name"]
       
   139         values = Manager.GetCurrentEntry(index)
       
   140         callbacks = Manager.HasCurrentEntryCallbacks(index)
       
   141         if index in variablelist:
       
   142             strIndex += "\n/* index 0x%(index)04X :   Mapped variable %(EntryName)s */\n"%texts
       
   143         else:
       
   144             strIndex += "\n/* index 0x%(index)04X :   %(EntryName)s. */\n"%texts
       
   145         if type(values) == ListType:
       
   146             texts["value"] = values[0]
       
   147             strIndex += "                    UNS8 %(NodeName)s_highestSubIndex_obj%(index)04X = %(value)d; // number of subindex - 1\n"%texts
       
   148         
       
   149         # Entry type is VAR
       
   150         if type(values) != ListType:
       
   151             subentry_infos = Manager.GetSubentryInfos(index, 0)
       
   152             typename = Manager.GetTypeName(subentry_infos["type"])
       
   153             typeinfos = GetValidTypeInfos(typename)
       
   154             if typeinfos == None:
       
   155                 raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
       
   156             if typename not in internal_types:
       
   157                 internal_types[typename] = typeinfos[2]
       
   158             texts["subIndexType"] = typeinfos[0]
       
   159             texts["suffixe"] = typeinfos[1]
       
   160             if typeinfos[2] == "visible_string":
       
   161                 texts["value"] = "\"%s\""%values
       
   162             else:
       
   163                 texts["value"] = "0x%X"%values
       
   164             if index in variablelist:
       
   165                 texts["name"] = FormatName(subentry_infos["name"])
       
   166                 strDeclareHeader += "extern %(subIndexType)s %(name)s%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x00\n"%texts
       
   167                 if callbacks:
       
   168                     strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts
       
   169                 mappedVariableContent += "%(subIndexType)s %(name)s%(suffixe)s = %(value)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x00\n"%texts
       
   170             else:
       
   171                 strIndex += "                    %(subIndexType)s %(NodeName)s_obj%(index)04X%(suffixe)s = %(value)s;\n"%texts
       
   172             values = [values]
       
   173         else:
       
   174             
       
   175             # Entry type is RECORD
       
   176             if entry_infos["struct"] & OD_IdenticalSubindexes:
       
   177                 subentry_infos = Manager.GetSubentryInfos(index, 1)
       
   178                 typename = Manager.GetTypeName(subentry_infos["type"])
       
   179                 typeinfos = GetValidTypeInfos(typename)
       
   180                 if typeinfos == None:
       
   181                     raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
       
   182                 if typename not in internal_types:
       
   183                     internal_types[typename] = typeinfos[2]
       
   184                 texts["subIndexType"] = typeinfos[0]
       
   185                 texts["suffixe"] = typeinfos[1]
       
   186                 texts["length"] = values[0]
       
   187                 if index in variablelist:
       
   188                     texts["name"] = FormatName(entry_infos["name"])
       
   189                     strDeclareHeader += "%(subIndexType)s %(name)s[%(length)d]%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X\n"%texts
       
   190                     if callbacks:
       
   191                         strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts
       
   192                     mappedVariableContent = "%(subIndexType)s %(name)s[] =\t\t// Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X\n  {\n"%texts
       
   193                     for subIndex, value in enumerate(values):
       
   194                         sep = ","
       
   195                         if subIndex > 0:
       
   196                             if subIndex == len(values)-1:
       
   197                                 sep = ""
       
   198                             if typeinfos[2] == "visible_string":
       
   199                                 value = "\"%s\""%value
       
   200                             else:
       
   201                                 value = "0x%X"%value
       
   202                             mappedVariableContent += "    %s%s\n"%(value, sep)
       
   203                     mappedVariableContent += "  }\n"
       
   204                 else:
       
   205                     strIndex += "                    %(subIndexType)s %(NodeName)s_obj%(index)04X[] = \n                    {\n"%texts
       
   206                     for subIndex, value in enumerate(values):
       
   207                         sep = ","
       
   208                         if subIndex > 0:
       
   209                             if subIndex == len(values)-1:
       
   210                                 sep = ""
       
   211                             if typeinfos[2] == "visible_string":
       
   212                                 value = "\"%s\""%value
       
   213                             else:
       
   214                                 value = str(value)
       
   215                             strIndex += "                      %s%s\n"%(value, sep)
       
   216                     strIndex += "                    };\n"
       
   217             else:
       
   218                 
       
   219                 # Entry type is ARRAY
       
   220                 for subIndex, value in enumerate(values):
       
   221                     texts["subIndex"] = subIndex
       
   222                     if subIndex > 0:
       
   223                         subentry_infos = Manager.GetSubentryInfos(index, subIndex)
       
   224                         typename = Manager.GetTypeName(subentry_infos["type"])
       
   225                         typeinfos = GetValidTypeInfos(typename)
       
   226                         if typeinfos == None:
       
   227                             raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
       
   228                         if typename not in internal_types:
       
   229                             internal_types[typename] = typeinfos[2]
       
   230                         texts["subIndexType"] = typeinfos[0]
       
   231                         texts["suffixe"] = typeinfos[1]
       
   232                         if typeinfos[2] == "visible_string":
       
   233                             texts["value"] = "\"%s\""%value
       
   234                         else:
       
   235                             texts["value"] = "0x%X"%value
       
   236                         texts["name"] = FormatName(subentry_infos["name"])
       
   237                         if index in variablelist:
       
   238                             strDeclareHeader += "extern %(subIndexType)s %(name)s%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X\n"%texts
       
   239                             mappedVariableContent += "%(subIndexType)s %(name)s%(suffixe)s = %(value)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X\n"%texts
       
   240                         else:
       
   241                             strIndex += "                    %(subIndexType)s %(NodeName)s_obj%(index)04X_%(name)s%(suffixe)s = %(value)s;\n"%texts
       
   242                 if callbacks:
       
   243                     texts["name"] = FormatName(entry_infos["name"])
       
   244                     strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts
       
   245         
       
   246         # Generating Dictionary C++ entry
       
   247         if callbacks:
       
   248             if index in variablelist:
       
   249                 name = FormatName(entry_infos["name"])
       
   250             else:
       
   251                 name = "%(NodeName)s_Index%(index)04X"%texts
       
   252             strIndex += "                    ODCallback_t %s_callbacks[] = \n                     {\n"%name
       
   253             for subIndex in xrange(len(values)):
       
   254                 strIndex += "                       NULL,\n"
       
   255             strIndex += "                     };\n"
       
   256             indexCallbacks[index] = "*callbacks = %s_callbacks; "%name
       
   257         else:
       
   258             indexCallbacks[index] = ""
       
   259         strIndex += "                    subindex %(NodeName)s_Index%(index)04X[] = \n                     {\n"%texts
       
   260         for subIndex in xrange(len(values)):
       
   261             subentry_infos = Manager.GetSubentryInfos(index, subIndex)
       
   262             if subIndex < len(values) - 1:
       
   263                 sep = ","
       
   264             else:
       
   265                 sep = ""
       
   266             typename = Manager.GetTypeName(subentry_infos["type"])
       
   267             typeinfos = GetValidTypeInfos(typename)
       
   268             if typename.startswith("VISIBLE_STRING"):
       
   269                 subIndexType = "visible_string"
       
   270             elif typename in internal_types:
       
   271                 subIndexType = internal_types[typename]
       
   272             else:
       
   273                 subIndexType = typename
       
   274             if subIndex == 0:
       
   275                 if entry_infos["struct"] & OD_MultipleSubindexes:
       
   276                     name = "%(NodeName)s_highestSubIndex_obj%(index)04X"%texts
       
   277                 elif index in variablelist:
       
   278                     name = FormatName(subentry_infos["name"])
       
   279                 else:
       
   280                     name = FormatName("%s_obj%04X"%(texts["NodeName"], texts["index"]))
       
   281             elif entry_infos["struct"] & OD_IdenticalSubindexes:
       
   282                 if index in variablelist:
       
   283                     name = "%s[%d]"%(FormatName(entry_infos["name"]), subIndex - 1)
       
   284                 else:
       
   285                     name = "%s_obj%04X[%d]"%(texts["NodeName"], texts["index"], subIndex - 1)
       
   286             else:
       
   287                 if index in variablelist:
       
   288                     name = FormatName(subentry_infos["name"])
       
   289                 else:
       
   290                     name = "%s_obj%04X_%s"%(texts["NodeName"], texts["index"], FormatName(subentry_infos["name"]))
       
   291             if subIndexType == "visible_string":
       
   292                 sizeof = name
       
   293             else:
       
   294                 sizeof = typeinfos[0]
       
   295             params = Manager.GetCurrentParamsEntry(index, subIndex)
       
   296             if params["save"]:
       
   297                 save = "|TO_BE_SAVE"
       
   298             else:
       
   299                 save = ""
       
   300             strIndex += "                       { %s%s, %s, sizeof (%s), (void*)&%s }%s\n"%(subentry_infos["access"].upper(),save,subIndexType,sizeof,name,sep)
       
   301         strIndex += "                     };\n"
       
   302         indexContents[index] = strIndex
       
   303 
       
   304 #-------------------------------------------------------------------------------
       
   305 #                     Declaration of Particular Parameters
       
   306 #-------------------------------------------------------------------------------
       
   307 
       
   308     if 0x1006 not in communicationlist:
       
   309         entry_infos = Manager.GetEntryInfos(0x1006)
       
   310         texts["EntryName"] = entry_infos["name"]
       
   311         indexContents[0x1006] = """\n/* index 0x1006 :   %(EntryName)s */
       
   312                     UNS32 %(NodeName)s_obj1006 = 0;
       
   313 """%texts
       
   314 
       
   315     if 0x1016 in communicationlist:
       
   316         texts["nombre"] = Manager.GetCurrentEntry(0x1016, 0)
       
   317     else:
       
   318         texts["nombre"] = 0
       
   319         entry_infos = Manager.GetEntryInfos(0x1016)
       
   320         texts["EntryName"] = entry_infos["name"]
       
   321         indexContents[0x1016] = """\n/* index 0x1016 :   %(EntryName)s */
       
   322                     UNS8 %(NodeName)s_highestSubIndex_obj1016 = 0;
       
   323                     UNS32 %(NodeName)s_obj1016[0];
       
   324                     subindex %(NodeName)s_Index1016[0];
       
   325 """%texts
       
   326     if texts["nombre"] > 0:
       
   327         strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[%(nombre)d] = {TIMER_NONE,};\n"%texts
       
   328     else:
       
   329         strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[0];\n"%texts
       
   330 
       
   331     if 0x1017 not in communicationlist:
       
   332         entry_infos = Manager.GetEntryInfos(0x1017)
       
   333         texts["EntryName"] = entry_infos["name"]
       
   334         indexContents[0x1017] = """\n/* index 0x1017 :   %(EntryName)s */ 
       
   335                     UNS16 %(NodeName)s_obj1017 = 0;
       
   336 """%texts
       
   337 
       
   338 #-------------------------------------------------------------------------------
       
   339 #               Declaration of navigation in the Object Dictionary
       
   340 #-------------------------------------------------------------------------------
       
   341 
       
   342     strDeclareIndex = ""
       
   343     strDeclareSwitch = ""
       
   344     strQuickIndex = ""
       
   345     quick_index = {}
       
   346     for index_cat in index_categories:
       
   347         quick_index[index_cat] = {}
       
   348         for cat, idx_min, idx_max in categories:
       
   349             quick_index[index_cat][cat] = 0
       
   350     maxPDOtransmit = 0
       
   351     for i, index in enumerate(listIndex):
       
   352         texts["index"] = index
       
   353         strDeclareIndex += "  { (subindex*)%(NodeName)s_Index%(index)04X,sizeof(%(NodeName)s_Index%(index)04X)/sizeof(%(NodeName)s_Index%(index)04X[0]), 0x%(index)04X},\n"%texts
       
   354         strDeclareSwitch += "		case 0x%04X: i = %d;%sbreak;\n"%(index, i, indexCallbacks[index])
       
   355         for cat, idx_min, idx_max in categories:
       
   356             if idx_min <= index <= idx_max:
       
   357                 quick_index["lastIndex"][cat] = i
       
   358                 if quick_index["firstIndex"][cat] == 0:
       
   359                     quick_index["firstIndex"][cat] = i
       
   360                 if cat == "PDO_TRS":
       
   361                     maxPDOtransmit += 1
       
   362     texts["maxPDOtransmit"] = max(1, maxPDOtransmit)
       
   363     for index_cat in index_categories:
       
   364         strQuickIndex += "\nquick_index %s_%s = {\n"%(texts["NodeName"], index_cat)
       
   365         sep = ","
       
   366         for i, (cat, idx_min, idx_max) in enumerate(categories):
       
   367             if i == len(categories) - 1:
       
   368                 sep = ""
       
   369             strQuickIndex += "  %s : %d%s\n"%(cat, quick_index[index_cat][cat], sep)
       
   370         strQuickIndex += "};\n"
       
   371 
       
   372 #-------------------------------------------------------------------------------
       
   373 #                            Write File Content
       
   374 #-------------------------------------------------------------------------------
       
   375 
       
   376     fileContent = copyright_notice + generated_tag + """
       
   377 #include "%s"
       
   378 """%(headerfilepath)
       
   379 
       
   380     fileContent += """
       
   381 /**************************************************************************/
       
   382 /* Declaration of the mapped variables                                    */
       
   383 /**************************************************************************/
       
   384 """ + mappedVariableContent
       
   385 
       
   386     fileContent += """
       
   387 /**************************************************************************/
       
   388 /* Declaration of the value range types                                   */
       
   389 /**************************************************************************/
       
   390 """ + valueRangeContent
       
   391 
       
   392     fileContent += """
       
   393 /**************************************************************************/
       
   394 /* The node id                                                            */
       
   395 /**************************************************************************/
       
   396 /* node_id default value.*/
       
   397 UNS8 %(NodeName)s_bDeviceNodeId = 0x%(NodeID)02X;
       
   398 
       
   399 //*****************************************************************************/
       
   400 /* Array of message processing information */
       
   401 
       
   402 const UNS8 %(NodeName)s_iam_a_slave = %(iam_a_slave)d;
       
   403 
       
   404 """%texts
       
   405     fileContent += strTimers
       
   406     
       
   407     fileContent += """
       
   408 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
       
   409 //
       
   410 //                       OBJECT DICTIONARY
       
   411 //                   
       
   412 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
       
   413 """%texts
       
   414     contentlist = indexContents.keys()
       
   415     contentlist.sort()
       
   416     for index in contentlist:
       
   417         fileContent += indexContents[index]
       
   418 
       
   419     fileContent += """
       
   420 const indextable %(NodeName)s_objdict[] = 
       
   421 {
       
   422 """%texts
       
   423     fileContent += strDeclareIndex
       
   424     fileContent += """};
       
   425 
       
   426 const indextable * %(NodeName)s_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks)
       
   427 {
       
   428 	int i;
       
   429 	*callbacks = NULL;
       
   430 	switch(wIndex){
       
   431 """%texts
       
   432     fileContent += strDeclareSwitch
       
   433     fileContent += """		default:
       
   434 			*errorCode = OD_NO_SUCH_OBJECT;
       
   435 			return NULL;
       
   436 	}
       
   437 	*errorCode = OD_SUCCESSFUL;
       
   438 	return &%(NodeName)s_objdict[i];
       
   439 }
       
   440 
       
   441 // To count at which received SYNC a PDO must be sent.
       
   442 // Even if no pdoTransmit are defined, at least one entry is computed
       
   443 // for compilations issues.
       
   444 UNS8 %(NodeName)s_count_sync[%(maxPDOtransmit)d] = {0,};
       
   445 """%texts
       
   446     fileContent += strQuickIndex
       
   447     fileContent += """
       
   448 UNS16 %(NodeName)s_ObjdictSize = sizeof(%(NodeName)s_objdict)/sizeof(%(NodeName)s_objdict[0]); 
       
   449 
       
   450 CO_Data %(NodeName)s_Data = CANOPEN_NODE_DATA_INITIALIZER(%(NodeName)s);
       
   451 
       
   452 """%texts
       
   453 
       
   454 #-------------------------------------------------------------------------------
       
   455 #                          Write Header File Content
       
   456 #-------------------------------------------------------------------------------
       
   457 
       
   458     HeaderFileContent = copyright_notice + generated_tag + """
       
   459 #include "data.h"
       
   460 
       
   461 // prototypes of function to be filled by app
       
   462 void %(NodeName)s_SDOtimeoutError(UNS8 line);
       
   463 void %(NodeName)s_heartbeatError(UNS8);
       
   464 
       
   465 UNS8 %(NodeName)s_canSend(Message *);
       
   466 
       
   467 void %(NodeName)s_initialisation();
       
   468 void %(NodeName)s_preOperational();
       
   469 void %(NodeName)s_operational();
       
   470 void %(NodeName)s_stopped();
       
   471 
       
   472 void %(NodeName)s_post_sync();
       
   473 void %(NodeName)s_post_TPDO();
       
   474 
       
   475 // Master node data struct
       
   476 extern CO_Data %(NodeName)s_Data;
       
   477 
       
   478 """%texts
       
   479     HeaderFileContent += strDeclareHeader
       
   480     
       
   481     return fileContent,HeaderFileContent
       
   482 
       
   483 #-------------------------------------------------------------------------------
       
   484 #                             Main Function
       
   485 #-------------------------------------------------------------------------------
       
   486 
       
   487 def GenerateFile(filepath, manager):
       
   488     headerfilepath = os.path.splitext(filepath)[0]+".h"
       
   489     content, header = GenerateFileContent(manager, os.path.split(headerfilepath)[1])
       
   490     WriteFile(filepath, content)
       
   491     WriteFile(headerfilepath, header)
       
   492     return True