libusb学习——简单介绍
文章目录
- 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.h
、version.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
相关文章:
libusb学习——简单介绍
文章目录 libusb 简介libusb 编译libusb 源码目录介绍核心代码文件平台支持例子 API使用libusb初始化和去初始化libusb设备处理和枚举libusb 杂项libusb USB描述符libusb 设备热插拔事件通知libusb 异步设备I/Olibusb 同步设备I/Olibusb 轮询与定时 libusb 涉及技术参考 libusb…...
Vue进阶(贰幺叁)node 版本切换
文章目录 一、前言1.1 什么是nvm? 二、查看已安装好的 node 版本三、下载 node 版本四、切换 node 版本五、查看在用 node 版本六、拓展阅读 一、前言 项目开发阶段,会涉及多node版本切换应用场景,可应用nvm实现node版本切换。 1.1 什么是nvm? nvm是…...
[AI] 大模型提示词:理解与高效使用指南
随着大模型(如GPT、Claude、PaLM等)在各领域的应用逐步普及,**提示词(Prompt)**的重要性愈发凸显。提示词作为与大模型交互的主要方式,不仅直接影响生成结果的质量,还决定了模型在特定任务中的适…...
关于linux网桥(Linux Bridge)的一些个人记录
文章目录 1. Linux Bridge简述2. 网桥创建创建配置持久化在Debian/Ubuntu系统上:在CentOS/RHEL系统上: 启用和验证 3. 关于linux网桥不转发ip帧的问题原因解决配置持久化 4. 查看网桥学习交换表手动添加或删除条目添加条目删除条目 配置静态条目设置条目…...
黑马天机学堂学习计划模块
核心功能 系统设计思路 代码分析 1. 学习记录管理 • 存储学习记录到 Redis: 利用 Redis 缓存学习记录,减少频繁的数据库访问。 public void writeRecordCache(LearningRecord record) {String key String.format("LEARNING:R…...
【华为云开发者学堂】基于华为云 CodeArts CCE 开发微服务电商平台
实验目的 通过完成本实验,在 CodeArts 平台完成基于微服务的应用开发,构建和部署。 ● 理解微服务应用架构和微服务模块组件 ● 掌握 CCE 平台创建基于公共镜像的应用的操作 ● 掌握 CodeArts 平台编译构建微服务应用的操作 ● 掌握 CodeArts 平台部署微…...
小R的蛋糕分享
小R的蛋糕分享 问题描述 小R手里有一个大小为 n 行 m 列的矩形蛋糕,每个小正方形区域都有一个代表美味度的整数。小R打算切割出一个正方形的小蛋糕给自己,而剩下的部分将给小S。她希望两人吃的部分的美味度之和尽量接近。 我们定义小R吃到的部分的美味度…...
24级 秋季学期期末考试安排(专升本)
1.删除 delete 2.耐心 patience 3.设计师 designer 4.身体的 physical 5.材料,物质 material 6.极其,极端 extremely 7.摩托车 motorbike 8.城市的 urban 9.意识 awareness 10.事故 accident 16.choose B:挑选 17.prove C:证明 1…...
点击底部的 tabBar 属于 wx.switchTab 跳转方式,目标页面的 onLoad 不会触发(除非是第一次加载)
文章目录 1. tabBar 的跳转方式2. tabBar 跳转的特点3. 你的配置分析4. 生命周期触发情况5. 总结 很多人不明白什么是第一次加载,两种情况讨论,第一种情况假设我是开发者,第一次加载就是指点击微信开发者工具上边的编译按钮,每点击…...
Web枚举:深入了解目标应用系统
Web枚举是渗透测试中重要的第一步,旨在全面收集目标系统的信息,以便后续攻击载荷的构建更具针对性和效率。本文将详细讨论如何通过各种方法识别目标Web应用的技术栈,并提取关键信息。 1. 识别目标系统的技术栈 技术栈指Web应用所依赖的技术组…...
【动态规划篇】欣赏概率论与镜像法融合下,别出心裁探索解答括号序列问题
本篇鸡汤:没有人能替你承受痛苦,也没有人能拿走你的坚强. 欢迎拜访:羑悻的小杀马特.-CSDN博客 本篇主题:带你解答洛谷的括号序列问题(绝对巧解) 制作日期:2025.01.10 隶属专栏:C/C题…...
Windows Docker 安装
使用别人写好的软件/工具最大的障碍是什么——必然是配环境。配环境带来的折磨会极大地消解你对软件、编程本身的兴趣。虚拟机可以解决配环境的一部分问题,但它庞大笨重,且为了某个应用的环境配置好像也不值得模拟一个全新的操作系统。 Docker 的出现让…...
Spring 设计模式:经典设计模式
Spring 设计模式:经典设计模式 引言 Spring 框架广泛使用了经典设计模式。 这些模式在 Spring 内部发挥着重要作用。 通过理解这些设计模式在 Spring 中的应用,开发者可以更深入地掌握 Spring 框架的设计哲学和实现细节。 经典设计模式 控制反转&am…...
vscode支持ssh远程开发
文章目录 一、生成ssh使用的公钥/密钥对二、使用vscode通过ssh连接服务器1.安装插件2.配置文件3.连接服务器4.新建文件夹,存放不同的任务 三、使用scp命令与服务器互传文件、文件夹1.检查Windows 系统是否支持scp命令2.在Windows系统本地的电脑向服务器传输文件、文…...
ssh2-sftp-client和ssh2配合使用js脚本快速部署项目到服务器
有时候因为服务器不能实现github或者gitlab的自动部署服务,所以就需要使用脚本来实现自动部署,可以省时省力,一劳永逸。这里就使用ssh2-sftp-client和ssh2来实现,即便是需要sudo权限,也是可以的。 1.先将本地打包后的…...
CODESYS MODBUS TCP通信(禾川Q1 PLC作为MODBUS TCP从站)
禾川Q1 PLC MODBUS TCP 通信(PLC作为MODBUS TCP通信主站) 禾川Q1 PLC MODBUS TCP通信(CODESYS平台完整配置+代码)-CSDN博客文章浏览阅读28次。MATLAB和S7-1200PLC水箱液位高度PID控制联合仿真(MODBUSTCP通信)_将matlab仿真导入plc-CSDN博客文章浏览阅读722次。本文详细介绍了如…...
2025年第三届“华数杯”国际大学生数学建模竞赛A题题目
问题A:他能游得更快吗? 背景介绍 在2024年巴黎奥运会上,中国游泳运动员潘展乐凭借出色的表现成为全球瞩目的焦点。年仅19岁的他在男子100米自由泳比赛中以46秒40 的成绩夺冠,并创造了自己保持的世界纪录。在男子4100米混合泳接力…...
一、智能体强化学习——强化学习基础
1.1 强化学习与深度学习的基本概念 1.1.1 强化学习的核心思想 什么是强化学习? 强化学习(Reinforcement Learning, RL):指在与环境(Environment)的反复交互中,智能体(Agent&#x…...
USB学习——基本概念
文章目录 USB(Universal Serial Bus)概述USB系统的描述USB总线传输方式USB的拓扑结构 USB的连接模型USB控制器及分类USB描述符USB 端点USB枚举过程USB 四种传输类型USB 事务批量传输(Bulk)中断传输(Interrupt)等时传输(Isochronous)控制传输(Control)端点…...
vue3 初体验
git代码git clone https://github.com/kailong321200875/vue-element-plus-admin.git 后端自己写python,Django架构 1.报错:跨域,代理的方式解决 server: {port:4000, ##前端启动端口proxy: {// 选项写法/api: {target: http://127.0.0.1…...
CAPL语法基础
CAPL语法基础 目录 CAPL语法基础1. 引言2. 数据类型、变量与常量2.1 数据类型2.2 变量2.3 常量2.4 案例1:使用变量和常量计算圆的面积 3. 运算符与表达式3.1 算术运算符3.2 关系运算符3.3 逻辑运算符3.4 位运算符3.5 案例2:使用运算符实现简单的逻辑判断…...
代码的形状:重构的方向
大概2周前写了一篇《代码的形状:从外到内的探索与实践》 涵树:代码的形状:从外到内的探索与实践 觉得这个话题还可以继续,它是一个从无形到有形的过程,而这个过程感觉就是王阳明先生说的“心即理”的探寻过程。 我讨论代码的形状ÿ…...
144.《在 macOS 上安装 Redis》
文章目录 在 macOS 上安装 Redis先决条件安装在前台启动和停止 Redis使用 launchd 启动和停止 Redis连接到 Redis后续步骤Next steps redis 官方安装教程是英文,本文只是将英文文档翻译成中文,方便大家阅读 redis官方安装教程:download redis…...
使用mysql报Communications link failure异常解决
背景 线上使用polarDB,基于mysql(5.7),架构为springbootmybatisplusdurid连接池,部分业务场景涉及大表更新和查询操作,在查询慢sql且超过一定时间时就会报出"Communications link failure"异常,主要体现在界…...
搭建一个fastapi的项目,调用ollama服务
1. 项目结构 my_project/ │ ├── app/ │ ├── main.py # FastAPI应用的入口 │ ├── services/ # 包含服务逻辑 │ │ └── ollama_service.py │ ├── models/ # 定义数据模型 │ │ └── response.py │ ├─…...
【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列
系列文章目录 🎀🎀🎀 .NET开源 ORM 框架 SqlSugar 系列 🎀🎀🎀 文章目录 系列文章目录前言 🍃一、实体对象更新1.1 单条与批量1.2 不更新某列1.3 只更新某列1.4 NULL列不更新1.5 无主键/指定列…...
Elasticsearch—索引库操作(增删查改)
Elasticsearch中Index就相当于MySQL中的数据库表 Mapping映射就类似表的结构。 因此我们想要向Elasticsearch中存储数据,必须先创建Index和Mapping 1. Mapping映射属性 Mapping是对索引库中文档的约束,常见的Mapping属性包括: type:字段数据类…...
C#进阶-在Ubuntu上部署ASP.NET Core Web API应用
随着云计算和容器化技术的普及,Linux 服务器已成为部署 Web 应用程序的主流平台之一。ASP.NET Core 作为一个跨平台、高性能的框架,非常适合在 Linux 环境中运行。本篇博客将详细介绍如何在 Linux 服务器上部署 ASP.NET Core Web API 应用,包…...
执行这个composer require topthink/think-mongo 报错
安装tp5 mongodb扩展 执行这个composer require topthink/think-mongo 报错 解决方法: 1 把composer.json里的"overtrue/wechat": "4.2.11",注释掉再执行 2 composer require topthink/think-mongo1.* 安装mongo的1版本...
大语言模型训练数据集格式
1. SFT(有监督微调)的数据集格式 对于大语言模型的训练中,SFT(Supervised Fine-Tuning)的数据集格式可以采用以下方式: 输入数据:输入数据是一个文本序列,通常是一个句子或者一个段…...
stringRedisTemplate.execute执行lua脚本
stringRedisTemplate.execute执行lua脚本 1. 引入必要依赖 确保项目中已经引入了Spring Data Redis相关依赖,例如在 Maven 项目中,一般会有如下依赖(版本号根据实际情况调整): <dependency><groupId>or…...
鸿蒙UI(ArkUI-方舟UI框架)
参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-layout-development-overview-V13 ArkUI简介 ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能ÿ…...
Linux-蓝牙协议
SPP (Serial Port Profile): 串口协议(SPP)是一个蓝牙配置文件,允许设备通过蓝牙模拟传统的串行端口通信。它通常用于无线串口连接,允许设备如计算机和外设(例如打印机或条形码扫描器)之间进行数据传输。A…...
CES Asia 2025:科技盛宴即将开启,续写辉煌篇章
随着2025年国际消费类电子产品展览会(CES)在美国拉斯维加斯盛大开幕并展现出诸多令人瞩目的发展趋势,亚洲科技界也对即将到来的CES Asia 2025充满期待,一场科技盛宴即将在亚洲大陆续写辉煌。 在刚刚拉开帷幕的CES 2025上ÿ…...
tutorial3.c
这个教程程序展示了如何使用 libxlsxwriter 库向 Excel 文件中写入不同类型的数据,包括字符串、数字和日期。以下是程序的主要步骤和功能: 定义数据结构: 定义了一个 expense 结构体,包含三个成员:item(项…...
C# 获取当前运行路径的6种实用方法
C# 获取当前运行路径的多种方法 在C#中,获取当前运行路径(即程序的工作目录)是常见的需求,尤其在处理文件读写、日志记录和配置文件时。不同的场景可能需要使用不同的方法来获取路径。本文将介绍几种常用的获取当前运行路径的方法…...
龙蜥Linux系统部署docker21.1.3版本
龙蜥系统配置docker环境 更新yum源 更新软件源中的包。 yum update安装底层工具 yum install -y yum-utils device-mapper-persistent-data lvm2添加阿里云仓库 # 添加阿里云的docker镜像仓库 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/c…...
.NET中的框架和运行环境
在.NET生态系统中,框架和运行环境是两个不同的概念,它们各自扮演着重要的角色。 下面我将分别介绍.NET中的框架和运行环境,并解释它们之间的区别。 .NET 框架(Frameworks) 框架提供了一套预定义的类库、工具和服务&…...
STM32的存储结构
STM32F103 芯片是基于 ARM Cortex-M3 内核的微控制器,它集成了多种类型的存储器,每种存储器都有其特定的作用和存储对象。以下是关于 STM32F103 中 Flash、ROM 和 SRAM 的详细介绍: 1. Flash Memory (闪存) 作用:Flash 是非易失性…...
微信小程序
一、小程序文件结构 1.目录结构 pages文件夹:存放【页面文件夹】,一个【页面文件夹】就是一个页面,存放着小程序页面文件。即pages中的每一个文件夹都存放着一个小程序页面的文件(js、wxml、json、wxss) 页面文件夹…...
《CPython Internals》阅读笔记:p76-p95
《CPython Internals》学习第 5 天,p76-p95 总结,总计 20 页。 一、技术总结 无。 二、英语总结(生词:1) 1.check vi/vt. to exam sth to ensure it is correct, true, or in good condition.示例: (1)After I’d finished …...
HOW - Form 表单 label 和 wrapper 对齐场景
一、背景 在日常使用 表单 时,我们一般有如下布局: 可以通过 Form 表单提供的配置直接设置: <Formform{form}labelCol{{ span: 4 }}wrapperCol{{ span: 20 }}onFinish{handleSubmit}><Form.Itemlabel"输入框"name"…...
Js的回调函数
一、什么是回调函数(Callback)? 回调函数(Callback Function)是指一个函数被作为参数传递给另一个函数,并在特定事件发生或操作完成时执行。 可以通俗地理解为一种“委托”机制。 在JavaScript中࿰…...
FairGuard游戏安全2024年度报告
导 读:2024年,国内游戏市场实际销售收入3257.83亿元,同比增长7.53%,游戏用户规模6.74亿人,同比增长0.94%,市场收入与用户规模双双实现突破,迎来了历史新高点。但游戏黑灰产规模也在迅速扩大&…...
ant-design-vue 1.X 通过id获取a-input组件失败
1.ant-design-vue 1.X 问题描述 当我在a-form组件中,以v-decorator指令绑定表单组件时,无法根据我设置的verify-code-input获取元素 <a-input type"text" id"verify-code-input" class"paIpt":placeholder"$t(…...
JS爬虫实战演练
在这个小红书私信通里面进行一个js的爬虫 文字发送 async function sendChatMessage(content) {const url https://pro.xiaohongshu.com/api/edith/ads/pro/chat/chatline/msg;const params new URLSearchParams({porch_user_id: 677e116404ee000000000001});const messageD…...
JVM vs JDK vs JRE
JVM是Java虚拟机的缩写, 用于实现Java的一次编译,处处运行。 Java代码写成.class后,由本地的虚拟机运行。 JDK(Java Development Kit)是一个功能齐全的 Java 开发工具包,供开发者使用。 JDK包含了JRE。…...
OpenCV相机标定与3D重建(47)从两幅图像中的一组匹配点恢复相机的姿态(旋转和平移)函数recoverPose()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 从两幅不同相机拍摄的图像中对应的点恢复相对相机旋转和平移,使用手性检查。返回通过该检查的内点数量。 cv::recoverPose 是 OpenCV…...
代码随想录算法训练营day27
代码随想录算法训练营 —day27 文章目录 代码随想录算法训练营前言一、贪心算法理论基础二、455.分发饼干三、376. 摆动序列53. 最大子数组和总结 前言 今天是算法营的第27天,希望自己能够坚持下来! 今日任务: ● 贪心算法理论基础 ● 455.…...
基于华为ENSP的OSPF状态机、工作过程、配置保姆级别详解(2)
本篇技术博文摘要 🌟 基于华为enspOSPF状态机、OSPF工作过程、.OSPF基本配置等保姆级别具体详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法 引言 📘 在这个快速发展的技术时代,与时俱进是每个IT人的必修课。我…...