Subject:
|
Retry count too small for nqc linux usb driver
|
Newsgroups:
|
lugnet.robotics
|
Date:
|
Sun, 13 Jan 2002 03:56:35 GMT
|
Original-From:
|
PC CHAN <PC.CHAN@ALCATEL.COMantispam>
|
Viewed:
|
1185 times
|
| |
| |
Hi Thomas,
I just found that the retry count for EAGAIN in
RCX_USBTowerPipe_linux::Write() was too small (10) for handling the
large packets used in firmware downloading. It ran out of retries
middle way in sending the continue downloading command (0x45). (It is
normal for legousbtower to return EAGAIN when it is busy dealing with
the previous 8 byte batch. We would see many EAGAI's when sending a
large packet.)
The firmware down loading completed successfull after increasing retry
to 100.
I've changed retry to 1000 to deal with it.
If you ever need to send a very big packet, you may consider disabling
the retry control completely.
Please use the enclosed file or the listing below to build your nqc.
Regards,
P.C. Chan
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Initial Developer of RCX_USBTowerPipe_win.c is David Baum.
* Portions created by David Baum are Copyright (C) 1998 David Baum.
* This is adapted as RCX_USBTowerPipe_linux.c by P.C. Chan
* All Rights Reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include "RCX_Pipe.h"
#include <stdio.h>
/*
* This file provides USB tower support by thunking over to the
* /dev/tower0 device which is almost like a serial port (just
* can't control speed, parity, etc.).
*
*/
class RCX_USBTowerPipe_linux : public RCX_Pipe
{
public:
RCX_USBTowerPipe_linux() : fd(-1) {}
virtual ~RCX_USBTowerPipe_linux() { Close(); }
virtual RCX_Result Open(const char *name, int mode);
virtual void Close();
virtual int GetCapabilities() const;
virtual RCX_Result SetMode(int mode);
virtual long Read(void *ptr, long count, long
timeout_ms);
virtual long Write(const void *ptr, long count);
private:
int fd;
};
RCX_Pipe* RCX_NewUSBTowerPipe()
{
return new RCX_USBTowerPipe_linux();
}
#define DEFAULT_TOWER_NAME "/dev/tower0"
RCX_Result RCX_USBTowerPipe_linux::Open(const char *name, int mode)
{
if (name == 0 || *name==0)
{
name = DEFAULT_TOWER_NAME;
}
if (mode != kNormalIrMode) return kRCX_PipeModeError;
fd = open (name, O_RDWR|O_NONBLOCK|O_SYNC);
if (fd == -1) return kRCX_OpenSerialError;
return kRCX_OK;
}
void RCX_USBTowerPipe_linux::Close()
{
if (fd == -1) return;
close(fd);
fd = -1;
}
long RCX_USBTowerPipe_linux::Write(const void *ptr, long count)
{
long actual = 0;
long rc;
char * cptr;
int retry = 1000;
if (count < 1) return count;
cptr = (char *) ptr;
while (actual < count) {
rc = (long) write(fd, cptr+actual, count-actual);
if (rc == -1) {
if ((errno == EINTR) || (errno == EAGAIN)) {
rc = 0;
usleep(10);
retry --;
} else return -1;
}
actual += rc;
if (retry < 1) return actual;
}
return count;
}
long RCX_USBTowerPipe_linux::Read(void *ptr, long count, long timeout)
{
long actual = 0;
long timer = timeout;
long rc;
char *cptr;
if (timer == 0) timer = 40;
cptr = (char *) ptr;
while (timer > 0) {
do {
rc = (long) read(fd, cptr+actual, count-actual);
if (rc == 0) return actual;
} while ((rc == -1) && (errno == EINTR));
if ((rc == -1) && (errno == EAGAIN)) {
usleep(100);
timer -= 1;
} else actual += rc;
if (actual >= count) return count;
}
return actual;
}
int RCX_USBTowerPipe_linux::GetCapabilities() const
{
// only normal IR mode is supported, and
// the ABSORB_0x55_FLAG is needed to tell the
// transport that initial 0x55 bytes don't make
// it through the USB/driver shim
return kNormalIrMode + kAbsorb55Flag;
}
RCX_Result RCX_USBTowerPipe_linux::SetMode(int mode)
{
switch(mode)
{
case kNormalIrMode:
return kRCX_OK;
default:
return kRCX_PipeModeError;
}
}
--
MIME ATTACHMENTS DISCARDED:
1. Content-Type: text/plain;
name="RCX_USBTowerPipe_linux.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="RCX_USBTowerPipe_linux.cpp"
Content-Length: 3667
|
|
1 Message in This Thread:
- Entire Thread on One Page:
- Nested:
All | Brief | Compact | Dots
Linear:
All | Brief | Compact
|
|
|
|