使用FTDI与USB设备通信时分割故障

Segmentation fault when communicating with USB device using ftdi

本文关键字:通信 分割 故障 FTDI USB 使用      更新时间:2023-10-16

我有一个项目,需要在Linux下使用Maxon Epos。他们提供库和代码以在Linux下集成。链接可在下面提供,2个文件libeposcmd.so和libftd2xx.so将复制到/etc/etc/local/lib和/etc/lib和defacit.h file.h文件。

遵循该过程后,编译文件hellyeposcmd.cpp并尝试通过USB测试与硬件进行测试的程序,该代码会得出细分故障。

我在其他机器上尝试了相同的过程,Ubuntu 14.04和16.04毫无麻烦。因此,在这一点

如果可以帮助您,我的笔记本电脑是MSI GL62,并且在Ubuntu 16.04LTS上运行64位。我对Ubuntu并不熟悉。

您可以找到两个库文件,definition.h file和helloeposcmd.cpp文件。http://www.maxonmotor.com/medias/sys_master/root/8815100330014/epos-linux-linux-lirary-en.zip和安装指南:http://www.maxonmotor.com/medias/sys_master/root/8821690073118/epos-command-library-en.pdf at 9-Integration at 9- Integration段。

这是代码的示例:

#include <iostream>
#include "Definitions.h"
#include <string.h>
#include <sstream>
#include <unistd.h>
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <list>
#include <math.h>
typedef void* HANDLE;
typedef int BOOL;
using namespace std;
void* g_pKeyHandle = 0;
unsigned short g_usNodeId = 1;
string g_deviceName;
string g_protocolStackName;
string g_interfaceName;
string g_portName;
int g_baudrate = 0;
const string g_programName = "HelloEposCmd";
#ifndef MMC_SUCCESS
#define MMC_SUCCESS 0
#endif
#ifndef MMC_FAILED
#define MMC_FAILED 1
#endif
#ifndef MMC_MAX_LOG_MSG_SIZE
#define MMC_MAX_LOG_MSG_SIZE 512
#endif
void  LogError(string functionName, int p_lResult, unsigned int p_ulErrorCode);
void  LogInfo(string message);
void  PrintUsage();
void  PrintHeader();
void  PrintSettings();
int   OpenDevice(unsigned int* p_pErrorCode);
int   CloseDevice(unsigned int* p_pErrorCode);
void  SetDefaultParameters();
int   ParseArguments(int argc, char** argv);
int   DemoProfilePositionMode(HANDLE p_DeviceHandle, unsigned short p_usNodeId, unsigned int & p_rlErrorCode);
int   Demo(unsigned int* p_pErrorCode);

出现segfault的功能:

int OpenDevice(unsigned int* p_pErrorCode)
{
int lResult = MMC_FAILED;
char* pDeviceName = new char[255];
char* pProtocolStackName = new char[255];
char* pInterfaceName = new char[255];
char* pPortName = new char[255];
strcpy(pDeviceName, g_deviceName.c_str());
strcpy(pProtocolStackName, g_protocolStackName.c_str());
strcpy(pInterfaceName, g_interfaceName.c_str());
strcpy(pPortName, g_portName.c_str());
LogInfo("Open device...");
g_pKeyHandle = VCS_OpenDevice(pDeviceName, pProtocolStackName, pInterfaceName, pPortName, p_pErrorCode);
if(g_pKeyHandle!=0 && *p_pErrorCode == 0)
{
    unsigned int lBaudrate = 0;
    unsigned int lTimeout = 0;
    if(VCS_GetProtocolStackSettings(g_pKeyHandle, &lBaudrate, &lTimeout, p_pErrorCode)!=0)
    {
        if(VCS_SetProtocolStackSettings(g_pKeyHandle, g_baudrate, lTimeout, p_pErrorCode)!=0)
        {
            if(VCS_GetProtocolStackSettings(g_pKeyHandle, &lBaudrate, &lTimeout, p_pErrorCode)!=0)
            {
                if(g_baudrate==(int)lBaudrate)
                {
                    lResult = MMC_SUCCESS;
                }
            }
        }
    }
}
else
{
    g_pKeyHandle = 0;
}
delete []pDeviceName;
delete []pProtocolStackName;
delete []pInterfaceName;
delete []pPortName;
return lResult;
}

主要:

int main(int argc, char** argv)
{
int lResult = MMC_FAILED;
unsigned int ulErrorCode = 0;
PrintHeader();
SetDefaultParameters();
if((lResult = ParseArguments(argc, argv))!=MMC_SUCCESS)
{
    return lResult;
}
PrintSettings();
if((lResult = OpenDevice(&ulErrorCode))!=MMC_SUCCESS)
{
    LogError("OpenDevice", lResult, ulErrorCode);
    return lResult;
}
if((lResult = PrepareDemo(&ulErrorCode))!=MMC_SUCCESS)
{
    LogError("PrepareDemo", lResult, ulErrorCode);
    return lResult;
}
if((lResult = Demo(&ulErrorCode))!=MMC_SUCCESS)
{
    LogError("Demo", lResult, ulErrorCode);
    return lResult;
}
if((lResult = CloseDevice(&ulErrorCode))!=MMC_SUCCESS)
{
    LogError("CloseDevice", lResult, ulErrorCode);
    return lResult;
}
return lResult;
}

GDB回溯的结果:

