interrupts to notify events in linux - linux

I want to write a program which notifies when the laptop battery level falls below a certain threshold level. I am using ubuntu 11.04 . Is there a way in which i can generate an interrupt without polling the battery. What system calls in linux are used to achieve this ?

There is no system call interface to ACPI in Linux... All of the I/O is done using /proc/acpi or /sys/class entries. Easiest implementation would be a polling software, and read the interface periodically (going to sleep if the threshold is not there yet) — this is because typically /proc and /sys files construct the desired information while handling the read(2).

Related

Can external hardware devices use System Calls?

Is it possible for an external hardware device to use system calls and access the operating system? It reminds me of the auto-run of a disk-on-key device but I'm not sure whether it occurs because of the operating system or the device itself.
A system call requires a process. Unless there is a process tied to the device, there is no way to do a system call.
Normally devices access the operating system through interrupts. Interrupts are handled in a manner that is similar to the way system calls are dispatched. The difference that system calls are triggered by exceptions,rather than interrupts.
I am sure someone could or perhaps has built one. But in general that is not how it works. The hardware causes some software via interrupt or polling or other to handle that hardware event (the insertion of a usb key and enabled features of the usb driver or operating system software above the driver level to search for autorun files and run them).
when you click the mouse button it simply sends a signal to the computer which in turn wakes up some software that handles that button press. that software is either part of or interacts with the operating system.
In the case of automatically mounting a drive or cd or dvd when inserted starts with signals being sent that wakes up low level software for that interface, then that is passed up/over to the operating system which then if it has features enabled might automatically mount that drive, then if it has features and they are enabled might then search for certain agreed upon files that would allow software on that device to be run by the operating system. All the operating system interaction is done by software.

kernel driver or user space driver?

I would like to ask your advice on the following: I need to write drivers for omap3, for accessing external dsp through fpga (through gpmc interface). The dsp is required to load file to dsp, and to read/write buffer from dsp. There is already FPGA driver in kernel. The kernel is 2.6.32. So I thought of the following options:
writing dsp driver in kernel, which uses the existing fpga driver.
writing a user space driver which interfaces with the fpga kernel driver.
writing user space driver using UIO , which will not use the kernel fpga driver, but shall do the access to fpga, as part of the user space single and complete dsp driver.
What do you think is prefered option ?
What is the advantage of kernel driver over user sace and vise versa ?
Thanks, Ran
* User-space driver:
Easier to debug.
Loads of libraries to support you.
Allows you to hide the details of your IP if you want to ( people will really hate you if you did! )
A crash won't affect the whole system.
Higher latency in handling interrupts since the kernel will have to relay the interrupt to the user space somehow.
You can't control access to your device from user space.
* Kernel-space driver:
Harder to debug.
Only linux kernel frameworks are supported.
You can always provide a binary blob to hide the details of your IP but this is annoying since it has to be generated against a specific kernel.
A crash will bring down the whole system.
Less latency in handling interrupts.
You can control access to your device from kernel space because it's a global context that all processes see.
As a kernel engineer I'm more comfortable/happy hacking code in a kernel context, that's probably why I would write the whole driver in the kernel.
However, I would say that the best thing to do is to divide the functionality of your driver into units and only put the unit in the kernel when there's a reason to do so.
For example:
If your device has a shared resource ( like an MMU, hardware FIFO ) and you want multiple processes to be able to use it safely, then probably you need some buffer manager to be in the kernel and all the processes would be communicating with it through ioctl.
If your driver needs to respond to an interrupt as fast as possible ( very low-latency ), then you will need to put the part of the code that handles interrupts in the kernel interrupt handler rather than putting it in user space and notifying user space when an interrupt occurs.

Suspend a device in Linux

I am thinking of suspending a particular platform device driver, while keeping rest of the system active.
Can this selective suspend be achieved by Linux Power Management? Or
Can I write a separate driver that can do this for me, by calling suspend directly on the platform device driver?
For hard disks you can try hdparm command for set hard disk in standby. The option you might be looking for is -S.
According linux man pages:
Put the drive into idle (low-power) mode, and also set the standby (spindown) timeout for the drive. This timeout value is used by the drive to determine how long to wait (with no disk activity) before turning off the spindle motor to save power.

Hardware clock signals implementation in Linux Kernel

