Which h/w knoledge needed to have to become a Device driver programmer? - linux

I am very interested in device driver programming .I have started reading the LDD3 ,there author said
"to become a device driver programmer you have to understand your specific device well"
can any one tell me what is the meaning of the "understand your specific device" .what are the thing I should know before writing a device driver.
Thanks

That's a basic list with software and hardware combined.
The Operating System driver API
The processor architecture as it relates to hardware interfacing
The 'bus' structure that interfaces the device hardware to the processor
Interrupt Handling
Dma Control
Processor Caching
Processor MMU control
OS Semaphores and scheduling
Data/Byte Alignment
Assembly language when needed
Control of Instruction Execution Order and Optimization
Consideration of performance issues
What's IO and memory mapped hardware ?
http://www.cs.nmsu.edu/~pfeiffer/classes/473/notes/io.html
This link talks about generic hardware access in Linux device drivers.
http://www.linuxforu.com/2011/06/generic-hardware-access-in-linux/
This is specifically about USB hardware
http://www.beyondlogic.org/usbnutshell/usb2.shtml
Check lwn.net it never disappoints a device driver developer.
https://lwn.net/Archives/
Last, but not least, They have everythig, CPU, Memory, Camera, PCI..
http://www.hardwaresecrets.com/page/memory

-
Hi, I'm very pleased to share what I have learnt with you guys.
Yes, it is the basic need to know your device if you wanna be a device driver programmer. I also want to be a linux device driver programmer, or even more, though I have some device driver experience under other software platforms.
The reason why you wanna contact with it is that you wanna make it do something for you.
Normally, what it can do is the first thing you must know. It's very obvious that you will never send Ethernet frames through UART or SPI, right?
There exist various kinds of devices in the world, such as, storage device, FLASH, SD card, harddisk; communicating devices, network card, wifi; interconnected bus, PCI-express; how many there are.
After that, the next thing you will concern is how you can do to reach your goal.
To access the device, reading, or writing, there is usually a controller embedded in the processor. Here, when I say "processor", it means it is a core integrated with various kinds of controllers, no matter pc desktop or embeded system areas.
The Controller is the interface you will face, to work on the device behind the controller.
Through the controller, you can ask the device to do what you want. In the controller, there are registers, which are the deepest points the software can touch. Beyond that lies the hardware, as you are a device driver programmer, it is very common for you to communicate with hardware engineers to make things done.
If going into details about the register, there are control registers used to tell device what you want it to do, status registers, used to reflect the status of operations underway in devices, if interrupt is supported by that device, there are also some registers for you to deal with interrupts.
Well, I almost forget there are also data registers, whicha are used to store the data to be sent or written, or to be read by user. According to the specific implementation, registers used to store data from upper users to be sent or written and registes used to hold data from outside that will be read by users may be the same, or may be not.
In a normal way, if you wanna let someone do something for you, you should provide something to him first. Whoever wants to do anything, there must be some inputs to him, right?
in a summary,
action(read,write,or others) + data(you give, or you ask for) + status(what progress it is)
what it can do
how it does that, how to assemble the command cell, time sequence?
what you must provide it to reach your goal
genarally, two kinds of things you should provide:
if you ask for, where to store what you ask for;
if you give, where are what you give
how it reflects the progress of operations, polling or interrupts
Well, that is all I want to share with you.
Thanks.

Related

Non-Hardware Device Drivers

