Special 11-LED driver design
Lesson 1 - device control character
- Device Control Theory
(1) the role of
Most drivers need to provide in addition to the ability to read and write device, also need to have the ability to control devices. For example: change the baud rate.
(2) Application Program Interface
In user space using ioctl system call to the control apparatus, the following prototype:
int ioctl(int fd,unsigned long cmd,...)
fd: file descriptor device to be controlled
cmd: the command sent to the control device
...: The third parameter is an optional parameter, is dependent on the presence or absence of a control command (second parameter).
(3) The method of driving the device
When an application using the ioctl system call, in response to the driver by the following function:
1: The kernel before 2.6.36
long (*ioctl) (struct inode* node ,struct file* filp, unsigned int cmd,unsigned long arg)
2: After the 2.6.36 kernel
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long arg)
Parameters cmd: command transmitting down by applying the ioctl function
- Device control is realized
(1) define the command
Command from its very nature is an integer, but in order to make this integer with better readability, we usually put this integer is divided into several sections: type (8), serial number, direction of transmission parameters, parameter length.
Type (Type / magic number): Indicates that this is the command which device belongs to.
Number (No.), the different commands for the same device to distinguish
Direction: the direction of transmission parameters, the values may be _IOC_NONE (no data transmission), _IOC_READ, _IOC_WRITE (write parameter to the device)
Size: length parameter
Linux system provides the following macro to help define the command:
_IO (type, nr): command with no arguments
_IOR (type, nr, datatype): command parameters read from the device
_IOW (type, nr, datatype): command parameters are written to the device
Example:
#define MEM_MAGIC 'm' // defined magic number
#define MEM_SET _IOW(MEM_MAGIC, 0, int)
(2) operation to achieve
Achieve unlocked_ioctl function is usually a switch statement is executed according to the command. However, when the command number does not match any of the commands supported by the device of a return -EINVAL.
Programming model:
Switch cmd
Case command A:
// perform an operation corresponding to A
Case command B:
// perform an operation corresponding to B
Default:
// return -EINVAL
- Write himself driving
Led.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <mach/gpio-bank-k.h>
#include "led.h"
#define LEDCON 0x7f008800
#define LEDDAT 0x7f008808
unsigned int *led_config;
unsigned int *led_data;
struct cdev cdev;
dev_t devno;
int led_open(struct inode *node, struct file *filp)
{
led_config = ioremap(LEDCON,4);
writel(0x11110000,led_config);
led_data = ioremap(LEDDAT,4);
return 0;
}
long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case LED_ON:
writel(0x00,led_data);
return 0;
case LED_OFF:
writel(0xff,led_data);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations led_fops =
{
.open = led_open,
.unlocked_ioctl = led_ioctl,
};
static int led_init()
{
cdev_init(&cdev,&led_fops);
alloc_chrdev_region(&devno, 0 , 1 , "myled");
cdev_add (& cdev, devno, 1);
return 0;
}
static void led_exit()
{
cdev_del(&cdev);
unregister_chrdev_region(devno,1);
}
module_init(led_init);
module_exit(led_exit);
led_app.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "led.h"
int main(int argc, char *argv[])
{
int fd;
int cmd;
if (argc <2 )
{
printf("please enter the second para!\n");
return 0;
}
cmd = atoi(argv[1]);
fd = open("/dev/myled",O_RDWR);
if (cmd == 1)
ioctl(fd,LED_ON);
else
ioctl(fd,LED_OFF);
return 0;
}