Difference between an API and a device driver - api

I try to understand how they both relate to each other. As far as I know, they both can be a part of the HAL. In case of a communication between an application and a graphics card - can an API get the job done on its own or do we have to rely on them both? Can an API directly communicate with the hardware or do we always need a driver in-between, which translates the command of the API?

TL;DR
Think of an API as a specification that describes what to do, while a driver is an implementation that describes how to do it.
Details
As a contrived example, imagine we have three different audio cards that we want to play nicely with multiple operating systems. We can define an API for the card manufacturers that says, "Each card must support four methods: mute(), playsound(sound), volumeup() and volumedown()". By defining the API, we get a common interface that allows the operating system designers to support the audio devices without worrying about the hardware details. They know that if they want to mute the sound card, they can call mute(), or if they want to turn the volume up, they call volumeup().
It is then up to the device manufacturers to implement a driver that actually performs those actions. The driver will vary between the three different audio cards because they are different at the hardware level, but the API is consistent so the next higher abstraction level (the OS) doesn't need to know how to deal with the hardware.
For a more concrete example, consider the Advanced Control & Power Interface (ACPI) specification. It defines a common interface for operating systems to manage power consumption and thermal characteristics of hardware devices. There are methods that a device driver or firmware must implement in order to be "ACPI Compliant". This allows Windows operating systems and Linux variants to both perform the same actions on hardware devices without needing to implement their own drivers for the hardware
Note: Windows performs ACPI actions through acpi.sys, which they call an "ACPI Driver". Don't let the terminology confuse you; even though they call it a driver, it is really a window into the ACPI interface. Linux uses the acpi kernel module to do the same thing, and Linux doesn't call it a driver. Perhaps ACPI wasn't the best example, but I don't have anything better at the moment.

Related

Are UART, SPI, I2C, etc implementations generic?

Is it possible to create one file, say for example uart.c to be generic, so that I can call the uart functions for different microcontrollers, say for example avr and arm? or is it a must that for every microcontroller I will have to create the the uart functions from scratch?
You can create a Hardware Abstraction Layer (HAL) that acts as a common interface for all hardware of the same kind. A correctly designed HAL allows portable application-layer code, which is the sole purpose of having one.
The HAL should be in the form of an API library that then acts as a header file template for how the drivers should be designed, the simplest form of "polymorphism". The application programmer calls the HAL, and the MCU-specific functions in the driver will then get called.
In case of UART you might have an init function taking baudrate, stop bit, parity, handshaking etc as parameters. And then a read function and a write function, with some error handling. Overrun and framing errors are universal, for example. It is then up to the specific driver for MCU "x" to implement itself according to your specified HAL.
Generally, one should not create abstaction layers needlessly though. It is quite qualified work and easy to get wrong. If you don't need portability or code re-use between projects, there's no obvious need for a HAL and you could as well call the driver directly from the application code.
The hardware implementations and register interfaces across different vendors certainly differ. ARM do not make MCUs they licence the core - the peripherals are not defined by the core so even amongst ARM devices the peripheral implementations differ between vendors.
What you can do is define a common device-layer interface and implement that interface for each device family you need, then you can reuse the application layer code across architectures.
The alternative is to stick with a common family. AVR for example covers a wide range of devices and the peripherals generally are common across the range. Similarly STM32 (ARM Cortex-M) devices share common peripherals across the range.
So the answer is no, but you can deal with that by abstracting the hardware (or the vendor supplied abstraction or device layer).
For a UART you might use stdio as your abstraction layer and access the device via fprintf, fputchar, fread, fwrite etc. Though typically you'd build that on a lower level layer too.

Abstraction layers in device drivers

in my project I need to work with device drivers, but have a hard time to understand the naming, scope and function of the abstraction layers. As I see the main layer is HAL - "hardware abstraction layer".
What are the clients of HAL, whom is HAL interfacing?
Are you talking about a specific HAL in windows or linux or something or in general?
When accessing registers from a device driver (code that drives a device, doesnt have to be a kernel thing or have an operating system at all) for example I generally recommend to create functions like PUT32(address,data), data=GET32(address). Or writel and readl, whatever you fancy. The point being to avoid creating a pointer with the address and using that pointer directly. There is a performance gain to the pointer type solution, and performance hit to the abstract PUT32(). Why I use it though is because if the code is clean enough that driver can be used as part of a kernel driver for this os, a kernel driver for that os, run standalone embedded, connect to an hdl simulation of the logic, run on a processor on the same chip, or run on a host computer that reaches into the chip via PCI or jtag, etc. One chunk of code reused from the birth of the logic (hdl sim) to the end user kernel driver.
Perhaps more to your question though think about a uart, you want to send some bytes and receive some bytes right? Create a uart_send() function and a uart_recv() function, everything above the abstraction layer uses these two functions, when you target this code to a specific platform then you implement those functions for the specific uart in that specific hardware. later on you can replace that uart with something else, so long as the new uart can send and receive the code above the abstraction layer does not have to change. Even though you have created an abstraction layer with the functions above, I personally would still use PUT8() and GET8() functions in the implementation of uart_send() and uart_recv() for the specific uart, and in a separate file implement PUT8() and GET8().
How many layers of abstraction between the driver and the actual hardware, how and where are often specific to the task and the hardware.
In computers, a hardware abstraction layer (HAL) is a layer of programming that allows a computer operating system to interact with a hardware device at a general or abstract level rather than at a detailed hardware level. Windows 2000 is one of several operating systems that include a hardware abstraction layer. The hardware abstraction layer can be called from either the operating system's kernel or from a device driver. In either case, the calling program can interact with the device in a more general way than it would otherwise.

