1 #!/usr/bin/python |
|
2 |
|
3 #----------------------------------------------------------------------------- |
|
4 # |
|
5 # $Id$ |
|
6 # |
|
7 # Convert a slave information file to a slave description Xml. |
|
8 # |
|
9 #----------------------------------------------------------------------------- |
|
10 |
|
11 from xml.dom.minidom import Document |
|
12 import sys |
|
13 import re |
|
14 import os |
|
15 import getopt |
|
16 |
|
17 #----------------------------------------------------------------------------- |
|
18 |
|
19 infoFileName = 'info' |
|
20 |
|
21 #----------------------------------------------------------------------------- |
|
22 |
|
23 class PdoEntry: |
|
24 def __init__(self, index, subindex, name, bitlength): |
|
25 self.index = index |
|
26 self.subindex = subindex |
|
27 self.name = name |
|
28 self.bitlength = bitlength |
|
29 |
|
30 def toXml(self, doc, element): |
|
31 entryElement = doc.createElement('Entry') |
|
32 |
|
33 indexElement = doc.createElement('Index') |
|
34 indexText = doc.createTextNode('#x%04x' % self.index) |
|
35 indexElement.appendChild(indexText) |
|
36 entryElement.appendChild(indexElement) |
|
37 |
|
38 if (self.index != 0): |
|
39 subIndexElement = doc.createElement('SubIndex') |
|
40 subIndexText = doc.createTextNode(str(self.subindex)) |
|
41 subIndexElement.appendChild(subIndexText) |
|
42 entryElement.appendChild(subIndexElement) |
|
43 |
|
44 lengthElement = doc.createElement('BitLen') |
|
45 lengthText = doc.createTextNode(str(self.bitlength)) |
|
46 lengthElement.appendChild(lengthText) |
|
47 entryElement.appendChild(lengthElement) |
|
48 |
|
49 if (self.index != 0): |
|
50 nameElement = doc.createElement('Name') |
|
51 nameText = doc.createTextNode(self.name) |
|
52 nameElement.appendChild(nameText) |
|
53 entryElement.appendChild(nameElement) |
|
54 |
|
55 dataTypeElement = doc.createElement('DataType') |
|
56 dataTypeText = doc.createTextNode(self.dataType()) |
|
57 dataTypeElement.appendChild(dataTypeText) |
|
58 entryElement.appendChild(dataTypeElement) |
|
59 |
|
60 element.appendChild(entryElement) |
|
61 |
|
62 def dataType(self): |
|
63 if self.bitlength == 1: |
|
64 return 'BOOL' |
|
65 elif self.bitlength % 8 == 0: |
|
66 if self.bitlength <= 64: |
|
67 return 'UINT%u' % self.bitlength |
|
68 else: |
|
69 return 'STRING(%u)' % (self.bitlength / 8) |
|
70 else: |
|
71 assert False, 'Invalid bit length %u' % self.bitlength |
|
72 |
|
73 #----------------------------------------------------------------------------- |
|
74 |
|
75 class Pdo: |
|
76 def __init__(self, dir, index): |
|
77 self.dir = dir |
|
78 self.index = index |
|
79 self.entries = [] |
|
80 |
|
81 def appendEntry(self, entry): |
|
82 self.entries.append(entry) |
|
83 |
|
84 def toXml(self, doc, element): |
|
85 pdoElement = doc.createElement('%sxPdo' % self.dir) |
|
86 |
|
87 indexElement = doc.createElement('Index') |
|
88 indexText = doc.createTextNode('#x%04x' % self.index) |
|
89 indexElement.appendChild(indexText) |
|
90 pdoElement.appendChild(indexElement) |
|
91 |
|
92 nameElement = doc.createElement('Name') |
|
93 pdoElement.appendChild(nameElement) |
|
94 |
|
95 for e in self.entries: |
|
96 e.toXml(doc, pdoElement) |
|
97 |
|
98 element.appendChild(pdoElement) |
|
99 |
|
100 #----------------------------------------------------------------------------- |
|
101 |
|
102 class Device: |
|
103 def __init__(self): |
|
104 self.vendor = 0 |
|
105 self.product = 0 |
|
106 self.revision = 0 |
|
107 self.pdos = [] |
|
108 |
|
109 def parseInfoFile(self, fileName): |
|
110 reVendor = re.compile('Vendor ID:.*\((\d+)\)') |
|
111 reProduct = re.compile('Product code:.*\((\d+)\)') |
|
112 reRevision = re.compile('Revision number:.*\((\d+)\)') |
|
113 rePdo = re.compile('([RT])xPdo\s+0x([0-9A-F]+)') |
|
114 rePdoEntry = \ |
|
115 re.compile('0x([0-9A-F]+):([0-9A-F]+),\s+(\d+) bit,\s+"([^"]*)"') |
|
116 pdo = None |
|
117 f = open(fileName, 'r') |
|
118 while True: |
|
119 line = f.readline() |
|
120 if not line: break |
|
121 |
|
122 match = reVendor.search(line) |
|
123 if match: |
|
124 self.vendor = int(match.group(1)) |
|
125 |
|
126 match = reProduct.search(line) |
|
127 if match: |
|
128 self.product = int(match.group(1)) |
|
129 |
|
130 match = reRevision.search(line) |
|
131 if match: |
|
132 self.revision = int(match.group(1)) |
|
133 |
|
134 match = rePdo.search(line) |
|
135 if match: |
|
136 pdo = Pdo(match.group(1), int(match.group(2), 16)) |
|
137 self.pdos.append(pdo) |
|
138 |
|
139 match = rePdoEntry.search(line) |
|
140 if match: |
|
141 pdoEntry = PdoEntry(int(match.group(1), 16), \ |
|
142 int(match.group(2), 16), match.group(4), \ |
|
143 int(match.group(3))) |
|
144 pdo.appendEntry(pdoEntry) |
|
145 |
|
146 f.close() |
|
147 |
|
148 def toXmlDocument(self): |
|
149 doc = Document() |
|
150 |
|
151 rootElement = doc.createElement('EtherCATInfo') |
|
152 doc.appendChild(rootElement) |
|
153 |
|
154 vendorElement = doc.createElement('Vendor') |
|
155 rootElement.appendChild(vendorElement) |
|
156 |
|
157 vendorIdElement = doc.createElement('Id') |
|
158 |
|
159 idText = doc.createTextNode(str(self.vendor)) |
|
160 vendorIdElement.appendChild(idText) |
|
161 |
|
162 vendorElement.appendChild(vendorIdElement) |
|
163 |
|
164 descriptionsElement = doc.createElement('Descriptions') |
|
165 rootElement.appendChild(descriptionsElement) |
|
166 |
|
167 devicesElement = doc.createElement('Devices') |
|
168 descriptionsElement.appendChild(devicesElement) |
|
169 |
|
170 deviceElement = doc.createElement('Device') |
|
171 devicesElement.appendChild(deviceElement) |
|
172 |
|
173 typeElement = doc.createElement('Type') |
|
174 typeElement.setAttribute('ProductCode', '#x%08x' % self.product) |
|
175 typeElement.setAttribute('RevisionNo', '#x%08x' % self.revision) |
|
176 deviceElement.appendChild(typeElement) |
|
177 |
|
178 for p in self.pdos: |
|
179 p.toXml(doc, deviceElement) |
|
180 |
|
181 return doc |
|
182 |
|
183 #----------------------------------------------------------------------------- |
|
184 |
|
185 def usage(): |
|
186 print """slaveinfo2xml.py [OPTIONS] [FILE] |
|
187 File defaults to 'info'. |
|
188 Options: |
|
189 -h Print this help.""" |
|
190 |
|
191 #----------------------------------------------------------------------------- |
|
192 |
|
193 try: |
|
194 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) |
|
195 except getopt.GetoptError, err: |
|
196 print str(err) |
|
197 usage() |
|
198 sys.exit(2) |
|
199 |
|
200 if len(args) > 1: |
|
201 print "Only one argument allowed!" |
|
202 usage() |
|
203 sys.exit(2) |
|
204 elif len(args) == 1: |
|
205 infoFileName = args[0] |
|
206 |
|
207 for o, a in opts: |
|
208 if o in ("-h", "--help"): |
|
209 usage() |
|
210 sys.exit() |
|
211 else: |
|
212 assert False, "unhandled option" |
|
213 |
|
214 d = Device() |
|
215 d.parseInfoFile(infoFileName) |
|
216 doc = d.toXmlDocument() |
|
217 |
|
218 # Print our newly created XML |
|
219 print doc.toprettyxml(indent=' ') |
|
220 |
|
221 #----------------------------------------------------------------------------- |
|
222 |
|