gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
IIODevice.H
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16 */
17 
18 #ifndef IIODEVICE_H_
19 #define IIODEVICE_H_
20 
21 #include "DirectoryScanner.H"
22 #include "IIOChannel.H"
23 
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <poll.h>
29 
30 //#define IIO_NONBLOCK_READS ///< define this to enable nonblocking read
31 
34 class IIODevice : public std::vector<IIOChannel> {
35  std::string devicePath;
36  std::string chipName;
37  float scale;
38 
39  std::string readDev;
40 
41  int fd;
42 
43 public:
48  IIODevice(const std::string &devicePathIn, const std::string &chipNameIn) {
49  fd=-1;
50  devicePath=devicePathIn;
51  chipName=chipNameIn;
52  // format the expected read device name :
53  readDev="/dev/iio:device"+devicePath.substr(devicePath.find(":device")+7);
54  }
55 
56  virtual ~IIODevice() {
57  close(); // if the device is open then close it.
58  }
59 
63  int scanDevice(void) {
64  int ret=NO_ERROR;
65  if (size()>0) {
66  close();
67  resize(0);
68  }
69 
70  // find how many channes exist on the device
71  std::string scanPath=devicePath+"/scan_elements";
72  std::string extName="_en";
73  DirectoryScanner ds(scanPath);
74  ds.findAll(std::vector<std::string>());
75  ds.keepWithPattern(extName);
76 
77  // count the number of enabled channels and store their base names
78  int enabled; // temporary variable to store enabled flag
79  for (unsigned int i=0; i<ds.size(); i++) {
80  std::ifstream inputF((scanPath+"/"+ds[i]).c_str());
81  if (!inputF.good())
82  return IIODebug().evaluateError(IIODEVICE_FILE_OPEN_ERROR, " Couldn't open the enabled file "+scanPath+"/"+ds[i]);
83  inputF>>enabled;
84  inputF.close();
85  if (enabled) {// create a channel, note its name and scan the elements.
86  IIOChannel iIOChannel;
87  iIOChannel.chName=ds[i].substr(0,ds[i].length()-extName.length()); // such as "in_voltage"
88  iIOChannel.chGenericName=iIOChannel.chName.substr(0,iIOChannel.chName.find("_")); // such as "in"
89  ret=iIOChannel.scanElements(scanPath, size()); // scan the elements from the _type file
90  if (ret!=NO_ERROR)
91  return ret;
92 
93  // For the new channel, add it to the list and scan its nature ...
94  push_back(iIOChannel); // Add the channel to the list of enabled channels
95 // operator[](size()-1).printInfo();
96 // std::cout<<std::endl;
97  }
98  }
99 
100  std::cout<<"IIODevice : bufferSize="<<getBufferSize()<<std::endl;
101  return ret;
102  }
103 
107  uint getChCnt(void) {
108  return size();
109  }
110 
113  void printInfo() {
114  std::cout<<"chip "<<chipName<<std::endl;
115  if (size()<1)
117  for (unsigned int i=0; i<getChCnt(); i++) {
118  std::cout<<"\n channel "<<i<<'\n';
119  operator[](i).printInfo();
120  }
121  }
122 
126  int open(void) {
127  int flags=O_RDONLY;
128 #ifdef IIO_NONBLOCK_READS
129  int flags|=O_NONBLOCK;
130 #endif
131  return open(flags);
132  }
133 
138  int open(int flags) {
139  close();
140  // can't read and write yet
141  int cntRead=0, cntWrite=0;
142  for (unsigned int i=0; i<size(); i++)
143  if (operator[](i).isReadCh())
144  cntRead++;
145  else
146  cntWrite++;
147  if (cntRead!=0 && cntWrite!=0)
149  if (cntWrite!=0)
151 
152  fd=::open(readDev.c_str(), flags);
153  if (fd<0) {
154  perror(NULL);
155  return IIODebug().evaluateError(IIODEVICE_OPEN_ERROR, "When trying to open the device path "+readDev);
156  }
157  return NO_ERROR;
158  }
159 
163  int close(void) {
164  enable(false); // disable the buffer
165  if (fd!=-1) {
166  fd=::close(fd);
167  if (fd<0) {
168  perror(NULL);
169  return IIODebug().evaluateError(IIODEVICE_OPEN_ERROR, "When trying to close the device path "+readDev);
170  }
171  fd=-1;
172  }
173  return NO_ERROR;
174  }
175 
181  int read(uint frames, void *buf) {
182  int bytesPerFrame=getChFrameSize()*getChCnt();
183  uint bytesToRead=frames*bytesPerFrame;
184  if (fd<0)
185  return IIODebug().evaluateError(IIODEVICE_OPEN_ERROR, "The device should already be opened before trying to read error. ");
186 
187 #ifdef IIO_NONBLOCK_READS
188  struct pollfd pfd = { .fd = fd, .events = POLLIN,};
189  poll(&pfd, 1, -1);
190 #endif
191 
192  ssize_t N=::read(fd, buf, bytesToRead);
193  if (N!=bytesToRead) {
194  if (N>=0)
195  return N/bytesPerFrame;
196  else {
197  std::cout<<"read returned "<<N<<"\n";
198  if (N == -EAGAIN)
199  std::cout<<"nothing available\n";
200  else {
201  std::cout<<strerror(errno)<<"\n";
202  perror(NULL);
203  return IIODebug().evaluateError(IIODEVICE_READ_ERROR, "Error during read.");
204  }
205  }
206  }
207  //std::cout<<"read "<<N<<" bytes, wanted "<<bytesToRead<<" bytes"<<std::endl;
208  return frames;
209  }
210 
215  if (size()<1)
217  unsigned int frameSize=operator[](0).bitCnt/8;
218  for (unsigned int i=1; i<size(); i++)
219  if (operator[](i).bitCnt/8 != frameSize)
221  return frameSize;
222  }
223 
228  int enable(bool enable) {
229  std::ofstream enableFile((devicePath+"/buffer/enable").c_str());
230  if (!enableFile.good())
231  return IIODebug().evaluateError(IIODEVICE_ENABLEFILE_ERROR, "Error when trying to open the enable file "+devicePath+"/buffer/enable");
232  enableFile<<enable;
233  enableFile.close();
234  return NO_ERROR;
235  }
236 
241  std::ifstream lengthFile((devicePath+"/buffer/length").c_str());
242  if (!lengthFile.good())
243  return IIODebug().evaluateError(IIODEVICE_LENGTHFILE_ERROR, "Error when trying to open the buffer length file "+devicePath+"/buffer/length");
244  int bufferSize;
245  lengthFile>>bufferSize;
246  return bufferSize;
247  }
248 
252  int setBufferSize(int bufferSize) {
253  if (getBufferSize()!=bufferSize){
254  std::ofstream lengthFile((devicePath+"/buffer/length").c_str());
255  if (!lengthFile.good())
256  return IIODebug().evaluateError(IIODEVICE_LENGTHFILE_ERROR, "Error when trying to open the buffer length file "+devicePath+"/buffer/length");
257  lengthFile<<bufferSize;
258  }
259  return getBufferSize();
260  }
261 
266  return getBufferSize()/getChCnt();
267  }
268 
273  int setChannelBufferCnt(int chBufferCnt) {
274  setBufferSize(chBufferCnt*getChCnt()); // if an error is returned, assume that the buffer length file is still valid
275  return getBufferSize()/getChCnt();
276  }
277 
281  int getFD(){
282  return fd;
283  }
284 };
285 #endif // IIODEVICE_H_
int close(void)
Definition: IIODevice.H:163
size(signal)
#define IIODEVICE_FILE_OPEN_ERROR
Error when trying to open an IIODevice subdirectory file.
Definition: IIOChannel.H:28
#define IIODEVICE_OPEN_ERROR
Couldn&#39;t open the device.
Definition: IIOChannel.H:32
int N
virtual ~IIODevice()
Definition: IIODevice.H:56
IIODevice(const std::string &devicePathIn, const std::string &chipNameIn)
Definition: IIODevice.H:48
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
int getChannelBufferCnt()
Definition: IIODevice.H:265
uint getChCnt(void)
Definition: IIODevice.H:107
int getBufferSize()
Definition: IIODevice.H:240
std::string chName
The name of each of the enabled channels.
Definition: IIOChannel.H:99
std::string chipName
The device chip name.
Definition: IIODevice.H:36
#define NO_ERROR
There is no error.
Definition: Debug.H:33
#define IIODEVICE_ENABLEFILE_ERROR
There was an error when trying to open the buffer enable file.
Definition: IIOChannel.H:39
float scale
How to scale the input value to get a real world value.
Definition: IIODevice.H:37
#define IIODEVICE_READ_ERROR
There was an error whilst reading from a device.
Definition: IIOChannel.H:38
#define IIODEVICE_READANDWRITE_ERROR
Don&#39;t know how to hbandle read and write yet.
Definition: IIOChannel.H:30
int findAll(const std::vector< std::string > &dontInclude)
int setBufferSize(int bufferSize)
Definition: IIODevice.H:252
unsigned int uint
Definition: Box.H:28
std::string chGenericName
The generic name of each of the enabled channels.
Definition: IIOChannel.H:100
#define IIODEVICE_WRITEABLE_ERROR
Don&#39;t know how to write yet.
Definition: IIOChannel.H:31
uint getChFrameSize(void)
Definition: IIODevice.H:214
int read(uint frames, void *buf)
Definition: IIODevice.H:181
std::string devicePath
The device path.
Definition: IIODevice.H:35
int fd
The file descriptor of the open device.
Definition: IIODevice.H:41
int setChannelBufferCnt(int chBufferCnt)
Definition: IIODevice.H:273
void printInfo()
Definition: IIODevice.H:113
int enable(bool enable)
Definition: IIODevice.H:228
int scanElements(std::string scanPath, uint cIndex)
Definition: IIOChannel.H:112
#define IIODEVICE_NOCHANNELS_ERROR
Error when trying to open the device, but the channels aren&#39;t initialised.
Definition: IIOChannel.H:29
void keepWithPattern(const std::string pattern)
int getFD()
Definition: IIODevice.H:281
int scanDevice(void)
Definition: IIODevice.H:63
int open(int flags)
Definition: IIODevice.H:138
int open(void)
Definition: IIODevice.H:126
#define IIODEVICE_FRAEMSIZE_MISMATCH_ERROR
The frame sizes differ between channels on one device.
Definition: IIOChannel.H:33
#define IIODEVICE_LENGTHFILE_ERROR
There was an error when trying to open the buffer length file.
Definition: IIOChannel.H:40
std::string readDev
The read buffer device, e.g. "/dev/iio:device0".
Definition: IIODevice.H:39
gtkIOStream: /tmp/gtkiostream/include/IIO/IIODevice.H Source File
GTK+ IOStream  Beta