I am currently working on some preliminaries for the integration of Apple CarPlay on an infotainment unit (IU) based on Linux. One requirement of Apple is a USB role reversal, where the IU starts as USB host and becomes a USB device. The Apple device is in the end the USB Host.
The Apple specification requires, that the IU must present a configuration with three different interfaces, an iAP2 interface, a USB NCM control interface and a USB NCM data interface. An example configuration is given in the specification. It defines things like Class, Subclass, Protocol, Attributes, Endpoints, etc. This required configuration seems to be covered by the Device descriptor, configuration descriptor, interface descriptor and endpoint descriptor which is supplied by the device upon connection to a host.
For the NCM support, I activated the USB Gadget support and set Network Control Model (NCM) Support under USB Gadget precomposed configurations. For the USB interface, we use the DWC3 driver. As soon as I set the driver into the device mode, this NCM gadget driver is loaded and a new NIC appears.
How can I configure the USB descriptors of the USB device (the linux based IU) which are sent to the USB host (the Apple device)? As said above, two NCM interfaces and one iAP2 interface must be offered.
I have found some hints that this might be done with libcomposite through /sys/kernel/config/usb_gadget/ once the configfs is enabled (e.g. https://unix.stackexchange.com/questions/631138/unable-to-set-usb-gadget-device-class-and-protocol). Is this somewhere documented? Shall different endpoints have subfolders like they have under /sys/bus/usb/devices?
Afaik each interface can have a separate driver. Does this apply for both sides, Host and devicen side?
How are the driver and the defined interfaces in the descriptors linked? I assume the USB device driver must have some sort of configuration of the descriptors as well as the associated drivers for each interface?
The two NCM interfaces shall be handled by the NCM driver and the iAP2 interface by the iAP2 driver.
As I figured it out now, I would like to answer my own questions and provide some details to this topic.
USB Descriptors of the USB device can be configured through the configfs. Therefore CONFIG_USB_CONFIGFS needs to be enabled in buildroot and the corresponding gadget (Network Control Model (CDC NCM) in my case) needs to be selected (<*>).
You then need to mount the configfs, create a new folder for the gadget and will find several files in place, where you can customize some of the USB descriptors. This procedure is described in detail in the kernel configuration docu for the Linux USB gadget configurable through configfs. They list an example directory structure which tells you what descriptors are modifyable
./strings/0x409/serialnumber
./strings/0x409/product
./strings/0x409/manufacturer
./configs/c.1/bmAttributes
./configs/c.1/MaxPower
./bcdUSB
./bcdDevice
./idProduct
./idVendor
./bMaxPacketSize0
./bDeviceProtocol
./bDeviceSubClass
./bDeviceClass
The Gadget function itself can also offer configuration through the configfs, however this depends on the used gadget. In case of the NCM, the MAC Addresses, the interface name and queue length multiplier for high and super speed can be configured
./functions/ncm.usb0/ifname
./functions/ncm.usb0/qmult
./functions/ncm.usb0/host_addr
./functions/ncm.usb0/dev_addr
What is called interface on the USB host side is a function on the USB device side. When you create/associate a new function (like NCM) to the gadget, this will appear as interface on the USB host side (Some functions like NCM will create multiple interfaces). You can assign multiple functions to the gadget (mass storage, MIDI, NCM, ...) and the host will see multiple interfaces. The configuration of those functions/interfaces e.g. regarding endpoints is limited to the files available in the configfs. Endpoints, Packet size, etc regarding NCM is not configurable as this is more or less hardcoded in the source code which also defines the remaining descriptors, not configurable through the configfs and the behavior of the function itself.
If a configuration beyond the offered files in the configfs is required, the source code of the function needs to be changed. But one then needs to take care, that this still reflects the capabilities of the interface!
Related
I'm a software developer but I'm a newbie to embedded software development.
I have a Zynq Ultrascale board that has an Axi DMA in its Hardware and I want to access this DMA from Linux.
I know I should use DMA-Engine to Access DMA in Linux and I found the following link which is the Xilinx DMA driver, but I can't add these files to my qt project without any errors and I received file(header file) not found errors.
drivers/dma/xilinx/xilinx_dma.c
I have a piece of scattered information about the DMA driver, Device tree, and DMA-Engine but I know nothing about how to utilize these to access hardware DMA.
I built a Petalinux project and add DMA-Engine and DMA Test client to its kernel.
I don't know adding DMAEngine to the Petalinux project is enough or I should have a driver as well.
I don't know adding hardware specification (by .xsa file and .bit file) to the Petalinux project is enough or I should add a device tree to my Linux for detecting DMA as well
I lookup a step-by-step tutorial on how to set up Linux and qt creator for accessing DMA,
or at least a clear roadmap to my target.
thank you in advance.
First of all, you are facing errors when adding xilinx_dma.c to the Qt project because this file is meant to be compiled as part of kernel or as a kernel module.
Adding DMA Engine to Petalinux is not enough to work with DMA from user space. DMA Engine only provides a standardized API to let different DMAs be integrated into kernel. You need to add a client driver as well. Xilinx, as far as I know, has provided a simple client driver called DMA Proxy Driver. It also includes some simple examples that show how you can access DMA from the user space. However, if your application needs high bandwidth, you probably need to consider other options.
There is also an open source client driver for Axi DMA which achieves higher bandwidths compared to Proxy DMA Driver. It's user space API also allows you to register a callback function to be called whenever a transaction is finished.
The third option is to implement the driver in the user space. This can be done by defining the DMA as a UIO device in the device tree and access its register map directly from the user space. In this case, you need to allocate some contiguous memory blocks in the kernel space to avoid complications with MMU, which cannot be dealt with from the user space.
I want to understand the performance of one device driver module in linux kernel. In this case I use carl9170 device driver in linux.
If I use two physical interfaces, how can the single module carl9170 handle 2 different physical interfaces?
Because so far, I have known that these 2 physical interfaces will make 2 instances and use different packet buffers for each but just using single carl9170 module. So it's confusing me.
And which file in linux kernel source code can I find about this handling method (relates to carl9170 device driver)?
Thank you very much for your help
For 2, take a look at the folder:
drivers/net/wireless/ath/carl9170/
This folder is located under your kernel source directory. It contains all the sources of the driver.
For 1:
It is pretty much how classes works on oriented object programming: how does an object know which instance of the data it must work with? The this pointer references the correct in memory data.
Take a look at the file drivers/net/wireless/ath/carl9170/carl9170.h. Every function exported by the driver is declared at this file. Note that every function has at its first parameter a reference to the struct ar9170 data type. This is exactly the data set that the driver must work with. It specifies everything the driver need to know about the device and its sates, since the USB buses address where the device is connected, to the state of the device, like its power, connection state and any other data the driver itself need in order to keep the device working properly.
Note that this is driver internal data thought. The kernel has its own set of data to keep both the driver, the device and the kernel itself working.
Take a look at the 546 line of carl9170.h. It is where the function declarations starts. This file is as of the kernel 3.8.8.
Just like in Object Oriented Programming you would allocate as many instances of a class as you need, the kernel will allocate as many ar9170 structures a it needs, one referencing each device.
The device ids can be obtained under the /sys/class/net directory. There will be a soft link for each of the network devices attached to your computer. This link will point the device to something like the following:
$ ls -l eth0
../../devices/pci0000:00/0000:00:04.0/0000:02:00.0/net/eth0
The pci0000:00 is the bus. The 0000:00:04.0 I believe is the bus address. Finally, the 0000:02:00.0 is the device id. Afaik, every registered device follows the same logic.
Finally, if you have two carl9170 devices, both will be under the directory /sys/class/net but probably one of them will be named wifi0 and the other wifi1. Also, each of them will point to different devices (check it with the command ls -l /sys/class/net).
I just would like to note that in the explanation I haven't used any wireless card. So I'm not sure whether wireless cards are shown under /sys/class/net or not. Anyway, it will be something very similar, like /sys/class/wireless.
I am writing a program to transfer files through a lan computers, it's been a while I'm searching for file transferring methods in Delphi. I found UDP is a good solution, but there is a problem: in every example or article I found there was a client program beside a server program, but my program have to send and receive to/from every computer in network, there is no specific server or client, something like p2p, I don't want to make a computer Server and another one Client, what should I do? I searched Indy articles too, it's working in Server/Client mode too (as far as I found).
UDP can work in broadcast mode, which is what you need. But such UDP broadcasts are not routable outside the current network (i.e. they are blocked by routers), so you have to implement something more complex if your project needs to be accessible outside the primary physical network.
Do not reinvent the wheel! If you want to see some working source implementing this concept, see Ares Galaxy:
"Delphi self-organizing p2p network project featuring high scale
capability and fast broadcast-type search system. Client supports
multi-source file transfers, partial file sharing, built-in
audio/video player and decentralized chat rooms".
The source code files are available from SourceForge. You could re-use/adapt the P2P network layer for your needs - but take attention to the license terms of Ares source code, if you use it in your projects.
Have a look at Indy's TIdTrivialFTP and TIdTrivialFTPServer components. TFTP is a UDP-based file transfer protocol.
I want to write a program which will "lock" a computer to a user determined wireless network.
It should automatically establish and maintain the connection with the specified network
Other networks should be hidden and/or inaccessible while the program is running
Should be compatible with Windows XP - 8
Should work for all wireless cards
Could I create an NDIS filter driver or NDIS intermediate driver for this? Which one is a better option? Also, the MSDN documentation I linked does not seem to provide good information about how to actually write the driver, where can I find that?
Have a single PCI device which contains three NICs, courtesy of Altera Ethernet cores. Must implement for WinXPe thus NDIS 5.1. MVPs have suggested implementing a WDM driver for each core, then a single NDIS driver that talks to the individual WDM drivers, which I do not understand, given that a single NDIS driver does not appear to have any concept of multiple ports or channels.
What if at DriverEntry the NDIS driver called NdisMInitializeWrapper once for each ethernet core? It would need to call each time with the same DriverObject, but would presumably get back a different NdisWrapperHandle with each call. That unique NdisWrapperHandle could be used as a context specifier for calls to all other NDIS driver functions.
That won't work; NdisMInitializeWrapper can only be called once per driver.
The rule is: you need to have one device node per network interface. Therefore, if you want 3 Ethernet interfaces, you'll need 3 device nodes in the system. There are a couple ways to get there:
The PCI bus will create a device node for each PCI function number. If your PCI device exposes 3 functions to the bus, then Windows will enumerate 3 miniport device objects. This makes the driver super simple. But, obviously, you have to be able to rejigger the hardware to do this.
Alternatively, if you are stuck with only one PCI device with one PCI function, then you need to multiplex the PCI-enumerated device node yourself. This means you should create your own Virtual Bus Driver (VBD). The PCI bus enumerates one device node, which is associated with the driver for your VBD. Then your VBD turns around and enumerates 3 child nodes, each of which is associated with a miniport.
This approach takes considerably more work, since now you need to write two drivers. Fortunately, WDF makes writing a bus driver possible for mere mortals. Your VBD needs to implement code to share resources (interrupts, config space) among the child network miniports.
The big-name vendors are split on whether they chose option #1 or option #2, so both can work. From your description, it sounds like you've already been given advice to implement a VBD.