improve performance by using threads
This commit is contained in:
parent
75417531f3
commit
3cc5a0bc5a
73
jtagkey.c
73
jtagkey.c
@ -1,15 +1,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "usb-driver.h"
|
#include "usb-driver.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "jtagkey.h"
|
#include "jtagkey.h"
|
||||||
|
|
||||||
#define USBBUFSIZE 4096
|
#define USBBUFSIZE 1048576
|
||||||
#define SLOW_AND_SAFE 1
|
#define SLOW_AND_SAFE 1
|
||||||
|
|
||||||
static struct ftdi_context ftdic;
|
static struct ftdi_context ftdic;
|
||||||
static unsigned int usb_maxlen = 0;
|
|
||||||
static unsigned char bitbang_mode;
|
static unsigned char bitbang_mode;
|
||||||
|
|
||||||
static int jtagkey_init(unsigned short vid, unsigned short pid) {
|
static int jtagkey_init(unsigned short vid, unsigned short pid) {
|
||||||
@ -36,15 +36,15 @@ static int jtagkey_init(unsigned short vid, unsigned short pid) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ret = ftdi_write_data_set_chunksize(&ftdic, USBBUFSIZE)) != 0) {
|
||||||
#ifdef SLOW_AND_SAFE
|
fprintf(stderr, "unable to set write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
usb_maxlen = 384;
|
return ret;
|
||||||
#else
|
}
|
||||||
if ((ret = ftdi_write_data_get_chunksize(&ftdic, &usb_maxlen)) != 0) {
|
|
||||||
fprintf(stderr, "unable to get write chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
if ((ret = ftdi_read_data_set_chunksize(&ftdic, USBBUFSIZE)) != 0) {
|
||||||
|
fprintf(stderr, "unable to set read chunksize: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
|
if ((ret = ftdi_set_latency_timer(&ftdic, 1)) != 0) {
|
||||||
fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
fprintf(stderr, "unable to set latency timer: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
|
||||||
@ -93,6 +93,7 @@ void jtagkey_close(int handle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SLOW_AND_SAFE
|
||||||
static int jtagkey_set_bbmode(unsigned char mode) {
|
static int jtagkey_set_bbmode(unsigned char mode) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -117,6 +118,7 @@ static int jtagkey_set_bbmode(unsigned char mode) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void jtagkey_state(unsigned char data) {
|
void jtagkey_state(unsigned char data) {
|
||||||
fprintf(stderr,"Pins high: ");
|
fprintf(stderr,"Pins high: ");
|
||||||
@ -139,6 +141,25 @@ void jtagkey_state(unsigned char data) {
|
|||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct jtagkey_reader_arg {
|
||||||
|
int num;
|
||||||
|
unsigned char *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *jtagkey_reader(void *thread_arg) {
|
||||||
|
struct jtagkey_reader_arg *arg = (struct jtagkey_reader_arg*)thread_arg;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
DPRINTF("reader for %d bytes\n", arg->num);
|
||||||
|
while (i < arg->num) {
|
||||||
|
i += ftdi_read_data(&ftdic, arg->buf + i, arg->num - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) {
|
int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase, int ecpbase, int num) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -150,6 +171,8 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
static unsigned char writebuf[USBBUFSIZE], *writepos = writebuf;
|
static unsigned char writebuf[USBBUFSIZE], *writepos = writebuf;
|
||||||
static unsigned char readbuf[USBBUFSIZE], *readpos;
|
static unsigned char readbuf[USBBUFSIZE], *readpos;
|
||||||
unsigned char data, prev_data;
|
unsigned char data, prev_data;
|
||||||
|
struct jtagkey_reader_arg targ;
|
||||||
|
pthread_t reader_thread;
|
||||||
|
|
||||||
/* Count reads */
|
/* Count reads */
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
@ -160,27 +183,30 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
if ((writepos-writebuf > sizeof(writebuf)-num) || (nread && writepos-writebuf)) {
|
if ((writepos-writebuf > sizeof(writebuf)-num) || (nread && writepos-writebuf)) {
|
||||||
unsigned char *pos = writebuf;
|
unsigned char *pos = writebuf;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num);
|
DPRINTF("writing %d bytes due to %d following reads in %d chunks or full buffer\n", writepos-writebuf, nread, num);
|
||||||
|
|
||||||
#ifndef SLOW_AND_SAFE
|
#ifndef SLOW_AND_SAFE
|
||||||
jtagkey_set_bbmode(BITMODE_BITBANG);
|
jtagkey_set_bbmode(BITMODE_BITBANG);
|
||||||
|
#endif
|
||||||
|
#ifdef SLOW_AND_SAFE
|
||||||
|
targ.num = writepos-pos;
|
||||||
|
targ.buf = readbuf;
|
||||||
|
pthread_create(&reader_thread, NULL, &jtagkey_reader, &targ);
|
||||||
#endif
|
#endif
|
||||||
while (pos < writepos) {
|
while (pos < writepos) {
|
||||||
len = writepos-pos;
|
len = writepos-pos;
|
||||||
|
|
||||||
if (len > usb_maxlen)
|
if (len > USBBUFSIZE)
|
||||||
len = usb_maxlen;
|
len = USBBUFSIZE;
|
||||||
|
|
||||||
DPRINTF("combined write of %d/%d\n",len,writepos-pos);
|
DPRINTF("combined write of %d/%d\n",len,writepos-pos);
|
||||||
ftdi_write_data(&ftdic, pos, len);
|
ftdi_write_data(&ftdic, pos, len);
|
||||||
#ifdef SLOW_AND_SAFE
|
|
||||||
i = 0;
|
|
||||||
while (i < len) {
|
|
||||||
i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
pos += len;
|
pos += len;
|
||||||
}
|
}
|
||||||
|
#ifdef SLOW_AND_SAFE
|
||||||
|
pthread_join(reader_thread, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
writepos = writebuf;
|
writepos = writebuf;
|
||||||
}
|
}
|
||||||
@ -256,7 +282,7 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nread || (*writepos != prev_data))
|
if (nread || (*writepos != prev_data) || (i == num-1))
|
||||||
writepos++;
|
writepos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,13 +293,14 @@ int jtagkey_transfer(WD_TRANSFER *tr, int fd, unsigned int request, int ppbase,
|
|||||||
*writepos = last_data;
|
*writepos = last_data;
|
||||||
writepos++;
|
writepos++;
|
||||||
|
|
||||||
|
#ifndef SLOW_AND_SAFE
|
||||||
jtagkey_set_bbmode(BITMODE_SYNCBB);
|
jtagkey_set_bbmode(BITMODE_SYNCBB);
|
||||||
|
#endif
|
||||||
|
targ.num = writepos-writebuf;
|
||||||
|
targ.buf = readbuf;
|
||||||
|
pthread_create(&reader_thread, NULL, &jtagkey_reader, &targ);
|
||||||
ftdi_write_data(&ftdic, writebuf, writepos-writebuf);
|
ftdi_write_data(&ftdic, writebuf, writepos-writebuf);
|
||||||
|
pthread_join(reader_thread, NULL);
|
||||||
i = 0;
|
|
||||||
while (i < writepos-writebuf) {
|
|
||||||
i += ftdi_read_data(&ftdic, readbuf, sizeof(readbuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DPRINTF("write: ");
|
DPRINTF("write: ");
|
||||||
|
Reference in New Issue
Block a user