簡體   English   中英

使用 ftdi 與 USB 設備通信時出現分段錯誤

[英]Segmentation fault when communicating with USB device using ftdi

我有一個項目需要在 Linux 下使用 Maxon EPOS。 它們提供了在 Linux 下集成的庫和代碼。 鏈接如下,兩個文件 libEposCmd.so 和 libftd2xx.so 復制到 /etc/local/lib 和 /etc/lib 和一個 Definition.h 文件。

按照此過程編譯文件 HelloEposCmd.cpp 並嘗試程序通過 USB 測試與硬件的通信后,代碼會出現分段錯誤。

我在其他機器上嘗試過相同的程序,Ubuntu 14.04 和 16.04 沒有問題。 所以此時我不確定是什么問題,我的機器、代碼、USB 問題或其他問題。

如果有幫助,我的筆記本電腦是 MSI Gl62,在 Ubuntu 16.04LTS 64 位上運行。 我對 Ubuntu 不是很熟悉。

您可以找到 2 個庫文件,Definition.h 文件和 HelloEposCmd.cpp 文件。 http://www.maxonmotor.com/medias/sys_master/root/8815100330014/EPOS-Linux-Library-En.zip以及安裝指南:http: //www.maxonmotor.com/medias/sys_master/root/8821690073118/ EPOS-Command-Library-En.pdf在 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 64 位 - 英特爾酷睿 i7-6700HQ CPU 2.60GHw - Nividia GTX950M

我已經閱讀了 Intel 內核的 elision-unlock 問題,也可能是由顯卡引起的,盡管我不完全理解這些問題,以及這個簡單的程序如何與顯卡相關,甚至使用多個內核。

確保您的 USB 設備從 USB 端口獲得足夠的電量。 如果可能,請嘗試提供外部電源。 如果設備沒有外接電源,請嘗試使用帶外接電源的 USB 集線器。

根據我的經驗,如果 USB 設備消耗過多的電流,它可能會導致 USB 供電設備暫時關閉(例如,由於突然的高電流消耗,5V 電源電壓降至 3v 以下,導致設備重置,PC 認為它得到了拔掉電源)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM