7using namespace boost::unit_test_framework;
9#define PCIEDEV_TEST_SLOT 0
10#define LLRFDRV_TEST_SLOT 4
11#define PCIEUNI_TEST_SLOT 6
31#define WORD_FIRMWARE_OFFSET 0x0
32#define WORD_COMPILATION_OFFSET 0x4
33#define WORD_USER_OFFSET 0xC
34#define WORD_CLK_CNT_OFFSET 0x10
35#define WORD_DUMMY_OFFSET 0x3C
36#define DMMY_AS_ASCII 0x444D4D59
37#define WORD_ADC_ENA_OFFSET 0x44
39#define PCIE_DEVICE "PCIE6"
40#define LLRF_DEVICE "LLRF10"
42#define PCIE_UNI_DEVICE "PCIE0"
43#define NON_EXISTING_DEVICE "DUMMY9"
53 std::vector<std::string>
usedNodes{
"mtcadummys0",
"llrfdummys4",
"noioctldummys5",
"pcieunidummys6"};
56 mkdir(
"/var/run/lock/mtcadummy",
59 std::string
lockfile =
"/var/run/lock/mtcadummy/" + node;
62 int fd = open(
lockfile.c_str(), O_WRONLY | O_CREAT, 0777);
64 std::cout <<
"Cannot open file '" <<
lockfile <<
"' for locking." << std::endl;
69 int res = flock(
fd, LOCK_EX);
71 std::cout <<
"Cannot acquire lock on file 'shareddummyTest.dmap'." << std::endl;
79 std::string
lockfile =
"/var/run/lock/mtcadummy/" + node;
139 std::string _deviceFileName;
142 boost::shared_ptr<PcieBackend> _pcieBackendInstance;
146 std::string checkDmaValues(std::vector<int32_t>
const& dmaBuffer);
153 PcieBackendTestSuite(std::string
const& deviceFileName,
unsigned int slot) : test_suite(
"PcieBackend test suite") {
156 boost::shared_ptr<PcieBackendTest> pcieBackendTest(
new PcieBackendTest(deviceFileName, slot));
176 createBackendTestCase->depends_on(testConstructor);
177 openTestCase->depends_on(createBackendTestCase);
178 readTestCase->depends_on(openTestCase);
179 writeAreaTestCase->depends_on(readTestCase);
180 readRegisterTestCase->depends_on(writeAreaTestCase);
181 writeRegisterTestCase->depends_on(readRegisterTestCase);
182 readDMATestCase->depends_on(writeRegisterTestCase);
183 writeDMATestCase->depends_on(readDMATestCase);
184 readDeviceInfoTestCase->depends_on(writeDMATestCase);
185 closeTestCase->depends_on(readDeviceInfoTestCase);
187 add(testConstructor);
189 add(createBackendTestCase);
193 add(writeAreaTestCase);
195 add(readRegisterTestCase);
196 add(writeRegisterTestCase);
198 add(readDMATestCase);
199 add(writeDMATestCase);
201 add(readDeviceInfoTestCase);
212 framework::master_test_suite().p_name.value =
"PcieBackend test suite";
214 std::stringstream llrfdummyFileName;
221 std::stringstream mtcadummyFileName;
226 std::stringstream pcieunidummyFileName;
238 std::cout <<
"testConstructor" << std::endl;
240 BOOST_CHECK(pcieBackend.
isOpen() ==
false);
244: _pcieBackend(deviceFileName), _deviceFileName(deviceFileName), _slot(slot) {}
246std::string PcieBackendTest::checkDmaValues(std::vector<int32_t>
const& dmaBuffer) {
247 std::cout <<
"testDmaValues" << std::endl;
248 bool dmaValuesOK =
true;
250 for(i = 0; i < dmaBuffer.size(); ++i) {
251 if(dmaBuffer[i] !=
static_cast<int32_t
>(i * i)) {
258 return std::string();
261 std::stringstream errorMessage;
262 errorMessage <<
"Content of transferred DMA block is not valid. First wrong "
264 << i <<
" is " << dmaBuffer[i] << std::endl;
266 return errorMessage.str();
272 std::cout <<
"testReadDeviceInfo" << std::endl;
282 std::stringstream referenceInfo;
283 referenceInfo <<
"SLOT: " << _slot <<
" DRV VER: " << major <<
"." << minor;
285 std::string deviceInfo;
286 deviceInfo = _pcieBackendInstance->readDeviceInfo();
287 BOOST_CHECK_EQUAL(referenceInfo.str(), deviceInfo);
293 std::cout <<
"testReadDMA" << std::endl;
300 std::vector<int32_t> dmaUserBuffer(
N_WORDS_DMA, -1);
302 _pcieBackendInstance->read( 2, 0, &dmaUserBuffer[0],
N_WORDS_DMA *
sizeof(int32_t));
304 std::string errorMessage = checkDmaValues(dmaUserBuffer);
305 BOOST_CHECK_MESSAGE(errorMessage.empty(), errorMessage);
309 std::vector<int32_t> smallBuffer(20, -1);
310 static const unsigned int readOffset = 5;
311 _pcieBackendInstance->read(
312 2, readOffset *
sizeof(int32_t), &smallBuffer[0],
313 smallBuffer.size() *
sizeof(int32_t));
315 for(
size_t i = 0; i < smallBuffer.size(); ++i) {
316 BOOST_CHECK(smallBuffer[i] ==
static_cast<int32_t
>((i + readOffset) * (i + readOffset)));
323 std::cout <<
"testWriteDMA" << std::endl;
329 std::cout <<
"testRead" << std::endl;
336 int32_t firmwareContent;
338 int32_t compilationContent;
343 twoWords[0] = 0xFFFFFFFF;
344 twoWords[1] = 0xFFFFFFFF;
347 BOOST_CHECK((twoWords[0] == firmwareContent) && (twoWords[1] == compilationContent));
361 _pcieBackendInstance->read( 2, 0, &bar2Buffer[0],
N_WORDS_DMA *
sizeof(int32_t));
363 std::string errorMessage = checkDmaValues(bar2Buffer);
364 BOOST_CHECK_MESSAGE(errorMessage.empty(), errorMessage);
370 std::cout <<
"testWriteArea" << std::endl;
375 int32_t originalClockCounts[2];
376 int32_t increasedClockCounts[2];
377 int32_t readbackClockCounts[2];
379 _pcieBackendInstance->read( 0,
WORD_CLK_CNT_OFFSET, originalClockCounts, 2 *
sizeof(int32_t));
380 increasedClockCounts[0] = originalClockCounts[0] + 1;
381 increasedClockCounts[1] = originalClockCounts[1] + 1;
382 _pcieBackendInstance->write( 0,
WORD_CLK_CNT_OFFSET, increasedClockCounts, 2 *
sizeof(int32_t));
383 _pcieBackendInstance->read( 0,
WORD_CLK_CNT_OFFSET, readbackClockCounts, 2 *
sizeof(int32_t));
385 (increasedClockCounts[0] == readbackClockCounts[0]) && (increasedClockCounts[1] == readbackClockCounts[1]));
389 BOOST_CHECK_THROW(_pcieBackendInstance->write( 0,
WORD_CLK_CNT_OFFSET, originalClockCounts,
395 std::vector<int32_t> writeBuffer(
N_WORDS_DMA, 0xABCDEF01);
396 std::vector<int32_t> readbackBuffer(
N_WORDS_DMA, -1);
397 _pcieBackendInstance->write( 2, 0, &writeBuffer[0],
N_WORDS_DMA *
sizeof(int32_t));
398 _pcieBackendInstance->read( 2, 0, &readbackBuffer[0],
N_WORDS_DMA *
sizeof(int32_t));
399 BOOST_CHECK(readbackBuffer == writeBuffer);
405 std::cout <<
"testReadRegister" << std::endl;
410 int32_t dataWord = 0;
412 _pcieBackendInstance->open();
422 BOOST_CHECK_THROW(_pcieBackendInstance->getRegisterAccessor<
int>(
"#6/0x3C", 4, 0, {}),
ChimeraTK::logic_error);
428 std::cout <<
"testWriteRegister" << std::endl;
435 int32_t originalUserWord, newUserWord;
437 int32_t data = originalUserWord + 1;
441 BOOST_CHECK_EQUAL(originalUserWord + 1, newUserWord);
447 std::cout <<
"testClose" << std::endl;
449 _pcieBackendInstance->close();
451 BOOST_CHECK(_pcieBackendInstance->isOpen() ==
false);
453 _pcieBackendInstance->close();
454 BOOST_CHECK(_pcieBackendInstance->isOpen() ==
false);
460 std::cout <<
"testOpen" << std::endl;
461 _pcieBackendInstance->open();
462 BOOST_CHECK(_pcieBackendInstance->isOpen() ==
true);
464 _pcieBackendInstance->open();
465 BOOST_CHECK(_pcieBackendInstance->isOpen());
471 std::cout <<
"testCreateBackend" << std::endl;
475 _pcieBackendInstance = boost::dynamic_pointer_cast<PcieBackend>(factoryInstance.
createBackend(_deviceFileName));
476 BOOST_CHECK(_pcieBackendInstance !=
nullptr);
478 BOOST_CHECK(_pcieBackendInstance->isOpen() ==
false);
494 firstDevice.
open(
"PCIE0");
496 firstDevice.
write<
double>(
"WORD_USER", 48);
503 secondDevice.
open(
"(pci:pcieunidummys6?map=mtcadummy.map)");
504 BOOST_CHECK(secondDevice.
read<
double>(
"BOARD/WORD_USER") == 48);
508 secondDevice2.
open(
"(pci:pcieunidummys6?map=mtcadummy.map)");
509 BOOST_CHECK(secondDevice2.
read<
double>(
"BOARD/WORD_USER") == 48);
513 thirdDevice.
open(
"(pci:pcieunidummys6)");
514 BOOST_CHECK(thirdDevice.
read<int32_t>(BAR() / 0 / 0xC) == 48 << 3);
521 fourthDevice.
open(
"PCIE_DOUBLEMAP");
522 BOOST_CHECK(fourthDevice.
read<
double>(
"BOARD/WORD_USER") == 48);
526 _pcieBackendInstance->close();
BackendFactory is a the factory class to create devices.
static BackendFactory & getInstance()
Static function to get an instance of factory.
void setDMapFilePath(std::string dMapFilePath)
This function sets the _DMapFilePath.
boost::shared_ptr< DeviceBackend > createBackend(const std::string &aliasOrUri)
Create a new backend and return the instance as a shared pointer.
bool isOpen() override
Return whether a device has been opened or not.
Class allows to read/write registers from device.
UserType read(const RegisterPath ®isterPathName, const AccessModeFlags &flags=AccessModeFlags({})) const
Inefficient convenience function to read a single-word register without obtaining an accessor.
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
void write(const RegisterPath ®isterPathName, UserType value, const AccessModeFlags &flags=AccessModeFlags({}))
Inefficient convenience function to write a single-word register without obtaining an accessor.
A class to provide the Pcie device functionality.
Exception thrown when a logic error has occured.
Exception thrown when a runtime error has occured.
PcieBackendTest(std::string const &deviceFileName, unsigned int slot)
void testReadDeviceInfo()
void testFailIfBackendClosed()
Test that all functions throw an exception if the backend is not opened.
void testFailIfClosed()
Tests whether openig of the backend works, and that the exception is thrown correctly if the backend ...
static void testConstructor()
A simple test which calls the default constructor and checks that the backend is closed.
PcieBackendTestSuite(std::string const &deviceFileName, unsigned int slot)
RegisterPath BAR()
The numeric_address::BAR() function can be used to directly access registers by numeric addresses,...
const std::string lockfile
std::vector< std::string > usedNodes
#define NON_EXISTING_DEVICE
#define WORD_FIRMWARE_OFFSET
#define PCIEDEV_TEST_SLOT
#define LLRFDRV_TEST_SLOT
#define PCIEUNI_TEST_SLOT
#define WORD_CLK_CNT_OFFSET
#define WORD_COMPILATION_OFFSET
#define WORD_DUMMY_OFFSET
#define WORD_ADC_ENA_OFFSET