libusb学习——简单介绍

news2025/1/12 14:00:31

文章目录

    • libusb 简介
    • libusb 编译
    • libusb 源码
      • 目录介绍
      • 核心代码文件
      • 平台支持
      • 例子
    • API使用
      • libusb初始化和去初始化
      • libusb设备处理和枚举
      • libusb 杂项
      • libusb USB描述符
      • libusb 设备热插拔事件通知
      • libusb 异步设备I/O
      • libusb 同步设备I/O
      • libusb 轮询与定时
    • libusb 涉及技术
    • 参考

libusb 简介

libusb 是一个 C 库,提供对 USB 设备的通用访问。它旨在帮助开发人员开发与 USB 硬件通信的应用程序。
它有以下三个特点:

  • 它是可移植的:使用单个跨平台 API,它可以访问 Linux、macOS、Windows 等上的 USB 设备。
  • 它是用户模式:应用程序与设备通信不需要特殊权限或提升。
  • 它与版本无关:支持所有版本的 USB 协议,从 1.0 到 3.1(最新)。

libusb的优点:

  • 支持主流平台:Linux, OS X, Windows, OpenBSD/NetBSD, Solaris and Haiku
  • 支持所有USB版本, from 1.0 to 3.1
  • Unified modern API, that provides both synchronous and asynchronous access
  • User-mode: no need for kernel access

libusb 编译

直接从libusb的官网下载或者从git下载:https://github.com/libusb/libusb.git

$ git clone git://github.com/libusb/libusb.git
$ cd libusb
#安装依赖
$ sudo apt install autoconf automake libtool libudev-dev m4
#配置编译源码
$ ./bootstrap.sh
$ ./autogen.sh
$ make

编译之后的产物在目录libusb/.libs下面

libusb 源码

目录介绍

在这里插入图片描述

  • Xcode:Apple 平台相关文件。
  • android:顾名思义,用于生成 Android 版本的 libusb 库及测试用例。
  • doc:用于生成 API 文档。在doc/目录下执行:doxygen doxygen.cfg 或者 make docs。
  • examples:libusb 的使用示例。后续代码分析即以各个示例作为实例。
  • libusb:libusb 核心代码
    • libusb/os:平台相关的代码支持
  • msvc:微软编译环境相关文件。
  • tests:libusb 的测试。

核心代码文件

在这里插入图片描述
core.c:libusb核心功能实现
descriptor.c:libusb中处理usb描述符功能实现
hotplugin.c:libusb中处理hotplug相关功能
io.c:libusb中I/O相关功能
libusb.h:该文件是libusb对外提供的头文件,里面声明了libusb对外的接口,定义了libusb接口使用的数据结构。
libusbi.h:libusb库内部头文件
strerror.c:libusb内部错误定义
sync.c:libusb中处理同步I/O相关功能
version_nano.hversion.h:libusb版本文件

平台支持

在这里插入图片描述
这部分文件较多,根据编译时的配置,可以编译不同的支持平台。
以linux为例,在默认配置下编译,会生成中间文件:
在这里插入图片描述
这说明linux平台后端支持为:

  • events_posix.h/events_posix.c
  • threads_posix.h/threads_posix.c
  • linux_udev.c
  • linux_usbfs.h/linux_usbfs.cpp
    这里因为系统中有libudev库,所以使用了libudev,如果也可以不使用libudev,此时就是使用netlink即linux_netlink.c

例子

examples目录下面,libusb提供了一些官方案例:
在这里插入图片描述

  • dpfp.c
    一款指纹识别器的应用程序,将采集到的指纹图像保存为文件。用到了control、interrupt、bulk三种传输方式。
  • ezusb.h/exusb.c
    “EZ-USB的固件下载程序,可实现下载固件(image)到Cypress EZ-USB microcontrollers,ezusb系列芯片使用端点0和厂商特定命令将数据写到片上SRAM,并且也支持写数据到CPUCS register或者eeprom。程序使用控制传输方式进行指令和数据的传输,libusb_control_transfer()的形参bmRequestType使用LIBUSB_REQUEST_TYPE_VENDOR(厂商自定义请求)。程序支持五种下载类型(Target type): an21, fx, fx2, fx2lp, fx3,支持四种固件(image)类型:“Intel HEX”, “Cypress 8051 IIC”, “Cypress 8051 BIX”, “Cypress IMG format”。”
  • fxload.c
