How to know when i'm waiting in a poll system call? - linux

We're accessing an FPGA device via the Linux UIO device infrastructure. Under this model, we receive interrupts from the FPGA by poll(2)ing the device node /dev/uio0.
We'd like to make sure that we don't miss any interrupts. Hence we need a way to notify clients of the class encapsulating the device file descriptor when our polling thread is ready waiting in the poll(2) system call, so that we can be sure that we're only telling the FPGA to start generating interrupts when we're actually waiting for them.
Do you know of any way to achieve that?
Thanks,
Damian

Related

Why are interrupts needed for MMIO on pcie?

This blog post talks about the difficulties in bringing pci passtrhough support for ARM devices: https://www.linaro.org/blog/kvm-pciemsi-passthrough-armarm64/
It cies GICv2/GICv3 which are ARM's interrupt controllers. You can write to it via MMIO and make it deliver interrupts to CPUs.
However, why interrupts are needed? Shouldn't the PCIe driver talk with the PCIe device through MMIO. That is, writing/reading from memory?
It is necessary because otherwise the operating-system doesn't have any way of knowing an event happened. Operating-systems are not polling memory constantly. They still need to know that an event happened and when. That's where interrupts come in.
Imagine you have an hard-disk PCIe controller. How does the operating-system know when the disk is done writing its data to RAM?

Does WebUSB support timeouts?

Usb libraries always support setting timeouts on operation with device. And this is important feature for soft which works with usb devices, because that's how you can understand that device don't answer to your command. I look through WebUSB Api and look's like it's not support timeouts at the moment.
Is it true? Is the only way is to manually start timeouts before every usb operation, and stop timeout after operation success?
WebUSB does not currently support transfer timeouts or aborting transfers because after surveying the various platform APIs for USB it did not seem possible to implement them in a consistent way. Ideally it would be possible to cancel a transfer by removing it from the USB controller's transfer schedule. This is possible on Linux with the USBDEVFS_DISCARDURB ioctl and timeouts are supported on macOS using ReadPipeAsyncTO() and similar functions. On Windows however the only way to cancel a transfers is to call WinUsb_AbortPipe() which affects all pending transfers on the pipe, not just the one that timed out.
If you need to react to a device not replying to a USB request in a timely fashion then doing so manually with setTimeout() and clearTimeout() is the best option. Keep in mind that USB transfer itself will remain active and could complete at a later time.

I2C concurrent access on Linux, mutex

I'm writing a multithread C program in embedded Linux that accesses from userspace a number of I2C devices (slaves). Also, I access the same I2C device from multiple threads. I'm using SMBUS functions (i2c_smbus_write_byte_data, i2c_smbus_read_byte_data, i2c_smbus_read_i2c_block_data,...).
Is there any protection from concurrent access built in or do I need to add mutexes myself?
For instance: I have a Read function that read data from one sensor over I2C. But the same function can be called from another thread as well, resulting in possible concurrent access. Do I have to use some static mutex in that function or is it already in the I2C access functions?
I2C is a shared bus with multiple devices, which could be accessed from multiple processes as well as threads. So the Linux I2C driver code uses a mutex to manage access to each I2C bus.
For SMBus functions, see the Linux kernel function i2c_smbus_xfer() in i2c-core-smbus.c. It gets a lock for the I2C adapter before beginning a transfer (look at the source code, and see the call to __i2c_lock_bus_helper()). All SMBus transactions are based on that function.
For I2C functions, see the Linux kernel function i2c_transfer() in i2c-core-base.c. It gets a lock for the I2C adapter before beginning a transfer. All I2C transaction are based on that function.
So yes, there is protection from concurrent access built-in.
(links are for Linux kernel 5.13)
Use a mutex in your program. The driver has no way to know the operations that each thread is going to do.

Blocking I/O Write Operation on UART Serial Port in Linux

I am trying to communicate with a device over a RS-485 half duplex serial line. When I send a command to the device, it processes the command and replies immediately after processing. The problem is I have to turn my RS-485 chip into receive mode immediately after sending the command in order to receive the reply of the device. But because my write function of the UART is a non-blocking IO operation I have no way of knowing when to turn my RS-485 chip into receive mode.
How can I do a blocking write operation into the UART that the function will not exit unless all of the bytes are actually sent over the serial line?
What is your hardware platform? I have solved that problem before (atmel AT91SAM9260) by configuring the hardware to automatically set the RTS signal. That is your best bet unless you modify the serial drivers in the kernel (and sometimes not even doing that you can do it)

Netlink user-space and kernel-space communication

I am learning programming in embedded systems using Linux as my main platform. And I want to create a Device Event Management Service. This service is a user-space application/daemon that will detect if a connected hardware module triggered an event. But my problem is I don't know where should I start.
I read about Netlink implementation for userspace-kernelspace communication and it seems its a good idea but not sure if it is the best solution. But I read that the UDEV device manager uses Netlink to wait a "uevent" from the kernel space but it is not clear for me how to do that.
I read about polling sysfs but it seems it is not a good idea to poll filesystem.
What do you think the implementation that should I use in my service? Should I use netlink(hard/no clue how to) or just polling the sysfs(not sure if it works)?
Thanks
Yes, polling is ill-advised. These resources: LJ article on Netlink, "Understanding and Programming with Netlink Sockets" make it seem not so hard to do netlink. Here's an example of netlink sockets in python.
udevtrigger is a great utility for reacting to udev changes.
http://www.linuxjournal.com/article/7356
http://smacked.org/docs/netlink.pdf
http://guichaz.free.fr/misc/iotop.py
http://manpages.ubuntu.com/manpages/gutsy/man8/udevtrigger.8.html
If all you do is wait for an event you can use sysfs, which will be a lot simpler than netlink. An example is the GPIO system's edge file.

Resources