Hi,
sometimes, if not enough bytes are received from ftdi device, avrdude
hangs in ft245r_recv, to avoid this sem_wait is replaced with
sem_timedwait. I tested this patch on linux.
--
Best regards,
Andrey Skvortsov
Secure eMail with gnupg: See http://www.gnupg.org/
PGP Key ID: 0x57A3AEAD
--- avrdude-upstream/ft245r.c 2015-01-26 14:57:06.694284064 +0300
+++ avrdude/ft245r.c 2015-01-26 17:46:42.898258686 +0300
@@ -131,8 +131,34 @@
#define sem_init(psem,x,val) *psem = dispatch_semaphore_create(val)
#define sem_post(psem) dispatch_semaphore_signal(*psem)
#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
+#define sem_wait_with_timeout(psem,to_ns) sem_wait(psem)
#else
#include <semaphore.h>
+
+int sem_wait_with_timeout(sem_t * psem, long to_ns)
+{
+ struct timespec ts;
+ const long sec_ns = 1000000000;
+ long nsec;
+ int ret;
+
+ if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
+ return sem_wait(psem);
+
+ ts.tv_sec += to_ns/sec_ns;
+ nsec = ts.tv_nsec + to_ns%sec_ns;
+ if (nsec >= sec_ns) {
+ ts.tv_sec++;
+ nsec -= sec_ns;
+ }
+ ts.tv_nsec = nsec;
+
+ while ((ret = sem_timedwait(psem, &ts)) == -1 && errno == EINTR)
+ continue; /* Restart if interrupted by handler */
+
+ return ret;
+}
+
#endif
#define FT245R_CYCLES 2
@@ -197,12 +223,16 @@
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
int i;
+ int ret;
+ long timeout = 10*1000000; // 10 ms
- // Copy over data from the circular buffer..
- // XXX This should timeout, and return error if there isn't enough
- // data.
for (i=0; i<len; i++) {
- sem_wait (&buf_data);
+ ret = sem_wait_with_timeout(&buf_data, timeout);
+ if ((ret == -1) && (errno == ETIMEDOUT)) {
+ avrdude_message(MSG_INFO, "receive timeout\n");
+ return -1;
+ }
+
buf[i] = buffer[tail];
if (tail == (BUFSIZE -1)) tail = 0;
else tail++;
_______________________________________________
avrdude-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avrdude-dev