51 str << getName() << " [OPTIONS] <OFFSET> <DATA>" << endl |
51 str << getName() << " [OPTIONS] <OFFSET> <DATA>" << endl |
52 << endl |
52 << endl |
53 << getBriefDescription() << endl |
53 << getBriefDescription() << endl |
54 << endl |
54 << endl |
55 << "This command requires a single slave to be selected." << endl |
55 << "This command requires a single slave to be selected." << endl |
56 << endl |
56 << endl |
57 << "Arguments:" << endl |
57 << "Arguments:" << endl |
58 << " OFFSET is the register address to write to." << endl |
58 << " OFFSET is the register address to write to." << endl |
59 << " DATA depends on whether a datatype was specified" << endl |
59 << " DATA depends on whether a datatype was specified" << endl |
60 << " with the --type option: If not, DATA must be" << endl |
60 << " with the --type option: If not, DATA must be" << endl |
61 << " either a path to a file with data to write," << endl |
61 << " either a path to a file with data to write," << endl |
62 << " or '-', which means, that data are read from" << endl |
62 << " or '-', which means, that data are read from" << endl |
63 << " stdin. If a datatype was specified, VALUE is" << endl |
63 << " stdin. If a datatype was specified, VALUE is" << endl |
64 << " interpreted respective to the given type." << endl |
64 << " interpreted respective to the given type." << endl |
65 << endl |
65 << endl |
66 << "These are the valid data types:" << endl |
66 << "These are the valid data types:" << endl |
67 << " int8, int16, int32, int64, uint8, uint16, uint32," << endl |
67 << " int8, int16, int32, int64, uint8, uint16, uint32," << endl |
68 << " uint64, string." << endl |
68 << " uint64, string." << endl |
69 << endl |
69 << endl |
70 << "Command-specific options:" << endl |
70 << "Command-specific options:" << endl |
71 << " --alias -a <alias>" << endl |
71 << " --alias -a <alias>" << endl |
72 << " --position -p <pos> Slave selection. See the help of" << endl |
72 << " --position -p <pos> Slave selection. See the help of" << endl |
73 << " the 'slaves' command." << endl |
73 << " the 'slaves' command." << endl |
74 << " --type -t <type> Data type (see above)." << endl |
74 << " --type -t <type> Data type (see above)." << endl |
99 if (strOffset.fail()) { |
99 if (strOffset.fail()) { |
100 err << "Invalid offset '" << args[0] << "'!"; |
100 err << "Invalid offset '" << args[0] << "'!"; |
101 throwInvalidUsageException(err); |
101 throwInvalidUsageException(err); |
102 } |
102 } |
103 |
103 |
104 if (getDataType().empty()) { |
104 if (getDataType().empty()) { |
105 if (args[1] == "-") { |
105 if (args[1] == "-") { |
106 loadRegData(&data, cin); |
106 loadRegData(&data, cin); |
107 } else { |
107 } else { |
108 file.open(args[1].c_str(), ifstream::in | ifstream::binary); |
108 file.open(args[1].c_str(), ifstream::in | ifstream::binary); |
109 if (file.fail()) { |
109 if (file.fail()) { |
110 err << "Failed to open '" << args[1] << "'!"; |
110 err << "Failed to open '" << args[1] << "'!"; |
111 throwCommandException(err); |
111 throwCommandException(err); |
112 } |
112 } |
113 loadRegData(&data, file); |
113 loadRegData(&data, file); |
114 file.close(); |
114 file.close(); |
115 } |
115 } |
116 } else { |
116 } else { |
117 stringstream strValue; |
117 stringstream strValue; |
118 const DataType *dataType = findDataType(getDataType()); |
118 const DataType *dataType = findDataType(getDataType()); |
119 |
119 |
120 if (!dataType) { |
120 if (!dataType) { |
121 err << "Invalid data type '" << getDataType() << "'!"; |
121 err << "Invalid data type '" << getDataType() << "'!"; |
122 throwInvalidUsageException(err); |
122 throwInvalidUsageException(err); |
123 } |
123 } |
124 |
124 |
125 if (dataType->byteSize) { |
125 if (dataType->byteSize) { |
126 data.length = dataType->byteSize; |
126 data.length = dataType->byteSize; |
127 data.data = new uint8_t[data.length]; |
127 data.data = new uint8_t[data.length]; |
128 } |
128 } |
129 |
129 |
130 strValue << args[1]; |
130 strValue << args[1]; |
131 strValue >> resetiosflags(ios::basefield); // guess base from prefix |
131 strValue >> resetiosflags(ios::basefield); // guess base from prefix |
132 strValue.exceptions(ios::failbit); |
132 strValue.exceptions(ios::failbit); |
133 |
133 |
134 try { |
134 try { |
135 if (string(dataType->name) == "int8") { |
135 if (string(dataType->name) == "int8") { |
136 int16_t val; // uint8_t is interpreted as char |
136 int16_t val; // uint8_t is interpreted as char |
137 strValue >> val; |
137 strValue >> val; |
138 if (val > 127 || val < -128) |
138 if (val > 127 || val < -128) |
139 throw ios::failure("Value out of range"); |
139 throw ios::failure("Value out of range"); |
140 *data.data = (int8_t) val; |
140 *data.data = (int8_t) val; |
141 } else if (string(dataType->name) == "int16") { |
141 } else if (string(dataType->name) == "int16") { |
142 int16_t val; |
142 int16_t val; |
143 strValue >> val; |
143 strValue >> val; |
144 *(int16_t *) data.data = cpu_to_le16(val); |
144 *(int16_t *) data.data = cpu_to_le16(val); |
145 } else if (string(dataType->name) == "int32") { |
145 } else if (string(dataType->name) == "int32") { |
146 int32_t val; |
146 int32_t val; |
147 strValue >> val; |
147 strValue >> val; |
148 *(int32_t *) data.data = cpu_to_le32(val); |
148 *(int32_t *) data.data = cpu_to_le32(val); |
149 } else if (string(dataType->name) == "int64") { |
149 } else if (string(dataType->name) == "int64") { |
150 int64_t val; |
150 int64_t val; |
151 strValue >> val; |
151 strValue >> val; |
152 *(int64_t *) data.data = cpu_to_le64(val); |
152 *(int64_t *) data.data = cpu_to_le64(val); |
153 } else if (string(dataType->name) == "uint8") { |
153 } else if (string(dataType->name) == "uint8") { |
154 uint16_t val; // uint8_t is interpreted as char |
154 uint16_t val; // uint8_t is interpreted as char |
155 strValue >> val; |
155 strValue >> val; |
156 if (val > 0xff) |
156 if (val > 0xff) |
157 throw ios::failure("Value out of range"); |
157 throw ios::failure("Value out of range"); |
158 *data.data = (uint8_t) val; |
158 *data.data = (uint8_t) val; |
159 } else if (string(dataType->name) == "uint16") { |
159 } else if (string(dataType->name) == "uint16") { |
160 uint16_t val; |
160 uint16_t val; |
161 strValue >> val; |
161 strValue >> val; |
162 *(uint16_t *) data.data = cpu_to_le16(val); |
162 *(uint16_t *) data.data = cpu_to_le16(val); |
163 } else if (string(dataType->name) == "uint32") { |
163 } else if (string(dataType->name) == "uint32") { |
164 uint32_t val; |
164 uint32_t val; |
165 strValue >> val; |
165 strValue >> val; |
166 *(uint32_t *) data.data = cpu_to_le32(val); |
166 *(uint32_t *) data.data = cpu_to_le32(val); |
167 } else if (string(dataType->name) == "uint64") { |
167 } else if (string(dataType->name) == "uint64") { |
168 uint64_t val; |
168 uint64_t val; |
169 strValue >> val; |
169 strValue >> val; |
170 *(uint64_t *) data.data = cpu_to_le64(val); |
170 *(uint64_t *) data.data = cpu_to_le64(val); |
171 } else if (string(dataType->name) == "string" || |
171 } else if (string(dataType->name) == "string" || |
172 string(dataType->name) == "octet_string") { |
172 string(dataType->name) == "octet_string") { |
173 data.length = strValue.str().size(); |
173 data.length = strValue.str().size(); |
174 if (!data.length) { |
174 if (!data.length) { |
175 err << "Zero-size string now allowed!"; |
175 err << "Zero-size string now allowed!"; |
176 throwCommandException(err); |
176 throwCommandException(err); |
177 } |
177 } |
178 data.data = new uint8_t[data.length]; |
178 data.data = new uint8_t[data.length]; |
179 strValue >> (char *) data.data; |
179 strValue >> (char *) data.data; |
180 } else { |
180 } else { |
181 err << "Invalid data type " << dataType->name; |
181 err << "Invalid data type " << dataType->name; |
182 throwCommandException(err); |
182 throwCommandException(err); |
183 } |
183 } |
184 } catch (ios::failure &e) { |
184 } catch (ios::failure &e) { |
185 delete [] data.data; |
185 delete [] data.data; |
186 err << "Invalid value argument '" << args[1] |
186 err << "Invalid value argument '" << args[1] |
187 << "' for type '" << dataType->name << "'!"; |
187 << "' for type '" << dataType->name << "'!"; |
188 throwInvalidUsageException(err); |
188 throwInvalidUsageException(err); |
189 } |
189 } |
190 } |
190 } |
191 |
191 |
192 if ((uint32_t) data.offset + data.length > 0xffff) { |
192 if ((uint32_t) data.offset + data.length > 0xffff) { |
193 err << "Offset and length exceeding 64k!"; |
193 err << "Offset and length exceeding 64k!"; |
194 delete [] data.data; |
194 delete [] data.data; |
195 throwInvalidUsageException(err); |
195 throwInvalidUsageException(err); |