Is it possible to intercept and change the voice during a call on a Symbian S60?

On a Symbian S60 phone, is it possible to create an application that awakes when a voice call starts; intercepts what the user says; applies a filter to the voice stream and makes it sound like, say, Darth Vader or Donald Duck ?
The short answer is no. Voice call audio is not available to applications, mainly for two reasons:
(The technical reason) On many devices, voice audio is entirely handled on a separate processor from the one on which applications run. The call audio processor is typically referred to as the baseband processor, and runs its own real-time (often proprietary) operating system. A separate processor (the 'application processor') hosts Symbian OS, on which the applications run.
Clearly, these two processors can talk to one another, for example to transfer packet-switched data between the network and the Symbian OS IP stack. In some circumstances - for instance video telephony - circuit-switched data is also routed via the AP, since this in necessary in order to capture/encode/decode/render the two video streams. Voice calls, however, typically cannot be routed via the AP. Since the telephony stack must meet real-time deadlines during a call, allowing the data path to cross to a separate processor introduces a large amount of additional complexity. Given that there is no existing use case which requires this data path, manufacturers understandably don't go to the trouble of making it work.
(The legal reason) Even if voice call audio was available on the AP, device manufacturers would use the Symbian OS security model to ensure that it could not be accessed by third-party applications. This is because the device would likely fail cellular communications type approval if the manufacturer could not guarantee that applications cannot tamper with voice calls.
Furthermore, in some jurisdictions, recording telephone calls without the knowledge of the other party is illegal. Allowing applications to access voice call data would clearly allow them to perform surrepticious recording, exposing the OEMs to liability. Even if the application was not doing anything malicious with the data (applying a Donald Duck filter for example), it may still fall foul of these kinds of legal restrictions.
So, while your idea is a fun one, it is unlikely to be possible on a commercial Symbian device.

How can I program a wireless adapter?

Is it possible to program a wireless adapter attached to a computer?
I need to modify how they work, not just using them to perform a task such as scanning or connecting.
I have already tried the Native Wifi API, but that library is too high level. I cannot modify how exactly the wireless adapter works.
Any solution in any programming language in any operating system is very welcomed. (Sounds so desperate lol)
You need an open-source operating system then. Hardware varies in how programmable it is, but for example, Atheros wireless cards do not have an on-board processor, and therefore they do the absolute minimum of the 802.11 protocol in hardware, leaving everything else to the device driver. More info in these places: http://linuxwireless.org/ http://git.kernel.org/?p=linux/kernel/git/linville/wireless-testing.git;a=summary;
If you really need to go further that what commodity hardware can do, look in to GNU Radio and the USRP/USRP2: http://gnuradio.org/redmine/wiki/gnuradio
And yes, you do have to be careful about the legal implications of this stuff, but then if you don't turn off the regulatory framework, there is software to help with that.
Generally speaking, the manufacturer will attempt to prevent you from doing this. Since what you're working with is really a radio transceiver, its operation is regulated. In the US, for example, such things fall under the purview of the FCC. Depending on the country, changing how it operates (and then operating it) is likely to be illegal.
If you have an atheros chipset on your WLAN card then load up linux and install ath5k/ath9k or madwifi and you can do some interesting things with the driver.

Ethernet - USB communication

I have a piece of hardware that sends USB data over ethernet (only the data stored in the package will be send). On a remote PC the data is recieved via ethernet. How can I send this data to the USB driver so it translates the data into commands applications can use?
You're better off getting hardware that does the reciprocal, sends the IP-based USB information to the USB subsystem, rather than try and hack the software driver itself. I can't imagine your hardware vendor doesn't have a device that does this.
You need a server listening on whatever port/socket that you are trying to connect to. Twisted Matrix makes decent Python libraries for network communications.
I think this is going to be troublesome.
USB is generally set up to associate a driver with a connected device, based on the device's various ID numbers, as discovered during bus traversal.
Your data comes in over Ethernet, so the platform's USB driver stack won't know anything about the device in question. This means you somehow need to directly talk to the proper driver, and also get it prepared to handle events from a (from its point of view) non-connected device.
I can think of several reasons why even a well-designed USB stack won't handle this happily.
On Linux, you might be able to "cheat" by interpreting the data yourself and sending it on, using the same API:s the actual driver would have used. That won't work for any USB device of course, it requires you know what the device is.
It's doable on windows as well, but you need a lot of kernel/usb knowledge to make it work i don't think i will be wrong by estimating this task as few man years (you can reduce this estimation dramatically if you have a limited selection of devices/types of device to support.
You will need to develop a bus driver that will simulate the host controller driver to the native usb host, unfortunately this interface is not public and we did not managed to get MS cooperation on that.
There is additional option to work on hub level, instead on controller level, this interface is available, but i did not managed to find my notes on that.
You can download the evaluation version and investigate the driver stack it might give you a clue where to start.