~/EPOS_Linux_Library/example/src$ gdb HelloEposCmd coreGNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from HelloEposCmd...(no debugging symbols found)...done.
[New LWP 2436]
[New LWP 2437]
[New LWP 2439]
[New LWP 2440]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./HelloEposCmd'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fc3eca0a960 in _xend ()
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:33
33  ../sysdeps/unix/sysv/linux/x86/elision-unlock.c: No such file or directory.
[Current thread is 1 (Thread 0x7fc3edcbc740 (LWP 2436))]

(gdb) backtrace
#0  0x00007fc3eca0a960 in _xend ()
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:33
 #1  __lll_unlock_elision (lock=0x10a1138, private=0)
at ../sysdeps/unix/sysv/linux/x86/elision-unlock.c:29
#2  0x00007fc3ec7e2934 in EventDestroy () from /usr/local/lib/libftd2xx.so
#3  0x00007fc3ec7db2e8 in FT_Close () from /usr/local/lib/libftd2xx.so
#4  0x00007fc3ec7e166b in FT_CreateDeviceInfoList ()
 from /usr/local/lib/libftd2xx.so
#5  0x00007fc3ed82c911 in CMmcFtd2xxHndlBase::CreateDeviceInfoList(unsigned int*) () from /usr/local/lib/libEposCmd.so
#6  0x00007fc3ed82ca88 in CMmcFtd2xxHndlBase::GetDeviceInfos(std::list<CUsbDeviceInfo*, std::allocator<CUsbDeviceInfo*> >&, unsigned short, unsigned short) ()
from /usr/local/lib/libEposCmd.so
#7  0x00007fc3ed7e2346 in CGatewayUSBToFtd2xxDrv::GetDeviceInfos(std::list<CUsbDeviceInfo*, std::allocator<CUsbDeviceInfo*> >&) ()
from /usr/local/lib/libEposCmd.so
#8  0x00007fc3ed7e2b48 in CGatewayUSBToFtd2xxDrv::InitPortList() ()
from /usr/local/lib/libEposCmd.so
#9  0x00007fc3ed7deed1 in CPort_USB::InitGateway(CStdStr<char>, CGatewayIToDrv*) () from /usr/local/lib/libEposCmd.so
#10 0x00007fc3ed7df232 in CPort_USB::InitPort(CStdStr<char>, CGatewayIToDrv*, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
 #11 0x00007fc3ed7cb04f in CInterface_USB::InitPort(CStdStr<char>, CErrorInfo*)
---Type <return> to continue, or q <return> to quit---
() from /usr/local/lib/libEposCmd.so
#12 0x00007fc3ed7cb19e in CInterface_USB::InitInterface(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#13 0x00007fc3ed7caada in CInterface_USB::InitInterface(CErrorInfo*) ()
 from /usr/local/lib/libEposCmd.so
#14 0x00007fc3ed7a6a92 in CInterfaceManager::I_InitInterface(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#15 0x00007fc3ed7923ec in CProtocolStackBase::InitProtocolStack(CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#16 0x00007fc3ed7646e9 in CProtocolStackManager::PS_InitProtocolStack(CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#17 0x00007fc3ed73ce84 in CDeviceBase::InitDevice(CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#18 0x00007fc3ed6d06de in CDeviceCommandSetManager::DCS_InitDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) ()
 from /usr/local/lib/libEposCmd.so
#19 0x00007fc3ed6aebd6 in CVirtualDeviceBase::InitVirtualDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) () from /usr/local/lib/libEposCmd.so
#20 0x00007fc3ed684deb in CVirtualCommandSet_Manager::VCS_InitVirtualDevice(CStdStr<char>, CStdStr<char>, CStdStr<char>, CStdStr<char>, CErrorInfo*) ()
 from /usr/local/lib/libEposCmd.so
#21 0x00007fc3ed66d112 in CCommunicationModel::CreateVirtualCommandSetManager()
 () from /usr/local/lib/libEposCmd.so
---Type <return> to continue, or q <return> to quit---
#22 0x00007fc3ed67ca75 in VCS_OpenDevice () from /usr/local/lib/libEposCmd.so
 #23 0x000000000040206e in OpenDevice(unsigned int*) ()
 #24 0x0000000000403a6c in main ()

对于USB通信,我修改了提供的99-ftdi.rules文件:

SUBSYSTEM=="usb|usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a8b0", GROUP="dialout", MODE="666", SYMLINK+="ftd2xx%n"

并复制到"/etc/udev/rules.d/"(与其他机器一起使用)。

感谢您的帮助

更新:使用最新版本的FTDI(1.3.6)无济于事。

由于它特定于我的计算机,以下是规格,如果可以有所帮助: - 双启动Windows 10 -Ubuntu 16.04LTS 64BITS-Intel Core i7-6700HQ CPU 2.60GHW-Nividia gtx950m

我已经阅读了用英特尔内核阅读Elision-unlock的问题,也许也可能是由图形卡引起的,尽管我不完全理解这些问题,以及这个简单的程序与图形卡有何关系,甚至使用多个内核。

确保您的USB设备从USB端口获得足够的电源。尽可能尝试提供外部电源。如果设备没有外部电源,请尝试使用带有外部电源的USB集线器。

根据我的经验,如果USB设备绘制过多的电流,则可能导致暂时关闭到USB驱动的设备(例如,由于突然的高电流绘制而导致3V以下的5V电源降低,导致设备重置,其中PC认为它被拔掉了)。