./fxload 
no firmware specified!

Usage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p bus,addr] [-s loader] -i firmware
  -i <path>       -- Firmware to upload
  -s <path>       -- Second stage loader
  -t <type>       -- Target type: an21, fx, fx2, fx2lp, fx3
  -d <vid:pid>    -- Target device, as an USB VID:PID
  -p <bus,addr>   -- Target device, as a libusb bus number and device address path
  -v              -- Increase verbosity
  -q              -- Decrease verbosity (silent mode)
  -V              -- Print program version

  • hotplugtest.c
    hotplugtest 用于监听系统中 USB 设备的 attached(插入)和 detached(拔出)。
./hotplugtest 
Device attached: 058f:6387
No access to device: Access denied (insufficient permissions)
Device detached: 058f:6387
  • listdevs.c
    获取并显示系统当前的 USB 设备信息,包含:VID、PID、bus 编号、设备地址、端口号。
./listdevs 
2109:0817 (bus 2, device 2) path: 6
1d6b:0003 (bus 2, device 1)
2f4c:2000 (bus 1, device 7) path: 8
3434:03a1 (bus 1, device 6) path: 4.3
046d:c52b (bus 1, device 5) path: 4.2
2109:2817 (bus 1, device 3) path: 4
046d:0825 (bus 1, device 2) path: 2
8087:0026 (bus 1, device 4) path: 14
058f:6387 (bus 1, device 11) path: 12.1
1a40:0101 (bus 1, device 8) path: 12
1d6b:0002 (bus 1, device 1)

  • sam3u_benchmark.c
    Atmel SAM3U isochronous(等时传输)性能测试。程序不断接收来自SAM3U iso端点的数据,当按下CTRL-C时,计算花费时间和传输的总数据量。
  • testlibusb.c
    打印usb设备列表的详细信息:包括设备描述符、配置、接口、端点描述符
/testlibusb 
Dev (bus 2, device 2): 2109 - 0817 speed: 5G
Dev (bus 2, device 1): 1D6B - 0003 speed: 10G
Dev (bus 1, device 7): 2F4C - 2000 speed: 12M
Dev (bus 1, device 6): 3434 - 03A1 speed: 12M
Dev (bus 1, device 5): 046D - C52B speed: 12M
Dev (bus 1, device 3): 2109 - 2817 speed: 480M
Dev (bus 1, device 2): 046D - 0825 speed: 480M
Dev (bus 1, device 4): 8087 - 0026 speed: 12M
Dev (bus 1, device 11): 058F - 6387 speed: 480M
Dev (bus 1, device 8): 1A40 - 0101 speed: 480M
Dev (bus 1, device 1): 1D6B - 0002 speed: 480M

  • xusb.c
    一个综合的USB测试程序,包括:HID设备(xbox、PS3和Joystick)、Mass Storage,涉及control、interrupt、bulk传输。
    其中Mass Storage可以使用普通的U盘进行测试,只需修改VID和PID即可,可以实现的功能有:读取描述符、查询U盘信息、读取U盘容量、读取U盘数据(因为没有使用文件系统,读取出来的数据是原始二进制数据)。关于Mass Storage中涉及的SCSI命令,参考: USB Mass Stroage - SCSI指令格式详解。
./xusb 
usage: ./xusb [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] [-x] [-s] [-p] [-w] [vid:pid]
   -h      : display usage
   -d      : enable debug output
   -i      : print topology and speed info
   -j      : test composite FTDI based JTAG device
   -k      : test Mass Storage device
   -b file : dump Mass Storage data to file 'file'
   -p      : test Sony PS3 SixAxis controller
   -s      : test Microsoft Sidewinder Precision Pro (HID)
   -x      : test Microsoft XBox Controller Type S
   -l lang : language to report errors in (ISO 639-1)
   -w      : force the use of device requests when querying WCID descriptors
If only the vid:pid is provided, xusb attempts to run the most appropriate test

API使用

API文档直接参考官方在线文档:https://libusb.sourceforge.io/api-1.0/,也可以直接看提供的头文件libusb.h

libusb初始化和去初始化

  • 初始化
