libftdi1学习笔记 1 - 打开/关闭设备

目录

[1. 获取版本信息](#1. 获取版本信息)

[2. 创建上下文对象](#2. 创建上下文对象)

[3. 查找FTDI设备](#3. 查找FTDI设备)

[4. 获取字符串描述符](#4. 获取字符串描述符)

[5. 指定接口](#5. 指定接口)

[6. 打开设备](#6. 打开设备)

[6.1 指定VID/PID的方式](#6.1 指定VID/PID的方式)

[6.2 指定描述符的方式](#6.2 指定描述符的方式)

[6.3 指定描述符和设备索引的方式](#6.3 指定描述符和设备索引的方式)

[6.4 其他方式](#6.4 其他方式)

[7. 关闭设备](#7. 关闭设备)


libftdi1是一个升级版本的库(旧的版本是libftdi),用于与FTDI芯片进行通信。在Ubuntu系统中可以先安装好ibftdi1库。

bash 复制代码
sudo apt-get install libftdi1-dev

其他系统可以下载源代码编译安装。

下载一个通用makefile。

bash 复制代码
####################################################
# Generic makefile - 万能Makefile
# for compiling and linking C++ projects on Linux 
# Author: George Foot  Modified:Jackie Lee
####################################################
### Customising
#
# Adjust the following if necessary; EXECUTABLE is the target
# executable's filename, and LIBS is a list of libraries to link in
# (e.g. alleg, stdcx, iostr, etc). You can override these on make's
# command line of course, if you prefer to do it that way.
#
#
# 可执行文件名
EXECUTABLE := 
# 静态库目录
LIBDIR:=                                    
# 静态库 文 件 名
LIBS := 
# 头文件目录
INCLUDES:=
# 除了当前目录外,其他的源代码文件目录
SRCDIR:=
#
# # Now alter any implicit rules' variables if you like, e.g.:
 
CC:=gcc
CPP:=g++
CFLAGS := -g -Wall -O3
CPPFLAGS := $(CFLAGS)
CPPFLAGS += $(addprefix -I,$(INCLUDES))
CPPFLAGS += -MMD
#
# # The next bit checks to see whether rm is in your djgpp bin
# # directory; if not it uses del instead, but this can cause (harmless)
# # `File not found' error messages. If you are not using DOS at all,
# # set the variable to something which will unquestioningly remove
# # files.
#

RM-F := rm -f 
 
# # You shouldn't need to change anything below this point.
#
SRCS_CPP = $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp, $(SRCDIR)))
SRCS_C := $(wildcard *.c) $(wildcard $(addsuffix /*.c, $(SRCDIR))) 
OBJS_C := $(patsubst %.c,%.o,$(SRCS_C))
OBJS_CPP := $(patsubst %.cpp,%.o,$(SRCS_CPP))
DEPS := $(patsubst %.o,%.d,$(OBJS_C)) $(patsubst %.o,%.d,$(OBJS_CPP))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))

.PHONY : all deps objs clean veryclean rebuild info

all: $(EXECUTABLE)

deps : $(DEPS)

clean :
		@$(RM-F) *.o
		@$(RM-F) *.d
veryclean: clean
		@$(RM-F) $(EXECUTABLE)

rebuild: veryclean all
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
		@$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS_CPP) $(OBJS_C)
		$(CC) -o $(EXECUTABLE) $(OBJS_CPP) $(OBJS_C) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS)) -lstdc++
info:
		@echo $(SRCS_CPP)
		@echo $(SRCS_C)
		@echo $(OBJS_CPP)
		@echo $(OBJS_C)
		@echo $(DEPS)
		@echo $(MISSING_DEPS)
		@echo $(MISSING_DEPS_SOURCES)

新建一个libftdi1-example的文件夹,然后在该文件夹内创建上面的makefile和main.c。编辑makefile文件:

bash 复制代码
EXECUTABLE := libftdi1-example
# 静态库目录
LIBDIR:= /usr/lib/x86_64-linux-gnu/
# 静态库 文 件 名
LIBS := ftdi1

下载libftdi1的源代码,找到ftdi.h文件,拷贝到当前文件夹。编辑main.c

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include "ftdi.h"

int main(void)
{

    return -1;
}

运行make编译,此时应该可以编译通过。

bash 复制代码
libftdi-example$ make
gcc -o libftdi1-example  main.o -L/usr/lib/x86_64-linux-gnu/ -lftdi1 -lstdc++

1. 获取版本信息

可以通过函数ftdi_get_library_version获取库的版本信息。

cpp 复制代码
struct ftdi_version_info version;
version = ftdi_get_library_version();
fprintf(stdout, "version:%d.%d.%d, %s\n", 
    version.major, version.minor, version.micro, version.version_str);

运行结果:

bash 复制代码
libftdi-example$ ./libftdi1-example 
version:1.5.0, 1.5

2. 创建上下文对象

在使用libftdi1的API函数前,需要先创建一个FTDI的上下文对象。

cpp 复制代码
struct ftdi_context *ftdi_new(void)

使用结束后需要通过ftdi_free释放该对象。

cpp 复制代码
void ftdi_free(struct ftdi_context *ftdi)

参考例程:

cpp 复制代码
struct ftdi_context *ftdi;
if ((ftdi = ftdi_new()) == 0)
{
    fprintf(stderr, "ftdi_new failed\n");
    return EXIT_FAILURE;
}

ftdi_free(ftdi);

3. 查找FTDI设备

查找USB总线上指定VID:PID的所有ftdi设备。注意,使用后需要由ftdi_list_free()释放。

cpp 复制代码
int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, int vendor, int product)

参数说明:

  • ftdi - 上下文对象,即ftdi_new的返回值。
  • devlist - 保存找到的设备列表
  • vendor, product - 指定设备的VID和PID,如果为0则表示查找所有的FTDI设备。

返回值表示找到的设备数。

参考例程:

cpp 复制代码
struct ftdi_device_list *devlist;
int devnum = 0;
if ((devnum = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0)
{
    fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ftdi_get_error_string(ftdi));
    ftdi_free(ftdi);
    return EXIT_FAILURE;
}

ftdi_list_free(&devlist);

4. 获取字符串描述符

获取设备的制造商、产品描述和序列号。

cpp 复制代码
int ftdi_usb_get_strings(struct ftdi_context *ftdi,
                         struct libusb_device *dev,
                         char *manufacturer, int mnf_len,
                         char *description, int desc_len,
                         char *serial, int serial_len)
  • ftdi - 上下文对象,即ftdi_new的返回值。
  • dev - USB设备对象
  • manufacturer/mnf_len - 制造商字符串缓存及长度
  • description/desc_len - 产品字符串缓存及长度
  • serial/serial_len - 序列号缓存及长度

注意,这个函数必须放在ftdi_usb_find_all后执行,因为使用后关闭了内部"usb_dev"。

如果manufacturer、description和serial设置为NULL则表示不读取该字符串。

参考例程:

bash 复制代码
    struct ftdi_device_list *curdev;
    char manufacturer[128], description[128], serial[128];
    int i;

    printf("Number of FTDI devices found: %d\n", devnum);
    curdev = devlist;
    for(i = 0; i < devnum; i++)
    {
        if (ftdi_usb_get_strings(ftdi, curdev->dev, manufacturer, 128, description, 128, serial, 128) < 0)
        {
            fprintf(stderr, "ftdi_usb_get_strings failed: (%s)\n", ftdi_get_error_string(ftdi));
            ftdi_list_free(&devlist);
            ftdi_free(ftdi);
            return EXIT_FAILURE;
        }
        printf("Manufacturer: %s, Description: %s, Serial: %s\n\n", manufacturer, description, serial);
        curdev = curdev->next;
    }

注意,运行这个例程时需要管理员权限(sudo ./libftd1i-example),否则会报

bash 复制代码
ftdi_usb_get_strings failed: (libusb_open() failed)

运行结果:

bash 复制代码
libftdi-example$ sudo ./libftdi1-example 
version:1.5.0, 1.5
Number of FTDI devices found: 1
Manufacturer: FTDI, Description: FT4232H MiniModule, Serial: FT8NZV77

5. 指定接口

对于多接口的设备(例如FT2232H/FT4232H),可以指定不同的接口(例如FT2232H支持2路接口,而FT4232H支持4路)。

cpp 复制代码
int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface)

参数说明:

  • ftdi - 上下文对象,即ftdi_new的返回值。
  • interface - 指定的接口。INTERFACE_ANY表示第一个
cpp 复制代码
enum ftdi_interface
{
    INTERFACE_ANY = 0,
    INTERFACE_A   = 1,
    INTERFACE_B   = 2,
    INTERFACE_C   = 3,
    INTERFACE_D   = 4
};

返回值说明:

  • 0 - 指定成功
  • -1 - 指定的接口不支持
  • -2 - 无效的USB设备
  • -3 - 设备已经打开,不能再指定接口

参考例程:

cpp 复制代码
ftdi_set_interface(ftdi, INTERFACE_A);

6. 打开设备

6.1 指定VID/PID的方式

cpp 复制代码
int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product)

该函数实际上是调用ftdi_usb_open_desc,其中字符串描述符参数部分为NULL

6.2 指定描述符的方式

cpp 复制代码
int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product,
                       const char* description, const char* serial)

该函数实际上是调用ftdi_usb_open_desc_index,其中设备索引参数部分为0

6.3 指定描述符和设备索引的方式

cpp 复制代码
int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product,
                             const char* description, const char* serial, unsigned int index)

参数说明:

  • 其他略
  • index - 设备索引值,一般为0,当有多个相同设备(PID、VID、描述符都相同)时才有意义。

注意参数vendor和product必须指定,不能设置为0。

返回值说明:

  • 0 - 打开设备成功
  • -1 - 调用底层usb_find_busses()失败
  • -2 - 调用底层usb_find_devices()失败
  • -3 - 没找到对应设备
  • -4 - 打开设备失败
  • -5 - 无法声明设备
  • -6 - 复位失败
  • -7 - 设置波特率失败
  • -8 - 获取产品描述符失败
  • -9 - 获取序列号失败
  • -10 - 无法关闭设备
  • -11 - ftdi上下文对象无效
  • -12 - 调用底层libusb_get_device_list()失败

参考例程:

cpp 复制代码
    int ret;
    ret = ftdi_usb_open_desc_index(ftdi, 0x0403, 0x6011, NULL, NULL, 0);
    if(ret < 0)
    {
        printf("Open device Fail: %d\n", ret);
        ftdi_list_free(&devlist);
        ftdi_free(ftdi);
        return EXIT_FAILURE;
    }
    printf("Open device OK: %d\n", ret);

    ftdi_usb_close(ftdi);

运行结果:

cpp 复制代码
libftdi-example$ sudo ./libftdi1-example 
version:1.5.0, 1.5
Number of FTDI devices found: 1
Manufacturer: FTDI, Description: FT4232H MiniModule, Serial: FT8NZV77

Open device OK: 0

6.4 其他方式

略过,包括ftdi_usb_open_bus_addr、ftdi_usb_open_string、ftdi_usb_open_dev

7. 关闭设备

cpp 复制代码
int ftdi_usb_close(struct ftdi_context *ftdi)

在ftdi_free前要关闭设备。

相关推荐
懒惰的bit2 小时前
基础网络安全知识
学习·web安全·1024程序员节
2401_858286113 小时前
L7.【LeetCode笔记】相交链表
笔记·leetcode·链表
Natural_yz4 小时前
大数据学习09之Hive基础
大数据·hive·学习
龙中舞王5 小时前
Unity学习笔记(2):场景绘制
笔记·学习·unity
Natural_yz5 小时前
大数据学习10之Hive高级
大数据·hive·学习
love_and_hope5 小时前
Pytorch学习--神经网络--完整的模型训练套路
人工智能·pytorch·python·深度学习·神经网络·学习
青椒大仙KI115 小时前
24/11/7 算法笔记 PCA主成分分析
笔记·算法·信息可视化
夜雨星辰4876 小时前
Android Studio 学习——整体框架和概念
android·学习·android studio
奔跑的花短裤6 小时前
少儿编程启蒙学习
学习·青少年编程·机器人·ai编程
光明中黑暗6 小时前
机器学习 笔记
人工智能·笔记·机器学习