In Windows Internal 7th Edition - Book following text is Mentioned Under Windows Kernel Architecture
Device drivers -This includes both hardware device drivers, which translate user I/O function
calls into specific hardware device I/O requests, and non-hardware device drivers, such as file
system and network drivers.
Can anyone please elaborate on hardware device drivers and non-hardware device drivers?
Assume you have multiple layers - e.g. when a process makes a file IO request it goes to a virtual file system layer, which may send a request to a file system layer, which may send request/s to a software RAID layer, which may send requests to a USB mass storage device driver, which may send a request to a USB controller driver.
You can split these layers into 2 main categories:
a) "device drivers", where there's an actual device. For these, the relationships between device drivers tends to mirror the hierarchical relationships between hardware devices (e.g. "PCI bus with controllers plugged in, with various devices plugged into those controllers, with various peripherals plugged into those devices" may become a tree of "parent device driver communicating with none or more child device drivers that are...").
b) "things that do not drive a device, and therefore are not technically device drivers". For the file IO example above, this is the VFS, file systems and software RAID layer. For networking it'll be code to handle a TCP/IP stack (and figure out routing, etc - which network card should send a packet based on the destination IP address). For user input (keyboard, etc) it could be things like Input Method Editors. For sound it can be code to determine how loud the sound should be on which speakers (on which sound card/s) based on a 2D position.
For most operating systems; device drivers need to be treated as "special" because they need to use interfaces (and possibly direct hardware access) that normal software/processes can't use. For example, for monolithic kernels they might be treated as a kernel extension and (dynamically) linked directly into the kernel.
However; "things that do not drive a device, and therefore are not technically device drivers" end up needing similar special support (e.g. the ability to use the same or similar interfaces that normal software/processes can't use but device drivers can use, the ability to be linked into a monolithic kernel, etc). For an OS designer, the differences between device drivers and "things that aren't technically device drivers but need the same access" is relatively insignificant (compared to normal software/processes which don't have/need special access); so it's tempting to use the same word to describe both - e.g. call them all "kernel modules" (regardless of whether they're device drivers or not); or call them all "device drivers" (regardless of whether they're technically device drivers or not).
Note that there's a few things that confuse this even more:
a) There's actually a third category - "virtual devices". In some cases software is trying to emulate a real device (e.g. RAM disks that use software/RAM to emulate a hard drive; printers that use a PDF file format converter to "print" to a file, etc). For these cases, emulation/virtualization necessitates implementation as a device driver (but there's technically no device being driven).
b) To make terminology seem more consistent; some operating systems are biased towards defining interfaces as "virtual devices". If you try hard enough you can pretend anything is some kind of abstract virtual device ("It's not a compression/decompression library, it's a virtual compression/decompression device", "It's not a database management engine, it's a virtual relational data storage device", ...).
c) Some operating systems also try to pretend that everything is a file (e.g. Unix - https://en.wikipedia.org/wiki/Everything_is_a_file ). In this case you might have a directory of "device drivers pretending to be files" (e.g. /dev) and end up with "things that are not device drivers that are pretending to be device drivers that are pretending to be files" slapped into the same directory.
Your question is unclear. If you ask for an example of a non-hardware device driver, an example would be the random number generator device. On Linux, for example, the "/dev/random" device provides a software implementation of a random number generator so systems without the necessary hardware can still have this function

Getting WIFI signal strength- seeking the best way (IOCTL, iwlist (iw) etc.)

I want to scan the signal strength received from 3 AP.
I would be happy if that could happen every 300ms (max.500ms). I flashed OpenWRT on the routers.
I was seeking for a good tool to do that.
First I found iwconfig which worked, but only with networks that I was connected to. So I used iwlist (iw didn't work- maybe I need to update it?). Do you know how accurate is the output of it? Can I trust it?
After that, I came across the IOCTL. It looks really powerful* and professional. But is the output from getting the signal stregnth from a WIFI more reliable than the simple method like iwlist/iw?
*even too much powerful as I failed to compile any program I wrote using it
If you want to determine the signal strength of WLAN access points to which you are not connected, scanning is the right way.
The scanning is performed by the wireless network card with much or little "help" from the driver, depending on the design of the wireless card. There are cards (chipsets, to be more specific) that have their own processor and run their own firmware code independently from the host computer. On the other end, there are "stupid" cards where the driver on the host computer does most of the work.
Between the driver and the rest of the operating system, there is an interface (API) for sending commands to the driver and reading back information in a standardized way. With Linux, there are at least two different APIs. The older one is named Wireless Extensions, and the newer one is named cfg80211. Normally, a driver supports only one of the APIs. Most current drivers use cfg80211, but there may be older drivers that still use Wireless Extensions.
For each of the two APIs, there's a user-space tool (or family of tools) to use it. For Wireless Extensions, there is iwconfig (and iwlist, iwpriv etc.) For cfg80211, there is just iw.
So, the questions about the right tool depends on what API the wireless driver uses. To add confusion ;-), cfg80211 does some emulation which allows you to perform some Wireless Extension calls to drivers that use the newer cfg80211 API.
Regarding your questions about ioctl(): This is a generic method for communication between user-space and kernel-space in Unix operating systems. The old Wireless Extensions API uses ioctl(). The newer cfg80211 API does not use an ioctl()-based interface, but uses nl80211 instead.
To sum it up: whether to use iw/cfg80211/nl80211 or iwconfig/Wireless Extensions/ioctl depends on the driver or your wireless card.
Regarding your desired scanning interval, I would say that 300ms is rather short. This is because for a useful scan, the client needs to leave its current channel for a short time, switch to another channel and listen to signals from other access points on this channel. Since leaving its channel interrupts communication, these off-channel times are usually kept short and are carried out infrequently.
Calling iw <dev> scan or iwlist <dev> scan, respectively, will not necessarily cause a new scan, but may return an old (cached) list of access points. Depending on your wireless card/driver it may be (im)possible to enforce a new scan.

How should I structure a linux driver that uses several chips in one device?

I have a hardware device that consists of 3 separate chips on an I2C bus. I would like to group them together and expose them to userland as one logical device. The user would see the logical device represented by a single directory somewhere in /sys as well as the nodes you'd expect from the I2C chips under /sys/class/i2c-adapter/i2c-?/*.
One of the chips is an MCP23017 which as far as I can tell already has a driver (drivers/gpio/gpio-mcp23s08.c) and I'd like to reuse it. Another of the chips is a PCA9685 and I would like to contribute a driver for this chip that uses the PWM system in include/linux/pwm.h. The third chip is an MCU running custom firmware.
How should I structure the set of drivers? One idea I had is to register a platform driver to present the logical device, and use I2C drivers from within that. Is this a good way to go? Are there better ways?
The logical device is a motor driver board and IR receiver. I have a simple diagram of its structure.
I'm looking to create two interfaces. The first similar to /sys/class/gpio where motors can be 'exported' and then accessed via reading and writing attributes. This would be useful for shell script access and quick debugging of the mechanical parts of the system attached to the motors. The second a character device node in /dev where data can be read or written in binary format, more useful for application control.
it seems not usual design, are you sure you have access to I2C bus of all chips ?
I think you should be able to talk only to MCU, and MCU should manage other devices.
Otherwise, why MCU is there ?
However, I cannot see your diagram, perhaps link is wrong.

HAL layer vs Device driver

In Linux, HAL provides hardware abstraction and device driver too provide hardware abstraction. Can you please clarify me the difference between two ?
The device driver communicates with a specific device at a specific buffer and control flag block location. A hardware abstraction layer abstracts away the details of how specific devices work. For example, the driver for a USB mouse is very different from the driver for a PS2 mouse but at the HAL layer they are both mice and can be treated interchangeably.
I would say that HAL provides hardware abstraction using device drivers. From a certain point of view, no device can work without a driver. HAL goes one step ahead, offering a uniform (or, "easier") API for the application.
You can bypass HAL and talk directly to the device driver, but you can not bypass the device driver and talk directly to the hardware (this last sentence is more or less valid in general, depending on OS and environment).
The main difference is what they provide abstraction for. HAL abstracts processors, device drivers abstract different devices. So in a sense HAL is the "device" driver of the processor or the motherboard in PCs.
Back in the day, every programmer who coded an app also codes drivers for the various hardware that they wanted to support. So, if you have an idea to develop an app which needs to use network capabilities, you also needed to know how to program hardware drivers for the network card. Then came in the HAL.
So instead of having your software and OS directly reaching out to the hardware, there is now a layer in between called the HAL. The HAL lies underneath the operating system layer or within.
Now nobody is allowed to access the hardware, except that they do it through and by the hardware abstraction layer(HAL). Just the HAL is allowed to access the hardware.
Now it's something which is standard. All Devs have to do is make the game/app work with the HAL.
Now we have the drivers. The drivers tell the HAL how to access the actual hardware.
So whoever makes the sound card, they just make a driver that tells the HAL how to access that sound card.
So overall, our software interacts with the HAL, The HAL uses drivers to interact with the hardware. We are telling the HAL how to access that sound card or network card etc. with the use of the drivers.

What are some minimal requirements of a device in order to make it possible to write a device driver for it?

I started lately reading some articles about the kernel space and especially about device drivers. So I was wondering are there some minimal requirements for a device in order to make it easy to write a device driver for it?
A possibility to communicate with it from the kernel (PCI, USB, etc...) and documentation. Obviously a kind of hardware debugging process can improve things.
(This doesn't count as "minimal", but it does meet your desire to "make it easy".)
Some sort of testing mode, or device simulator, which allows you to
(a) see the messages that are being sent to it, so you can see when there is a bug in your code.
(b) stimulate events that cause communications to occur.
For example, if you are writing a driver for a burglar alarm, a way of triggering the device to send an alert from a window sensor, without having to actually throw a brick through a window.

Resources