int LIBUSB_CALL libusb_init(libusb_context **ctx);
// libusb_init属于旧接口,官方推荐下面的libusb_init_context接口
int LIBUSB_CALL libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options);

初始化 libusb 内部资源,所以在使用 libusb 其他函数之前,必需优先调用该函数。

  • 去初始化
void LIBUSB_CALL libusb_exit(libusb_context *ctx);

去初始化libusb,应该在程序退出前关闭所有已经打开的设备后调用该接口来去初始化libusb。

  • 设置日志
void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level);
/* may be deprecated in the future in favor of lubusb_init_context()+libusb_set_option() */
void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);

int LIBUSB_CALLV libusb_set_option(libusb_context *ctx, enum libusb_option option, ...);

libusb设备处理和枚举

ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx,
	libusb_device ***list);
void LIBUSB_CALL libusb_free_device_list(libusb_device **list,
	int unref_devices);
libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev);
void LIBUSB_CALL libusb_unref_device(libusb_device *dev);
int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev,
	int *config);
uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev);
uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev);
int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t *port_numbers, int port_numbers_len);
LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers)
int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t *path, uint8_t path_length);
libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev);
uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev);
int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev);
int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev,
	unsigned char endpoint);
int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev,
	unsigned char endpoint);
int LIBUSB_CALL libusb_get_max_alt_packet_size(libusb_device *dev,
	int interface_number, int alternate_setting, unsigned char endpoint);

int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **dev_handle);
void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle);

int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev_handle,
	int configuration);
int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle,
	int interface_number);
int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle,
	int interface_number);

libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
	libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);

int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
	int interface_number, int alternate_setting);
int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev_handle,
	unsigned char endpoint);
int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev_handle);

int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev_handle,
	int interface_number);
int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
	int interface_number);
int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
	int interface_number);
int LIBUSB_CALL libusb_set_auto_detach_kernel_driver(
	libusb_device_handle *dev_handle, int enable);

libusb 杂项

const struct libusb_version * LIBUSB_CALL libusb_get_version(void);
int LIBUSB_CALL libusb_has_capability(uint32_t capability);
const char * LIBUSB_CALL libusb_error_name(int error_code);
int LIBUSB_CALL libusb_setlocale(const char *locale);
const char * LIBUSB_CALL libusb_strerror(int errcode);

libusb USB描述符

int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev,
	struct libusb_device_descriptor *desc);
int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev,
	struct libusb_config_descriptor **config);
int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev,
	uint8_t config_index, struct libusb_config_descriptor **config);
int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev,
	uint8_t bConfigurationValue, struct libusb_config_descriptor **config);
void LIBUSB_CALL libusb_free_config_descriptor(
	struct libusb_config_descriptor *config);
int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor(
	libusb_context *ctx,
	const struct libusb_endpoint_descriptor *endpoint,
	struct libusb_ss_endpoint_companion_descriptor **ep_comp);
void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor(
	struct libusb_ss_endpoint_companion_descriptor *ep_comp);
int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *dev_handle,
	struct libusb_bos_descriptor **bos);
void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos);
int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor(
	libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension);
void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor(
	struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension);
int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor(
	libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap);
void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor(
	struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap);
int LIBUSB_CALL libusb_get_ssplus_usb_device_capability_descriptor(
	libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_ssplus_usb_device_capability_descriptor **ssplus_usb_device_cap);
void LIBUSB_CALL libusb_free_ssplus_usb_device_capability_descriptor(
	struct libusb_ssplus_usb_device_capability_descriptor *ssplus_usb_device_cap);
int LIBUSB_CALL libusb_get_container_id_descriptor(libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_container_id_descriptor **container_id);
void LIBUSB_CALL libusb_free_container_id_descriptor(
	struct libusb_container_id_descriptor *container_id);
int LIBUSB_CALL libusb_get_platform_descriptor(libusb_context *ctx,
	struct libusb_bos_dev_capability_descriptor *dev_cap,
	struct libusb_platform_descriptor **platform_descriptor);
void LIBUSB_CALL libusb_free_platform_descriptor(
	struct libusb_platform_descriptor *platform_descriptor);

