Microsoft MVP성태의 닷넷 이야기
Linux: 3. Synology NAS(DS216+II)에서 FTDI 장치를 C/C++로 제어 [링크 복사], [링크+제목 복사],
조회: 21199
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 8개 있습니다.)
개발 환경 구성: 399. Synology NAS(DS216+II)에 gcc 컴파일러 설치
; https://www.sysnet.pe.kr/2/0/11705

개발 환경 구성: 403. Synology NAS(DS216+II)에 docker 설치 후 .NET Core 2.1 응용 프로그램 실행하는 방법
; https://www.sysnet.pe.kr/2/0/11713

개발 환경 구성: 404. (opkg가 설치된) Synology NAS(DS216+II)에 cmake 설치
; https://www.sysnet.pe.kr/2/0/11718

Linux: 3. Synology NAS(DS216+II)에서 FTDI 장치를 C/C++로 제어
; https://www.sysnet.pe.kr/2/0/11733

Linux: 4. Synology NAS(DS216+II)에 FTDI 장치 연결 후 C#(.NET Core)으로 DTR 제어
; https://www.sysnet.pe.kr/2/0/11734

사물인터넷: 51. Synology NAS(DS216+II)를 이용한 원격 컴퓨터의 전원 스위치 제어
; https://www.sysnet.pe.kr/2/0/11740

개발 환경 구성: 446. Synology NAS를 Windows 10에서 iSCSI로 연결하는 방법
; https://www.sysnet.pe.kr/2/0/11967

개발 환경 구성: 720. Synology NAS - docker 원격 제어를 위한 TCP 바인딩 추가
; https://www.sysnet.pe.kr/2/0/13712




Synology NAS(DS216+II)에서 FTDI 장치를 C/C++로 제어

지난 글에서 살펴본 FTDI 장치도,

PC에 연결해 동작하는 자신만의 USB 장치 만들어 보기
; https://www.sysnet.pe.kr/2/0/11606

Raspberry PI Zero (W)에 FTDI 장치 연결 후 C/C++로 DTR 제어
; https://www.sysnet.pe.kr/2/0/11716

DS216+II 제품에 그냥 USB 케이블로 연결하면 다음과 같이 "FT232 Serial (UART) IC - Future Technology Devices International, Ltd" 장치로 인식이 됩니다.

ftdi_ds216_1.png

연결 및 해제 시 dmesg 로그를 보면 마지막에 다음의 라인이 추가되는데,

[연결했을 때]
usb 1-2: new full-speed USB device number 4 using xhci_hcd

[해제했을 때]
usb 1-2: USB disconnect, device number 4

메시지로 봐서는 USB 장치로써만 인식했을 뿐 Serial 장치로 인식은 안 한 것입니다. 일례로 라즈베리 파이 제로에 연결했을 때는, "FTDI USB Serial Device converter now attached to ttyUSB0"와 같은 메시지로 "ttyUSB0" 장치에 연결되었으므로 명백히 직렬 통신을 할 수 있었지만 "usb 1-2: new full-speed USB device number 4 using xhci_hcd" 이 정도의 메시지로는 그냥 범용 USB 장치가 연결된 것에 불과하므로 직렬 통신 코드를 사용할 수 없습니다.




그런데, 저 장치 정도의 인식만으로 제어를 할 수 있는 라이브러리가 있습니다.

D2XX Direct Drivers
; https://www.ftdichip.com/Drivers/D2XX.htm

FTDI Drivers Installation Guide for Linux - FTDI Chip
; https://www.ftdichip.com/Support/Documents/AppNotes/AN_220_FTDI_Drivers_Installation_Guide_for_Linux.pdf

문서에 따라, 우선 다음의 파일을 내려받아 압축을 해제하고,

~# sudo -i
~# https://www.ftdichip.com/Drivers/D2XX/Linux/libftd2xx-x86_64-1.4.8.gz  // DS216+II 모델의 경우 Intel CPU이므로
~# gunzip libftd2xx1.1.12.tar.gz
~# tar -xvf libftd2xx1.1.12.tar

링크를 걸어준 후 실행 옵션을 변경합니다.

~# cp ./releases/build/lib* /usr/local/lib
~# cd /usr/local/lib
~# ln -s libftd2xx.so.1.1.12 libftd2xx.so
~# chmod 0755 libftd2xx.so.1.1.12

그다음 빌드를 해야 하는데 다음의 글에 따라 gcc 환경을 갖춰야 합니다.

Synology NAS(DS216+II)에 gcc 컴파일러 설치
; https://www.sysnet.pe.kr/2/0/11705

Synology NAS(DS216+II)에서 실행한 gcc의 Segmentation fault
; https://www.sysnet.pe.kr/2/0/11706

이와 함께 make 도구도 설치한 다음,

~# opkg install make

