1 Introduction
Linux has been widely used in embedded systems due to its many advantages such as a powerful and stable kernel, easy expansion and downsizing, and rich hardware support. Many embedded Linux systems, especially those with strong interaction with users, often need to be equipped with a special keyboard. At this time, developers need to write drivers for their own special keyboards based on actual conditions.
2 Introduction to Linux Keyboard Driver
Most drivers in Linux adopt a hierarchical architecture, and keyboard drivers are no exception. In Linux, the keyboard driver is implemented in two layers. Among them, the upper layer is a general keyboard abstraction layer, which completes some functions of the keyboard driver that do not depend on the underlying specific hardware, and is responsible for providing services to the underlying layer; the lower layer is the hardware processing layer, which is closely related to the specific hardware and is mainly responsible for hardware processing. Direct operation. The upper public parts of the keyboard driver are in driver/keyboard.c. The most important thing in this file is the handle_scancode function exported by the kernel using the EXPORT_SYMBOL macro. The function completed by handle_scancode is: first convert the scan code into a key code, then convert the key code into a target code according to the pressing of shift, alt and other extended keys, usually an ASCII code, and finally put the ASCII code into the terminal device buffer, and schedules a tasklet to echo it on the monitor. It can be seen that this function completes some of the core work in the keyboard driver, and these core logical functions do not depend on the underlying hardware, so they can be isolated and exported to the underlying hardware processing function calls. Several other callback functions are also defined in this file, which are called by the upper-level public parts of the keyboard driver and implemented by the underlying hardware processing functions. For example, kbd_init_hw, kbd_translate, kbd_unexpected_up, etc. Among them, kbd_translate is called by handle_scancode, which is responsible for converting the scan code into a key code; the underlying hardware processing part of the keyboard driver has different implementations according to different hardware. For example, the underlying hardware processing functions of the standard keyboard on the PC platform are concentrated in driver/Pc_keyb.c. This file includes the keyboard interrupt processing function keyboard_interrupt, the scan code to key code conversion function pckbd_translate and other functions closely related to the underlying hardware.
Under this architecture, it is particularly clear to add a special keyboard to the system. Developers only need to write the underlying hardware processing functions in the driver to drive the keyboard. Generally speaking, the most important job in the underlying hardware processing function is to obtain the scan code of the pressed key in the keyboard interrupt processing, and call handle_scancode with it as a parameter. The scan code can be defined by yourself, but it must uniquely identify it. The position of the pressed key on the keyboard. In addition, developers also need to provide the corresponding conversion function kbd_translate from custom scan codes to key codes. Specific key code conversion, placing the target code in the input buffer of the terminal, and echoing are all completed by handle_scancode. We can also see here that the kernel export function handle_scancode plays a key role in gluing the upper general abstraction layer and the underlying hardware processing layer in the entire keyboard driver.
3 Application Example
Below we will use a specific application example to illustrate the specific process of writing a driver for a special keyboard in an embedded Linux system.
3.1 Hardware module description
The construction of this system uses Samsung's S3C2410 development board as the hardware platform. The hardware module of the special keyboard is mainly composed of two SN74hc164 chips and a matrix scanning circuit with 4 rows and 16 columns. SN74hc164 is an 8-bit serial input and parallel output shift register, which is composed of 8 D flip-flops connected in series. Its working principle is simply as follows. The SN74hc164 chip outputs the serial input on the A and B pins to the output pins QA to QH in parallel after 8 clock pulses on the rising edge of the clock CLK pulse. Its truth table is shown in Figure 1.
After connecting the two SN74hc164 chips in series, connect their CLK pin and CLR pin to the GPB2 and GPB4 ports of the S3C2410 development board respectively, and connect the A and B pins of the first SN74hc164 chip to the development board On the GPB1 port, these three GPIO ports are configured as output ports. In this way, we use two SN74hc164 registers to occupy only 3 GPIO ports and provide input to the 16 columns of the matrix scanning circuit, thereby saving costs and avoiding the waste of GPIO resources. But this also brings certain troubles to the implementation of the keyboard driver. The driver must first drive the SN74hc164, and then it can control the 16 columns of the matrix circuit. The four row pins of the matrix circuit are respectively connected to the GPG6, GPG7, GPG8, and GPG9 ports of the S3C2410, and these four ports are configured as interrupt sources. When no key is pressed, it is directly read as high potential. When using it, the 16 columns of the keyboard are first set to low potential through the SN74hc164 chip. When any key is pressed, the corresponding row GPG port will have a voltage jump from high to low. This triggers an interrupt.
3.2 Software module description
The above is the content of the keyboard driver implementation of an embedded Linux system (1). For more related content, please pay attention to the PHP Chinese website (www.php.cn)!