int LIBUSB_CALL libusb_get_interface_association_descriptors(libusb_device *dev,
	uint8_t config_index, struct libusb_interface_association_descriptor_array **iad_array);
int LIBUSB_CALL libusb_get_active_interface_association_descriptors(libusb_device *dev,
	struct libusb_interface_association_descriptor_array **iad_array);
void LIBUSB_CALL libusb_free_interface_association_descriptors(
	struct libusb_interface_association_descriptor_array *iad_array);

static inline int libusb_get_descriptor(libusb_device_handle *dev_handle,
	uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length);
static inline int libusb_get_string_descriptor(libusb_device_handle *dev_handle,
	uint8_t desc_index, uint16_t langid, unsigned char *data, int length);
int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev_handle,
	uint8_t desc_index, unsigned char *data, int length);

libusb 设备热插拔事件通知

int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx,
	int events, int flags,
	int vendor_id, int product_id, int dev_class,
	libusb_hotplug_callback_fn cb_fn, void *user_data,
	libusb_hotplug_callback_handle *callback_handle);
void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx,
	libusb_hotplug_callback_handle callback_handle);
void * LIBUSB_CALL libusb_hotplug_get_user_data(libusb_context *ctx,
	libusb_hotplug_callback_handle callback_handle);

libusb 异步设备I/O

int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev_handle,
	uint32_t num_streams, unsigned char *endpoints, int num_endpoints);
int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev_handle,
	unsigned char *endpoints, int num_endpoints);

unsigned char * LIBUSB_CALL libusb_dev_mem_alloc(libusb_device_handle *dev_handle,
	size_t length);
int LIBUSB_CALL libusb_dev_mem_free(libusb_device_handle *dev_handle,
	unsigned char *buffer, size_t length);

static inline unsigned char *libusb_control_transfer_get_data(
	struct libusb_transfer *transfer);
static inline struct libusb_control_setup *libusb_control_transfer_get_setup(
	struct libusb_transfer *transfer);
static inline void libusb_fill_control_setup(unsigned char *buffer,
	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
	uint16_t wLength);
struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets);
int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer);
int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer);
void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer);
void LIBUSB_CALL libusb_transfer_set_stream_id(
	struct libusb_transfer *transfer, uint32_t stream_id);
uint32_t LIBUSB_CALL libusb_transfer_get_stream_id(
	struct libusb_transfer *transfer);
static inline void libusb_fill_control_transfer(
	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
	unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data,
	unsigned int timeout);
static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
	libusb_device_handle *dev_handle, unsigned char endpoint,
	unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
	void *user_data, unsigned int timeout);
static inline void libusb_fill_bulk_stream_transfer(
	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
	unsigned char endpoint, uint32_t stream_id,
	unsigned char *buffer, int length, libusb_transfer_cb_fn callback,
	void *user_data, unsigned int timeout);
static inline void libusb_fill_interrupt_transfer(
	struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
	unsigned char endpoint, unsigned char *buffer, int length,
	libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout);
static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
	libusb_device_handle *dev_handle, unsigned char endpoint,
	unsigned char *buffer, int length, int num_iso_packets,
	libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout);
static inline void libusb_set_iso_packet_lengths(
	struct libusb_transfer *transfer, unsigned int length);
static inline unsigned char *libusb_get_iso_packet_buffer(
	struct libusb_transfer *transfer, unsigned int packet);
static inline unsigned char *libusb_get_iso_packet_buffer_simple(
	struct libusb_transfer *transfer, unsigned int packet);

libusb 同步设备I/O

int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle,
	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
	unsigned char *data, uint16_t wLength, unsigned int timeout);

int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle,
	unsigned char endpoint, unsigned char *data, int length,
	int *transferred, unsigned int timeout);

int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle,
	unsigned char endpoint, unsigned char *data, int length,
	int *transferred, unsigned int timeout);

libusb 轮询与定时

int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx);
void LIBUSB_CALL libusb_lock_events(libusb_context *ctx);
void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx);
int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx);
int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx);
void LIBUSB_CALL libusb_interrupt_event_handler(libusb_context *ctx);
void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx);
void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx);
int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv);

int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx,
	struct timeval *tv);
int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx,
	struct timeval *tv, int *completed);
