The USB composite framework

mini2440 usb device controller 驱动的分析--gadget设备(三)--- usb device framework 下面接着分析class driver 和 usb device framework。 首先需要说明的是 这两部分其实是可以合并在一起的。对于我们的例子:zero.c和composite.c 是把这两部分分开进行了实现,实现了composite_driver和gadget_driver。但是对于file_storage.c里面,就是将这两部分功能合并在一起,只实现了gadget_driver。这些 阅读详情

http://lwn.net/Articles/395712/

Linux is widely used in mobile devices, which should not come as a surprise. It is a powerful and versatile system, and one of its strengths is its support for USB devices of all kinds. That includes "gadgets" — devices that act as USB slaves — like USB flash drives (i.e. pendrives). The USB composite framework makes writing drivers for these kinds of devices relatively easy.

As users keep more data on their mobile devices, the demand for interoperability with desktop computers increases. No one wants to buy a special cable or a "docking station" just to copy a few photos. What users want is to connect the device via a USB cable and get it working out of the box. Linux can give that to them.

Have you ever wondered how this actually works? What happens behind the scenes when a USB connection is established? Better yet, have you wondered how to write a USB gadget for your new and shiny embedded evaluation board?

In this article, I will try to shed some light on that topic.

USB overview

The Universal Serial Bus (or USB) standard defines a master-slave communication protocol. This means that there is one control entity (a master or a host), which decides who can transmit data through the wire. The other entities (slaves, devices, or gadgets) must obey and respond to the host's requests. Slaves do not communicate with each other. A host is usually a desktop computer, while the gadgets are devices such as mice, keyboards, phones, printers, etc.

People are used to seeing Linux systems in the master or host role on a USB bus. But the Linux USB stack also provides support for the slave or gadget role — the device at the other end of the wire. For example, when one connects a pendrive to a Linux host, it handles it with a usb-storage driver. However, if we had a Linux machine with a USB Device Controller (or UDC), we could run Alan Stern's File Storage Gadget (or FSG). FSG is, as its name implies, a gadget driver which implements the USB mass storage device class (or UMC). That would allow the machine in question to act as a USB drive (aka pendrive).

When a device is connected, an enumeration process begins. During this process, the device is assigned a unique 7-bit identifier used for addressing. As a consequence, up to 127 slaves (including hubs) can be connected to a single host.

Communication is based on logical pipes which join the master with one of a slave's endpoints (or EPs). There can be up to 16 endpoints (numbered from 0 to 15) on a device. Endpoint zero (or EP0) is reserved for setup requests (eg. a query for descriptors, request to set a particular configuration, etc.).

