ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
testDummyRegisterAccessor.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
7#include "DummyBackend.h"
9
10#include <boost/bind/bind.hpp>
11#include <boost/date_time/posix_time/posix_time.hpp>
12#include <boost/function.hpp>
13#include <boost/lambda/lambda.hpp>
14#include <boost/make_shared.hpp>
15
16#include <math.h>
17
18#include <algorithm>
19
20using namespace boost::unit_test_framework;
21using namespace ChimeraTK;
22
23#define TEST_MAPPING_FILE "testDummyRegisterAccessors.map"
24#define INVALID_MAPPING_FILE "invalidSequences.map"
25
26// Test implementation of the dummy backend with two accessors
29 public:
30 explicit TestableDummyBackend(std::string mapFileName)
31 : DummyBackend(mapFileName), someRegister(this, "APP0", "SOME_REGISTER"),
32 someMuxedRegister(this, "APP0", "DAQ0_ADCA") {}
33
36
37 friend class DummyRegisterTest;
38};
39
40// Test implementation of the dummy backend for the invalid map file
42 public:
43 explicit InvalidDummyBackend(std::string mapFileName)
44 : DummyBackend(mapFileName), invalidRegister(this, "INVALID", "NO_WORDS") {}
45
47
48 friend class DummyRegisterTest;
49};
50
51/**********************************************************************************************************************/
53 public:
54 DummyRegisterTest() { device = boost::shared_ptr<TestableDummyBackend>(new TestableDummyBackend(TEST_MAPPING_FILE)); }
55
57 void testExceptions();
58
61
64
65 private:
66 boost::shared_ptr<TestableDummyBackend> device;
68};
69
70/**********************************************************************************************************************/
71class DummyRegisterTestSuite : public test_suite {
72 public:
73 DummyRegisterTestSuite() : test_suite("DummyRegister test suite") {
74 boost::shared_ptr<DummyRegisterTest> dummyDeviceTest(new DummyRegisterTest);
75
76 add(BOOST_CLASS_TEST_CASE(&DummyRegisterTest::testRegisterAccessor, dummyDeviceTest));
77 add(BOOST_CLASS_TEST_CASE(&DummyRegisterTest::testMuxedRegisterAccessor, dummyDeviceTest));
78 add(BOOST_CLASS_TEST_CASE(&DummyRegisterTest::testExceptions, dummyDeviceTest));
79 }
80};
81
82/**********************************************************************************************************************/
84 framework::master_test_suite().p_name.value = "DummyRegister test suite";
85 framework::master_test_suite().add(new DummyRegisterTestSuite);
86
87 return true;
88}
89
90/**********************************************************************************************************************/
92 std::cout << "testExceptions" << std::endl;
93
95}
96
97/**********************************************************************************************************************/
99 std::cout << "testRegisterAccessor" << std::endl;
100
101 // open the device
102 device->open();
103
104 // check number of elements getter
105 BOOST_CHECK(device->someRegister.getNumberOfElements() == 10);
106
107 // test operator=
108 device->someRegister = 3;
109 BOOST_CHECK(device->_barContents[1][0] == 3);
110
111 // test operator[] on r.h.s.
112 device->_barContents[1][0] = 5;
113 device->_barContents[1][3] = 77;
114 BOOST_CHECK(device->someRegister[0] == 5);
115 BOOST_CHECK(device->someRegister[3] == 77);
116
117 // test operator[] on l.h.s.
118 device->someRegister[0] = 666;
119 device->someRegister[9] = 999;
120 BOOST_CHECK(device->_barContents[1][0] == 666);
121 BOOST_CHECK(device->_barContents[1][9] == 999);
122 device->someRegister[1] = 111;
123 device->someRegister[2] = 222;
124 device->someRegister[3] = 333;
125 device->someRegister[4] = 444;
126 BOOST_CHECK(device->_barContents[1][1] == 111);
127 BOOST_CHECK(device->_barContents[1][2] == 222);
128 BOOST_CHECK(device->_barContents[1][3] == 333);
129 BOOST_CHECK(device->_barContents[1][4] == 444);
130
131 // test increment and decrement operators
132 BOOST_CHECK(device->someRegister[1]++ == 111);
133 BOOST_CHECK(device->someRegister[2]-- == 222);
134 BOOST_CHECK(++device->someRegister[3] == 334);
135 BOOST_CHECK(--device->someRegister[4] == 443);
136 BOOST_CHECK(device->_barContents[1][1] == 112);
137 BOOST_CHECK(device->_barContents[1][2] == 221);
138 BOOST_CHECK(device->_barContents[1][3] == 334);
139 BOOST_CHECK(device->_barContents[1][4] == 443);
140
141 // close the device
142 device->close();
143}
144
145/**********************************************************************************************************************/
147 std::cout << "testMuxedRegisterAccessor" << std::endl;
148
149 // open the device
150 device->open();
151
152 // check number of elements getter
153 BOOST_CHECK(device->someMuxedRegister.getNumberOfElements() == 4096);
154 BOOST_CHECK(device->someMuxedRegister.getNumberOfSequences() == 16);
155
156 // the area offset is 1000 bytes. When addressing the index of the 32 bit word
157 // in the bar, we have to divide by 4
158 static const int areaIndexOffset = 1000 / 4;
159
160 // since our register does not have a fixed type, we use this union/struct to
161 // fill the bar content directly the packed attribute prevents the compiler
162 // from adding a padding between the struct fields
163 union _mixedReg {
164 struct _cooked {
165 int32_t r0;
166 int16_t r1;
167 int16_t r2;
168 int8_t r3;
169 int8_t r4;
170 int32_t r5;
171 int16_t r6;
172 int32_t r7;
173 int32_t r8;
174 int32_t r9;
175 int32_t r10;
176 int32_t r11;
177 int32_t r12;
178 int32_t r13;
179 int32_t r14;
180 uint32_t r15;
181 } __attribute__((packed)) cooked;
182 int32_t raw[13];
183 } mixedReg;
184
185 int pitch = sizeof(mixedReg.raw);
186
187 // fill the register
188 mixedReg.cooked.r0 = 42;
189 mixedReg.cooked.r1 = 120;
190 mixedReg.cooked.r2 = 222;
191 mixedReg.cooked.r3 = -110;
192 mixedReg.cooked.r4 = 1;
193 mixedReg.cooked.r5 = 33;
194 mixedReg.cooked.r6 = 6;
195 mixedReg.cooked.r7 = 7;
196 mixedReg.cooked.r8 = 8;
197 mixedReg.cooked.r9 = 9;
198 mixedReg.cooked.r10 = 10;
199 mixedReg.cooked.r11 = 11;
200 mixedReg.cooked.r12 = 12;
201 mixedReg.cooked.r13 = 13;
202 mixedReg.cooked.r14 = 14;
203 mixedReg.cooked.r15 = 15;
204 for(int i = 0; i < 13; i++) device->_barContents[0xD][areaIndexOffset + i] = mixedReg.raw[i];
205
206 // test the test, to be sure the union is not going wrong
207 BOOST_CHECK((int)((char*)&(mixedReg.cooked.r5) - (char*)&(mixedReg.cooked.r0)) == 10);
208 BOOST_CHECK((int)((char*)&(mixedReg.cooked.r10) - (char*)&(mixedReg.cooked.r0)) == 28);
209 BOOST_CHECK((int)((char*)&(mixedReg.cooked.r15) - (char*)&(mixedReg.cooked.r0)) == pitch - 4);
210 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + 0] == 42);
211 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + 1] == 120 + 0x10000 * 222);
212 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + 9] == 12);
213 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + 12] == 15);
214
215 mixedReg.cooked.r0 = 1;
216 mixedReg.cooked.r1 = 11;
217 mixedReg.cooked.r2 = 22;
218 mixedReg.cooked.r3 = 33;
219 mixedReg.cooked.r4 = 0;
220 mixedReg.cooked.r5 = 55;
221 mixedReg.cooked.r6 = 66;
222 mixedReg.cooked.r7 = 77;
223 mixedReg.cooked.r8 = 88;
224 mixedReg.cooked.r9 = 99;
225 mixedReg.cooked.r10 = 100;
226 mixedReg.cooked.r11 = 111;
227 mixedReg.cooked.r12 = 222;
228 mixedReg.cooked.r13 = 333;
229 mixedReg.cooked.r14 = 444;
230 mixedReg.cooked.r15 = 555;
231 for(int i = 0; i < 13; i++) device->_barContents[0xD][areaIndexOffset + pitch / 4 + i] = mixedReg.raw[i];
232
233 // test the test, to be sure the union is not going wrong
234 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + pitch / 4 + 0] == 1);
235 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + pitch / 4 + 1] == 11 + 0x10000 * 22);
236 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + pitch / 4 + 9] == 222);
237 BOOST_CHECK(device->_barContents[0xD][areaIndexOffset + pitch / 4 + 12] == 555);
238
239 // fill the rest of the register (has 4096 samples per channel)
240 for(int i = 2; i < 4096; i++) {
241 mixedReg.cooked.r0 = i + 0;
242 mixedReg.cooked.r1 = i + 1;
243 mixedReg.cooked.r2 = i + 2;
244 mixedReg.cooked.r3 = i + 3;
245 mixedReg.cooked.r4 = i + 4;
246 mixedReg.cooked.r5 = i + 5;
247 mixedReg.cooked.r6 = i + 6;
248 mixedReg.cooked.r7 = i + 7;
249 mixedReg.cooked.r8 = i + 8;
250 mixedReg.cooked.r9 = i + 9;
251 mixedReg.cooked.r10 = i + 10;
252 mixedReg.cooked.r11 = i + 11;
253 mixedReg.cooked.r12 = i + 12;
254 mixedReg.cooked.r13 = i + 13;
255 mixedReg.cooked.r14 = i + 14;
256 mixedReg.cooked.r15 = i + 15;
257 for(int k = 0; k < 13; k++) device->_barContents[0xD][areaIndexOffset + i * (pitch / 4) + k] = mixedReg.raw[k];
258 }
259
260 // test reading by [][] operator
261 BOOST_CHECK(device->someMuxedRegister[0][0] == 42);
262 BOOST_CHECK(device->someMuxedRegister[1][0] == 120);
263 BOOST_CHECK(device->someMuxedRegister[2][0] == 222);
264 BOOST_CHECK(device->someMuxedRegister[3][0] == -110);
265 BOOST_CHECK(device->someMuxedRegister[4][0] == 1);
266 BOOST_CHECK(device->someMuxedRegister[5][0] == 33);
267 BOOST_CHECK(device->someMuxedRegister[6][0] == 6);
268 BOOST_CHECK(device->someMuxedRegister[7][0] == 7);
269 BOOST_CHECK(device->someMuxedRegister[8][0] == 8);
270 BOOST_CHECK(device->someMuxedRegister[9][0] == 9);
271 BOOST_CHECK(device->someMuxedRegister[10][0] == 10);
272 BOOST_CHECK(device->someMuxedRegister[11][0] == 11);
273 BOOST_CHECK(device->someMuxedRegister[12][0] == 12);
274 BOOST_CHECK(device->someMuxedRegister[13][0] == 13);
275 BOOST_CHECK(device->someMuxedRegister[14][0] == 14);
276 BOOST_CHECK(device->someMuxedRegister[15][0] == 15);
277
278 BOOST_CHECK(device->someMuxedRegister[0][1] == 1);
279 BOOST_CHECK(device->someMuxedRegister[1][1] == 11);
280 BOOST_CHECK(device->someMuxedRegister[2][1] == 22);
281 BOOST_CHECK(device->someMuxedRegister[3][1] == 33);
282 BOOST_CHECK(device->someMuxedRegister[4][1] == 0);
283 BOOST_CHECK(device->someMuxedRegister[5][1] == 55);
284 BOOST_CHECK(device->someMuxedRegister[6][1] == 66);
285 BOOST_CHECK(device->someMuxedRegister[7][1] == 77);
286 BOOST_CHECK(device->someMuxedRegister[8][1] == 88);
287 BOOST_CHECK(device->someMuxedRegister[9][1] == 99);
288 BOOST_CHECK(device->someMuxedRegister[10][1] == 100);
289 BOOST_CHECK(device->someMuxedRegister[11][1] == 111);
290 BOOST_CHECK(device->someMuxedRegister[12][1] == 222);
291 BOOST_CHECK(device->someMuxedRegister[13][1] == 333);
292 BOOST_CHECK(device->someMuxedRegister[14][1] == 444);
293 BOOST_CHECK(device->someMuxedRegister[15][1] == 555);
294
295 for(int i = 2; i < 65536 / 16; i++) {
296 for(int k = 0; k < 16; k++) {
297 int expectedValue = i + k;
298 void* ptr = (void*)&expectedValue;
299 if(k == 1 || k == 2 || k == 6) { // 16 bit
300 expectedValue = *(reinterpret_cast<int16_t*>(ptr));
301 }
302 else if(k == 3) { // 8 bit
303 expectedValue = *(reinterpret_cast<int8_t*>(ptr));
304 }
305 else if(k == 4) { // 1 bit
306 expectedValue = expectedValue & 0x1;
307 }
308 else if(k == 7) { // 24 bit
309 expectedValue = expectedValue & 0xFFFFFF;
310 }
311 std::stringstream message;
312 message << "someMuxedRegister[" << k << "][" << i << "] == " << device->someMuxedRegister[k][i] << " but "
313 << expectedValue << " expected.";
314 BOOST_CHECK_MESSAGE(device->someMuxedRegister[k][i] == expectedValue, message.str());
315 }
316 }
317
318 // test writing by [][] operator
319 device->someMuxedRegister[0][0] = 666;
320 device->someMuxedRegister[1][0] = 999;
321 device->someMuxedRegister[2][0] = 222;
322 device->someMuxedRegister[3][0] = -111;
323 device->someMuxedRegister[4][0] = 0;
324 device->someMuxedRegister[5][0] = 555;
325 device->someMuxedRegister[6][0] = 666;
326 device->someMuxedRegister[7][0] = 777;
327 device->someMuxedRegister[8][0] = 888;
328 device->someMuxedRegister[9][0] = 999;
329 device->someMuxedRegister[10][0] = 1111;
330 device->someMuxedRegister[11][0] = 2222;
331 device->someMuxedRegister[12][0] = 3333;
332 device->someMuxedRegister[13][0] = 4444;
333 device->someMuxedRegister[14][0] = 5555;
334 device->someMuxedRegister[15][0] = 6666;
335
336 for(int i = 1; i < 65536 / 16; i++) {
337 for(int k = 0; k < 16; k++) {
338 device->someMuxedRegister[k][i] = 10 * k + i;
339 }
340 }
341
342 for(int k = 0; k < 13; k++) mixedReg.raw[k] = device->_barContents[0xD][areaIndexOffset + k];
343 BOOST_CHECK(mixedReg.cooked.r0 == 666);
344 BOOST_CHECK(mixedReg.cooked.r1 == 999);
345 BOOST_CHECK(mixedReg.cooked.r2 == 222);
346 BOOST_CHECK(mixedReg.cooked.r3 == -111);
347 BOOST_CHECK(mixedReg.cooked.r4 == 0);
348 BOOST_CHECK(mixedReg.cooked.r5 == 555);
349 BOOST_CHECK(mixedReg.cooked.r6 == 666);
350 BOOST_CHECK(mixedReg.cooked.r7 == 777);
351 BOOST_CHECK(mixedReg.cooked.r8 == 888);
352 BOOST_CHECK(mixedReg.cooked.r9 == 999);
353 BOOST_CHECK(mixedReg.cooked.r10 == 1111);
354 BOOST_CHECK(mixedReg.cooked.r11 == 2222);
355 BOOST_CHECK(mixedReg.cooked.r12 == 3333);
356 BOOST_CHECK(mixedReg.cooked.r13 == 4444);
357 BOOST_CHECK(mixedReg.cooked.r14 == 5555);
358 BOOST_CHECK(mixedReg.cooked.r15 == 6666);
359
360 for(int i = 1; i < 65536 / 16; i++) {
361 for(int k = 0; k < 13; k++) mixedReg.raw[k] = device->_barContents[0xD][areaIndexOffset + i * (pitch / 4) + k];
362 BOOST_CHECK(mixedReg.cooked.r0 == 10 * 0 + i);
363 BOOST_CHECK(mixedReg.cooked.r1 == std::min(10 * 1 + i, 32767));
364 BOOST_CHECK(mixedReg.cooked.r2 == std::min(10 * 2 + i, 32767));
365 BOOST_CHECK(mixedReg.cooked.r3 == std::min(10 * 3 + i, 127));
366 BOOST_CHECK(mixedReg.cooked.r4 == std::min(10 * 4 + i, 1));
367 BOOST_CHECK(mixedReg.cooked.r5 == 10 * 5 + i);
368 BOOST_CHECK(mixedReg.cooked.r6 == std::min(10 * 6 + i, 32767));
369 BOOST_CHECK(mixedReg.cooked.r7 == 10 * 7 + i);
370 BOOST_CHECK(mixedReg.cooked.r8 == 10 * 8 + i);
371 BOOST_CHECK(mixedReg.cooked.r9 == 10 * 9 + i);
372 BOOST_CHECK(mixedReg.cooked.r10 == 10 * 10 + i);
373 BOOST_CHECK(mixedReg.cooked.r11 == 10 * 11 + i);
374 BOOST_CHECK(mixedReg.cooked.r12 == 10 * 12 + i);
375 BOOST_CHECK(mixedReg.cooked.r13 == 10 * 13 + i);
376 BOOST_CHECK(mixedReg.cooked.r14 == 10 * 14 + i);
377 BOOST_CHECK(mixedReg.cooked.r15 == (unsigned int)(10 * 15 + i));
378 }
379
380 // close the device
381 device->close();
382}
The dummy device opens a mapping file instead of a device, and implements all registers defined in th...
Register accessor for accessing multiplexed 2D array registers internally of a DummyBackend implement...
Register accessor for accessing single word or 1D array registers internally of a DummyBackend implem...
Exception thrown when a logic error has occured.
Definition Exception.h:51
void testExceptions()
test exceptions
void testMuxedRegisterAccessor()
test the register accessor
void testRegisterAccessor()
test the register accessor
DummyMultiplexedRegisterAccessor< int > invalidRegister
InvalidDummyBackend(std::string mapFileName)
The TestableDummybackend is derived from DummyBackend to get access to the protected members.
DummyRegisterAccessor< int > someRegister
TestableDummyBackend(std::string mapFileName)
DummyMultiplexedRegisterAccessor< int > someMuxedRegister
@ raw
Raw access: disable any possible conversion from the original hardware data type into the given UserT...
bool init_unit_test()
#define TEST_MAPPING_FILE
#define INVALID_MAPPING_FILE