Installing make (4.2.1-2) to root...
Downloading http://pkg.entware.net/binaries/x86-64/make_4.2.1-2_x86-64.ipk
Configuring make.

빌드할 디렉터리로 이동해,

cd ./release/examples

Makefile의 내용에 CC를 gcc로 명명해 줍니다.

export CC = gcc

SUBDIRS = \
        BitMode \
        EEPROM/erase \
        EEPROM/read \
        EEPROM/write \
        EEPROM/user/read \
        EEPROM/user/size \
        EEPROM/user/write \
        Events \
        LargeRead \
        loopback \
        MultiThread \
        SetVIDPID \
        Simple \
        static \
        Timeouts \
        W32/escapeseq \
        W32/events \
        W32/simple \
        W32/timeouts \
        write \

all: subdirs

subdirs:
        for n in $(SUBDIRS); do "$(MAKE)" -C $$n || exit 1; done

clean:
        rm -f *.o *~
        for n in $(SUBDIRS); do "$(MAKE)" -C $$n clean; done

자, 이제 빌드를 하고 ^^

~# make -B

FTDI 장치를 연결한 후 빌드된 예제 중의 하나인 read 프로그램을 수행해 보면,

$ cd ./EEPROM/read
$ ./read

다음과 같은 식의 출력 결과를 확인할 수 있습니다.

~# ./read
Library version = 0x10408
Opening port 0
FT_Open succeeded.  Handle is 0x2582910
FT_GetDeviceInfo succeeded.  Device is type 5.
FT_EE_Read succeeded.

Signature1 = 0
Signature2 = -1
Version = 2
VendorId = 0x0403
ProductId = 0x6001
Manufacturer = FTDI
ManufacturerId = A9
Description = FT232R USB UART
SerialNumber = A901J4AU
MaxPower = 90
PnP = 0
SelfPowered = 0
RemoteWakeup = 1
232R:
-----
        UseExtOsc = 0x0
        HighDriveIOs = 0x0
        EndpointSize = 0x40
        PullDownEnableR = 0x0
        SerNumEnableR = 0x1
        InvertTXD = 0x0
        InvertRXD = 0x0
        InvertRTS = 0x0
        InvertCTS = 0x0
        InvertDTR = 0x0
        InvertDSR = 0x0
        InvertDCD = 0x0
        InvertRI = 0x0
        Cbus0 = 0x3
        Cbus1 = 0x2
        Cbus2 = 0x0
        Cbus3 = 0x1
        Cbus4 = 0x5
        RIsD2XX = 0x0
Returning 0

일단은 좋은 소식입니다. 그런데, 소스 코드를 보면 직렬 통신을 이용하지 않고 FTDI 라이브러리를 직접 사용하는 것을 볼 수 있습니다.

$ cat main.c

/*
        To build use the following gcc statement
        (assuming you have the d2xx library in the /usr/local/lib directory).
        gcc -o read main.c -L. -lftd2xx -Wl,-rpath,/usr/local/lib
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "../../ftd2xx.h"

int main(int argc, char *argv[])
{
        FT_STATUS       ftStatus;
        FT_HANDLE       ftHandle0;
        int iport;
        static FT_PROGRAM_DATA Data;
        static FT_DEVICE ftDevice;
        DWORD libraryVersion = 0;
        int retCode = 0;

        ftStatus = FT_GetLibraryVersion(&libraryVersion);
        if (ftStatus == FT_OK)
        {
                printf("Library version = 0x%x\n", (unsigned int)libraryVersion);
        }
        else
        {
                printf("Error reading library version.\n");
                return 1;
        }

        if(argc > 1) {
                sscanf(argv[1], "%d", &iport);
        }
        else {
                iport = 0;
        }
        printf("Opening port %d\n", iport);

        ftStatus = FT_Open(iport, &ftHandle0);
        if(ftStatus != FT_OK) {
                /*
                        This can fail if the ftdi_sio driver is loaded
                        use lsmod to check this and rmmod ftdi_sio to remove
                        also rmmod usbserial
                 */
                printf("FT_Open(%d) failed\n", iport);
                return 1;
        }

        printf("FT_Open succeeded.  Handle is %p\n", ftHandle0);

        ftStatus = FT_GetDeviceInfo(ftHandle0,
                                    &ftDevice,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL);
        if (ftStatus != FT_OK)
        {
                printf("FT_GetDeviceType FAILED!\n");
                retCode = 1;
                goto exit;
        }

        // ...[생략]...

        FT_Close(ftHandle0);
        printf("Returning %d\n", retCode);
        return retCode;
}

비록 시리얼 통신으로 제어할 수는 없지만 일단 어떻게든 제어할 수 있게 되었으니 이 정도에서 ^^ 만족하겠습니다.




참고로, FTDI 장치를 연결한 상태에서 lsusb 명령어를 내리면 다음과 같은 출력을 보입니다.

