- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在为科学相机编写驱动程序。它使用 Cypress FX3 USB 外设 Controller 。为了与之通信,我使用 libusb1 for python,特别是模块 usb1。我的操作系统是 Ubuntu 16.04 LTS。
通信有两个步骤:
摄像头已配置。计算机同步发送指令对摄像头进行编程,每条指令后摄像头响应一个状态字,同步读取。
拍了一张照片。计算机同步发送一条指令,相机开始传输数据。计算机以异步方式读取此数据。
异步通信在主线程中完成。所以即使通信本身是异步的,操作也是阻塞的。
每次异步传输时我都得到 TRANSFER_NO_DEVICE 状态,这很奇怪,因为我刚刚在配置步骤中与相机通信。我在 Windows 中使用 cypress 库在 C# 中有一个类似的代码并且它工作正常,所以我可以排除相机。此外,在尝试拍照后,部分图像数据出现在 FX3 缓冲区中,我可以使用 cypress 提供的示例应用程序恢复这些数据。
我已经构建了一个最小的示例脚本。注意 configure 和 take_picture 函数:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# StackOverflow.py
import usb1 as usb1 # Libusb, needed to provide a usb context
import GuideCamLib.binary as binary # Handles bytecode formatting
import GuideCamLib.ccd as ccd # Generates configuration information
import GuideCamLib.usb as usb # Manages communication
# Camera usb parameters
vid = 0x04B4;
pid = 0x00F1;
read_addr = 0x81;
write_addr = 0x01;
interface = 0;
success = [0x55, 0x55, 0x55, 0x55] + [0]*(512 - 4); # A successful response
# Objects that generate instructions for the camera
ccd0 = ccd.CCD_47_10();
formatter = binary.ByteCode();
def configure(context):
# Generating bytes to transfer, outputs a list of int lists
bytecode_lines = ccd0.create_configuration_bytecode(formatter);
# Opens device
with usb.Device(vid=vid, pid=pid, context= context) as dev:
# Opens read / write ports
port_write = dev.open_port(write_addr);
port_read = dev.open_port(read_addr);
print(" Start configuration...")
# Transfer synchronously
for line in bytecode_lines:
written_bytes = port_write.write_sync(line);
response = port_read.read_sync(512);
if(response != success):
raise RuntimeError(" Configuration failed. (" + str(response) + ")");
print(" End configuration")
def take_picture(context):
# Generating bytes to transfer, generates a list of ints
take_photo_bytecode = formatter.seq_take_photo(ccd0.get_take_photo_mode_address());
# Opens device
with usb.Device(vid=vid, pid=pid, context= context) as dev:
# Opens read / write ports
port_write = dev.open_port(write_addr);
port_read = dev.open_port(read_addr, 10000); # 10 sec timeout
# Prepare asynchronous read
print(" Prepare read")
with port_read.read_async(512) as data_collector:
print(" Writing")
written_bytes = port_write.write_sync(take_photo_bytecode); # Write synchronously
print(" Reading...")
recieved_image = data_collector(); # Read asynchronously (but in a blocking manner)
print " Recieved: " + str(len(recieved_image)) + " bytes.";
with usb1.USBContext() as context:
print "Configuring camera:"
configure(context); # Configure camera
print "Taking picture:"
take_picture(context); # Take picture
print "Done."
这是用于所需上下文的 GuideCamLib/usb.py。类 _TransferCollector 完成大部分工作,而 _AsyncReader 只是一个具有状态的函数。端口和设备只是辅助类,以减少每次传输中的样板代码:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# GuideCamLib/usb.py
import usb1 as usb
import six as six
import traceback
# For human-readable printing
transfer_status_dict = \
{ \
usb.TRANSFER_COMPLETED : "TRANSFER_COMPLETED",
usb.TRANSFER_ERROR : "TRANSFER_ERROR",
usb.TRANSFER_TIMED_OUT : "TRANSFER_TIMED_OUT",
usb.TRANSFER_CANCELLED : "TRANSFER_CANCELLED",
usb.TRANSFER_STALL : "TRANSFER_STALL",
usb.TRANSFER_NO_DEVICE : "TRANSFER_NO_DEVICE",
usb.TRANSFER_OVERFLOW : "TRANSFER_OVERFLOW" \
};
# Callback to accumulate succesive transfer calls
class _AsyncReader:
def __init__(self):
self.transfers = [];
def __call__(self, transfer):
print "Status: " + transfer_status_dict[transfer.getStatus()]; # Prints the status of the transfer
if(transfer.getStatus() != usb.TRANSFER_COMPLETED):
return;
else:
self.transfers.append(transfer.getBuffer()[:transfer.getActualLength()]);
transfer.submit();
# A collector of asyncronous transfer's data.
# Stops collection after port.timeout time of recieving the last transfer.
class _TransferCollector:
# Prepare data collection
def __init__(self, transfer_size, pararell_transfers, port):
self.interface_handle = port.device.dev.claimInterface(port.interface);
self.reader = _AsyncReader();
self.port = port;
transfers = [];
# Queue transfers
for ii in range(pararell_transfers):
transfer = port.device.dev.getTransfer();
transfer.setBulk(
port.address,
transfer_size,
callback=self.reader,
timeout=port.timeout );
transfer.submit();
transfers.append(transfer);
self.transfers = transfers;
def __enter__(self):
self.interface_handle.__enter__();
return self;
def __exit__(self, exception_type, exception_value, traceback):
self.interface_handle.__exit__(exception_type, exception_value, traceback);
# Activate data collection
def __call__(self):
# Collect tranfers with _AsyncReader while there are active transfers.
while any(x.isSubmitted() for x in self.transfers):
try:
self.port.device.context.handleEvents();
except usb.USBErrorInterrupted:
pass;
return [six.byte2int(d) for data in self.reader.transfers for d in data];
# Port class for creating syncronous / asyncronous transfers
class Port:
def __init__(self, device, address, timeout = None):
self.device = device;
self.address = address;
self.interface = self.device.interface;
self.timeout = timeout;
if(timeout is None):
self.timeout = 0;
def read_sync(self, length):
with self.device.dev.claimInterface(self.interface):
data = self.device.dev.bulkRead(self.address, length, timeout=self.timeout);
return [six.byte2int(d) for d in data];
def write_sync(self, data):
data = [six.int2byte(d) for d in data];
with self.device.dev.claimInterface(self.interface):
return self.device.dev.bulkWrite(self.address, data, timeout=self.timeout);
# Make asyncronous transfers blocking. Collects data as long as the device
# sends data more frecuently than self.timeout or all the transfers fails
def read_async(self, length, pararell_transfers = 32):
return _TransferCollector(length, pararell_transfers, self);
# Device class for creating ports
class Device:
def __init__(self, vid = None, pid = None, context = None, interface = 0):
if(not context):
self.backend = usb.USBContext();
context = self.backend.__enter__();
self.context = context;
self.interface = interface;
self.dev = context.openByVendorIDAndProductID(vid, pid, skip_on_error = False);
if self.dev is None:
raise RuntimeError('Device not found');
def __enter__(self):
return self;
def __exit__(self, exception_type, exception_value, traceback):
if(hasattr(self, "backend")):
self.backend.__exit__(exception_type, exception_value, traceback);
def open_port(self, address, timeout = None):
return Port(self, address, timeout);
脚本输出以下内容,清楚地表明同步传输是成功的,但每个排队的异步传输都失败并返回 NO_DEVICE:
>>> python StackOverflow.py
Configuring camera:
Start configuration...
End configuration
Taking picture:
Prepare read
Writing
Reading...
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Status: TRANSFER_NO_DEVICE
Traceback (most recent call last):
File "StackOverflow.py", line 70, in <module>
take_picture(context); # Take picture
File "StackOverflow.py", line 62, in take_picture
recieved_image = data_collector();
File "/media/jabozzo/Data/user_data/jabozzo/desktop/sigmamin/code/workspace_Python/USB/USB wxglade libusb1/GuideCamLib/usb.py", line 62, in __exit__
self.interface_handle.__exit__(exception_type, exception_value, traceback);
File "/home/jabozzo/.local/lib/python2.7/site-packages/usb1.py", line 1036, in __exit__
self._handle.releaseInterface(self._interface)
File "/home/jabozzo/.local/lib/python2.7/site-packages/usb1.py", line 1171, in releaseInterface
libusb1.libusb_release_interface(self.__handle, interface),
File "/home/jabozzo/.local/lib/python2.7/site-packages/usb1.py", line 121, in mayRaiseUSBError
raiseUSBError(value)
File "/home/jabozzo/.local/lib/python2.7/site-packages/usb1.py", line 117, in raiseUSBError
raise STATUS_TO_EXCEPTION_DICT.get(value, USBError)(value)
usb1.USBErrorNotFound: LIBUSB_ERROR_NOT_FOUND [-5]
我已经更改了 Device 和 Port 类,以便在打开设备时打开接口(interface)。这样接口(interface)只打开(和关闭)一次,与打开的端口数无关:
# Port class for creating syncronous / asyncronous transfers
class Port:
def __init__(self, device, address, timeout = None):
self.device = device;
self.address = address;
self.timeout = timeout;
if(timeout is None):
self.timeout = 0;
def read_sync(self, length):
data = self.device.dev.bulkRead(self.address, length, timeout=self.timeout);
return [six.byte2int(d) for d in data];
def write_sync(self, data):
data = [six.int2byte(d) for d in data];
return self.device.dev.bulkWrite(self.address, data, timeout=self.timeout);
# Make asyncronous transfers blocking. Collects data as long as the device
# sends data more frecuently than self.timeout or all the transfers fails
def read_async(self, length, pararell_transfers = 32):
return _TransferCollector(length, pararell_transfers, self);
# Device class for creating ports
class Device:
def __init__(self, vid = None, pid = None, context = None, interface = 0):
if(not context):
self.backend = usb.USBContext();
context = self.backend.__enter__();
self.context = context;
self.interface = interface;
self.dev = context.openByVendorIDAndProductID(vid, pid, skip_on_error = False);
if self.dev is None:
raise RuntimeError('Device not found');
self.interface_handle = self.dev.claimInterface(self.interface);
def __enter__(self):
self.interface_handle.__enter__();
return self;
def __exit__(self, exception_type, exception_value, traceback):
self.interface_handle.__exit__(exception_type, exception_value, traceback);
if(hasattr(self, "backend")):
self.backend.__exit__(exception_type, exception_value, traceback);
def open_port(self, address, timeout = None):
return Port(self, address, timeout);
我仍然有同样的错误。但是打印显示它在读取准备时失败了:
>>> python StackOverflow.py
Configuring camera:
Start configuration...
End configuration
Taking picture:
Prepare read
Traceback (most recent call last):
...
我开始怀疑我不需要打开接口(interface)来执行异步传输。
最佳答案
作为dryman指出,我在完成之前释放了上下文(因为我打开了上下文两次)。如果我们在代码提取中内联 read_async 和 write_sync 调用:
print(" Prepare read")
with port_read.read_async(512) as data_collector:
print(" Writing")
written_bytes = port_write.write_sync(take_photo_bytecode); # Write synchronously
print(" Reading...")
recieved_image = data_collector(); # Read asynchronously (but in a blocking manner)
我们会得到类似下面的伪代码:
print(" Prepare read")
with port_read.claimInterface(0) as ?:
# Read preparation code
print(" Writing")
with port_write.claimInterface(0) as ?:
written_bytes = # Write synchronously
# Here the port_write.claimInterface context has exited,
# leaving the prepared read transfers in a invalid state.
print(" Reading...")
recieved_image = # Read asynchronously (Fails, out of interface context)
在我的问题更新中,我忘记删除 _TransferCollector 上的接口(interface)声明,所以我遇到了类似的问题。应用问题更新并将 _TransferCollector 定义为:
# A collector of asyncronous transfer's data.
# Stops collection after port.timeout time of recieving the last transfer.
class _TransferCollector:
# Prepare data collection
def __init__(self, transfer_size, pararell_transfers, port):
self.reader = _AsyncReader();
self.port = port;
transfers = [];
# Queue transfers
for ii in range(pararell_transfers):
transfer = port.device.dev.getTransfer();
transfer.setBulk(
port.address,
transfer_size,
callback=self.reader,
timeout=port.timeout );
transfer.submit();
transfers.append(transfer);
self.transfers = transfers;
# Activate data collection
def __call__(self):
# Collect tranfers with _AsyncReader while there are active transfers.
while any(x.isSubmitted() for x in self.transfers):
try:
self.port.device.context.handleEvents();
except usb.USBErrorInterrupted:
pass;
return [six.byte2int(d) for data in self.reader.transfers for d in data];
解决了这个问题。
请注意,现在必须对调用 read_async 进行一些更改:
# Prepare asynchronous read
print(" Prepare read")
data_collector = port_read.read_async(512):
print(" Writing")
written_bytes = port_write.write_sync(take_photo_bytecode); # Write synchronously
print(" Reading...")
recieved_image = data_collector(); # Read asynchronously (but in a blocking manner)
print " Recieved: " + str(len(recieved_image)) + " bytes.";
关于 python libusb1 : asynchronous TRANSFER_NO_DEVICE status just after successful syncronous transfers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38779019/
I made an example , 我直接从 jQuery website 复制了它然而,它不会转移.. HTML: BLAHHHH
所以我对名字有一些误解STATE TRANSFER在 REPRESENTATIONAL STATE TRANSFER. 是 state transfer意味着传输当前时间实例中服务器中存在的资源的表示
我的代码将文件从远程服务器下载到我们的服务器。 通常,一个文件最多需要一分钟左右的时间才能完成下载。但有时下载时间会超过 5 分钟。 如果当前下载时间超过 5 分钟,是否可以重新开始下载? Tamir
Representational State Transfer中的State Transfer是指什么? 找到了一些关于这个的解释(例如 here )但我还是不明白。例如文章中说 The repres
在阅读 C# 时,我遇到了“数据传输类型”和“数据传输对象”这两个术语。这显示在匿名类型周围,其中动态创建类型以保存结果,例如来自 LINQ。这两个术语指的是同一件事吗? 谢谢, 斯科特 最佳答案 我
以下代码: public string add_button_tooltip_markup { get { return add_button.get_tooltip_markup (); }
您可以在下面看到外部测试人员的测试已关闭: 内部测试相同: 但是当我转移应用程序时,不满足其中一个条件: 为什么? 最佳答案 我遇到了完全相同的问题,通过如上所述从 TestFlight 中删除所有
我对 Java 和 REST/REST 很陌生。我正在尝试创建一个设置了“Transfer-Encoding: chunked”的 POST 请求(通过 header ),但出现异常“org.apac
我是 mysql 新手,想知道我在代码中会怎么说。如果 Narrive = "transfer"则将 AccountID 更改为 2001 请有人给我一步一步的说明,并请解释一下我会将这段代码放在哪里
我有一个对象是数据库查询的结果,看起来像这样(var_dump 输出): object(stdClass)#17 (6) { ["id"]=> string(1) "1" ["title"
使用方法 Server.Transfer("default.aspx")以获得更好的在网站内导航的性能。当我使用它时,它不会更改地址栏中的 url。如何通过 server.transfer 获取新 u
我正在使用 lftp 将文件从本地传输到仅允许 SFTP 访问的远程服务器。 我使用以下语法来传输文件: lftp -c "open -u $UN,$Pass sftp://$Server ; mir
使用我编写的FTP客户端,有时上传完成后,有时会从FileZilla服务器收到226 Transfer OK消息,有时我什么也收不到。并不是在收到226 Transfer OK之前客户端已断开连接,因
我的 Chrome 应用程序和一个简单的设备之间没有发生任何类型的传输,只是等待数据进入其 uart rx 线路。设备接口(interface)的端点类型为bulk,尽管我已经尝试了所有可用的传输类型
我正在通过 SFTP 和 FileZilla 传输一个非常大的 (35GB) 文件。 现在传输已完成59.7%,但我不断收到此错误,并且几个小时内该数字都没有更改。 Error: File t
经过大量研究,我仍然没有答案。 我使用 WebForm 应用程序 VS 2013。 我的代码相当简单: Server.Transfer("~/Success.aspx",true); 此后,执行 Su
抱歉,标题令人困惑;然而,描述和插图应该可以解决这个问题。 本质上,我有表 A 表示表 B 的行之间“金额”转移的实例。 我希望加入 A 和 B 以便我可以显示转帐的详细信息: ===========
我正在使用 iOS 版 Plaid API 编写一个程序,该程序在身份验证后访问银行帐户并显示交易数据。 我需要知道是否可以在帐户之间转移资金(支票到储蓄)以及如何转移。 我知道 acorns 使用相
我需要通过同一网络在不同计算机之间复制/传输一些文件。经过一些阅读和搜索后,我认为尝试 Java 的 jsch 可能是一个不错的选择。令人痛苦的事实是,可能没有针对 jsch 的好的文档。但据我所知,
我正在使用 XMLHttpRequest 读取 json 文件,发现“通过网络传输”明显大于资源大小。 xmlhttp.open("GET", "resources.json", true); 而其他
我是一名优秀的程序员,十分优秀!