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 xml.parsers import expat
00025
00026 import node
00027 from node import *
00028
00029 maxObjects = 8
00030
00031 currentPDOIndex = 0
00032 currentBitsMapped = 0
00033 currentMaxObjects = 0
00034 currentNbMappedObjects = 0
00035
00036 nextPdoIndex = {"rx":0x1400,"tx":0x1800}
00037
00038 valid_elements = ["node","heartbeat_consumers","sdo_clients","pdo","mapped_object",
00039 "pdo_param","pdo_receive","pdo_transmit","mapped_variable","mapped_table",
00040 "mapped_string_variable","mapped_string_table"]
00041
00042
00043
00044
00045
00046 def StartElement(name, attrs):
00047 if name in valid_elements:
00048 if name == "node":
00049 startNode(attrs)
00050 elif name == "heartbeat_consumers":
00051 startHeartBeatConsumers(attrs)
00052 elif name == "sdo_clients":
00053 startSdoClients(attrs)
00054 elif name in ["pdo_param","pdo_receive","pdo_transmit"]:
00055 raise ValueError, """!!! The XML grammar has changed.
00056 Please, open your xml file, delete the tags pdo_param, pdo_receive and pdo_transmit.
00057 Use instead the tag pdo for each pdo to create, and (optional) use the tag mapped_object (menu pdo/map and object ...)."""
00058 elif name == "pdo":
00059 startPdo(attrs)
00060 elif name == "mapped_object":
00061 startMappedObject(attrs)
00062 elif name == "mapped_variable":
00063 startMappedVariable(attrs)
00064 elif name == "mapped_table":
00065 startMappedTable(attrs)
00066 elif name == "mapped_string_variable":
00067 startMappedVariable(attrs)
00068 elif name == "mapped_string_table":
00069 startMappedTable(attrs)
00070
00071 def EndElement(name):
00072 if name in valid_elements:
00073 if name == "node":
00074 stopNode()
00075
00076 def CharacterData(data):
00077 pass
00078
00079
00080
00081
00082
00083 def startNode(attrs):
00084 name = attrs["name"]
00085 Node.SetNodeName(name)
00086
00087 if "node_id" in attrs and len(attrs["node_id"]) > 0:
00088 node_id = eval(attrs["node_id"])
00089 else:
00090 node_id = 0x01
00091 Node.SetNodeID(node_id)
00092
00093 typeNode = attrs["type_node"]
00094 Node.SetNodeType(typeNode)
00095
00096 if "device_type_1000" in attrs:
00097 device_type = eval(attrs["device_type_1000"])
00098 else:
00099 device_type = 0
00100 Node.AddEntry(0x1000, 0, device_type)
00101 Node.AddEntry(0x1001, 0, 0)
00102 Node.AddEntry(0x1005, 0, 0x00000080)
00103 Node.AddEntry(0x1006, 0, 0)
00104 Node.AddEntry(0x1007, 0, 0)
00105
00106 if "manufacturer_device_name_1008" in attrs:
00107 manufacturer_device_name = attrs["manufacturer_device_name_1008"]
00108 else:
00109 manufacturer_device_name = ""
00110 Node.AddEntry(0x1008, 0, manufacturer_device_name)
00111
00112 if "manufacturer_hardware_version_1009" in attrs:
00113 manufacturer_hardware_version = attrs["manufacturer_hardware_version_1009"]
00114 else:
00115 manufacturer_hardware_version = "__DATE__"
00116 Node.AddEntry(0x1009, 0, manufacturer_hardware_version)
00117
00118 if "manufacturer_software_version_100A" in attrs:
00119 manufacturer_software_version = attrs["manufacturer_software_version_100A"]
00120 else:
00121 manufacturer_software_version = 0
00122 Node.AddEntry(0x100A, 0, manufacturer_software_version)
00123
00124 if "vendor_id_1018" in attrs:
00125 vendor_id = eval(attrs["vendor_id_1018"])
00126 else:
00127 vendor_id = 0
00128 if "product_code_1018" in attrs:
00129 product_code = eval(attrs["product_code_1018"])
00130 else:
00131 product_code = 0
00132 if "revision_number_1018" in attrs:
00133 revision_number = eval(attrs["revision_number_1018"])
00134 else:
00135 revision_number = 0
00136 if "serial_number_1018" in attrs:
00137 serial_number = eval(attrs["serial_number_1018"])
00138 else:
00139 serial_number = 0
00140 Node.AddEntry(0x1018, 1, vendor_id)
00141 Node.AddEntry(0x1018, 2, product_code)
00142 Node.AddEntry(0x1018, 3, revision_number)
00143 Node.AddEntry(0x1018, 4, serial_number)
00144
00145 def stopNode():
00146 heartBeatProducer()
00147 sdoServer()
00148
00149
00150
00151
00152
00153 def startPdo(attrs):
00154 global currentPdoIndex
00155 global currentMaxObjects
00156 global currentNbMappedObjects
00157 global currentBitsMapped
00158 global maxObjects
00159
00160 cobId = 0
00161 transmissionType = 253
00162
00163
00164 type = attrs["type_rx_tx"]
00165 index = nextPdoIndex[type]
00166
00167
00168 if "index_communication_parameter" in attrs:
00169 index = eval(attrs["index_communication_parameter"])
00170 if type == "rx" and not 0x1400 <= index <= 0x15FF:
00171 raise ValueError, """!!! Abort because Index PDO receive : 0x%04X not valid.
00172 Valid index is 0x1400 ... 0x15FF"""%index
00173 if type == "tx" and not 0x1800 <= index <= 0x19FF:
00174 raise ValueError, """!!! Abort because Index PDO transmit : 0x%04X not valid.
00175 Valid index is 0x1800 ... 0x19FF"""%index
00176
00177
00178 if "cob_id" == attrs:
00179 cobId = eval(attrs["cob_id"])
00180 if "max_objects_in_pdo" == attrs:
00181 maxObjects = eval(attrs["max_objects_in_pdo"])
00182 if "transmission_type" in attrs:
00183 transmissionType = eval(attrs["transmission_type"])
00184
00185 if Node.IsEntry(index):
00186 raise ValueError, """!!! Abort because the PDO at index : 0x%04X have been already defined."""%index
00187
00188
00189 Node.AddEntry(index, 1, cobId)
00190 Node.AddEntry(index, 2, transmissionType)
00191
00192
00193 mapping_index = index + 0x200
00194 for i in xrange(1, maxObjects + 1):
00195 Node.AddEntry(mapping_index, i, 0x0)
00196
00197 currentPdoIndex = index
00198 currentMaxObjects = maxObjects
00199 currentBitsMapped = 0
00200 currentNbMappedObjects = 0
00201
00202 nextPdoIndex[type] = index + 1
00203
00204 def startMappedObject(attrs):
00205 global currentPdoIndex
00206 global currentMaxObjects
00207 global currentNbMappedObjects
00208 global currentBitsMapped
00209
00210 index = currentPdoIndex
00211 mapping_index = index + 0x200
00212
00213 indexObject = eval(attrs["index"])
00214 subIndexObject = eval(attrs["sub_index"])
00215 sizeInBitsObject = eval(attrs["size_in_bits"])
00216
00217 if currentMaxObjects == 0:
00218 raise ValueError, """!!! Abort because of a bogue for mapped object (defined at index 0x%04X, subIndex 0x%025X)
00219 in PDO. index : 0x%04X is undefined."""%(indexObject,subindexObject,mapping_index)
00220 if currentNbMappedObjects >= currentMaxObjects:
00221 raise ValueError, """!!! Abort mapping object (defined at index 0x%04X, subIndex 0x%02X)
00222 in PDO index 0x%04X. max objects (%d) reached."""%(IndexObject,subIndexObject,mapping_index,pdo[mapping_index]["maxObjects"])
00223 if currentBitsMapped + sizeInBitsObject > 64:
00224 raise ValueError, """!!! Abort mapping object (defined at index 0x%04X, subIndex 0x%02X)
00225 in PDO index 0x%04X. No room to put %d bits in the PDO."""%(IndexObject,subIndexObject,mapping_index,sizeInBitsObject)
00226
00227 value = eval("0x%04X%02X%02X"%(indexObject,subIndexObject,sizeInBitsObject))
00228 Node.SetEntry(mapping_index, currentNbMappedObjects + 1, value)
00229
00230 currentNbMappedObjects += 1
00231 currentBitsMapped += sizeInBitsObject
00232
00233
00234
00235
00236
00237 def startMappedVariable(attrs):
00238 name = attrs["name"]
00239 index = eval(attrs["index"])
00240 subIndex = eval(attrs["sub_index"])
00241
00242 if "size_in_bits" in attrs:
00243 size = eval(attrs["size_in_bits"])
00244 if "type" in attrs:
00245 type = attrs["type"]
00246 if (type == "UNS"):
00247 type = "UNSIGNED"
00248 else:
00249 type = "UNSIGNED"
00250 typename = "%s%d"%(type,size)
00251
00252 type_index = Manager.GetTypeIndex(typename, False)
00253 if type_index == None:
00254 raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Unrecognized type : %s"""%(name,index,subIndex,typename)
00255
00256
00257 if "min_value" in attrs or "max_value" in attrs:
00258 if "min_value" in attrs and "max_value" in attrs:
00259 minValue = eval(attrs["min_value"])
00260 maxValue = eval(attrs["max_value"])
00261 if (minValue > maxValue):
00262 raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : error in value-range : min > max"""%(name,index,subIndex)
00263 else:
00264 raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : You have defined only a min or a max value. \nIf you define one, you must define both."""%(name,index,subIndex)
00265
00266 type_index = findRangeType(type_index, minValue, maxValue)
00267 if type_index == None:
00268 raise ValueError, """!!! Sorry, too many different value range have been defined"""
00269
00270
00271 if "size_in_byte" in attrs:
00272 size = eval(attrs["size_in_byte"])
00273 type_index = findStringType(Manager.GetTypeIndex("VISIBLE_STRING", False), size)
00274 if type_index == None:
00275 raise ValueError, """!!! Sorry, too many different string length have been defined"""
00276
00277 if "access" in attrs:
00278 access = attrs["access"].lower()
00279 else:
00280 access = "rw"
00281
00282 if index < 0x2000 or index > 0xBFFF:
00283 raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Variable can't be defined using this index-subindex."""%(name,index,subIndex)
00284
00285 if subIndex == 0:
00286 Node.AddMappingEntry(index, name = name, struct = 1)
00287 elif subIndex == 1:
00288 Node.AddMappingEntry(index, struct = 3)
00289 Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
00290 result = Node.AddMappingEntry(index, subIndex, values = {"name" : name, "type" : type_index, "access" : access, "pdo" : True})
00291
00292 if result:
00293 Node.AddEntry(index, subIndex, 0)
00294 else:
00295 raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Unable to map"""%(name,index,subIndex)
00296
00297 def startMappedTable(attrs):
00298 name = attrs["name"]
00299 number_elements = eval(attrs["number_elements"])
00300 index = eval(attrs["index"])
00301
00302 if "size_in_bits" in attrs:
00303 size = eval(attrs["size_in_bits"])
00304 if "type" in attrs:
00305 type = attrs["type"]
00306 if (type == "UNS"):
00307 type = "UNSIGNED"
00308 else:
00309 type = "UNSIGNED"
00310 typename = "%s%d"%(type,size)
00311
00312 type_index = Manager.GetTypeIndex(typename, False)
00313 if type_index == None:
00314 raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Unrecognized type : %s"""%(name,index,typename)
00315
00316
00317 if "min_value" in attrs or "max_value" in attrs:
00318 if "min_value" in attrs and "max_value" in attrs:
00319 minValue = eval(attrs["min_value"])
00320 maxValue = eval(attrs["max_value"])
00321 if (minValue > maxValue):
00322 raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : error in value-range : min > max"""%(name,index)
00323 else:
00324 raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : You have defined only a min or a max value. \nIf you define one, you must define both."""%(name,index)
00325
00326 type_index = findRangeType(type_index, minValue, maxValue)
00327 if type_index == None:
00328 raise ValueError, """!!! Sorry, too many different value range have been defined"""
00329
00330
00331 if "size_in_byte" in attrs:
00332 size = eval(attrs["size_in_byte"])
00333 type_index = findStringType(Manager.GetTypeIndex("VISIBLE_STRING", False), size)
00334 if type_index == None:
00335 raise ValueError, """!!! Sorry, too many different string length have been defined"""
00336
00337 if "access" in attrs:
00338 access = attrs["access"].lower()
00339 else:
00340 access = "rw"
00341
00342 if index < 0x2000 or index > 0xBFFF:
00343 raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Variable can't be defined using this index-subindex."""%(name,index)
00344
00345 result = Node.AddMappingEntry(index, name = name, struct = 7)
00346 if not result:
00347 raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Unable to map because a variable or a table is using this index"""%(name,index)
00348 Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
00349 Node.AddMappingEntry(index, 1, values = {"name" : name, "type" : type_index, "access" : access, "pdo" : True, "nbmax" : number_elements})
00350
00351 for subIndex in xrange(1,number_elements+1):
00352 Node.AddEntry(index, subIndex, 0)
00353
00354 def findRangeType(type, minValue, maxValue):
00355 index = 0xA0
00356 while index < 0x100 and Node.IsEntry(index):
00357 current_type = Node.GetEntry(index, 1)
00358 if current_type == type:
00359 current_minValue = Node.GetEntry(index, 2)
00360 current_maxValue = Node.GetEntry(index, 3)
00361 if current_minValue == minValue and current_maxValue == maxValue:
00362 return index
00363 index += 1
00364 if index < 0x100:
00365 infos = Manager.GetEntryInfos(type, False)
00366 name = "%s[%d-%d]"%(infos["name"], minValue, maxValue)
00367 Node.AddMappingEntry(index, name = name, struct = 3, size = infos["size"], default = infos["default"])
00368 Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
00369 Node.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False})
00370 Node.AddMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False})
00371 Node.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False})
00372 Node.AddEntry(index, 1, type)
00373 Node.AddEntry(index, 2, minValue)
00374 Node.AddEntry(index, 3, maxValue)
00375 return index
00376 return None
00377
00378 def findStringType(type, length):
00379 index = 0xA0
00380 while index < 0x100 and Node.IsEntry(index):
00381 current_type = Node.GetEntry(index, 1)
00382 if current_type == type:
00383 current_length = Node.GetEntry(index, 2)
00384 if current_length == length:
00385 return index
00386 index += 1
00387 if index < 0x100:
00388 infos = Manager.GetEntryInfos(type, False)
00389 name = "%s%d"%(Manager.GetTypeName(type), length)
00390 Node.AddMappingEntry(index, name = name, struct = 3, size = infos["size"], default = infos["default"])
00391 Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False})
00392 Node.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False})
00393 Node.AddMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False})
00394 Node.AddEntry(index, 1, type)
00395 Node.AddEntry(index, 2, length)
00396 return index
00397 return None
00398
00399
00400
00401
00402
00403 def heartBeatProducer():
00404 Node.AddEntry(0x1017, 0, 0)
00405
00406 def startHeartBeatConsumers(attrs):
00407 nombre = eval(attrs["nombre"])
00408 for i in xrange(nombre):
00409 Node.AddEntry(0x1016, i + 1, 0)
00410
00411
00412
00413
00414
00415 def sdoServer():
00416 Node.AddEntry(0x1200, 1, 0x600 + Node.GetNodeID())
00417 Node.AddEntry(0x1200, 2, 0x580 + Node.GetNodeID())
00418
00419 def startSdoClients(attrs):
00420 nombre = eval(attrs["nombre"])
00421 for i in xrange(nombre):
00422 Node.AddEntry(0x1280 + i, 1, 0x600)
00423 Node.AddEntry(0x1280 + i, 2, 0x580)
00424 Node.AddEntry(0x1280 + i, 3, 0)
00425
00426
00427
00428
00429
00430 def ParseFile(filepath):
00431 xmlfile = open(filepath,"r")
00432 Parser = expat.ParserCreate()
00433 Parser.StartElementHandler = StartElement
00434 Parser.EndElementHandler = EndElement
00435 Parser.CharacterDataHandler = CharacterData
00436 ParserStatus = Parser.ParseFile(xmlfile)
00437 xmlfile.close()
00438
00439 def GenerateNode(filepath, manager):
00440 global Node
00441 global Manager
00442 Manager = manager
00443 Node = node.Node()
00444 ParseFile(filepath)
00445 return Node
00446
00447
00448
00449
00450
00451 if __name__ == '__main__':
00452 ParseFile("test.xml")
00453