int LIBUSB_CALL libusb_handle_events(libusb_context *ctx);
int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed);
int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx,
	struct timeval *tv);
int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx);
int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx,
	struct timeval *tv);

const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds(
	libusb_context *ctx);
void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds);
void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx,
	libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb,
	void *user_data);

libusb 涉及技术

针对 Linux 平台,涉及的技术有:

  • sysfs:内核把一些 USB 设备的信息通过文件系统的方式呈现给了用户空间,应用通过读取相应文件即可获取所需信息。如遍历 /sys/bus/usb/devices/ 目录下的信息就可以获取各个设备的基本信息
  • libudev:用于 USB 设备的热插拔
  • netlink:用于 USB 设备的热插拔。netlink 是 Linux 提供的用于内核和用户空间之间的通信方式。一旦内核监测到系统设备有变化(如ADD/DEL/REMOVE),则通知用户进程。libudev 和 Netlink 二选一即可,可以认为 libudev 是对 Netlink 的封装
  • 多线程
  • 进程间通信:pipe/pipe2/eventfd。
  • USB 规范

参考

libusb
使用 libusb 与 USB 设备通信
usb

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML5 网站模板

HTML5 网站模板 参考 HTML5 Website Templates

阿里云ios镜像源

阿里云镜像源&#xff1a;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 下载centos7

【大数据】Apache Superset:可视化开源架构

Apache Superset是什么 Apache Superset 是一个开源的现代化数据可视化和数据探索平台&#xff0c;主要用于帮助用户以交互式的方式分析和展示数据。有不少丰富的可视化组件&#xff0c;可以将数据从多种数据源&#xff08;如 SQL 数据库、数据仓库、NoSQL 数据库等&#xff0…

【2024年华为OD机试】 (A卷,100分)- 端口合并(Java JS PythonC/C++)

一、问题描述 题目描述 有 M 个端口组 (1 < M < 10)&#xff0c; 每个端口组是长度为 N 的整数数组 (1 < N < 100)&#xff0c; 如果端口组间存在 2 个及以上不同端口相同&#xff0c;则认为这 2 个端口组互相关联&#xff0c;可以合并。 输入描述 第一行输入端…

【灵码助力安全3】——利用通义灵码辅助智能合约漏洞检测的尝试

前言 随着区块链技术的快速发展&#xff0c;智能合约作为去中心化应用&#xff08;DApps&#xff09;的核心组件&#xff0c;其重要性日益凸显。然而&#xff0c;智能合约的安全问题一直是制约区块链技术广泛应用的关键因素之一。由于智能合约代码一旦部署就难以更改&#xf…

AOP实现操作日志记录

文章目录 1.common-log4j2-starter1.目录2.pom.xml 引入依赖3.LogAspect.java4.Log4j2AutoConfiguration.java Log4j2自动配置类条件注入切面类 2.common-log4j2-starter-demo 测试1.目录2.application.yml 启用日志切面3.TraceController.java4.结果 1.common-log4j2-starter …

分布式ID—雪花算法

背景 现在的服务基本是分布式、微服务形式的&#xff0c;而且大数据量也导致分库分表的产生&#xff0c;对于水平分表就需要保证表中 id 的全局唯一性。 对于 MySQL 而言&#xff0c;一个表中的主键 id 一般使用自增的方式&#xff0c;但是如果进行水平分表之后&#xff0c;多…

JavaEE之定时器及自我实现

在生活当中&#xff0c;有很多事情&#xff0c;我们不是立马就去做&#xff0c;而是在规定了时间之后&#xff0c;在到该时间时&#xff0c;再去执行&#xff0c;比如&#xff1a;闹钟、定时关机等等&#xff0c;在程序的世界中&#xff0c;有些代码也不是立刻执行&#xff0c;…

深入Android架构(从线程到AIDL)_23 活用IBinder接口于近程通信01

1、 在同一进程里活用IBinder接口 议题 1. myActivity对象是谁创建的呢? 2. myService对象是谁创建的呢? 3. 当myService类里有个f1()函数&#xff0c;如何去调用它呢? 4. 必须先取得myService对象的指针&#xff0c;才能调用f1()函数去存取对象的属性(Attribute)值。 …

vue3后台系统动态路由实现

