OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [src/] [librlink/] [RlinkPort.cpp] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 wfjm
// $Id: RlinkPort.cpp 492 2013-02-24 22:14:47Z mueller $
2 10 wfjm
//
3 19 wfjm
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 10 wfjm
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16 19 wfjm
// 2013-02-23   492   1.2    use RparseUrl
17
// 2013-02-22   491   1.1    use new RlogFile/RlogMsg interfaces
18
// 2013-02-10   485   1.0.5  add static const defs
19
// 2013-02-03   481   1.0.4  use Rexception
20
// 2013-01-27   477   1.0.3  add RawRead(),RawWrite() methods
21 17 wfjm
// 2012-12-28   466   1.0.2  allow Close() even when not open
22
// 2012-12-26   465   1.0.1  add CloseFd() method
23 10 wfjm
// 2011-03-27   375   1.0    Initial version
24
// 2011-01-15   356   0.1    First draft
25
// ---------------------------------------------------------------------------
26
 
27
/*!
28
  \file
29 19 wfjm
  \version $Id: RlinkPort.cpp 492 2013-02-24 22:14:47Z mueller $
30 10 wfjm
  \brief   Implemenation of RlinkPort.
31
*/
32
 
33
#include <errno.h>
34
#include <unistd.h>
35
#include <poll.h>
36 19 wfjm
#include <sys/time.h>
37 10 wfjm
 
38
#include <iostream>
39
 
40
#include "librtools/RosFill.hpp"
41
#include "librtools/RosPrintf.hpp"
42
#include "librtools/RosPrintBvi.hpp"
43 19 wfjm
#include "librtools/Rexception.hpp"
44
#include "librtools/RlogMsg.hpp"
45 10 wfjm
 
46 19 wfjm
#include "RlinkPort.hpp"
47
 
48 10 wfjm
using namespace std;
49
 
50
/*!
51
  \class Retro::RlinkPort
52
  \brief FIXME_docs
53
*/
54
 
