- Hands-On Embedded Programming with C++17
- Maya Posch
- 477字
- 2021-08-20 10:20:49
Custom drivers
The exact format and integration of drivers (kernel modules) with the OS kernel differs for each OS and thus would be impossible to fully cover here. We will, however, look at how the driver for the RTC module we used earlier is implemented for Linux.
In addition, we will look at how to use an I2C peripheral from user space later in this chapter, in the club room monitoring example. Using a user space-based driver (library) is often a good alternative to implementing it as a kernel module.
The RTC functionality is integrated into the Linux kernel, with the code for it found in the /drivers/rtc folder (on GitHub, at https://github.com/torvalds/linux/tree/master/drivers/rtc).
The rtc-ds1307.c file contains two functions we need to read and set the RTC, respectively: ds1307_get_time() and ds1307_set_time(). The basic functionality of these functions is very similar to what we'll be using in the club room monitoring example later in this chapter, where we simply integrate I2C device support into our application.
A major advantage of communicating with I2C, SPI, and other such peripherals from user space is that we are not limited by the compile environment supported by the OS kernel. Taking the Linux kernel as an example, it is written mostly in C with some assembly. Its APIs are C-style APIs and thus we would have to use a distinctly C-style coding approach to writing our kernel modules.
Obviously, this would negate most of the advantages, not to mention the point, of attempting to write these modules in C++ to begin with. When moving our module code to user space and using it either as part of an application or as a shared library, we have no such limitations and can freely use any and all C++ concepts and functionality.
For completeness' sake, the basic template for a Linux kernel module looks as follows:
#include <linux/module.h> // Needed by all modules #include <linux/kernel.h> // Needed for KERN_INFO int init_module() { printk(KERN_INFO "Hello world.n"); return 0; } void cleanup_module() { printk(KERN_INFO "Goodbye world.n"); }
This is the requisite Hello World example, written in C++-style.
One final consideration when considering kernel- and user space-based driver modules is that of context switches. From an efficiency point of view, kernel modules are faster and have lower latency because the CPU does not have to switch from a user to kernel space context and back repeatedly to communicate with a device and pass messages from it back to the code communicating with it.
For high bandwidth devices (such as storage and capturing), this could make the difference between a smoothly functioning system and one that severely lags and struggles to perform its tasks.
However, when considering the club room monitoring example in this chapter and its occasional use of an I2C device, it should be obvious that a kernel module would be severe overkill without any tangible benefits.
- Istio入門與實(shí)戰(zhàn)
- 深入理解Spring Cloud與實(shí)戰(zhàn)
- Augmented Reality with Kinect
- INSTANT Wijmo Widgets How-to
- OUYA Game Development by Example
- VCD、DVD原理與維修
- Arduino BLINK Blueprints
- 筆記本電腦維修300問
- 單片機(jī)技術(shù)及應(yīng)用
- Spring Cloud微服務(wù)和分布式系統(tǒng)實(shí)踐
- 電腦組裝與維護(hù)即時通
- Corona SDK Mobile Game Development:Beginner's Guide
- Applied Deep Learning with Keras
- Spring微服務(wù)實(shí)戰(zhàn)(第2版)
- Hands-On Embedded Programming with C++17