$ lsusb
|__usb1          1d6b:0002:0310 09  2.00  480MBit/s 0mA 1IF  (xhci_hcd 0000:00:14.0) hub
  |__1-2         0403:6001:0600 00  2.00   12MBit/s 90mA 1IF  (FTDI FT232R USB UART A901J4AU)
  |__1-5         f400:f400:0100 00  2.00  480MBit/s 200mA 1IF  (Synology DiskStation 650076B3CCCA6016)
|__usb2          1d6b:0003:0310 09  3.00 5000MBit/s 0mA 1IF  (xhci_hcd 0000:00:14.0) hub

출력 결과의 xxxx:xxxx:xxxx 형식은 각각 device_id:vendor_id:revision을 의미합니다. 예를 들어, usb1의 1-2 장치인 경우 device id = 0x0403, vendor id = 0x6001, revision = 6.0이 됩니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 10/11/2018]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
12938정성태1/24/202218185개발 환경 구성: 633. Docker Desktop + k8s 환경에서 local 이미지를 사용하는 방법
12937정성태1/24/202215775.NET Framework: 1139. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 오디오(mp2) 인코딩하는 예제(encode_audio.c) [2]파일 다운로드1
12936정성태1/22/202215370.NET Framework: 1138. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 멀티미디어 파일의 메타데이터를 보여주는 예제(metadata.c)파일 다운로드1
12935정성태1/22/202216043.NET Framework: 1137. ffmpeg의 파일 해시 예제(ffhash.c)를 C#으로 포팅파일 다운로드1
12934정성태1/22/202215466오류 유형: 788. Warning C6262 Function uses '65564' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap. [2]
12933정성태1/21/202215944.NET Framework: 1136. C# - ffmpeg(FFmpeg.AutoGen)를 이용해 MP2 오디오 파일 디코딩 예제(decode_audio.c)파일 다운로드1
12932정성태1/20/202217056.NET Framework: 1135. C# - ffmpeg(FFmpeg.AutoGen)로 하드웨어 가속기를 이용한 비디오 디코딩 예제(hw_decode.c) [2]파일 다운로드1
12931정성태1/20/202213563개발 환경 구성: 632. ASP.NET Core 프로젝트를 AKS/k8s에 올리는 과정
12930정성태1/19/202214814개발 환경 구성: 631. AKS/k8s의 Volume에 파일 복사하는 방법
12929정성태1/19/202214786개발 환경 구성: 630. AKS/k8s의 Pod에 Volume 연결하는 방법
12928정성태1/18/202214583개발 환경 구성: 629. AKS/Kubernetes에서 호스팅 중인 pod에 shell(/bin/bash)로 진입하는 방법
12927정성태1/18/202215126개발 환경 구성: 628. AKS 환경에 응용 프로그램 배포 방법
12926정성태1/17/202215037오류 유형: 787. AKS - pod 배포 시 ErrImagePull/ImagePullBackOff 오류
12925정성태1/17/202215686개발 환경 구성: 627. AKS의 준비 단계 - ACR(Azure Container Registry)에 docker 이미지 배포
12924정성태1/15/202217198.NET Framework: 1134. C# - ffmpeg(FFmpeg.AutoGen)를 이용한 비디오 디코딩 예제(decode_video.c) [2]파일 다운로드1
12923정성태1/15/202215986개발 환경 구성: 626. ffmpeg.exe를 사용해 비디오 파일을 MPEG1 포맷으로 변경하는 방법
12922정성태1/14/202214793개발 환경 구성: 625. AKS - Azure Kubernetes Service 생성 및 SLO/SLA 변경 방법
12921정성태1/14/202212537개발 환경 구성: 624. Docker Desktop에서 별도 서버에 설치한 docker registry에 이미지 올리는 방법
12920정성태1/14/202213856오류 유형: 786. Camtasia - An error occurred with the camera: Failed to Add Video Sampler.
12919정성태1/13/202213396Windows: 199. Host Network Service (HNS)에 의해서 점유되는 포트
12918정성태1/13/202213851Linux: 47. WSL - shell script에서 설정한 환경 변수가 스크립트 실행 후 반영되지 않는 문제
12917정성태1/12/202213045오류 유형: 785. C# - The type or namespace name '...' could not be found (are you missing a using directive or an assembly reference?)
12916정성태1/12/202212325오류 유형: 784. TFS - One or more source control bindings for this solution are not valid and are listed below.
12915정성태1/11/202212945오류 유형: 783. Visual Studio - We didn't find any interpreters
12914정성태1/11/202216139VS.NET IDE: 172. 비주얼 스튜디오 2022의 파이선 개발 환경 지원
12913정성태1/11/202216558.NET Framework: 1133. C# - byte * (바이트 포인터)를 FileStream으로 쓰는 방법 [1]
... 31  32  33  34  35  36  37  38  39  [40]  41  42  43  44  45  ...