25 #include <linux/ioctl.h> 26 #include <linux/types.h> 28 #include <sys/ioctl.h> 31 #define IIO_BLOCK_ALLOC_IOCTL _IOWR('i', 0xa0, struct iio_buffer_block_alloc_req) 32 #define IIO_BLOCK_FREE_IOCTL _IO('i', 0xa1) 33 #define IIO_BLOCK_QUERY_IOCTL _IOWR('i', 0xa2, struct iio_buffer_block) 34 #define IIO_BLOCK_ENQUEUE_IOCTL _IOWR('i', 0xa3, struct iio_buffer_block) 35 #define IIO_BLOCK_DEQUEUE_IOCTL _IOWR('i', 0xa4, struct iio_buffer_block) 61 #define DEFAULT_BLOCK_COUNT 4 62 #define DEFAULT_BLOCK_SIZE 0x100000 76 perror(
"Failed to allocate memory blocks");
94 std::cout <<
"MMappedBlocks::memoryMap resizing blocks "<<req.count<<endl;
95 blocks.resize(req.count);
96 for (
uint i = 0; i < req.count; i++) {
97 std::cout <<
"MMappedBlocks::memoryMap query i="<<i<<endl;
98 blocks[i].block.id = i;
100 perror(
"Failed to query block");
104 std::cout <<
"MMappedBlocks::memoryMap mapping"<<endl;
105 blocks[i].addr = (
unsigned short *)mmap(0, blocks[i].block.size, PROT_READ, MAP_SHARED, fd, blocks[i].block.data.offset);
106 if (blocks[i].addr == MAP_FAILED) {
107 perror(
"Failed to mmap block");
111 std::cout <<
"MMappedBlocks::memoryMap enqueueing "<<endl;
113 perror(
"Failed to enqueue block");
117 fprintf(stderr,
"Sucessfully mapped block %d (offset %x, size %d) at %p\n", i, blocks[i].block.data.offset, blocks[i].block.size, blocks[i].addr);
125 cout<<__func__<<endl;
126 for (
uint i = 0; i < req.count; i++)
127 munmap(blocks[i].addr, blocks[i].
block.size);
172 if (count>0 && size>0) {
209 if (getDeviceCnt()<1)
212 for (
unsigned int i=0; i<getDeviceCnt(); i++) {
213 std::cout <<
"opening device "<<i<<endl;
214 if ((ret=
operator[](i).open(O_RDWR))!=
NO_ERROR) {
215 ostringstream deviceDetail;
216 deviceDetail<<
" Device "<<i;
222 std::cout <<
"mmapping"<<endl;
224 resizeMMapBlocks(count, sizeIn);
228 for (
unsigned int i=0; i<getDeviceCnt(); i++)
229 if ((closeRet=
operator[](i).close())!=
NO_ERROR)
242 std::cout <<
"mMappedBlocks resized"<<endl;
243 for (
unsigned int i=0; i<getDeviceCnt(); i++) {
244 std::cout <<
"resetting mmapped blocks "<<i<<endl;
245 int ret=mMappedBlocks[i].reset(
operator[](i).getFD(), count, sizeIn*
operator[](i).getChCnt()*
operator[](i).getChFrameSize());
256 mMappedBlocks.resize(0);
266 template<
typename TYPE>
267 int read(
uint N,
const Eigen::Array<TYPE, Eigen::Dynamic, Eigen::Dynamic> &array) {
269 if (mMappedBlocks.size()<=0)
271 if (
sizeof(TYPE)!=
operator[](0).getChFrameSize()) {
273 msg<<
"The provided array type has "<<
sizeof(TYPE)<<
" bytes per sample, where as the IIO devices have "<<getChFrameSize()<<
" bytes per sample\n";
276 if (array.rows()!=N*operator[](0).getChCnt() && array.cols()>getDeviceCnt()) {
278 msg<<
"The provided array is not shaped correctly, size=("<<array.rows()<<
", "<<array.cols()<<
") but size=(N*device ch cnt, device cnt) is required, where size=("<<N*getChCnt()<<
", "<<getDeviceCnt()<<
")\n";
284 for (
int i=0; i <array.cols(); i++) {
288 msg<<
"Couldn't dequeue a mmaped block from device "<<i<<endl;
291 int bytesPerFrame=operator[](i).getChFrameSize()*operator[](i).getChCnt();
292 uint bytesToRead=N*bytesPerFrame;
293 if (bytesToRead!=block.
size) {
295 msg<<
"The mmapped block has a size="<<block.
size<<
" and the input array requires size="<<bytesToRead<<
"\n";
299 TYPE *dataSrc=mMappedBlocks[i].blocks[block.
id].addr;
300 TYPE *dataDest=(
unsigned short *)array.col(i).data();
301 for (
int j=0; j<N*operator[](i).getChCnt(); j++)
302 dataDest[j]=dataSrc[j];
307 msg<<
"Couldn't enqueue the mmaped block to device "<<i<<endl;
318 if (mMappedBlocks.size()<=0)
320 double chCnt=(double)
operator[](0).getChCnt();
321 double periodN=(double)mMappedBlocks[0].blocks.size();
324 double N=(double)mMappedBlocks[0].blocks[0].
block.size;
325 double frameByteCnt=
operator[](0).getChFrameSize();
326 return periodN*N/fs/chCnt/frameByteCnt;
#define IIOMMAP_ALLOCATE_ERROR
Couldn't allocate the iio memory buffers in the kernel using ioctl.
int fd
The file descriptior of the device.
#define IIO_BLOCK_DEQUEUE_IOCTL
#define IIOMMAP_WRONGOPEN_ERROR
The wrong open method was called.
virtual int evaluateError(int errorNum)
#define IIOMMAP_NOINIT_ERROR
The MMapedBlocks system is not initialised.
#define IIOMMAP_QUERY_ERROR
Couldn't query the iio device for allocated kernel memory.
#define NO_ERROR
There is no error.
The iio_channel_info structure is external.
int read(uint N, const Eigen::Array< TYPE, Eigen::Dynamic, Eigen::Dynamic > &array)
#define IIODEVICE_READ_ERROR
There was an error whilst reading from a device.
#define IIO_ARRAY_FRAME_MISMATCH_ERROR
The sample type of the provided array doesn't match the sample type of the devices.
vector< struct block > blocks
The block information and address.
int reset(int fdIn, int count, int size)
virtual ~IIOMMap()
Destructor.
vector< MMappedBlocks > mMappedBlocks
The memory mapped blocks.
#define DEFAULT_BLOCK_SIZE
#define DEFAULT_BLOCK_COUNT
int resizeMMapBlocks(int count, int sizeIn)
#define IIO_ARRAY_SIZE_MISMATCH_ERROR
The provided array doesn't match the number of channels and requested samples.
#define IIOMMAP_ENQUEUE_ERROR
Couldn't enqueue the mmaped block.
~MMappedBlocks()
Destructor.
#define IIOMMAP_BLOCK_SIZE_MISMATCH_ERROR
The user and mmaped block sizes don't match.
#define IIO_NODEVICES_ERROR
There are no devices.
double getMaxDelay(float fs)
int open(int count, int sizeIn)
#define IIOMMAP_MMAP_ERROR
Couldn't execute mmap.
#define IIO_BLOCK_QUERY_IOCTL
#define IIO_BLOCK_FREE_IOCTL
#define IIO_BLOCK_ENQUEUE_IOCTL
#define IIO_BLOCK_ALLOC_IOCTL