Discussion:
Question about ftdi_readstream()
r***@agilent.com
2018-06-01 02:36:40 UTC
Permalink
Hi,


I'm trying to get ftdi_readstream() working but must have some fundamental misunderstanding.


I'd like it to work in the background (or in another thread) and simply parse data while I am free to use ftdi_write_data() to send commands to my application.


I declare a handler that simply prints data to the console:


static int readcallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata)
{
int i;
printf("callback! %d\n", length);
if (length) {
for (i = 0; i < length; i ++) {
printf("%d 0x%2x\n", i, buffer[i]);
}
}
return (exitRequested ? 1 : 0);
}



Then I register the callback:


err = ftdi_readstream(&ftdic, readcallback, NULL, 8, 256);
printf("error: %d\n", err);
if (err < 0 && !exitRequested) {
exit(1);
}

ftdi_readstream() never returns. I was expecting it to create a separate thread, and asynchronously handle incoming data. I expected that I could set it up and then start using ftdi_write_data() to send control requests to my application.

Digging a little deeper, I can determine that my readcallback() routine gets called continuously at high speed with length=0.

Do I have to start readcallback() in it's own thread myself?

I am also unclear on the purpose of the 8,256 arguments. I thought it should get a callback on every transfer. Do the 8,256 arguments bundle these up into larger chunks? Can I set them to be 1,1 for minimal latency?

Everything works fine if I simply do ftdi_write_data() followed by ftdi_read_data() in a while(1) loop. I'd just like to increase efficiency by making reads happen in the background.

kind regards,
--
Rick Walker




--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Heinrich du Toit
2018-06-01 05:37:24 UTC
Permalink
Ftdi_readstream is a callback. If you go look at the code this will be obvious.

If you want "background" or "async" I/O you should use ftdi_write_data_submit and ftdi_read_data_submit followed later by ftdi_transfer_data_done.
Note that ftdi_transfer_data_done is also a blocking call.

Alternatively you can use ftdi_readstream in a thread... this is called blocking I/O normally.



Heinrich du Toit

Specialist Engineer: Software

[cid:emailfooterbase_93ec2d11-74f4-4d98-9ea6-a2dc6dcb552e.png]<http://www.s-plane.com>

Disclaimers are available at: http://www.s-plane.com/disclaimer
From: ***@agilent.com <***@agilent.com>
Sent: Friday, 01 June 2018 4:37 AM
To: ***@developer.intra2net.com
Subject: Question about ftdi_readstream()


Hi,



I'm trying to get ftdi_readstream() working but must have some fundamental misunderstanding.



I'd like it to work in the background (or in another thread) and simply parse data while I am free to use ftdi_write_data() to send commands to my application.



I declare a handler that simply prints data to the console:


static int readcallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata)
{
int i;
printf("callback! %d\n", length);
if (length) {
for (i = 0; i < length; i ++) {
printf("%d 0x%2x\n", i, buffer[i]);
}
}
return (exitRequested ? 1 : 0);
}


Then I register the callback:


err = ftdi_readstream(&ftdic, readcallback, NULL, 8, 256);
printf("error: %d\n", err);
if (err < 0 && !exitRequested) {
exit(1);
}

ftdi_readstream() never returns. I was expecting it to create a separate thread, and asynchronously handle incoming data. I expected that I could set it up and then start using ftdi_write_data() to send control requests to my application.

Digging a little deeper, I can determine that my readcallback() routine gets called continuously at high speed with length=0.

Do I have to start readcallback() in it's own thread myself?

I am also unclear on the purpose of the 8,256 arguments. I thought it should get a callback on every transfer. Do the 8,256 arguments bundle these up into larger chunks? Can I set them to be 1,1 for minimal latency?

Everything works fine if I simply do ftdi_write_data() followed by ftdi_read_data() in a while(1) loop. I'd just like to increase efficiency by making reads happen in the background.

kind regards,
--
Rick Walker



________________________________

libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com<mailto:libftdi+***@developer.intra2net.com>



--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
r***@agilent.com
2018-06-01 20:57:12 UTC
Permalink
Thanks for the clarification, Heinrich. I appreciate your help.


I'll try putting ftdi_readstream in a pthread. It will field responses coming back from the network modules and keep a shared memory structure updated with the system state.


--

Rick

________________________________
From: Heinrich du Toit <***@s-plane.com>
Sent: Thursday, May 31, 2018 10:37:24 PM
To: ***@developer.intra2net.com
Subject: RE: Question about ftdi_readstream()


Ftdi_readstream is a callback. If you go look at the code this will be obvious.



If you want “background” or “async” I/O you should use ftdi_write_data_submit and ftdi_read_data_submit followed later by ftdi_transfer_data_done.

Note that ftdi_transfer_data_done is also a blocking call.



Alternatively you can use ftdi_readstream in a thread… this is called blocking I/O normally.





Heinrich du Toit

Specialist Engineer: Software

[cid:emailfooterbase_93ec2d11-74f4-4d98-9ea6-a2dc6dcb552e.png]<http://www.s-plane.com>

Disclaimers are available at: http://www.s-plane.com/disclaimer

From: ***@agilent.com <***@agilent.com>
Sent: Friday, 01 June 2018 4:37 AM
To: ***@developer.intra2net.com
Subject: Question about ftdi_readstream()



Hi,



I'm trying to get ftdi_readstream() working but must have some fundamental misunderstanding.



I'd like it to work in the background (or in another thread) and simply parse data while I am free to use ftdi_write_data() to send commands to my application.



I declare a handler that simply prints data to the console:



static int readcallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata)
{
int i;
printf("callback! %d\n", length);
if (length) {
for (i = 0; i < length; i ++) {
printf("%d 0x%2x\n", i, buffer[i]);
}
}
return (exitRequested ? 1 : 0);
}


Then I register the callback:



err = ftdi_readstream(&ftdic, readcallback, NULL, 8, 256);
printf("error: %d\n", err);
if (err < 0 && !exitRequested) {
exit(1);
}

ftdi_readstream() never returns. I was expecting it to create a separate thread, and asynchronously handle incoming data. I expected that I could set it up and then start using ftdi_write_data() to send control requests to my application.

Digging a little deeper, I can determine that my readcallback() routine gets called continuously at high speed with length=0.

Do I have to start readcallback() in it's own thread myself?

I am also unclear on the purpose of the 8,256 arguments. I thought it should get a callback on every transfer. Do the 8,256 arguments bundle these up into larger chunks? Can I set them to be 1,1 for minimal latency?

Everything works fine if I simply do ftdi_write_data() followed by ftdi_read_data() in a while(1) loop. I'd just like to increase efficiency by making reads happen in the background.

kind regards,
--
Rick Walker





________________________________

libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com<mailto:libftdi+***@developer.intra2net.com>



________________________________

libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com<mailto:libftdi+***@developer.intra2net.com>



--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+***@developer.intra2net.com
Loading...