44 |
44 |
45 string CommandPhyRead::helpString() const |
45 string CommandPhyRead::helpString() const |
46 { |
46 { |
47 stringstream str; |
47 stringstream str; |
48 |
48 |
49 str << getName() << " [OPTIONS] <OFFSET> <LENGTH>" << endl |
49 str << getName() << " [OPTIONS] <OFFSET> [LENGTH]" << endl |
50 << endl |
50 << endl |
51 << getBriefDescription() << endl |
51 << getBriefDescription() << endl |
52 << endl |
52 << endl |
53 << "This command requires a single slave to be selected." << endl |
53 << "This command requires a single slave to be selected." << endl |
54 << endl |
54 << endl |
55 << "Arguments:" << endl |
55 << "Arguments:" << endl |
56 << " OFFSET is the physical memory address. Must" << endl |
56 << " OFFSET is the physical memory address. Must" << endl |
57 << " be an unsigned 16 bit number." << endl |
57 << " be an unsigned 16 bit number." << endl |
58 << " LENGTH is the number of bytes to read and must also be" << endl |
58 << " LENGTH is the number of bytes to read and must also be" << endl |
59 << " an unsigned 16 bit number. OFFSET plus LENGTH" << endl |
59 << " an unsigned 16 bit number. OFFSET plus LENGTH" << endl |
60 << " may not exceed 64k." << endl |
60 << " may not exceed 64k. The length is ignored (and" << endl |
|
61 << " can be omitted), if a selected data type" << endl |
|
62 << " implies a length." << endl |
|
63 << endl |
|
64 << "These are the valid data types:" << endl |
|
65 << " int8, int16, int32, int64, uint8, uint16, uint32," << endl |
|
66 << " uint64, string, octet_string, raw." << endl |
61 << endl |
67 << endl |
62 << "Command-specific options:" << endl |
68 << "Command-specific options:" << endl |
63 << " --alias -a <alias>" << endl |
69 << " --alias -a <alias>" << endl |
64 << " --position -p <pos> Slave selection. See the help of" << endl |
70 << " --position -p <pos> Slave selection. See the help of" << endl |
65 << " the 'slaves' command." << endl |
71 << " the 'slaves' command." << endl |
|
72 << " --type -t <type> Data type (see above)." << endl |
66 << endl |
73 << endl |
67 << numericInfo(); |
74 << numericInfo(); |
68 |
75 |
69 return str.str(); |
76 return str.str(); |
70 } |
77 } |
73 |
80 |
74 void CommandPhyRead::execute(MasterDevice &m, const StringVector &args) |
81 void CommandPhyRead::execute(MasterDevice &m, const StringVector &args) |
75 { |
82 { |
76 SlaveList slaves; |
83 SlaveList slaves; |
77 ec_ioctl_slave_phy_t data; |
84 ec_ioctl_slave_phy_t data; |
78 stringstream strOffset, strLength, err; |
85 stringstream strOffset, err; |
79 uint16_t i; |
86 const DataType *dataType = NULL; |
80 |
87 |
81 if (args.size() != 2) { |
88 if (args.size() < 1 || args.size() > 2) { |
82 err << "'" << getName() << "' takes two arguments!"; |
89 err << "'" << getName() << "' takes one or two arguments!"; |
83 throwInvalidUsageException(err); |
90 throwInvalidUsageException(err); |
84 } |
91 } |
85 |
92 |
86 strOffset << args[0]; |
93 strOffset << args[0]; |
87 strOffset |
94 strOffset |
90 if (strOffset.fail()) { |
97 if (strOffset.fail()) { |
91 err << "Invalid offset '" << args[0] << "'!"; |
98 err << "Invalid offset '" << args[0] << "'!"; |
92 throwInvalidUsageException(err); |
99 throwInvalidUsageException(err); |
93 } |
100 } |
94 |
101 |
95 strLength << args[1]; |
102 if (args.size() > 1) { |
96 strLength |
103 stringstream strLength; |
97 >> resetiosflags(ios::basefield) // guess base from prefix |
104 strLength << args[1]; |
98 >> data.length; |
105 strLength |
99 if (strLength.fail()) { |
106 >> resetiosflags(ios::basefield) // guess base from prefix |
100 err << "Invalid length '" << args[1] << "'!"; |
107 >> data.length; |
101 throwInvalidUsageException(err); |
108 if (strLength.fail()) { |
|
109 err << "Invalid length '" << args[1] << "'!"; |
|
110 throwInvalidUsageException(err); |
|
111 } |
|
112 |
|
113 if (!data.length) { |
|
114 err << "Length may not be zero!"; |
|
115 throwInvalidUsageException(err); |
|
116 } |
|
117 } else { // no length argument given |
|
118 data.length = 0; |
|
119 } |
|
120 |
|
121 if (!getDataType().empty()) { |
|
122 if (!(dataType = findDataType(getDataType()))) { |
|
123 err << "Invalid data type '" << getDataType() << "'!"; |
|
124 throwInvalidUsageException(err); |
|
125 } |
|
126 |
|
127 if (dataType->byteSize) { |
|
128 // override length argument |
|
129 data.length = dataType->byteSize; |
|
130 } |
102 } |
131 } |
103 |
132 |
104 if (!data.length) { |
133 if (!data.length) { |
105 return; |
134 err << "The length argument is mandatory, if no datatype is " << endl |
|
135 << "specified, or the datatype does not imply a length!"; |
|
136 throwInvalidUsageException(err); |
106 } |
137 } |
107 |
138 |
108 if ((uint32_t) data.offset + data.length > 0xffff) { |
139 if ((uint32_t) data.offset + data.length > 0xffff) { |
109 err << "Offset and length exceeding 64k!"; |
140 err << "Offset and length exceeding 64k!"; |
110 throwInvalidUsageException(err); |
141 throwInvalidUsageException(err); |
125 } catch (MasterDeviceException &e) { |
156 } catch (MasterDeviceException &e) { |
126 delete [] data.data; |
157 delete [] data.data; |
127 throw e; |
158 throw e; |
128 } |
159 } |
129 |
160 |
130 for (i = 0; i < data.length; i++) { |
161 cout << setfill('0'); |
131 cout << data.data[i]; |
162 if (!dataType || |
|
163 dataType->name == "string" || |
|
164 dataType->name == "octet_string") { |
|
165 uint16_t i; |
|
166 for (i = 0; i < data.length; i++) { |
|
167 cout << data.data[i]; |
|
168 } |
|
169 } else if (dataType->name == "int8") { |
|
170 int sval = *(int8_t *) data.data; |
|
171 cout << sval << " 0x" << hex << setw(2) << sval << endl; |
|
172 } else if (dataType->name == "int16") { |
|
173 int sval = le16_to_cpup(data.data); |
|
174 cout << sval << " 0x" << hex << setw(4) << sval << endl; |
|
175 } else if (dataType->name == "int32") { |
|
176 int sval = le32_to_cpup(data.data); |
|
177 cout << sval << " 0x" << hex << setw(8) << sval << endl; |
|
178 } else if (dataType->name == "int64") { |
|
179 long long int sval = le64_to_cpup(data.data); |
|
180 cout << sval << " 0x" << hex << setw(16) << sval << endl; |
|
181 } else if (dataType->name == "uint8") { |
|
182 unsigned int uval = (unsigned int) *(uint8_t *) data.data; |
|
183 cout << uval << " 0x" << hex << setw(2) << uval << endl; |
|
184 } else if (dataType->name == "uint16") { |
|
185 unsigned int uval = le16_to_cpup(data.data); |
|
186 cout << uval << " 0x" << hex << setw(4) << uval << endl; |
|
187 } else if (dataType->name == "uint32") { |
|
188 unsigned int uval = le32_to_cpup(data.data); |
|
189 cout << uval << " 0x" << hex << setw(8) << uval << endl; |
|
190 } else if (dataType->name == "uint64") { |
|
191 long long unsigned int uval = le32_to_cpup(data.data); |
|
192 cout << uval << " 0x" << hex << setw(8) << uval << endl; |
|
193 } else { |
|
194 uint8_t *d = data.data; |
|
195 unsigned int size = data.length; |
|
196 |
|
197 cout << hex << setfill('0'); |
|
198 while (size--) { |
|
199 cout << "0x" << setw(2) << (unsigned int) *d++; |
|
200 if (size) |
|
201 cout << " "; |
|
202 } |
|
203 cout << endl; |
132 } |
204 } |
133 |
205 |
134 delete [] data.data; |
206 delete [] data.data; |
135 } |
207 } |
136 |
208 |
|
209 /****************************************************************************/ |
|
210 |
|
211 const CommandPhyRead::DataType *CommandPhyRead::findDataType( |
|
212 const string &str |
|
213 ) |
|
214 { |
|
215 const DataType *d; |
|
216 |
|
217 for (d = dataTypes; d->name; d++) |
|
218 if (str == d->name) |
|
219 return d; |
|
220 |
|
221 return NULL; |
|
222 } |
|
223 |
|
224 /****************************************************************************/ |
|
225 |
|
226 const CommandPhyRead::DataType CommandPhyRead::dataTypes[] = { |
|
227 {"int8", 1}, |
|
228 {"int16", 2}, |
|
229 {"int32", 4}, |
|
230 {"int64", 8}, |
|
231 {"uint8", 1}, |
|
232 {"uint16", 2}, |
|
233 {"uint32", 4}, |
|
234 {"uint64", 8}, |
|
235 {"string", 0}, |
|
236 {"octet_string", 0}, |
|
237 {"raw", 0}, |
|
238 {} |
|
239 }; |
|
240 |
137 /*****************************************************************************/ |
241 /*****************************************************************************/ |