00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 from node import *
00025 from types import *
00026
00027 import re, os
00028
00029 word_model = re.compile('([a-zA-Z_0-9]*)')
00030 type_model = re.compile('([\_A-Z]*)([0-9]*)')
00031 range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]')
00032
00033 categories = [("SDO_SVR", 0x1200, 0x127F), ("SDO_CLT", 0x1280, 0x12FF),
00034 ("PDO_RCV", 0x1400, 0x15FF), ("PDO_RCV_MAP", 0x1600, 0x17FF),
00035 ("PDO_TRS", 0x1800, 0x19FF), ("PDO_TRS_MAP", 0x1A00, 0x1BFF)]
00036 index_categories = ["firstIndex", "lastIndex"]
00037
00038 generated_tag = """\n/* File generated by gen_cfile.py. Should not be modified. */\n"""
00039
00040 internal_types = {}
00041
00042
00043 def FormatName(name):
00044 wordlist = [word for word in word_model.findall(name) if word != '']
00045 result = ''
00046 sep = ''
00047 for word in wordlist:
00048 result += "%s%s"%(sep,word)
00049 sep = '_'
00050 return result
00051
00052
00053 def GetValidTypeInfos(typename):
00054 if typename in internal_types:
00055 return internal_types[typename]
00056 else:
00057 result = type_model.match(typename)
00058 if result:
00059 values = result.groups()
00060 if values[0] == "UNSIGNED" and int(values[1]) in [i * 8 for i in xrange(1, 9)]:
00061 typeinfos = ("UNS%s"%values[1], "", "uint%s"%values[1])
00062 elif values[0] == "INTEGER" and int(values[1]) in [i * 8 for i in xrange(1, 9)]:
00063 typeinfos = ("INTEGER%s"%values[1], "", "int%s"%values[1])
00064 elif values[0] == "REAL" and int(values[1]) in (32, 64):
00065 typeinfos = ("%s%s"%(values[0], values[1]), "", "real%s"%values[1])
00066 elif values[0] == "VISIBLE_STRING":
00067 if values[1] == "":
00068 typeinfos = ("UNS8", "[10]", "visible_string")
00069 else:
00070 typeinfos = ("UNS8", "[%s]"%values[1], "visible_string")
00071 elif values[0] == "DOMAIN":
00072 typeinfos = ("UNS8*", "", "domain")
00073 elif values[0] == "BOOLEAN":
00074 typeinfos = ("UNS8", "", "boolean")
00075 else:
00076 raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
00077 internal_types[typename] = typeinfos
00078 else:
00079 raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename
00080 return typeinfos
00081
00082 def WriteFile(filepath, content):
00083 cfile = open(filepath,"w")
00084 cfile.write(content)
00085 cfile.close()
00086
00087 def GenerateFileContent(Manager, headerfilepath):
00088 global type
00089 global internal_types
00090 texts = {}
00091 texts["maxPDOtransmit"] = 0
00092 texts["NodeName"], texts["NodeID"], texts["NodeType"], texts["Description"] = Manager.GetCurrentNodeInfos()
00093 texts["iam_a_slave"] = 0
00094 if (texts["NodeType"] == "slave"):
00095 texts["iam_a_slave"] = 1
00096
00097
00098 rangelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0, 0x260)]
00099 listIndex = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0xFFFF)]
00100 communicationlist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0x11FF)]
00101 sdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1200, 0x12FF)]
00102 pdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1400, 0x1BFF)]
00103 variablelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x2000, 0xBFFF)]
00104
00105
00106
00107
00108
00109 valueRangeContent = ""
00110 strDefine = ""
00111 strSwitch = ""
00112 num = 0
00113 for index in rangelist:
00114 rangename = Manager.GetEntryName(index)
00115 result = range_model.match(rangename)
00116 if result:
00117 num += 1
00118 typeindex = Manager.GetCurrentEntry(index, 1)
00119 typename = Manager.GetTypeName(typeindex)
00120 typeinfos = GetValidTypeInfos(typename)
00121 internal_types[rangename] = (typeinfos[0], typeinfos[1], "valueRange_%d"%num)
00122 minvalue = str(Manager.GetCurrentEntry(index, 2))
00123 maxvalue = str(Manager.GetCurrentEntry(index, 3))
00124 strDefine += "\n#define valueRange_%d 0x%02X /* Type %s, %s < value < %s */"%(num,index,typeinfos[0],minvalue,maxvalue)
00125 strSwitch += """ case valueRange_%d:
00126 if (*(%s*)Value < (%s)%s) return OD_VALUE_TOO_LOW;
00127 if (*(%s*)Value > (%s)%s) return OD_VALUE_TOO_HIGH;
00128 break;\n"""%(num,typeinfos[0],typeinfos[0],minvalue,typeinfos[0],typeinfos[0],maxvalue)
00129
00130 valueRangeContent += strDefine
00131 valueRangeContent += "\nUNS32 %(NodeName)s_valueRangeTest (UNS8 typeValue, void * value)\n{"%texts
00132 valueRangeContent += "\n switch (typeValue) {\n"
00133 valueRangeContent += strSwitch
00134 valueRangeContent += " }\n return 0;\n}\n"
00135
00136
00137
00138
00139
00140 mappedVariableContent = ""
00141 strDeclareHeader = ""
00142 strDeclareCallback = ""
00143 indexContents = {}
00144 indexCallbacks = {}
00145 for index in listIndex:
00146 texts["index"] = index
00147 strIndex = ""
00148 entry_infos = Manager.GetEntryInfos(index)
00149 texts["EntryName"] = entry_infos["name"]
00150 values = Manager.GetCurrentEntry(index)
00151 callbacks = Manager.HasCurrentEntryCallbacks(index)
00152 if index in variablelist:
00153 strIndex += "\n/* index 0x%(index)04X : Mapped variable %(EntryName)s */\n"%texts
00154 else:
00155 strIndex += "\n/* index 0x%(index)04X : %(EntryName)s. */\n"%texts
00156
00157
00158 if type(values) != ListType:
00159 subentry_infos = Manager.GetSubentryInfos(index, 0)
00160 typename = Manager.GetTypeName(subentry_infos["type"])
00161 typeinfos = GetValidTypeInfos(typename)
00162 texts["subIndexType"] = typeinfos[0]
00163 texts["suffixe"] = typeinfos[1]
00164 if typeinfos[2] == "visible_string":
00165 texts["value"] = "\"%s\""%values
00166 texts["comment"] = ""
00167 else:
00168 texts["value"] = "0x%X"%values
00169 texts["comment"] = "\t/* %s */"%str(values)
00170 if index in variablelist:
00171 texts["name"] = FormatName(subentry_infos["name"])
00172 strDeclareHeader += "extern %(subIndexType)s %(name)s%(suffixe)s;\t\t/* Mapped at index 0x%(index)04X, subindex 0x00*/\n"%texts
00173 if callbacks:
00174 strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t/* Callbacks of index0x%(index)04X */\n"%texts
00175 mappedVariableContent += "%(subIndexType)s %(name)s%(suffixe)s = %(value)s;\t\t/* Mapped at index 0x%(index)04X, subindex 0x00 */\n"%texts
00176 else:
00177 strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X%(suffixe)s = %(value)s;%(comment)s\n"%texts
00178 values = [values]
00179 else:
00180 subentry_infos = Manager.GetSubentryInfos(index, 0)
00181 typename = Manager.GetTypeName(subentry_infos["type"])
00182 typeinfos = GetValidTypeInfos(typename)
00183 texts["value"] = values[0]
00184 texts["subIndexType"] = typeinfos[0]
00185 strIndex += " %(subIndexType)s %(NodeName)s_highestSubIndex_obj%(index)04X = %(value)d; /* number of subindex - 1*/\n"%texts
00186
00187
00188 if entry_infos["struct"] & OD_IdenticalSubindexes:
00189 subentry_infos = Manager.GetSubentryInfos(index, 1)
00190 typename = Manager.GetTypeName(subentry_infos["type"])
00191 typeinfos = GetValidTypeInfos(typename)
00192 texts["subIndexType"] = typeinfos[0]
00193 texts["suffixe"] = typeinfos[1]
00194 texts["length"] = values[0]
00195 if index in variablelist:
00196 texts["name"] = FormatName(entry_infos["name"])
00197 strDeclareHeader += "extern %(subIndexType)s %(name)s[%(length)d]%(suffixe)s;\t\t/* Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X */\n"%texts
00198 if callbacks:
00199 strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t/* Callbacks of index0x%(index)04X */\n"%texts
00200 mappedVariableContent += "%(subIndexType)s %(name)s[] =\t\t/* Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X */\n {\n"%texts
00201 for subIndex, value in enumerate(values):
00202 sep = ","
00203 comment = ""
00204 if subIndex > 0:
00205 if subIndex == len(values)-1:
00206 sep = ""
00207 if typeinfos[2] == "visible_string":
00208 value = "\"%s\""%value
00209 else:
00210 comment = "\t/* %s */"%str(value)
00211 value = "0x%X"%value
00212 mappedVariableContent += " %s%s%s\n"%(value, sep, comment)
00213 mappedVariableContent += " };\n"
00214 else:
00215 strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X[] = \n {\n"%texts
00216 for subIndex, value in enumerate(values):
00217 sep = ","
00218 comment = ""
00219 if subIndex > 0:
00220 if subIndex == len(values)-1:
00221 sep = ""
00222 if typeinfos[2] == "visible_string":
00223 value = "\"%s\""%value
00224 elif typeinfos[2] == "domain":
00225 value = "\"%s\""%''.join(["\\x%2.2x"%ord(char) for char in value])
00226 else:
00227 comment = "\t/* %s */"%str(value)
00228 value = "0x%X"%value
00229 strIndex += " %s%s%s\n"%(value, sep, comment)
00230 strIndex += " };\n"
00231 else:
00232
00233 texts["parent"] = FormatName(entry_infos["name"])
00234
00235 for subIndex, value in enumerate(values):
00236 texts["subIndex"] = subIndex
00237 if subIndex > 0:
00238 subentry_infos = Manager.GetSubentryInfos(index, subIndex)
00239 typename = Manager.GetTypeName(subentry_infos["type"])
00240 typeinfos = GetValidTypeInfos(typename)
00241 texts["subIndexType"] = typeinfos[0]
00242 texts["suffixe"] = typeinfos[1]
00243 if typeinfos[2] == "visible_string":
00244 texts["value"] = "\"%s\""%value
00245 texts["comment"] = ""
00246 else:
00247 texts["value"] = "0x%X"%value
00248 texts["comment"] = "\t/* %s */"%str(value)
00249 texts["name"] = FormatName(subentry_infos["name"])
00250 if index in variablelist:
00251 strDeclareHeader += "extern %(subIndexType)s %(parent)s_%(name)s%(suffixe)s;\t\t/* Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X */\n"%texts
00252 mappedVariableContent += "%(subIndexType)s %(parent)s_%(name)s%(suffixe)s = %(value)s;\t\t/* Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X */\n"%texts
00253 else:
00254 strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X_%(name)s%(suffixe)s = %(value)s;%(comment)s\n"%texts
00255 if callbacks:
00256 strDeclareHeader += "extern ODCallback_t %(parent)s_callbacks[];\t\t/* Callbacks of index0x%(index)04X */\n"%texts
00257
00258
00259 if callbacks:
00260 if index in variablelist:
00261 name = FormatName(entry_infos["name"])
00262 else:
00263 name = "%(NodeName)s_Index%(index)04X"%texts
00264 strIndex += " ODCallback_t %s_callbacks[] = \n {\n"%name
00265 for subIndex in xrange(len(values)):
00266 strIndex += " NULL,\n"
00267 strIndex += " };\n"
00268 indexCallbacks[index] = "*callbacks = %s_callbacks; "%name
00269 else:
00270 indexCallbacks[index] = ""
00271 strIndex += " subindex %(NodeName)s_Index%(index)04X[] = \n {\n"%texts
00272 for subIndex in xrange(len(values)):
00273 subentry_infos = Manager.GetSubentryInfos(index, subIndex)
00274 if subIndex < len(values) - 1:
00275 sep = ","
00276 else:
00277 sep = ""
00278 typename = Manager.GetTypeName(subentry_infos["type"])
00279 typeinfos = GetValidTypeInfos(typename)
00280 if subIndex == 0:
00281 if entry_infos["struct"] & OD_MultipleSubindexes:
00282 name = "%(NodeName)s_highestSubIndex_obj%(index)04X"%texts
00283 elif index in variablelist:
00284 name = FormatName(subentry_infos["name"])
00285 else:
00286 name = FormatName("%s_obj%04X"%(texts["NodeName"], texts["index"]))
00287 elif entry_infos["struct"] & OD_IdenticalSubindexes:
00288 if index in variablelist:
00289 name = "%s[%d]"%(FormatName(entry_infos["name"]), subIndex - 1)
00290 else:
00291 name = "%s_obj%04X[%d]"%(texts["NodeName"], texts["index"], subIndex - 1)
00292 else:
00293 if index in variablelist:
00294 name = FormatName("%s_%s"%(entry_infos["name"],subentry_infos["name"]))
00295 else:
00296 name = "%s_obj%04X_%s"%(texts["NodeName"], texts["index"], FormatName(subentry_infos["name"]))
00297 if typeinfos[2] in ["visible_string", "domain"]:
00298 sizeof = str(len(values[subIndex]))
00299 else:
00300 sizeof = "sizeof (%s)"%typeinfos[0]
00301 params = Manager.GetCurrentParamsEntry(index, subIndex)
00302 if params["save"]:
00303 save = "|TO_BE_SAVE"
00304 else:
00305 save = ""
00306 strIndex += " { %s%s, %s, %s, (void*)&%s }%s\n"%(subentry_infos["access"].upper(),save,typeinfos[2],sizeof,name,sep)
00307 strIndex += " };\n"
00308 indexContents[index] = strIndex
00309
00310
00311
00312
00313
00314 if 0x1006 not in communicationlist:
00315 entry_infos = Manager.GetEntryInfos(0x1006)
00316 texts["EntryName"] = entry_infos["name"]
00317 indexContents[0x1006] = """\n/* index 0x1006 : %(EntryName)s */
00318 UNS32 %(NodeName)s_obj1006 = 0x0; /* 0 */
00319 """%texts
00320
00321 if 0x1016 in communicationlist:
00322 texts["nombre"] = Manager.GetCurrentEntry(0x1016, 0)
00323 else:
00324 texts["nombre"] = 0
00325 entry_infos = Manager.GetEntryInfos(0x1016)
00326 texts["EntryName"] = entry_infos["name"]
00327 indexContents[0x1016] = """\n/* index 0x1016 : %(EntryName)s */
00328 UNS8 %(NodeName)s_highestSubIndex_obj1016 = 0;
00329 UNS32 %(NodeName)s_obj1016[]={0};
00330 """%texts
00331 if texts["nombre"] > 0:
00332 strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[%(nombre)d] = {TIMER_NONE,};\n"%texts
00333 else:
00334 strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[1];\n"%texts
00335
00336 if 0x1017 not in communicationlist:
00337 entry_infos = Manager.GetEntryInfos(0x1017)
00338 texts["EntryName"] = entry_infos["name"]
00339 indexContents[0x1017] = """\n/* index 0x1017 : %(EntryName)s */
00340 UNS16 %(NodeName)s_obj1017 = 0x0; /* 0 */
00341 """%texts
00342
00343
00344
00345
00346
00347 strDeclareIndex = ""
00348 strDeclareSwitch = ""
00349 strQuickIndex = ""
00350 quick_index = {}
00351 for index_cat in index_categories:
00352 quick_index[index_cat] = {}
00353 for cat, idx_min, idx_max in categories:
00354 quick_index[index_cat][cat] = 0
00355 maxPDOtransmit = 0
00356 for i, index in enumerate(listIndex):
00357 texts["index"] = index
00358 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
00359 strDeclareSwitch += " case 0x%04X: i = %d;%sbreak;\n"%(index, i, indexCallbacks[index])
00360 for cat, idx_min, idx_max in categories:
00361 if idx_min <= index <= idx_max:
00362 quick_index["lastIndex"][cat] = i
00363 if quick_index["firstIndex"][cat] == 0:
00364 quick_index["firstIndex"][cat] = i
00365 if cat == "PDO_TRS":
00366 maxPDOtransmit += 1
00367 texts["maxPDOtransmit"] = max(1, maxPDOtransmit)
00368 for index_cat in index_categories:
00369 strQuickIndex += "\nquick_index %s_%s = {\n"%(texts["NodeName"], index_cat)
00370 sep = ","
00371 for i, (cat, idx_min, idx_max) in enumerate(categories):
00372 if i == len(categories) - 1:
00373 sep = ""
00374 strQuickIndex += " %d%s /* %s */\n"%(quick_index[index_cat][cat],sep,cat)
00375 strQuickIndex += "};\n"
00376
00377
00378
00379
00380
00381 fileContent = generated_tag + """
00382 #include "%s"
00383 """%(headerfilepath)
00384
00385 fileContent += """
00386 /**************************************************************************/
00387 /* Declaration of the mapped variables */
00388 /**************************************************************************/
00389 """ + mappedVariableContent
00390
00391 fileContent += """
00392 /**************************************************************************/
00393 /* Declaration of the value range types */
00394 /**************************************************************************/
00395 """ + valueRangeContent
00396
00397 fileContent += """
00398 /**************************************************************************/
00399 /* The node id */
00400 /**************************************************************************/
00401 /* node_id default value.*/
00402 UNS8 %(NodeName)s_bDeviceNodeId = 0x%(NodeID)02X;
00403
00404 /**************************************************************************/
00405 /* Array of message processing information */
00406
00407 const UNS8 %(NodeName)s_iam_a_slave = %(iam_a_slave)d;
00408
00409 """%texts
00410 fileContent += strTimers
00411
00412 fileContent += """
00413 /*
00414 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
00415
00416 OBJECT DICTIONARY
00417
00418 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
00419 */
00420 """%texts
00421 contentlist = indexContents.keys()
00422 contentlist.sort()
00423 for index in contentlist:
00424 fileContent += indexContents[index]
00425
00426 fileContent += """
00427 const indextable %(NodeName)s_objdict[] =
00428 {
00429 """%texts
00430 fileContent += strDeclareIndex
00431 fileContent += """};
00432
00433 const indextable * %(NodeName)s_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks)
00434 {
00435 int i;
00436 *callbacks = NULL;
00437 switch(wIndex){
00438 """%texts
00439 fileContent += strDeclareSwitch
00440 fileContent += """ default:
00441 *errorCode = OD_NO_SUCH_OBJECT;
00442 return NULL;
00443 }
00444 *errorCode = OD_SUCCESSFUL;
00445 return &%(NodeName)s_objdict[i];
00446 }
00447
00448 /* To count at which received SYNC a PDO must be sent.
00449 * Even if no pdoTransmit are defined, at least one entry is computed
00450 * for compilations issues.
00451 */
00452 UNS8 %(NodeName)s_count_sync[%(maxPDOtransmit)d] = {0,};
00453 """%texts
00454 fileContent += strQuickIndex
00455 fileContent += """
00456 UNS16 %(NodeName)s_ObjdictSize = sizeof(%(NodeName)s_objdict)/sizeof(%(NodeName)s_objdict[0]);
00457
00458 CO_Data %(NodeName)s_Data = CANOPEN_NODE_DATA_INITIALIZER(%(NodeName)s);
00459
00460 """%texts
00461
00462
00463
00464
00465
00466 HeaderFileContent = generated_tag + """
00467 #include "data.h"
00468
00469 /* Prototypes of function provided by object dictionnary */
00470 UNS32 %(NodeName)s_valueRangeTest (UNS8 typeValue, void * value);
00471 const indextable * %(NodeName)s_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks);
00472
00473 /* Master node data struct */
00474 extern CO_Data %(NodeName)s_Data;
00475
00476 """%texts
00477 HeaderFileContent += strDeclareHeader
00478
00479 return fileContent,HeaderFileContent
00480
00481
00482
00483
00484
00485 def GenerateFile(filepath, manager):
00486 try:
00487 headerfilepath = os.path.splitext(filepath)[0]+".h"
00488 content, header = GenerateFileContent(manager, os.path.split(headerfilepath)[1])
00489 WriteFile(filepath, content)
00490 WriteFile(headerfilepath, header)
00491 return None
00492 except ValueError, message:
00493 return "Unable to Generate C File\n%s"%message
00494