author | Florian Pose <fp@igh-essen.com> |
Thu, 12 Jun 2008 07:15:54 +0000 | |
changeset 992 | 50a44cbd30af |
parent 937 | e2ee1bed5bd6 |
permissions | -rwxr-xr-x |
914 | 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 = \ |
|
937
e2ee1bed5bd6
Adapted to new entry syntax.
Florian Pose <fp@igh-essen.com>
parents:
915
diff
changeset
|
115 |
re.compile('0x([0-9A-F]+):([0-9A-F]+),\s+(\d+) bit,\s+"([^"]*)"') |
914 | 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), \ |
|
937
e2ee1bed5bd6
Adapted to new entry syntax.
Florian Pose <fp@igh-essen.com>
parents:
915
diff
changeset
|
142 |
int(match.group(2), 16), match.group(4), \ |
e2ee1bed5bd6
Adapted to new entry syntax.
Florian Pose <fp@igh-essen.com>
parents:
915
diff
changeset
|
143 |
int(match.group(3))) |
914 | 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) |
|
915 | 175 |
typeElement.setAttribute('RevisionNo', '#x%08x' % self.revision) |
914 | 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 |