- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在努力移植现有的功能性 C# 应用程序,该应用程序使用 FTDI D2XX C# .NET wrapper在 Windows 上,转向 Linux 和 Mono。我已按照有关安装 Linux D2XX driver 的说明进行操作.当检测到我们在 Linux 上运行时,我们会在 C# .NET 包装器中查找并加载 Linux 驱动程序,而不是 Windows 驱动程序。
完成这项工作后,我们的大部分应用程序代码仍然没有问题,但是当使用 SetEventNotification 函数设置的事件在 FT_EVENT_RXCHAR 事件上触发时,应用程序似乎崩溃了。
C# 应用程序的流程是:
更多细节:
几个问题:
非常感谢您提供的任何见解。
编辑:
堆栈跟踪现在附在下面。
我尝试转向轮询方法,但似乎在我们执行 FTDI 读取时可能会有一个“帧”数据未完全写入,并且我们将在数据中出现间隙。
我已联系 FTDI 寻求有关此问题的一些指导。如果我收到可行的回复,将会更新。
# mono --debug ./CT4USB.exe
Native stacktrace:
mono() [0x49d5fc]
mono() [0x424a0e]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10330) [0x7f3253539330]
/lib/x86_64-linux-gnu/libpthread.so.0(pthread_mutex_lock+0x4) [0x7f3253533404]
/usr/local/lib/libftd2xx.so(+0x12f52) [0x7f324b9d1f52]
/usr/local/lib/libftd2xx.so(+0x134f1) [0x7f324b9d24f1]
/usr/local/lib/libftd2xx.so(processor_thread+0x21b) [0x7f324b9d29bd]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x8184) [0x7f3253531184]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x7f325325e37d]
Debug info from gdb:
[New LWP 5654]
[New LWP 5653]
[New LWP 5652]
[New LWP 5645]
[New LWP 5644]
[New LWP 5643]
[New LWP 5642]
[New LWP 5641]
[New LWP 5640]
[New LWP 5639]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f3253538b9d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
Id Target Id Frame
11 Thread 0x7f32523ff700 (LWP 5639) "mono" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
10 Thread 0x7f3252a81700 (LWP 5640) "Finalizer" sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:85
9 Thread 0x7f3253efa700 (LWP 5641) "mono" __clock_nanosleep (clock_id=1, flags=1, req=0x7f3253ef9d80, rem=0x7f325326c974 <__clock_nanosleep+132>) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:49
8 Thread 0x7f324bfff700 (LWP 5642) "Threadpool work" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
7 Thread 0x7f324bdfe700 (LWP 5643) "Threadpool work" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
6 Thread 0x7f324b9be700 (LWP 5644) "Threadpool work" 0x00007f3253250fdd in poll () at ../sysdeps/unix/syscall-template.S:81
5 Thread 0x7f324b1bd700 (LWP 5645) "Threadpool work" 0x00007f3253250fdd in poll () at ../sysdeps/unix/syscall-template.S:81
4 Thread 0x7f324a7ff700 (LWP 5652) "Threadpool work" pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
3 Thread 0x7f3249ffe700 (LWP 5653) "Threadpool work" 0x00007f3253538ed9 in __libc_waitpid (pid=5655, stat_loc=0x7f3249ffce4c, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:40
2 Thread 0x7f32497fd700 (LWP 5654) "Threadpool work" pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
* 1 Thread 0x7f325405d7c0 (LWP 5638) "mono" 0x00007f3253538b9d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
Thread 11 (Thread 0x7f32523ff700 (LWP 5639)):
#0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1 0x00000000005f9aec in ?? ()
#2 0x00007f3253531184 in start_thread (arg=0x7f32523ff700) at pthread_create.c:312
#3 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 10 (Thread 0x7f3252a81700 (LWP 5640)):
#0 sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:85
#1 0x000000000061de28 in mono_sem_wait ()
#2 0x00000000005a2076 in ?? ()
#3 0x00000000005843d3 in ?? ()
#4 0x0000000000624666 in ?? ()
#5 0x00007f3253531184 in start_thread (arg=0x7f3252a81700) at pthread_create.c:312
#6 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 9 (Thread 0x7f3253efa700 (LWP 5641)):
#0 __clock_nanosleep (clock_id=1, flags=1, req=0x7f3253ef9d80, rem=0x7f325326c974 <__clock_nanosleep+132>) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:49
#1 0x00000000006122c8 in ?? ()
#2 0x0000000000588244 in ?? ()
#3 0x00000000005843d3 in ?? ()
#4 0x0000000000624666 in ?? ()
#5 0x00007f3253531184 in start_thread (arg=0x7f3253efa700) at pthread_create.c:312
#6 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 8 (Thread 0x7f324bfff700 (LWP 5642)):
#0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
#1 0x00000000005fef90 in ?? ()
#2 0x00000000006117a2 in ?? ()
#3 0x00000000005840fd in ?? ()
#4 0x00000000005853e6 in ?? ()
#5 0x00000000418b9b0e in ?? ()
#6 0x0000000000000000 in ?? ()
Thread 7 (Thread 0x7f324bdfe700 (LWP 5643)):
#0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
#1 0x000000000061b982 in ?? ()
#2 0x0000000000586b58 in ?? ()
#3 0x00000000005843d3 in ?? ()
#4 0x0000000000624666 in ?? ()
#5 0x00007f3253531184 in start_thread (arg=0x7f324bdfe700) at pthread_create.c:312
#6 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 6 (Thread 0x7f324b9be700 (LWP 5644)):
#0 0x00007f3253250fdd in poll () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007f324b9f2a52 in linux_netlink_event_thread_main () from /usr/local/lib/libftd2xx.so
#2 0x00007f3253531184 in start_thread (arg=0x7f324b9be700) at pthread_create.c:312
#3 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 5 (Thread 0x7f324b1bd700 (LWP 5645)):
#0 0x00007f3253250fdd in poll () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007f324b9eb14e in handle_events () from /usr/local/lib/libftd2xx.so
#2 0x00007f324b9eb569 in libusb_handle_events_timeout_completed () from /usr/local/lib/libftd2xx.so
#3 0x00007f324b9eb674 in libusb_handle_events_timeout () from /usr/local/lib/libftd2xx.so
#4 0x00007f324b9c924f in poll_async_libusb () from /usr/local/lib/libftd2xx.so
#5 0x00007f3253531184 in start_thread (arg=0x7f324b1bd700) at pthread_create.c:312
#6 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 4 (Thread 0x7f324a7ff700 (LWP 5652)):
#0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
#1 0x00007f324b9cf9fe in EventWait () from /usr/local/lib/libftd2xx.so
#2 0x00007f324b9d2651 in reader_thread () from /usr/local/lib/libftd2xx.so
#3 0x00007f3253531184 in start_thread (arg=0x7f324a7ff700) at pthread_create.c:312
#4 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 3 (Thread 0x7f3249ffe700 (LWP 5653)):
#0 0x00007f3253538ed9 in __libc_waitpid (pid=5655, stat_loc=0x7f3249ffce4c, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:40
#1 0x000000000049d689 in ?? ()
#2 0x0000000000424a0e in ?? ()
#3 <signal handler called>
#4 __GI___pthread_mutex_lock (mutex=0x0) at ../nptl/pthread_mutex_lock.c:66
#5 0x00007f324b9d1f52 in signalSomeEvents () from /usr/local/lib/libftd2xx.so
#6 0x00007f324b9d24f1 in ProcessBulkInData () from /usr/local/lib/libftd2xx.so
#7 0x00007f324b9d29bd in processor_thread () from /usr/local/lib/libftd2xx.so
#8 0x00007f3253531184 in start_thread (arg=0x7f3249ffe700) at pthread_create.c:312
#9 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 2 (Thread 0x7f32497fd700 (LWP 5654)):
#0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1 0x00007f324b9cf904 in EventWait () from /usr/local/lib/libftd2xx.so
#2 0x00007f324b9cbfd1 in write_thread () from /usr/local/lib/libftd2xx.so
#3 0x00007f3253531184 in start_thread (arg=0x7f32497fd700) at pthread_create.c:312
#4 0x00007f325325e37d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Thread 1 (Thread 0x7f325405d7c0 (LWP 5638)):
#0 0x00007f3253538b9d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
#1 0x00000000005fedfa in ?? ()
#2 0x000000000061101b in ?? ()
#3 0x000000000058415e in ?? ()
#4 0x0000000000585309 in ?? ()
#5 0x00000000418b3e8d in ?? ()
#6 0x00000000015de450 in ?? ()
#7 0x00007ffc9ba9b960 in ?? ()
#8 0x00007f3253fb8130 in ?? ()
#9 0x00007f3252400578 in ?? ()
#10 0x00007f3252400528 in ?? ()
#11 0x00000000015a41e0 in ?? ()
#12 0x00000000418b3e07 in ?? ()
#13 0x00007ffc9ba9b4d0 in ?? ()
#14 0x00007ffc9ba9b450 in ?? ()
/build/buildd/gdb-7.7.1/gdb/dwarf2-frame.c:692: internal-error: Unknown CFI encountered.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) [answered Y; input not from terminal]
/build/buildd/gdb-7.7.1/gdb/dwarf2-frame.c:692: internal-error: Unknown CFI encountered.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Create a core file of GDB? (y or n) [answered Y; input not from terminal]
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
Aborted (core dumped)
编辑第二个:
Mono 的 SafeWaitHandle 和 SetEventNotification 的预期参数的表示完全不同。因为 FTDI D2XX 库试图将 SafeWaitHandle 视为 EVENT_HANDLE(在 ftd2xx.h header 中定义;基本上是 pthread_cond_t 和 pthread_mutex_t),我认为这就是我们发生崩溃的原因。
我想我可以通过在 FTDI D2XX C# .NET 包装器中使用 P/Invoke 和 libpthread 来继续执行 pthread 条件和互斥锁以及 Mono SafeWaitHandle 之间的必要转换。此时,我需要工作的 C 代码,它将在 FTDI D2XX 的 pthread_cond_wait 上循环和阻塞。我还没有得到该代码的工作。如果有人有建议,请在下面列出:
/*/*
gcc -o SetEventNotification_separate_thread SetEventNotification_separate_thread.c -lpthread -lftd2xx -Wl,-rpath /usr/local/lib
*/
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include "../ftd2xx.h"
static FT_HANDLE ft_handle;
// Seems like this sort of stuff should have been provided by FTDI
static const char *ft_errors[] =
{
[FT_OK] = "Success",
[FT_INVALID_HANDLE] = "Invalid device handle",
[FT_DEVICE_NOT_FOUND] = "Device not found",
[FT_DEVICE_NOT_OPENED] = "Device not opened",
[FT_IO_ERROR] = "Input/output error",
[FT_INSUFFICIENT_RESOURCES] = "Insufficient resources",
[FT_INVALID_PARAMETER] = "Invalid parameter",
[FT_INVALID_BAUD_RATE] = "Invalid baud rate",
[FT_DEVICE_NOT_OPENED_FOR_ERASE] = "Device not opened for erase",
[FT_DEVICE_NOT_OPENED_FOR_WRITE] = "Device not opened for write",
[FT_FAILED_TO_WRITE_DEVICE] = "Failed to write device",
[FT_EEPROM_READ_FAILED] = "EEPROM read failed",
[FT_EEPROM_WRITE_FAILED] = "EEPROM write failed",
[FT_EEPROM_ERASE_FAILED] = "EEPROM erase failed",
[FT_EEPROM_NOT_PRESENT] = "EEPROM not present",
[FT_EEPROM_NOT_PROGRAMMED] = "EEPROM not programmed",
[FT_INVALID_ARGS] = "Invalid argument",
[FT_NOT_SUPPORTED] = "Not supported",
[FT_OTHER_ERROR] = "Other error"
};
static const int num_ft_errors = sizeof(ft_errors) / sizeof(ft_errors[FT_OK]);
static const char *ft_strerror(FT_STATUS ft_status)
{
if (ft_status < 0 // Should be impossible because it is unsigned
|| ft_status >= num_ft_errors
|| !ft_errors[ft_status])
{
return "Unknown error";
}
return ft_errors[ft_status];
}
static void ft_error_exit(const char *str, FT_STATUS ft_status)
{
if (str && *str)
fprintf(stderr, "%s: %sn", str, ft_strerror(ft_status));
else
fprintf(stderr, "%sn", ft_strerror(ft_status));
exit(1);
}
static void pthread_error_exit(const char *str, int err)
{
if (str && *str)
fprintf(stderr, "%s: %sn", str, strerror(err));
else
fprintf(stderr, "%sn", strerror(err));
exit(1);
}
static void std_error_exit(const char *str)
{
perror(str);
exit(1);
}
// Reader thread function
static void *reader_func(void *arg)
{
FT_STATUS ft_status;
EVENT_HANDLE eh;
DWORD chars_in_q;
char buf[8192];
int pterr;
if ((pterr = pthread_mutex_init(&eh.eMutex, NULL)))
pthread_error_exit("pthread_mutex_init", pterr);
if ((pterr = pthread_cond_init(&eh.eCondVar, NULL)))
pthread_error_exit("pthread_cond_init", pterr);
if ((ft_status = FT_SetEventNotification(ft_handle, FT_EVENT_RXCHAR,
(PVOID)&eh)) != FT_OK)
ft_error_exit("FT_SetEventNotification", ft_status);
for (;;)
{
printf("at for: chars_in_q: %d\n", chars_in_q);
if ((pterr = pthread_mutex_lock(&eh.eMutex))){
pthread_error_exit("pthread_mutex_lock", pterr);
printf("pthread_mutex_lock failed...\n");
}
printf("pthread_mutex_lock\n");
if ((ft_status = FT_GetQueueStatus(ft_handle, &chars_in_q)) != FT_OK)
ft_error_exit("FT_GetQueueStatus", ft_status);
printf("before if (chars_in_q == 0): chars_in_q: %d\n", chars_in_q);
// while (chars_in_q == 0)
// {
printf("<<----------- SetEventNotification pthread_cond_wait --------------->>\n");
if ((pterr = pthread_cond_wait(&eh.eCondVar, &eh.eMutex)))
pthread_error_exit("pthread_cond_wait", pterr);
printf("pthread_cond_wait\n");
if ((ft_status = FT_GetQueueStatus(ft_handle,
&chars_in_q)) != FT_OK)
ft_error_exit("FT_GetQueueStatus", ft_status);
printf("before if (chars_in_q == 0): chars_in_q: %d\n", chars_in_q);
// }
if ((pterr = pthread_mutex_unlock(&eh.eMutex)))
pthread_error_exit("pthread_mutex_unlock", pterr);
printf("pthread_mutex_unlock\n");
while (chars_in_q)
{
printf("at while (chars_in_q): chars_in_q: %d\n", chars_in_q);
DWORD len_to_read, len_read;
ssize_t len_written;
len_to_read = (chars_in_q > sizeof(buf)) ? sizeof(buf) : chars_in_q;
if ((ft_status = FT_Read(ft_handle, (LPVOID)buf,
len_to_read, &len_read)) != FT_OK)
ft_error_exit("FT_Read", ft_status);
if (!len_read)
{
fprintf(stderr, "FT_Read returned no data.n");
exit(1);
}
len_written = printf("%s\n", buf);
printf("len_to_read: %d\n", len_to_read);
printf("len_read: %d\n", len_read);
chars_in_q -= len_read;
}
}
}
int main(int argc, char *argv[])
{
FT_STATUS ft_status;
DWORD devCount;
DWORD devIndex = 0; // first device
DWORD numDevices = 1;
char serialNumber[64]; // more than enough room!
const unsigned int baudrate = 8000000;
FT_DEVICE_LIST_INFO_NODE * devInfo;
devInfo = malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevices);
ft_status = FT_CreateDeviceInfoList(&devCount);
if( ft_status != FT_OK)
{
printf("No devices connected!\n");
exit(-1);
}
printf("Devices found: %d\n", devCount);
ft_status = FT_ListDevices((PVOID)devIndex, serialNumber, FT_LIST_BY_INDEX|FT_OPEN_BY_SERIAL_NUMBER);
if ( ft_status == FT_OK)
{
// FT_ListDevices OK, serial number is in serialNumber
printf("Device Serial Number: %s\n", serialNumber);
}
else
{
// FT_ListDevices failed
}
ft_status = FT_OpenEx(serialNumber, FT_OPEN_BY_SERIAL_NUMBER, &ft_handle);
printf("after calling FT_OpenEx\n");
if ( ft_status == FT_OK)
{
// FT_OpenEx OK, ft_handle not null
printf("FT_OpenEx succeeded\n");
}
else
{
printf("FT_OpenEx failed\n");
}
ft_status = FT_SetBaudRate(ft_handle, baudrate);
if ( ft_status == FT_OK)
{
// FT_SetBaudRate OK
printf("FT_SetBaudRate succeeded\n");
}
else
{
printf("FT_SetBaudRate failed\n");
}
ft_status = FT_SetFlowControl(ft_handle, FT_FLOW_RTS_CTS, 0, 0);
if ( ft_status == FT_OK)
{
// FT_SetFlowControl OK
printf("FT_SetFlowControl succeeded\n");
}
else
{
printf("FT_SetFlowControl failed\n");
}
// Flush the FTDI's buffers
if ((ft_status = FT_Purge(ft_handle, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)
ft_error_exit("FT_Purge", ft_status);
// Create reader and writer threads.
int pterr;
sigset_t sig_set;
(void)sigfillset(&sig_set);
pthread_attr_t ptattr;
if ((pterr = pthread_attr_init(&ptattr)))
pthread_error_exit("pthread_attr_init", pterr);
if ((pterr = pthread_attr_setdetachstate(&ptattr,
PTHREAD_CREATE_DETACHED)))
pthread_error_exit("pthread_attr_setdetachstate", pterr);
pthread_t reader_id, writer_id;
if ((pterr = pthread_create(&reader_id, &ptattr, reader_func, NULL)))
pthread_error_exit("pthread_create reader", pterr);
// Now wait for a signal to terminate us
int caught_sig;
if (sigwait(&sig_set, &caught_sig))
std_error_exit("sigwait");
exit(0);
}
gcc -o SetEventNotification_separate_thread SetEventNotification_separate_thread.c -lpthread -lftd2xx -Wl,-rpath /usr/local/lib
*/
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include "../ftd2xx.h"
static FT_HANDLE ft_handle;
// Seems like this sort of stuff should have been provided by FTDI
static const char *ft_errors[] =
{
[FT_OK] = "Success",
[FT_INVALID_HANDLE] = "Invalid device handle",
[FT_DEVICE_NOT_FOUND] = "Device not found",
[FT_DEVICE_NOT_OPENED] = "Device not opened",
[FT_IO_ERROR] = "Input/output error",
[FT_INSUFFICIENT_RESOURCES] = "Insufficient resources",
[FT_INVALID_PARAMETER] = "Invalid parameter",
[FT_INVALID_BAUD_RATE] = "Invalid baud rate",
[FT_DEVICE_NOT_OPENED_FOR_ERASE] = "Device not opened for erase",
[FT_DEVICE_NOT_OPENED_FOR_WRITE] = "Device not opened for write",
[FT_FAILED_TO_WRITE_DEVICE] = "Failed to write device",
[FT_EEPROM_READ_FAILED] = "EEPROM read failed",
[FT_EEPROM_WRITE_FAILED] = "EEPROM write failed",
[FT_EEPROM_ERASE_FAILED] = "EEPROM erase failed",
[FT_EEPROM_NOT_PRESENT] = "EEPROM not present",
[FT_EEPROM_NOT_PROGRAMMED] = "EEPROM not programmed",
[FT_INVALID_ARGS] = "Invalid argument",
[FT_NOT_SUPPORTED] = "Not supported",
[FT_OTHER_ERROR] = "Other error"
};
static const int num_ft_errors = sizeof(ft_errors) / sizeof(ft_errors[FT_OK]);
static const char *ft_strerror(FT_STATUS ft_status)
{
if (ft_status < 0 // Should be impossible because it is unsigned
|| ft_status >= num_ft_errors
|| !ft_errors[ft_status])
{
return "Unknown error";
}
return ft_errors[ft_status];
}
static void ft_error_exit(const char *str, FT_STATUS ft_status)
{
if (str && *str)
fprintf(stderr, "%s: %sn", str, ft_strerror(ft_status));
else
fprintf(stderr, "%sn", ft_strerror(ft_status));
exit(1);
}
static void pthread_error_exit(const char *str, int err)
{
if (str && *str)
fprintf(stderr, "%s: %sn", str, strerror(err));
else
fprintf(stderr, "%sn", strerror(err));
exit(1);
}
static void std_error_exit(const char *str)
{
perror(str);
exit(1);
}
// Reader thread function
static void *reader_func(void *arg)
{
FT_STATUS ft_status;
EVENT_HANDLE eh;
DWORD chars_in_q;
char buf[8192];
int pterr;
if ((pterr = pthread_mutex_init(&eh.eMutex, NULL)))
pthread_error_exit("pthread_mutex_init", pterr);
if ((pterr = pthread_cond_init(&eh.eCondVar, NULL)))
pthread_error_exit("pthread_cond_init", pterr);
if ((ft_status = FT_SetEventNotification(ft_handle, FT_EVENT_RXCHAR,
(PVOID)&eh)) != FT_OK)
ft_error_exit("FT_SetEventNotification", ft_status);
for (;;)
{
printf("at for: chars_in_q: %d\n", chars_in_q);
if ((pterr = pthread_mutex_lock(&eh.eMutex))){
pthread_error_exit("pthread_mutex_lock", pterr);
printf("pthread_mutex_lock failed...\n");
}
printf("pthread_mutex_lock\n");
if ((ft_status = FT_GetQueueStatus(ft_handle, &chars_in_q)) != FT_OK)
ft_error_exit("FT_GetQueueStatus", ft_status);
printf("before if (chars_in_q == 0): chars_in_q: %d\n", chars_in_q);
// while (chars_in_q == 0)
// {
printf("<<----------- SetEventNotification pthread_cond_wait --------------->>\n");
if ((pterr = pthread_cond_wait(&eh.eCondVar, &eh.eMutex)))
pthread_error_exit("pthread_cond_wait", pterr);
printf("pthread_cond_wait\n");
if ((ft_status = FT_GetQueueStatus(ft_handle,
&chars_in_q)) != FT_OK)
ft_error_exit("FT_GetQueueStatus", ft_status);
printf("before if (chars_in_q == 0): chars_in_q: %d\n", chars_in_q);
// }
if ((pterr = pthread_mutex_unlock(&eh.eMutex)))
pthread_error_exit("pthread_mutex_unlock", pterr);
printf("pthread_mutex_unlock\n");
while (chars_in_q)
{
printf("at while (chars_in_q): chars_in_q: %d\n", chars_in_q);
DWORD len_to_read, len_read;
ssize_t len_written;
len_to_read = (chars_in_q > sizeof(buf)) ? sizeof(buf) : chars_in_q;
if ((ft_status = FT_Read(ft_handle, (LPVOID)buf,
len_to_read, &len_read)) != FT_OK)
ft_error_exit("FT_Read", ft_status);
if (!len_read)
{
fprintf(stderr, "FT_Read returned no data.n");
exit(1);
}
len_written = printf("%s\n", buf);
printf("len_to_read: %d\n", len_to_read);
printf("len_read: %d\n", len_read);
chars_in_q -= len_read;
}
}
}
int main(int argc, char *argv[])
{
FT_STATUS ft_status;
DWORD devCount;
DWORD devIndex = 0; // first device
DWORD numDevices = 1;
char serialNumber[64]; // more than enough room!
const unsigned int baudrate = 8000000;
FT_DEVICE_LIST_INFO_NODE * devInfo;
devInfo = malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevices);
ft_status = FT_CreateDeviceInfoList(&devCount);
if( ft_status != FT_OK)
{
printf("No devices connected!\n");
exit(-1);
}
printf("Devices found: %d\n", devCount);
ft_status = FT_ListDevices((PVOID)devIndex, serialNumber, FT_LIST_BY_INDEX|FT_OPEN_BY_SERIAL_NUMBER);
if ( ft_status == FT_OK)
{
// FT_ListDevices OK, serial number is in serialNumber
printf("Device Serial Number: %s\n", serialNumber);
}
else
{
// FT_ListDevices failed
}
ft_status = FT_OpenEx(serialNumber, FT_OPEN_BY_SERIAL_NUMBER, &ft_handle);
printf("after calling FT_OpenEx\n");
if ( ft_status == FT_OK)
{
// FT_OpenEx OK, ft_handle not null
printf("FT_OpenEx succeeded\n");
}
else
{
printf("FT_OpenEx failed\n");
}
ft_status = FT_SetBaudRate(ft_handle, baudrate);
if ( ft_status == FT_OK)
{
// FT_SetBaudRate OK
printf("FT_SetBaudRate succeeded\n");
}
else
{
printf("FT_SetBaudRate failed\n");
}
ft_status = FT_SetFlowControl(ft_handle, FT_FLOW_RTS_CTS, 0, 0);
if ( ft_status == FT_OK)
{
// FT_SetFlowControl OK
printf("FT_SetFlowControl succeeded\n");
}
else
{
printf("FT_SetFlowControl failed\n");
}
// Flush the FTDI's buffers
if ((ft_status = FT_Purge(ft_handle, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)
ft_error_exit("FT_Purge", ft_status);
// Create reader and writer threads.
int pterr;
sigset_t sig_set;
(void)sigfillset(&sig_set);
pthread_attr_t ptattr;
if ((pterr = pthread_attr_init(&ptattr)))
pthread_error_exit("pthread_attr_init", pterr);
if ((pterr = pthread_attr_setdetachstate(&ptattr,
PTHREAD_CREATE_DETACHED)))
pthread_error_exit("pthread_attr_setdetachstate", pterr);
pthread_t reader_id, writer_id;
if ((pterr = pthread_create(&reader_id, &ptattr, reader_func, NULL)))
pthread_error_exit("pthread_create reader", pterr);
// Now wait for a signal to terminate us
int caught_sig;
if (sigwait(&sig_set, &caught_sig))
std_error_exit("sigwait");
exit(0);
}
它总是卡在 pthread_cond_wait 上。如有任何想法,我们将不胜感激。
最佳答案
再次没有答案,但我不知道 Mono 是如何定义的EventWaitHandle.SafeWaitHandle.
在 FTDI for Linux (c) 提供的示例中,这是定义
FT_HANDLE ftHandle;
FT_STATUS ftStatus;
EVENT_HANDLE eh;
DWORD EventMask;
ftStatus = FT_Open(0, &ftHandle);
if(ftStatus != FT_OK) {
// FT_Open failed
return;
}
pthread_mutex_init(&eh.eMutex, NULL);
pthread_cond_init(&eh.eCondVar, NULL);
EventMask = FT_EVENT_RXCHAR | FT_EVENT_MODEM_STATUS;
ftStatus = FT_SetEventNotification(ftHandle, EventMask, (PVOID)&eh);
所以我想知道这是否与SafeWaitHandle的定义有关
关于c# - 在 Linux/Mono 上运行的 FTDI D2XX C# .NET Wrapper - SetEventNotification 被触发似乎使程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37056602/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!