Libusb interrupt transfer callback - c

I'am working on a real-time control system that calculates the control signals in a buffered fashion (a user-mode program) and outputs to the usb device the array through isochronous transfers. The usb device them reports the execution progress through interrupt transfer, so that pc software can then calculate and push the next control array.
The software runs based on raw win32 api, C based. (C++ used only on not time sensitive parts of the program, such as interface, 3D models...).
I would like to know if there is a way to register a callback function in response to a interrupt transfer?

From what I understand, although we are talking about interrupt transfers, the USB device still has to be polled using libusb_interrupt_transfer:
Interrupt transfers are typically non-periodic, small device
"initiated" communication requiring bounded latency. An Interrupt
request is queued by the device until the host polls the USB device
asking for data.
Excerpt from https://www.beyondlogic.org/usbnutshell/usb4.shtml#Interrupt

Related

What needs to be done to write interrupt handler on linux without actual hardware?

Is there any Hardware emulator which can generate hardware interrupt on Linux. I am looking to write device drivers that could process hardware interrupts, read or write into hardware memory, deferred work, top and bottom halves processing, etc. Basically, looking to learn complete device driver end to end. But what hurdle is - how to simulate hardware. Do I really need some hardware that could generate an interrupt. I went through book LDD3, but there they are using skull - a chunk of kernel space memory emulating as a hardware, but this cannot generate an interrupt, or it can? pls, throw some light.
The skull driver of LDD3 doesn't generate interrupts, because there's no actual hardware to generate them.
Device driver interrupts are a mechanism that allows the cpu to begin attending some other task because the action being performed will be handled by an asynchronous interrupt.
For example, a floppy disk drive interrupt's the cpu as each byte of a disk transfer is readin if no dma is in use. If DMA is being used, the disk will transfer directly to ram the bytes of the transfer until a full block (or a set of them) is actually transferred. Then some hardware interrupt will come in.
A serial interface interrupts your computer in a programmed basis. When a single character arrives, when a specific character arrives (let's say a \r char).
LDDP shows you how linux device drivers work..... but as the book cannot assume you have any concrete device, it is not capable of selecting a proper hardware to serve as usable (strange, as normally every pc has a parallel port or a serial port) I think LDDP3 has some driver using the parallel port, but you must continue reading the book before you start with interrupting hardware.
Asynchronous interrupts must be programmed into the device (the device must know that it has to generate an interrupt at the end of the transfer) so they have to be activated. For the interrupt to be properly catched, an interrupt handler must be installed before the first interrupt happens, or you'll get in an state in which no interrupt comes ever, because it arrived and was lost. And finally, interrupts have to be acknowledged. Once you have stored the data comming from the device, they have to be reactivated, so another interrupt can happen again. You need to learn that you have to protect your processes from accessing the data structures shared with an interrupt handler and how to do this. And all of this is explained in the book.... but you must read it, and don't stop in the skull driver which is the first driver developed in the book.
By the way, the kill(2) and sigaction(2) system calls of user mode are a very close approach into the world of hardware interrupts, because they are asynchronous, you can block them to occur, before entering a critical zone, and you can simulate them by kill(2)ing your process externally from another program. You will not see the difference, but instead of having a full system crash, you only get a hung process to kill.

How does serial console communication work in a microcontroller?

My doubt is regarding the physical layer of the communication, I know from practice that for using for example teraterm to communicate with a MCU is simply enabling and configuring an UART peripheral, and then connect via USB the microcontroller and voila.
But it doesnt make sense to me yet that if USB connects to DN and DP, and an UART uses RX and TX, how does the host effectively communicates to the microcontroller?
There are two possibilities.
You connect to a USB/UART bridge such as devices made by FTDI or Prolific,
The microcontroller has a USB device controller and USB stack implementing the CDC/ACM device class (virtual COM port).
In the first instance, the bridge chip presents the CDC/ACM device to the host and exchanges data with a UART connected to the microcontroller UART. I/O control such as setting the baud rate have no impact on the USB connection, rather they are used to configure the UART link.
In the bridge arrangement, the bridge chip may be on the micro board, or it may be in a USB/serial adapter cable. Moreover internally the bridge chip is a microcontroller with a CDC/ACM device stack.
Unlike say RS-232, USB is not a peer-to-peer full duplex connection, and is not merely an electrical connection; USB requires quite complex device and host controllers and is more analogous to a device bus such as PCI than it is to UART serial connections. A CDC/ACM class device conforms to a specific protocol to allow a "virtual" UART to appear at the host. The UART you see at the PC is emulated, and is not physically the UART in the bridge.
The physical actual USB connection is a master-slave connection, with data and I/O control commands (such as baud rate and flow control) sent in USB packets to be unpacked, interpreted and transferred to the application layer via the CDC/ACM USB stack. In this arrangement the device, acting as a slave cannot initiate an exchange; rather the host continuously polls the device to which the device may return a packet containing its "tx" data. The polling and data rate of USB are fast enough to allow the simplex master-slave exchange to emulate a full-duplex UART connection, at higher throughput than can normally be achieved by a typical real UART, and certainly faster than a physical RS-xxx connection.
You can get an idea of how all this works by observing the raw USB data exchange using a tool such as WireShark. You will see that a lot more than just your application "serial" data is being exchanged.
You need to use a uart-usb interface IC that can convert uart to usb (and vice versa).

ATSAM4s8b, how to wait until a usb device has been connected

I am very new to C and embedded programming.
I simply want to have my main thread wait until a usb device has been plugged in to my embedded device.
However, no matter how hard I look, I cant find documentation or examples about how to check if the usb has been plugged in.
I am using a ATSAM4S8B.
EDIT:
Actually I think the usb capabilities are built into the chip, I can use Atmel ASF libraries.
I am hoping that there is just a library function I can call to see if the usb has been connected too but I can't find anything like it.
There are two ways of detecting USB connection:
waiting for usb events occure and special USB flags to fire in hardware registers, which will signal if initiating process started. This solution depends on a particular chip you use and firmware burnt into MCU.
use sense IO pin. Attach USB 5V through 1k resistor to a pin of the MCU. High level on the pin will indicate, that USB was connected. Dont forget to use high value (>10k) pull-down resistor, which will pull the input low when USB disconnected.

Linux USB device driver misconception

My question is going to be rather vague but I will try to explain as detailed as I can what I am trying to resolve.
Trying to learn Linux kernel USB stack I have started to think of making a simple USB driver for my Atmel evaluation board based on ARM M0+ MCU to run away from Windows tools (Visual Studio plugin).
I have spent few days learning kernel's USB API and come to conclusion of how to make this. My driver aims to make my board connected to PC through USB cable act like a simple USB flash drive. Making that I then can easily program it with a new version of firmware written by me.
I have found that I need to find out specific interface (I am talking about interface in terms of USB specification, not interface we used to use as a code abstraction) that holds an endpoint (pipe) responsible for interaction with flash memory. And then I can map it to character device and interact with it using standard I/O operations that are described in struct file_operations structure.
Simply using cat on /proc/* file descriptor that was created by USB Core subsystem I have investigated that interface responsible for interaction with flash memory holds bulk endpoint (likewise, this terms come from USB specification, CMIIAW) that act as a "descriptor". Linux kernel USB Core subsystem gives neat interfaces to talk to different kind of endpoints whether it control, interrupt, bulk or asynchronous endpoint.
Now I have come closer to my very question.
Also the main transfer unit in communication between two USB devices is abstraction called urb - you allocate it, you fill it, you send it to USB Core subsystem, you read it if it was IN type of urb and, finally, you free it. What is confusing for me and tightly related to my question is the next API include/linux/usb.h:
static inline void usb_fill_bulk_urb(struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context)
Assume I have obtained an information from board's datasheet about where to write a program code. Let's say, we have 0x00100 - 0x10000 memory region. I will compile my code, obtain a binary and then using standard Linux tools or writing a simple user-space wrapper application I will use lseek to set file's offset to 0x00100 and write system call provided with a buffer (binary compiled previously) and it's length.
In kernel space, I will have to allocate urb in write system call handler, fill it with a buffer sent from user space and submit this urb to USB Core.
BUT I can not find a way how to specify an OFFSET set earlier by lseek. Do I miss something? Maybe I missed some concepts or, perhaps, I am watching in a wrong way?
When your embedded Linux device acts as a USB mass storage device, the flash as a peripheral on Linux device is unmounted, and the gadget driver is loaded. Linux then loses control to the flash, and now the PC connected to your Linux device fully controls the flash. This is because a flash as a USB device can only has one USb host.
The gadget driver works purely in kernel space. It does not receive or transmit data from/to user space. It calls vfs_read() and vfs_write() to access the files on the flash, with an field offset. The offset is got from the USB commands sent from your host - Windows PC.
There is no way to specify offset using USB subsystem's API. I misunderstood whole conception of USB as communication protocol, unwise me. You must first learn underlying protocol your device uses to communicate with others.
If your device acts as a USB HID device then learning specification of how to exchange data with USB HID device is the way to go. If there is something proprietary then you can do nothing but reverse engineer it (listening USB packets with a sniffer on system where a driver for your device exists).
As for my board it has embedded debugger that serves as a communication module besides being debugger itself. Specifically, my device is equipped with EDBG and here is a link on description of protocol it uses for communication.

how to find the interrupt source code in linux kernel?

I am looking for source code of interrupt service routine and searching net_bhi(); and netif_rx(); interrupt routine in the linux kernel. The above both api are the packet receiving of udp in the linux kernel. I want to modify interrupt routine as - I should calculate the timestamp when the interrupt occurs. So please someone help where is the location for the above file ??
Each network device (driver, really: the software that knows how to operate the device) will have its own interrupt service routine. The driver registers that routine's address with request_irq (in essence, "when this interrupt fires, call me here").
In the case of a network driver, the driver's interrupt routine will typically do little other than invoke a tasklet or softirq. This is to avoid running for long periods of time in a state that may block other critical interrupts.
In most modern network drivers, a softirq is actually triggered through a framework called NAPI. The driver will have registered its NAPI poll routine with netif_napi_add, and at interrupt time, the driver calls napi_schedule to communicate that its poll routine needs to run.
Once its tasklet or NAPI poll routine is invoked, the driver will access device registers to see why the device interrupted. If new packets are available, the driver will usually forward them to the linux TCP/IP stack with netif_rx or a variant thereof.
So, you'll have to choose where/how to record your timestamp. It would be easiest to do so in the tasklet or NAPI poll routine, but that may be some (possibly many) microseconds after the packet actually arrived. (Some delay between packet arrival and timestamp recording will be unavoidable in any case without specialized hardware.)
I am not sure about the path. But you must find it in /usr/src/linux-...
But if you want to have a time stamp printed with the interrupt, you can actually catch the interrupt using signal handlers, and then use gettimeofday() API to print the time.

Resources