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.
Related
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.
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.
I would like to have Arduino operating in a CAN network. Does the software that provides OSI model network layer exist for Arduino? I would imagine detecting the HI/LOW levels with GPIO/ADC and sending the signal to the network with DAC. It would be nice to have that without any extra hardware attached. I don't mind to have a terminating resistor required by the CAN network though.
By Arduino I mean any of them. My intention is to keep the development environmen.
If such a software does not exist, is there any technical obstacle for that, like limited flash size (again, I don't mean particular board with certain Atmega chip).
You can write a bit banging CAN driver, but it has many limitations.
First it's the timeing, it's hard to achieve the bit timing and also the arbitration.
You will be able to get 10kb or perhaps even 50kb but that consumes a huge amount of your cpu time.
And the code itself is a pain.
You have to calculate the CRC on the fly (easy) but to implement the collision detection and all the timing parameters is not easy.
Once, I done this for a company, but it was a realy bad idea.
Better buy a chip for 1 Euro and be happy.
There are several CAN Bus Shield boards available (e.g: this, and this), and that would be a far better solution. It is not just a matter of the controller chip, the bus interface, line drivers, and power all need to be considered. If you have the resources and skills you can of course create your own board or bread-board for less.
Even if you bit-bang it via GPIO you would need some hardware mods I believe to handle bus contention detection, and it would be very slow and may not interoperate well with "real" CAN controllers on the bus.
If your aim is to communicate between devices of your own design rather than off-the shelf CAN devices, then you don't need CAN for that, and something proprietary will suffice, and a UART will perform faster that a bit-banged CAN implementation.
I don't think, that such software exists. CAN bus is more complex, than for example I2C. Basically you would have to implement functionality of both CAN controller and CAN transceiver. See this thread for more details (in German).
Alternatively you could use one of the CAN shields. Another option were to use BeagleBone with suitable CAN cape.
Also take a look at AVR-CAN.
I want to read the global variables via the JTAG port, live, when a program is running on the microcontroller. Is it possible?
JTAG defines only a physical interface, it does not describe the on-chip debug capabilities of a particular processor which may or may not support access during execution.
Moreover whether it can be done in VB is not really the issue, the important issue is what hardware device and/or I/O port you are using for the JTAG interface, and whether a driver and API to access via .Net is available. That said VB.Net is not the first language I'd choose for that in any case.
A good place to start perhaps is OpenOCD, though it is not .Net specific.
"Almost-Live" is possibly doable, depending on the JTAG implementation. Often JTAG activity which reads memory does so by stealing cycles from the micro (or sometimes even inserting instructions into the pipeline). I'm not sure there's a micro which allows completely transparent access to memory over JTAG.
"All you need to do" is understand the JTAG implementation, know where the variable is located and issue a "memory read" command by wiggling the JTAG pins in the appropriate fashion. This is not a small task, which is why professional engineers are willing to pay (sometimes large amounts of) money for tools which perform this task.
Often the free (limited) toolchains the vendors provide can perform this also.
Yes, I suppose it is possible. But you'll need to drive the JTAG port (that sounds painful!) and know exactly where the data is stored on the chip, and what the formatting is.
I'm writing a virtual machine - not an existing architecture emulator like Virtualbox, but rather something like the JVM or BEAM - with its own instruction set, memory model, etc. Eventually I'm planning to implement a very small and simple (but turing-complete) high-level language that would compile into its bytecode, just for fun.
Of course, the machine must have some support of I/O, but I do not want to limit it only to manipulations with stdin/stdout. I imagine something like modular "virtual devices", which can be implemented as shared libraries so that the VM can load them at runtime and communicate with them through a standard interface. This way, for example, we can have "virtual devices" for standard input/output, graphics (imagine a virtual device that lets your VM program draw stuff inside an SDL window) or maybe even network.
The question is: how should the programs written for the VM communicate with the virtual devices? I decided to mimic techniques which are employed with actual hardware and learned about port-based I/O and memory-mapped I/O. However, I'm not sure which one of them is more suitable for my goals. Can you suggest which one is better or maybe even point out a totally different technique for dealing with input/output?
Thanks in advance.
Both memory-mapped and port based are inappropriate for most I/O.
DMA request with block-copy is usually what you want.