I am looking at some pointers for understanding how the Linux kernel implements the setting up of various hardware clocks. This basically relates to working with setting up the various clocks that hardware features like the LCD, UART etc will use. For example when Linux boots how does it handle setting up the clocks for UART or USB. Maybe something like a Clock manager or something.
I am basically trying to implement something similar for a different OS on a new hardware that i am working on. Any help would be really appreciated.
[Edit]
Thanks for the replies and the links. So here is what i have implemented up until now. This should give you an idea of where I'm headed.
I looked up the Hardware Reference Manual for the particular system I'm targeting and wrote some code to monitor/modify the signals/pins of the peripherals I am interested in i.e. turning them ON/OFF from the command line.Now a collection of these clocks/signals together control a peripheral.The HRM would say that if you want to turn on the UART or something then turn on such and such signals/pins. And #BjoernD yes I am using something like a mmap() function to talk to the peripherals.
The meat of my question is that I want to understand the design and implementation of a Clock/Peripheral Manager which uses the utility that I have already written. This Clock/Peripheral Manager would give me the control of enabling/disabling the peripherals I want.Basically this Manager would enable me to make changes in the init code that is right now running. Also during run time processes can call this Manager to turn ON/OFF the devices so that power consumption is optimized. It might not have made perfect sense but I'm myself trying to wrap my head around this.
Now I'm sure something like this would have been implemented in Linux or for that matter any OS for performance issues (nobody would want to waste power by turning on all peripherals at boot time). I want to understand the Software Architecture of it. Reference from any OS would do as of now to atleast get a headstart. Also I am not writing my own OS, there is an OS in place but Im looking more at a board level software aka BSP to work on. But thanks for the OS link anyways, they are really good. Appreciate it.
Thanks!
What you want to achieve is highly specific to a) the platform you are using and b) the device you want to use. For instance, on x86 there are 3 ways to communicate with a device:
Interrupts allow the device to signal the CPU. The OS usually provides mechanisms to register interrupt handlers - functions that are called upon occurrence of an interrupt. In Linux see request_irq() and friends in linux/include/interrupt.h
Memory-mapped I/O is physical memory of the device that the platform's BIOS makes available in the same way you also access plain physical memory - simply by writing to a memory address. What exactly is behind such memory (e.g., network interface config registers or an LCD frame buffer) depends on the device and is usually specified in the device's data sheet.
I/O ports are accessed through a special address space and special instructions (INB/OUTB & co.). Other than that they work similar to I/O memory.
There's a multitude of ways to find out what resources a device provies and where the BIOS mapped them. Some platforms use ACPI tables (google yourself for the 1,000k page spec), PCI provides info on devices in a standardized way through the PCI config space, USB has similar ways of discovering devices attached to the bus, and some devices, e.g., UARTS, are simply specified to be available at a pre-configured I/O range that is fixed for your platform.
As a start for understanding Linux, I'd recommend "Understanding the Linux kernel". For specifics on how Linux handles devices and what is there to write drivers, have a look at Linux Device Drivers. Furthermore, you will need to have a look at the peculiarities of your platform and the device you want to drive.
If you want to start an own OS, a UART is certainly something that will be veeery helpful to print debug output, so you might want to go for this first.
Now that I wrote down all this, it seems that your actual question is: How to get started with Operating System design. This question should be highly valuable for you: What are some resources for getting started in operating system development?
The two big power users in most computers are the CPU and the disks. Both of these have capabilities for power saving in Linux. The CPU clock can be slowed down when the system is not busy, and the disk motors can be stopped when no I/O is happening. For a UART, even if you save all of the power that it uses by turning off its clock, it is still tiny compared to the others because a UART doesn't have much logic in it.
Best ways to save power are
1) more efficient power supply
2) replace rotating disk with SSD
3) Slow down the CPU and memory bus

Graceful handing over resources from initramfs to userspace

There are hardware devices which need userspace suppport, like daemon running and handling parts of interaction not suitable (too complex or policy-related) for kernel space.
Running such daemons is easy once you reach userspace -- you can run'em as a result of hotplug event and don't worry much.
Once initramfs comes to the picture, everything suddenly breaks apart: if the daemon is run from initramfs then it needs to either keep running when execution is switched to regular rootfs, which is particularily hard, given initramfs is freed during switch_root or hand out resources and state to another copy of itself, run from rootfs. Both solutions seem inelegant and hacky.
Is there obvious way to manage such devices and their supporting daemons I overlooked?
Do you have a specific case? How have the other distributions handled this?
Looking at how Fedora does udev, it starts it up from the initramfs, gets it to do its stuff so the really root fs can be mounted, then shuts it down again before switching.
Do you need this daemon to mount your real root device ? I guess the answer is yes, otherwise the solution would be to wait for your real root.
I your device is so complicated it needs a daemon to just work, may be you could do part of the job in the kernel, and handle the policy through sysfs attribute ?
I fail to see an example of hardware invlved in mounting the real root deice that would need a daemon to work. Device discovery apply, but you don't need a daemon for the device to actually work. An example would be welcome.
Also, do you really need to switch root ? You could keep your initramfs, and mount whatever you need to have a fully functionnal system under /usr/ That is what I do with some of my embedded system.
Update :
mdev is an embedded alternative to udev, which runsin two mode: on scans sysfs to add device, the other is running for hotplug event. So I guess you don't need to "store" hotplug event, because all the info is still available in sysfs. So the solution is something like :
run udev from initramfs
mount real root and switch root
scan sysfs (does udev do that on startup ?)
normal operation (ie wait for hotplug event)

Resources