Pipes are unidirectional (one-way) and data can go to (via an IN endpoint) or from (via an OUT endpoint) the host. (It is important to remember that from a slave's point of view, an IN endpoint is the one it writes to and an OUT endpoint is the one it reads from.) There are also four transfer modes: bulk, isochronous, interrupt, and control.

[USB Gadget's descriptors structure]

Endpoints are grouped into interfaces which are then grouped intoconfigurations. Different configurations may contain different interfaces, as well as have different power demands. All that information is saved in various descriptors requested by the host during enumeration. One can see them using the lsusb tool. Here is the stripped-down (and annotated) output for a Kingston pendrive:

    Bus 001 Device 004: ID 0951:1614 Kingston Technology
    Device Descriptor:
      idVendor           0x0951 Kingston Technology
      idProduct          0x1614
      bNumConfigurations      1     [only one configuration]
      Configuration Descriptor:     [the first and only config]
        bNumInterfaces          1    [only one interface]
        MaxPower              200mA
        Interface Descriptor:        [the first and only intf.]
          bNumEndpoints           2   [two endpoints]
          bInterfaceClass         8 Mass Storage
          bInterfaceSubClass      6 SCSI
          bInterfaceProtocol     80 Bulk (Zip)
          Endpoint Descriptor:        [the first endpoint]
            bEndpointAddress     0x81  EP 1 IN
            bmAttributes            2
              Transfer Type            Bulk
              Usage Type               Data
          Endpoint Descriptor:        [the second endpoint]
            bEndpointAddress     0x02  EP 2 OUT
            bmAttributes            2
              Transfer Type            Bulk
              Usage Type               Data

After the host receives the descriptors and learns what kind of a gadget has been connected, it can choose a configuration to be used and start communicating. At most one configuration can be active at a time.

Linux USB composite framework

There is, however, another module that implements UMC: my Mass Storage Gadget (or MSG). The obvious question is, why there are two drivers that seem to do the very same thing. This has something to do with the Linux USB composite framework.

The "old way" of creating gadgets is to get the specification and implement everything as a single, monolithic module. Gadget Zero, File Storage Gadget, and GadgetFS are examples of such gadgets.

This approach has two rather big disadvantages:

  • many of the common USB functionalities (core device setup requests on EP0) have to be implemented in each and every module; and
  • it can be tricky to combine the code from several gadgets into a new gadget with combined functionality.

For those reasons, David Brownell came up with the composite framework which has two advantages over the old approach:

  • all of the core USB requests are implemented by the framework; and
  • a single functionality or a USB composite function is developed separately from other functions as well as from the USB bus logic that is not directly related to this function. Later, such functions are combined using the composite function to form a composite gadget.
[USB Composite Gadget's descriptors    structure]

From a composite gadget's perspective, a device has some functions grouped into configurations. One function may be present in any number of configurations. Each function may have several interfaces and other descriptors but that is transparent to the kernel module.

Put on top of the "raw" USB descriptors structure, a USB composite function can be regarded as an abstraction for a group of interfaces.

That is another excellent property of the framework — most implementation details are hidden "under the hood" and one does not need to think about them when developing a gadget. Instead of thinking about endpoints and interfaces, one thinks about functions. Therefore, FSG is a gadget developed in the "old way", whereas MSG is a composite gadget which uses only one composite function — the Mass Storage Function (or MSF). As a matter of fact, MSF has been created from FSG to allow for the creation of more complicated drivers that would have UMC as part of their functionality.

Overall driver structure

In this article, I will try to explain how to create a mass storage composite gadget. It is in the kernel already, but let's forget that FSG and MSG exist for a moment.

What is great about Linux, is that a lot has already been done and one can get results with relatively little effort. As such, I will show how to create a working driver using MSF and some "composite glue".

I will start with the structure of the module, while skipping the details of the Mass Storage Function. The first step is to define a device descriptor. It stores some basic information about the gadget:

    static struct usb_device_descriptor msg_dev_desc = {
    	.bLength =		sizeof msg_dev_desc,
    	.bDescriptorType =	USB_DT_DEVICE,
    	.bcdUSB =		cpu_to_le16(0x0200),
    	.idVendor =		cpu_to_le16(FSG_VENDOR_ID),
    	.idProduct =		cpu_to_le16(FSG_PRODUCT_ID),
    };

The usb_device_descriptor structure has some more fields but they are not required or not important for our module. What has been set is:

bLength and  bDescriptorType
A standard fields each descriptor has.
bsdUSB
The version of USB specification the device supports encoded in BCD (so  0x200 means  2.00).
idVendor and  idProduct
Each device must have a unique vendor and product identifier pair. To avoid collisions, companies (vendors) can buy a vendor ID which gives them a namespace of 65536 product IDs to use. NetChip has donated some product IDs to the Linux community. Later, the Linux Foundation got the whole vendor ID for use with Linux.  FSG_VENDOR_ID is actually NetChip's vendor ID and, along with  FSG_PRODUCT_ID, that is what FSG uses.

The next step is to define an USB configuration which will be provided by the driver. It is described by a usb_configuration structure which, among other things, points to a bind callback function. Its purpose is to bind all USB composite functions to the configuration. Usually, it is a simple function, as most of the job is done prior to its invocation.

Put together it looks as follows:

    static struct usb_configuration msg_config = {
    	.label			= "Linux Mass Storage",
    	.bind			= msg_do_config,
    	.bConfigurationValue	= 1,
    	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
    };

    static int __ref msg_do_config(struct usb_configuration *c)
    {
    	return fsg_add(c->cdev, c, &msg_fsg_common);
    }

The msg_config object specifies a label (used for debug messages), the bind callback, configuration's number (each configuration must have a unique, non-zero number), and indicates that the device is self powered. All that the msg_bind does is bind the MSF to the configuration.

That definition is then used by the msg_bind() function, which is a callback to set up composite functions, prepare descriptors, add all configurations supported by the device, etc.:

    static int __ref msg_bind(struct usb_composite_dev *cdev)
    {
    	int ret;

    	ret = msg_fsg_init(cdev);
    	if (ret < 0)
    		return ret;

    	ret = usb_add_config(cdev, &msg_config);
    	if (ret >= 0)
    		set_bit(0, &msg_registered);
    	fsg_common_put(&msg_fsg_common);
    	return ret;
    }
The  msg_bind() function does the following: initializes the Mass Storage Function, adds the previously defined configuration to the USB device, and (at the end)  puts the  msg_fsg_common object. . If everything succeeds, it sets the  msg_registered flag so it is recorded that the gadget has been registered and initialized.

With all of the above, a composite device can be defined. For this purpose, the usb_composite_driverstructure is used. Besides specifying the name, it points to the device descriptors and the bind callback:

    static struct usb_composite_driver msg_device = {
    	.name		= "g_my_mass_storage",
    	.dev		= &msg_dev_desc,
    	.bind		= msg_bind,
    };

At this point, all that is left are the init and exit module functions:

    static int __init msg_init(void)
    {
    	return usb_composite_register(&msg_device);
    }

    static void msg_exit(void)
    {
    	if (test_and_clear_bit(0, &msg_registered))
    		usb_composite_unregister(&msg_device);
    }

They use the usb_composite_register() and usb_composite_unregister() functions to register and unregister the device. The msg_registered variable is used to ensure the device is unregistered only once.

To sum things up:

  • A composite device (msg_device) is registered when in msg_init() when the module loads.
  • It has a device bind callback (msg_bind()) that initializes MSF and adds configuration to the gadget.
  • The configuration (msg_config) has its own bind callback (msg_do_config()), which binds MSF to the configuration.
  • The really hard work is done inside the MSF.
Mass Storage Function

With the big picture in mind, lets get into the finer details: the inner workings of the Mass Storage Function. There are a couple of things to watch out for when dealing with it.

First of all, because MSF can be bound to several configurations, it needs to share some data between the instances and at the same time store information specific for each configuration. The fsg_common structureis used for shared data. An instance of this structure needs to be initialized prior to binding MSF.

Because the common object is used by several MSF instances, it has no single owner thus a reference counter is needed to decide when it can be destroyed. That's the reason for the fsg_common_put() call at the end of msg_bind() function.

Closely connected with the fsg_common structure is a worker thread which MSF uses to handle all the host's requests. When a fsg_common object is created, a thread is started as well. It terminates either when thefsg_common object is destroyed or when it is killed with an INT, TERM, or KILL signal. In the latter case, the fsg_common object may still exist even after worker's death. Whatever reason, when thread exits athread_exits callback is invoked.

It is important to note that a signal may terminate the worker thread, but why would one want to do that? The reason is simple. As long as MSF is holding any open files, the filesystems which those files belong to cannot be unmounted. That is bad news for a shutdown script.

What Alan Stern came up with in FSG, is to close all backing files when the worker thread receives an INT, TERM, or KILL signal. Because MSF is to be used with various composite gadgets, rather than hardcoding that behavior a callback has been introduced.

The last thing to note is that MSF is customizable. The UMC specification allows for a single device to have several logical units (sometimes called LUNs, which is strictly speaking incorrect since LUN stands for Logical Unit Number). Each logical unit may be read-only or read-write, may emulate a CD-ROM or disk drive, and may be removable or not.

All of this configuration must be specified when the fsg_common structure is initialized. The fsg_configstructure is used for exactly that purpose. In most cases, a module author does not want to fill it themselves, but rather let a user of the module decide the settings.

To make it as easy as possible, an fsg_module_parameters structure and an FSG_MODULE_PARAMETERS() macro are provided by the MSF. The former stores user-supplied arguments, whereas the latter defines several module parameters.

Having an fsg_module_parameters object, one may use fsg_config_from_params() followed by fsg_common_init()to create an fsg_common object. Alternatively, fsg_common_from_params() can be used which merges the call to the other two functions.

Here is how it all works when put together:

    static struct fsg_module_parameters msg_mod_data = { .stall = 1 };
    FSG_MODULE_PARAMETERS(/* no prefix */, msg_mod_data);

    static struct fsg_common msg_fsg_common;

    static int msg_thread_exits(struct fsg_common *common)
    {
    	msg_exit();
    	return 0;
    }

    static int msg_fsg_init(struct usb_composite_dev *cdev)
    {
    	struct fsg_config config;
    	struct fsg_common *retp;

    	fsg_config_from_params(&config, &msg_mod_data);

    	config.thread_exits = msg_thread_exits;

    	retp = fsg_common_init(&msg_fsg_common, cdev, &config);
    	return IS_ERR(retp) ? PTR_ERR(retp) : 0;
    }

The msg_exit() function has been chosen as MSF's thread_exits callback. Since MSF is nonoperational after the thread has exited, there is no need to keep the composite device registered, instead the gadget is unregistered.

At this point, it should become obvious why the msg_registered flag is being used. Sinceusb_composite_unregister() can be called from two different places, a mechanism to guarantee that it will be called only once is needed — atomic bit operations are perfect for such tasks.

And that would be it. We are done. One can grab the full source code and start playing with it.

The beauty of the composite framework is that all the really hard stuff has been already written. One can write devices and experiment with different configurations without deep knowledge of the USB specification or the Linux gadget API. At the same time, it is a perfect introduction to some more serious USB programming.

Running

To use the gadget, one needs to provide a disk image that will act as a real USB device to the USB host. Using dd on the device is perfect for creating one:

    # dd if=/dev/zero of=disk.img bs=1M count=64

With disk image in place, the module can be loaded:

    # insmod g_my_mass.ko file=$PWD/disk.img

Connecting the device to the host should produce several messages in the host system log, among others:

    usb 1-4.4: new high speed USB device using ehci_hcd and address 8
    usb 1-4.4: New USB device found, idVendor=0525, idProduct=a4a5
    usb-storage: device scan complete
    sd 6:0:0:0: [sdb] Attached SCSI removable disk
    sd 6:0:0:0: [sdb] 131072 512-byte logical blocks: (67.1 MB/64.0 MiB)
     sdb: unknown partition table

All that is left is creating a partition with a filesystem and starting using the pendrive:

    # fdisk /dev/sdb
    ...
    # dmesg -c
    sd 6:0:0:0: [sdb] Assuming drive cache: write through
     sdb: sdb1

    # mkfs.vfat /dev/sdb1
    mkfs.vfat 3.0.9 (31 Jan 2010)
    # mount /dev/sdb1 /mnt/
    # touch /mnt/foo
    # umount /mnt

As has been shown, the gadget works like a charm.

Conclusion

The Linux USB composite framework provides a way to add USB devices in a fairly straightforward way. Before the composite framework came along, developers needed to implement all USB requests for each gadget they wanted to add to the system. The framework handles basic USB requests and separates each USB composite function, which allows gadget authors to think in terms of functions rather than low-level interfaces and communication handling.

As one might guess, this article just scratches the surface of what the composite framework can do. The driver that was shown is a single-configuration, single-function gadget, so the advantages over non-composite gadgets is not readily apparent. A future article may look at drivers for more powerful gadgets using the composite framework.


The USB composite framework

Posted Jul 15, 2010 9:31 UTC (Thu) by linusw (subscriber, #40300) [Link]

The first part of the article looks very inspired by the Wikipedia article on USB so why not link it:
http://en.wikipedia.org/wiki/Universal_Serial_Bus

The USB composite framework

Posted Jul 15, 2010 16:16 UTC (Thu) by jimparis (subscriber, #38647) [Link]

I'm finding this article very confusing. 
When you say things like "The really hard work is done inside the MSF", it sounds like you're talking about the fsg_* functions, which are separate (but mostly copied) from Alan Stern's FSG? So a function like fsg_main_thread in f_mass_storage.c is part of MSF, but the function
fsg_main_thread in file_storage.c is part of FSG?

Having 5 ".c" files #included directly in "the full source code" doesn't help clarify things. Doesn't that also cause symbol conflicts if we wanted to write two modules and install them both?

I guess this article mostly is focused on how to use the composite framework, but the actual implementation of the device (MSF/FSG/whatever) seems to be the more interesting part from a USB driver writer point of view. Does the composite framework make that part any easier?

I'd really look forward to a future article on "more powerful gadgets" as you mention. Particularly interesting would be how such a composite gadget is treated and works on typical operating systems (can each function usually be bound to a driver independently?) and how to deal with hardware limitations (as I understand, most hardware has various limitations on numbers of endpoints or restricts their sizes, etc).

The USB composite framework

Posted Jul 15, 2010 18:38 UTC (Thu) by iabervon (subscriber, #722) [Link]

I guess this article mostly is focused on how to use the composite framework, but the actual implementation of the device (MSF/FSG/whatever) seems to be the more interesting part from a USB driver writer point of view. Does the composite framework make that part any easier?
My impression is that the framework is not intended to make the interesting part any easier, but rather to make the uninteresting part trivial. Having written a USB gadget (not on Linux), I've found that handling EP0 is a big chunk of uninteresting code that needs to be correct and involves fiddly interactions with your drivers, in that you have to make sure that your driver, your descriptor as sent on EP0, and your hardware registers all agree on how the endpoints are configured, and weird things happen if they don't.

The USB composite framework

Posted Jul 25, 2010 11:49 UTC (Sun) by mina86 (subscriber, #68442) [Link]

As I've mentioned, Mass Storage Function is merely a conversion of the File-Storage Gadget so most of the code in MSF is copied with modifications from FSG. As such, your understanding is correct, by MSF I mean all the functions in f_mass_storage.c as well as storage_common.c (the latter is code that is identical (or nearly identical) in both MSF and FSG).

The prefix of the function names may be confusing. At one point I even wanted to use fsg_ for FSG stuff, msf_ for MSF stuff and stor_ for commons but Alan convinced my that it's too much hustle and modification not worth the effort. Hence, the fsg_ prefix stayed.

As far as including “.c” files... to be honest, I'm not entirely convinced why this is done this way but that's the way it is done in other composite gadget drivers as well. The comment you may find in those is:

> Kbuild is not very cooperative with respect to linking separately compiled library objects into one module. So for now we won't use separate compilation ... ensuring init/exit sections work to shrink the runtime footprint, and giving us at least some parts of what a "gcc --combine ... part1.c part2.c part3.c ... " build would.

Going further in your comment, the situation with composite is just like iabervon described. It makes uninteresting things trivial. I would also add that it makes the more interesting part a bit harder.

This is because composite function has to worry about registering interface and string IDs and never knows in how many configurations it will be present or ever how many configurations gadget has.

One of the most complicated thing about converting File-Storage Gadget to Mass Storage Function was to allow for it to be added to several USB configurations. To achieve that I have created the fsg_common structure with reference counting and some such.

As of next articles I can only thank you for interest and get back to work. ;) Nonetheless, the my next article probably won't cover most of your questions but should be valuable addition to this one.

I may only quickly point out that you deal with hardware limitations by obeying them. :P If your UDC has limited number of endpoints you won't be able to stash many composite functions in a single configuration in your gadget. Mass storage is rather simple since in bulk-only mode (the one implemented by MSF) it uses only one IN and one OUT endpoint but generally functions may need more endpoints.

The USB composite framework

Posted Jul 16, 2010 4:38 UTC (Fri) by pabs (subscriber, #43278) [Link]

It would be great to be able to modprobe a mass-storage gadget, a serial gadget and a network gadget and a userland gadget and instantly get a composite device that supports all four.

The USB composite framework

Posted Jul 25, 2010 11:53 UTC (Sun) by mina86 (subscriber, #68442) [Link]

Yep! It would.

As a matter of fact, I've been thinking about something like that for quite some time now (ever since I've started working on USB gadgets I think). I also have some ideas regarding such functionality.

I was thinking more along the lines that you modprobe a “stub” gadget which merely describes what configurations it want to support and then modprobe all the functions. In essence that's what you've described.

I hope to find time for actually implementing it so maybe it'll be even easier then before to write gadgets. :)

The USB composite framework

Posted Mar 9, 2011 21:35 UTC (Wed) by spectrum (guest, #73494) [Link]

I would like to create a USB composite driver that has functionalities of both file storage gadget and RNDIS gadget. 

Is this possible?


android usb 分析笔记 virtual device: android_usb 首先来看 drivers/usb/gadget/android.c。 init() 创建了虚拟设备   /sys/devices/virtual/android_usb/. static int __init init(void) { struct android_dev *dev; int err; android_ 阅读详情

相关推荐

NXP Layerscape嵌入式Linux开发:USB与GPU驱动配置实战指南

在嵌入式Linux系统开发中,设备驱动是连接硬件与操作系统的关键桥梁,其核心原理在于内核通过统一的驱动模型管理硬件资源。USB驱动框架遵循典型的分层架构,从底层主机控制器驱动到上层设备驱动,共同实现了外设的枚举与通信。GPU驱动则负责图形硬件的初始化与加速,为用户界面和多媒体应用提供性能保障。这些驱动的正确配置,对于实现稳定可靠的外设连接与流畅的图形显示至关重要,尤其在工业控制、网络设备和边缘计算等应用场景中。本文聚焦于NXP Layerscape平台,深入解析USB主机/设备/OTG模式切换、Vivant

a631278993的博客 396

Linux USB composite framework

最近在搞USB,学习并记录下来 一、Linux USB composite framework 从复合gadget的角度来看,一个设备将一些功能分组到配置中。一个函数可以出现在任意数量的配置中中。每个函数可能有几个接口和其他描述符,但这对内核模块是透明的。 在“原始的”USB描述符结构之上,USB复合功能可以看作是一组接口的抽象。这是该框架的另一个优秀特性——大多数实现细节都隐藏在“外壳”之下,在开发gadget时不需要考虑它们。我们不考虑端点和接口,而是考虑函数。因此,FSG是一个以“旧方式”开发的

qq_36860921的博客 1139

NXP平台TDM与USB 3.0驱动配置与调试实战指南

在嵌入式系统开发中,硬件接口的稳定驱动是连接底层硬件与上层应用的关键。TDM(时分复用)作为一种经典的时分复用技术,其原理是通过将时间划分为固定长度的时隙,让多个信号流轮流使用同一物理信道,从而实现高可靠性的实时数据传输,尤其适用于语音通信等场景。USB 3.0则是现代高速外设连接的通用标准,其超高速传输能力极大地扩展了嵌入式设备的连接性。理解这些接口的驱动配置原理,对于构建可靠的通信网关、语音处理设备或工业控制器具有重要价值。本文聚焦于NXP平台,深入解析TDM框架与USB 3.0 Dual-Role控制

weixin_30522095的博客 348

linux usb做复合设备,usb从设备驱动usb_composite_driver复合设备

Linux/arm 3.10.104drivers/usb/gadget/composite.cstatic const struct usb_gadget_driver composite_driver_template = {.bind = composite_bind,.unbind = composite_unbind,.setup = compo...

weixin_36466165的博客 974

HiFive1 RevB J-Link-OB 驱动安装 3 步排错:从设备管理器无端口到成功识别

本文详细介绍了HiFive1 RevB开发板J-Link-OB驱动安装与端口识别的完整解决方案。从设备管理器无端口显示的常见问题出发,提供三步排错指南,包括驱动安装、硬件连接检测和设备管理器深度解读,帮助用户快速解决USB连接问题并成功识别开发板。

weixin_33834628的博客 396

高通平台开发系列讲解(USB篇)Composite USB gadget framework

📢本篇章主要图解高通平台Composite USB gadget framework

内核笔记 2026

gadget之composite

gadget之composite composite简介 composite英文意思为复合/综合。其为整个gadget驱动的中间层,往下注册usb_gadget_driver并与usb_udc(usb_gadget设备)绑定,往上通过usb_composite_dev与usb_composite_driver实现usb_function的绑定。usb_function、composite、udc三者相互联系共同实现usb device的功能。 struct usb_composite_dev //作为com

枫潇潇 1640

Linux-USB-composite-device-driver:Linux USB复合设备驱动程序

Linux USB复合设备驱动程序示例包含USB以太网和自定义的小工具配置。

Usb Composite Device (audio+hid) Descriptor

近期开发USB Composite Device 撰写的USB 描述符 ,支持 USB speaker + USB Mic,同时支持USB HID 自定义设备。可以作为 开发设备的参考。(此描述符已经经过实战验证,支持WINDOWS) AUDIO支持:48KHZ,16BIT,MONO 录放 (2个 ISO endpoints) HID支持: 8字节 双向(2 interrupt endpoin

cnhighway的专栏 4469

kemeas算法继续优化——elkan kmeas算法

题记:又是凌晨3点的夜 elkan kmeans算法 在我的上一篇博客《kmeans算法性能改进_kmeans++算法+kmeans++优化算法+距离计算优化》中,在一般kmeans算法的基础上,添加了对于初始条件和距离计算更上的一些优化技巧。这篇博客聊一聊elkan算法,其实也是对于kmeans运行速度的优化算法。主要作用与kmeans的距离计算过程。 原理 假如我们已经知道任意两个样本之间的距离,再假设我们已经知道了样本1与聚类中心1之间的距离,根据三角性两边之和大于第三边,c+d>a,所以如果

铁血军的小博客 7065

抖音Web端私信Protobuf逆向解析实战

本文详细解析了抖音Web端私信通信的逆向过程,发现其核心采用WebSocket传输Protobuf序列化数据。通过抓包获取二进制样本,利用protoc工具进行原始解码,并逐步推导和编写出对应的.proto协议定义文件,最终实现模拟消息的编码与解码,为理解私有协议逆向提供了完整实战案例。

water的专栏 760

今天开始做一个ARM做为USB从设备的驱动

在网上搜索了很长时间发现init_module的注册函数都是usb_gadget_register_drive,而我的zero.c中的注册函数为usb_composite_register.之后跟踪代码发现int usb_composite_register(struct usb

1240

bugku渗透测试4-writeup

三、对这个主机进行全端口的扫描,发现存在22000 ssh端口,那么可以联想到时redis写入公钥来连接主机。又来了一个新的靶场,这个靶场打下来我觉得关键就是信息收集,走了很多的弯路。八、最后一个flag是要去看cms的数据库里面,这个数据库是sqlite。把这个数据库下载下来,登录密码是加密的,就直接用token。一、入口的漏洞是在登录的时候去抓包,修改action的值。六、没想到这个第一台机器的密码,在第二台里面。七、扫描第一台主机、使用之前的密码连接成功。获取最后一台主机的root密码。

vsdfbhsdhsdfh的博客 1295

USB gadget driver framework

USB gadget driver的框架可分为三部分:UDC-core, composite.c and android.c,其中 composite.c是核心,其他两部分都要bind 到 composit上。 1. UDC-core 结构体usb_gadget中包含指向usb_ep的link head,通过该link head,可以访问 所有的usb_ep, usb_ep中包含了具体的,最

u011279649的专栏 3787

(10)Proteus 8.9上的STM32仿真系列(HAL)---freertos

实验设计:通过cubemxide生成freertos工程,然后创建一个 pc13 led灯间隔200ms闪烁的任务。非常遗憾的是proteus8.9仿真失败,实物上没有问题,但还是把流程过一遍。 一、原理图 实物是淘宝上stm32f103 c8t6的核心板,proteus上没有这个芯片,这里图上大概表示一下,用的是核心板自带的pc13引脚的led灯。 二、cubemxide配置 1.RCC如之前工程一样配置 2、配置SYS timebase Source不要使用systick,自己选择一个定时器,我这

qq_35442550的博客 7342

在F1C100s上跑GBA游戏:手把手教你用Buildroot配置SDL和移植gpsp模拟器

本文详细介绍了在全志F1C100s开发板上配置Buildroot、移植SDL库和gpsp模拟器的完整流程,帮助开发者实现在ARM9平台上流畅运行GBA游戏。内容涵盖环境配置、交叉编译、常见问题解决及性能优化技巧,特别针对'段错误'和'无声音'等典型问题提供实用解决方案。

weixin_42566424的博客 397

UDC (usb device controller) Framework - USB gadget driver framework

http://blog.youkuaiyun.com/u011279649/article/details/11059433 USB gadget driver的框架可分为三部分:UDC-core, composite.c and Android.c,其中 composite.c是核心,其他两部分都要bind 到 composit上。 1. U...

gnimey的博客 1536

搞定ESD(四):ESD干扰耦合路径深入分析(二)

静电放电过程中静电干扰主要通过三种间接耦合方式干扰敏感源,即电场耦合、磁场耦合、地弹。前文已经深入分析了静电放电过程中的电场耦合,今天就谈谈静电放电过程中的磁场耦合,也可以理解环路耦合。熟话说的好〝人往高处走,水往低处流〞,静电电流也会选择阻抗最低的路径返回到源端。静电电流流会源端的路径实际上就构成了电流环路,当敏感信号形成的电流环路与静电电流环路存在共环路时,就会将静电放电干扰耦合到敏感信号环路内,干扰敏感信号。

记得诚 2793

linux usb gadget

上一篇谈到了usb host以及usb core,这一篇来介绍下usb gadget,usb gadget较usb host出现较晚,随着linux越来越用作嵌入式设备而出现,是一套独立的架构,与usb core没有任何关系。 由上图可以看出gadget架构有两个核心抽象层,composite framework和udc core。 composite framewor

festival的专栏 3890

基于Simulink的PR(比例谐振)控制器在单相整流中的应用

本文详细介绍了基于Simulink的单相整流系统中PR(比例谐振)控制器的设计与实现方法。首先阐述了PR控制器相较于传统PI控制器的优势,能够有效消除交流信号跟踪中的稳态误差。接着系统讲解了PR控制器的传递函数原理、实用型设计(带带宽)及参数整定方法。通过Simulink建模步骤,包括主功率电路搭建、电压外环PI设计、电流指令生成、PR控制器实现(推荐MATLAB Function方法)和SPWM调制等关键环节。仿真对比显示PR控制在电流跟踪精度(THD仅1.9%)、功率因数(0.998)和动态响应(突变恢

amy_mhd的博客 689

【WRF-Urban数据集】中国60个城市的1 km分辨率城市冠层参数(UCPs)

中国60个城市的1 km分辨率城市冠层参数(UCPs)

WW、forever的博客 1063

Android下USB Accessory的实现分析 (二)--- 底层驱动设计实现

接着前面的文章 《Android下USB Accessory的实现分析 (一)— AOA背景介绍》 2.Android下Usb Accessory的设计实现 Android下对Usb Accessory设备的支持包括内核驱动层的支持和Android Framework层的支持,如下是设计架构图: 下面就分别从Linux内核驱动,Android Framework层,以及相关的应用层代码来进行分...

|~~~热爱生活、努力学习的小伙汁~~~| 3619

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

USB开发实战资料:从协议解析到调试排错的全方位指南

USB(通用串行总线)作为一种广泛应用的主从式串行通信接口,其核心在于通过标准化的协议实现主机与设备间的高效数据传输。其工作原理基于分层的通信模型,包括物理层、链路层和协议层,通过令牌包、数据包和握手包构成的事务模型完成通信。这一技术价值在于提供了即插即用、高带宽和广泛兼容性的解决方案,极大地简化了外设连接。在应用场景上,USB技术覆盖了从键盘、鼠标等HID设备,到U盘、移动硬盘等大容量存储设备,再到音频接口和高速数据采集系统等多个领域。本文基于工程师多年积累的实战资料,深入探讨了USB 2.0协议框架、设

weixin_30719711的博客 391

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

怎么查看调用栈关系

前言最近在学习Linux USB Composite Framework的内容,经常看到函数指针跳转来跳转去。比如说会看到很多结构体中的.bind函数指针,但又不知道他们之间的调用关系。此时,就可以用dump_stack()这个函数来追踪函数调用关系。当然,还是要自己尝试学习理解这个框架结构,不然纯粹的知道函数调用关系意义不大。另外,dump_stack()可用来定位Kernel Panic和Oop

www.wowothink.com的专栏 3272

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: kernel.org复活了!
下一篇: Android Issues List
sanlinux
博客等级 码龄17年 92粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值