动态路由的流程&#xff1a;用户登录之后拿到用户信息和token&#xff0c;再去请求后端给的动态路由表&#xff0c;前端处理路由格式为vue路由格式。 1&#xff09;拿到用户信息里面的角色之后再去请求路由表&#xff0c;返回的路由为tree格式 后端返回路由如下&#xff1a; …

如何开启苹果手机(IOS)系统的开发者模式?

如何开启开发者模式&#xff1f; 一、打开设置二、隐私与安全性三、找到开发者模式四、开启开发者模式------------------------------------------------------------如果发现没有开发者模式的选项一、电脑下载爱思助手二、连接手机三、工具箱——虚拟定位——打开虚拟定位——…

国产编辑器EverEdit - 扩展脚本:在当前文件目录下新建同类型文件

1 扩展脚本&#xff1a;在当前文件目录下新建同类型文件 1.1 应用场景 用户在进行编程语言学习时&#xff0c;比如&#xff1a;Python&#xff0c;经常做完一个小练习后&#xff0c;又需要新建一个文件&#xff0c;在新建文件的时候&#xff0c;不但要选择文件类型&#xff0c…

011:利用大津算法完成图片分割

本文为合集收录&#xff0c;欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里。 上一篇文章介绍了大津算法可以完成图片的前景和背景分割。 总的来说&#xff0c;大津算法的核心思想就两个&#xff1a; 数学上&#xff0c;通过确定一个像素阈值&#xf…

Jenkins触发器--在其他项目执行后构建

前言&#xff1a; jenkins中有多种触发器可用&#xff0c;可以方便的控制构建的启动 这里简单介绍下项目后构建的配置方法 1. 解释&#xff1a; Build after other projects are built Set up a trigger so that when some other projects finish building, a new build is…

PowerApps助力PowerBI实现数据写回

原文发布日期: 2019-08-01 06:03:50 0000 注&#xff1a;本文旨在介绍Power BI如何利用PowerApps实现用户在前端对数据源进行增删查改&#xff0c;关于此&#xff0c;你也可以在Google上找到更详细但较零散的资料 正文 在SSAS多维数据集中&#xff0c;开发者可以给数据开启&q…

oracle 19c安装

文章目录 一 环境配置1、更换yum源2、文件配置 二 oracle环境配置1、下载依赖包2、创建用户和用户组3、创建目录并赋予权限4、修改资源限制参数5、修改内核参数6、配置安全7、配置Oracle环境变量 三 安装Oracle数据库四 创建Oracle实例五 启动数据库 一 环境配置 1、更换yum源…

LabVIEW启动时Access Violation 0xC0000005错误

问题描述 在启动LabVIEW时&#xff0c;可能出现程序崩溃并提示以下错误&#xff1a;Error 0xC0000005 (Access Violation) ​ Access Violation错误通常是由于权限不足、文件冲突或驱动问题引起的。以下是解决此问题的全面优化方案&#xff1a; 解决步骤 1. 以管理员身份运行…

xilinx平台使用多个 FIFO 拼接

Xilinx FIFO IP 输入 的最大位宽 是 1024 bit &#xff0c;当需要缓存的数据是 1280bit 又或者是 1536等 。怎么办呢&#xff1f; 有一个办法就是拆数据&#xff0c;将1280拆5个 256bit输入&#xff0c;也就是可以使用 5个 256位宽输入的FIFO拼接起来。&#xff08;其它位宽也…

Ceph分布式存储集群,不仅仅是一个简单的对象存储解决方案

Ceph 作为 OpenStack 的存储后端 块存储&#xff08;Cinder 后端&#xff09; Ceph 的 RBD&#xff08;RADOS Block Device&#xff09;模块作为 OpenStack Cinder 服务的后端&#xff0c;为虚拟机提供块级别的存储资源。RBD 支持快照、克隆和恢复等功能&#xff0c;能够满足虚…

SD ComfyUI工作流 老照片修复上色

文章目录 老照片修复上色SD模型Node节点工作流程开发与应用效果展示老照片修复上色 该工作流专门设计用于老照片的修复和上色,通过一系列高级的图像处理技术,包括深度图预处理、面部修复、上色和图像放大等步骤,来恢复老照片的质量并增加色彩。首先,工作流加载老照片并进行…