In the fourth quarter - the topic 11-LED driver design

Special 11-LED driver design

Lesson 1 - device control character

  1. 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

 

  1. 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

  1. 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;

}

 

Guess you like

Origin www.cnblogs.com/free-1122/p/10994938.html