I have the following program, which uses the ftd2xx library to write a byte to an USB device and then reads the reply.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include "../ftd2xx.h"
void fatal (const char *format,...) {
va_list argp;
fprintf(stderr, "FATAL: ");
va_start(argp, format);
vfprintf(stderr, format, argp);
va_end(argp);
fprintf(stderr, "\n");
exit(3);
}
int main(int argc, char* argv[]) {
int pid = fork();
if (pid > 0) { //replace with: if (pid == 0) {
FT_STATUS ftStatus;
printf("before FT_OpenEx\n");
FT_HANDLE ftHandle;
if ((ftStatus = FT_OpenEx("DA011SCV", FT_OPEN_BY_SERIAL_NUMBER, &ftHandle)) != FT_OK) fatal("FT_OpenEx failed");
printf("before FT_Write\n");
uint8_t buffer[1];
buffer[0] = 0x55;
DWORD bytesWritten;
if ((ftStatus = FT_Write(ftHandle, buffer, sizeof(buffer), &bytesWritten)) != FT_OK) fatal("FT_Write failed");
printf("before FT_Read\n");
DWORD bytesRead;
if ((ftStatus = FT_Read(ftHandle, buffer, 1, &bytesRead)) != FT_OK) fatal("FT_Read failed");
if (bytesRead > 0) {
printf("FT_Read data=0x%02X\n", buffer[0]);
} else {
printf("FT_Read no data\n");
}
printf("before FT_Close\n");
if ((ftStatus = FT_Close(ftHandle)) != FT_OK) fatal("FT_Close failed");
printf("press Enter to exit\n");
}
getchar();
exit(0);
}
The code as shown produces this output:
//Output if (pid > 0)
before FT_OpenEx
before FT_Write
before FT_Read
FT_Read data=0x55
before FT_Close
press Enter to exit
However, if I change the condition of the first if
from (pid > 0)
to (pid == 0)
, i.e. if I do the USB communication in the child process, then the program hangs in the FT_Read()
function and the output is:
//Output if (pid == 0)
before FT_OpenEx
before FT_Write
before FT_Read
Why does this happen?
Some details:
- The USB chip in the device is a FT240X with factory setting.
- The USB device acts like an echo: every byte it receives is immediately sent back.
- I checked with a protocol analyzer that the transmitted byte values are correct.
- The ftd2xx library version is 1.1.12.
What you're describing sounds like there's a bug in the ftd2xx library -- it's possible that the library performs some initialization when it's loaded which becomes invalid when the process ID changes.
The ftd2xx library is closed-source and distributed under a license that prohibits reverse-engineering, so there's no way for me to tell for sure what's going on. You may want to try using an open-source FTDI library, such as libftdi, instead.
The library is strange - I had the same problem. For me it helped to load the library dynamically after calling the
fork()
. Check this post https://stackoverflow.com/a/7626550/907675 to see how to dynamically load a function from a library.