55 19 wfjm
// all method definitions in namespace Retro
56
namespace Retro {
57
 
58 10 wfjm
//------------------------------------------+-----------------------------------
59 19 wfjm
// constants definitions
60
 
61
const int  RlinkPort::kEof;
62
const int  RlinkPort::kTout;
63
const int  RlinkPort::kErr;
64
 
65
//------------------------------------------+-----------------------------------
66 10 wfjm
//! Default constructor
67
 
68
RlinkPort::RlinkPort()
69
  : fIsOpen(false),
70
    fUrl(),
71
    fFdRead(-1),
72
    fFdWrite(-1),
73 19 wfjm
    fspLog(),
74 10 wfjm
    fTraceLevel(0),
75
    fStats()
76
{
77 19 wfjm
  fStats.Define(kStatNPortWrite,    "NPortWrite", "Port::Write() calls");
78
  fStats.Define(kStatNPortRead,     "NPortRead",  "Port::Read() calls");
79
  fStats.Define(kStatNPortTxByt,    "NPortTxByt", "Port Tx bytes send");
80
  fStats.Define(kStatNPortRxByt,    "NPortRxByt", "Port Rx bytes rcvd");
81
  fStats.Define(kStatNPortRawWrite, "NPortRawWrite", "Port::RawWrite() calls");
82
  fStats.Define(kStatNPortRawRead,  "NPortRawRead",  "Port::RawRead() calls");
83 10 wfjm
}
84
 
85
//------------------------------------------+-----------------------------------
86
//! Destructor
87
 
88
RlinkPort::~RlinkPort()
89
{
90
  if (IsOpen()) RlinkPort::Close();
91
}
92
 
93
//------------------------------------------+-----------------------------------
94
//! FIXME_docs
95
 
96
void RlinkPort::Close()
97
{
98 17 wfjm
  if (!IsOpen()) return;
99 10 wfjm
 
100 17 wfjm
  if (fFdWrite == fFdRead) fFdWrite = -1;
101
  CloseFd(fFdWrite);
102
  CloseFd(fFdRead);
103 10 wfjm
 
104
  fIsOpen  = false;
105 19 wfjm
  fUrl.Clear();
106 10 wfjm
 
107
  return;
108
}
109
 
110
//------------------------------------------+-----------------------------------
111
//! FIXME_docs
112
 
113
int RlinkPort::Read(uint8_t* buf, size_t size, double timeout, RerrMsg& emsg)
114
{
115
  if (!IsOpen())
116 19 wfjm
    throw Rexception("RlinkPort::Read()","Bad state: port not open");
117 10 wfjm
  if (buf == 0)
118 19 wfjm
    throw Rexception("RlinkPort::Read()","Bad args: buf==NULL");
119 10 wfjm
  if (size == 0)
120 19 wfjm
    throw Rexception("RlinkPort::Read()","Bad args: size==0");
121 10 wfjm
 
122
  fStats.Inc(kStatNPortRead);
123
 
124
  bool rdpoll = PollRead(timeout);
125
  if (!rdpoll) return kTout;
126
 
127
  int irc = -1;
128
  while (irc < 0) {
129
    irc = read(fFdRead, (void*) buf, size);
130
    if (irc < 0 && errno != EINTR) {
131
      emsg.InitErrno("RlinkPort::Read()", "read() failed : ", errno);
132 19 wfjm
      if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
133 10 wfjm
      return kErr;
134
    }
135
  }
136
 
137 19 wfjm
  if (fspLog && fTraceLevel>0) {
138
    RlogMsg lmsg(*fspLog, 'I');
139
    lmsg << "port  read nchar=" << RosPrintf(irc,"d",4);
140 10 wfjm
    if (fTraceLevel>1) {
141
      size_t ncol = (80-5-6)/(2+1);
142
      for (int i=0; i<irc; i++) {
143 19 wfjm
        if ((i%ncol)==0) lmsg << "\n     " << RosPrintf(i,"d",4) << ": ";
144
        lmsg << RosPrintBvi(buf[i],16) << " ";
145 10 wfjm
      }
146
    }
147
  }
148
 
149
  fStats.Inc(kStatNPortRxByt, double(irc));
150
 
151
  return irc;
152
}
153
 
154
//------------------------------------------+-----------------------------------
155
//! FIXME_docs
156
 
157
int RlinkPort::Write(const uint8_t* buf, size_t size, RerrMsg& emsg)
158
{
159
  if (!IsOpen())
160 19 wfjm
    throw Rexception("RlinkPort::Write()","Bad state: port not open");
161 10 wfjm
  if (buf == 0)
162 19 wfjm
    throw Rexception("RlinkPort::Write()","Bad args: buf==NULL");
163 10 wfjm
  if (size == 0)
164 19 wfjm
    throw Rexception("RlinkPort::Write()","Bad args: size==0");
165 10 wfjm
 
166
  fStats.Inc(kStatNPortWrite);
167
 
168 19 wfjm
  if (fspLog && fTraceLevel>0) {
169
    RlogMsg lmsg(*fspLog, 'I');
170
    lmsg << "port write nchar=" << RosPrintf(size,"d",4);
171 10 wfjm
    if (fTraceLevel>1) {
172
      size_t ncol = (80-5-6)/(2+1);
173
      for (size_t i=0; i<size; i++) {
174 19 wfjm
        if ((i%ncol)==0) lmsg << "\n     " << RosPrintf(i,"d",4) << ": ";
175
        lmsg << RosPrintBvi(buf[i],16) << " ";
176 10 wfjm
      }
177
    }
178
  }
179
 
180
  size_t ndone = 0;
181
  while (ndone < size) {
182
    int irc = -1;
183
    while (irc < 0) {
184
      irc = write(fFdWrite, (void*) (buf+ndone), size-ndone);
185
      if (irc < 0 && errno != EINTR) {
186
        emsg.InitErrno("RlinkPort::Write()", "write() failed : ", errno);
187 19 wfjm
        if (fspLog && fTraceLevel>0) fspLog->Write(emsg.Message(), 'E');
188 10 wfjm
        return kErr;
189
      }
190
    }
191
    // FIXME_code: handle eof ??
192
    ndone += irc;
193
  }
194
 
195
  fStats.Inc(kStatNPortTxByt, double(ndone));
196
 
197
  return ndone;
198
}
199
 
200
//------------------------------------------+-----------------------------------
201
//! FIXME_docs
202
 
203
bool RlinkPort::PollRead(double timeout)
204
{
205
  if (! IsOpen())
206 19 wfjm
    throw Rexception("RlinkPort::PollRead()","Bad state: port not open");
207 10 wfjm
  if (timeout < 0.)
208 19 wfjm
    throw Rexception("RlinkPort::PollRead()","Bad args: timeout < 0");
209 10 wfjm
 
210
  int ito = 1000.*timeout + 0.1;
211
 
212
  struct pollfd fds[1] = {{fFdRead,         // fd
213
                           POLLIN,          // events
214
                           0}};             // revents
215
 
216
 
217
  int irc = -1;
218
  while (irc < 0) {
219
    irc = poll(fds, 1, ito);
220
    if (irc < 0 && errno != EINTR)
221 19 wfjm
      throw Rexception("RlinkPort::PollRead()","poll() failed: rc<0: ", errno);
222 10 wfjm
  }
223
 
224
  if (irc == 0) return false;
225
 
226
  if (fds[0].revents == POLLERR)
227 19 wfjm
    throw Rexception("RlinkPort::PollRead()", "poll() failed: POLLERR");
228 10 wfjm
 
229
  return true;
230
}
231
 
232
//------------------------------------------+-----------------------------------
233
//! FIXME_docs
234 19 wfjm
int RlinkPort::RawRead(uint8_t* buf, size_t size, bool exactsize,
235
                       double timeout, double& tused, RerrMsg& emsg)
236
{
237
  if (timeout <= 0.)
238
    throw Rexception("RlinkPort::RawRead()", "Bad args: timeout <= 0.");
239
  if (size <= 0)
240
    throw Rexception("RlinkPort::RawRead()", "Bad args: size <= 0");
241 10 wfjm
 
242 19 wfjm
  fStats.Inc(kStatNPortRawRead);
243
  tused = 0.;
244
 
245
  struct timeval tval;
246
  gettimeofday(&tval, 0);
247
  double tbeg  = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
248
  double trest = timeout;
249
 
250
  size_t ndone = 0;
251
  while (trest>0. && ndone<size) {
252
    int irc = Read(buf+ndone, size-ndone, trest, emsg);
253
    gettimeofday(&tval, 0);
254
    double tend  = double(tval.tv_sec) + 1.e-6*double(tval.tv_usec);
255
    tused = tend - tbeg;
256
    if (irc <= 0) return irc;
257
    if (!exactsize) break;
258
 
259
    trest -= (tend-tbeg);
260
    ndone += irc;
261
  }
262
 
263
  return (int)ndone;
264 10 wfjm
}
265
 
266
//------------------------------------------+-----------------------------------
267
//! FIXME_docs
268 19 wfjm
int RlinkPort::RawWrite(const uint8_t* buf, size_t size, RerrMsg& emsg)
269 10 wfjm
{
270 19 wfjm
  fStats.Inc(kStatNPortRawWrite);
271
  return Write(buf, size, emsg);
272 10 wfjm
}
273
 
274
//------------------------------------------+-----------------------------------
275
//! FIXME_docs
276
 
277
void RlinkPort::Dump(std::ostream& os, int ind, const char* text) const
278
{
279
  RosFill bl(ind);
280
  os << bl << (text?text:"--") << "RlinkPort @ " << this << endl;
281
 
282
  os << bl << "  fIsOpen:         " << (int)fIsOpen << endl;
283 19 wfjm
  fUrl.Dump(os, ind+2, "fUrl: ");
284 10 wfjm
  os << bl << "  fFdRead:         " << fFdRead << endl;
285
  os << bl << "  fFdWrite:        " << fFdWrite << endl;
286 19 wfjm
  os << bl << "  fspLog:          " << fspLog.get() << endl;
287
  os << bl << "  fTraceLevel:     " << fTraceLevel << endl;
288 10 wfjm
  fStats.Dump(os, ind+2, "fStats: ");
289
  return;
290
}
291
 
292
//------------------------------------------+-----------------------------------
293
//! FIXME_docs
294
 
295 17 wfjm
void RlinkPort::CloseFd(int& fd)
296
{
297
  if (fd >= 0) {
298
    close(fd);
299
    fd  = -1;
300
  }
301
  return;
302
}
303
 
304 19 wfjm
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.