Getting Started with ARM Driver Development

Drive classification

1 General classification

1.1 Character device: a device with a byte as the smallest access unit, usually supporting open, close, read, and write system calls. Such as serial port, LED, button

1.2 Block device: A device with a block as the smallest access unit (a block is generally 512 bytes or a multiple of 512 bytes). In linux, block devices are allowed to transmit any number of bytes. Such as hard disk, flash, SD card.

1.3 Network interface: responsible for sending and receiving data packets, it can be a hardware device, such as a network card, or a pure software device, such as a loopback interface (lo)

2 Bus taxonomy

               1.1 USB devices

               1.2 PCI Devices

               1.3 Platform bus device

study method

1 Build the driver model

2 Add hardware operation

3 Drive test

hardware access

1 Address mapping

1.1 Static mapping

void *ioremap(physaddr,size)

physaddr: The physical address to be mapped

size: the length of the mapped area

Return value: mapped virtual address

1.2 Dynamic Mapping

The user specifies the mapping relationship in advance, and the physical address is automatically mapped to the virtual address when the kernel is started.

struct map_desc

{

     unsigned long virtual;/mapped virtual address

     unsigned long pfn;/page frame number where the physical address is located

     unsigned long length;/map length

     unsigned int type;/mapped device type

}

2 Register read and write

unsigned ioread8(void *addr)

unsigned ioread16(void *addr)

unsigned readb(address)

unsigned readw(address)

unsigned readl(address)

 

void iowrite8(u8 value,void *addr)

void iowrite16(u16 value,void *addr)

void iowrite32(u32 value,void *addr)

void writeb(unsigned value, address)

void writew(unsigned value, address)

void writel(unsigned value, address)

use of the drive

1 Compile and install the driver

1.1 Create Makefile

obj-m := memdev.o

KDIR: = / home /… / linux-tq2440

all:

make–C $( KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm

1.2 Copy the driver (kernel module) to /…/rootfs

1.3 Install the driver

insmod  memdev.ko

1.4 View lsmod

2 character device file

2.1 View the main device number

cat /proc/devices

Main device number Device name

2.2 Create device file

mknod /dev/file name c device number secondary device number (0~255)

3 applications

3.1 Open character device file

fd = open(“/dev/memdev0”,O_RDWR);

3.2 Manipulating character device files

write(fd,&buf,sizeof(int));

read(fd,&buf,sizeof(int));

3.3 Close character device file

close(fd);

3.4 Compilation (static compilation)

arm-linux-gcc –static filename.c –O filename

character device driver model

1 Device description structure cdev

1.1 Structure Definition

struct cdev

{

struct kobject kobl;

struct module *owner;

const struct file operations *ops ;//Device operation set

struct lis thead list;

dev_t dev;//Device number.

unsigned int count; number of devices

}

1.2 Device number type dev_t

1.2.1 Introduction to dev_t: It is essentially a 32-bit unsigned int, the upper 12 bits are the major device number, and the lower 20 bits are the minor device number.

1.2.2 Operation equipment number:

dev_t dev=MKDEV (major device number, minor device number)

Major device number=MAJOR(dev_t dev)

Minor device number = MINOR(dev_t dev)

1.2.3 Apply for equipment number:

Static application: intregister_chrdev_region(dev_t first, unsigned int count, char *name);

first: the starting device number to be allocated, usually 0;

count: total number of consecutive device numbers

name: device name (cat /proc/devices )

Dynamic application: intalloc_chrdev_region(dev_t *dev,unsigned int -firstminor,unsigned int -count,char*name)

dev: The location where the obtained device number is saved

-firstminor: The starting device number to be allocated, usually 0;

-count: total number of consecutive device numbers

name: device name (cat /proc/devices )

1.2.4 Unregister the device number: unregister_chardev_region

1.3 Operation set struct file operations

1.3.1 Introduction to structfile operations: A collection of function pointers that define the operations that can be performed on the device. Set to NULL for unsupported operations

1.3.2 例:struct file operations dev_fops =

{

.llseek  = NULL;

.read= dev_read,

.write= dev_write,

.ioctl= dev_inctl,

.open= dev_open,

.release= dev_release,

};

2 Driver initialization

2.1 Assign device description structure

    Static allocation: structcdev mdev;

Dynamic allocation: structcdev *pdev = cdev_alloc();

2.2 Initialize the device description structure

cdev_init(struct cdev*cdev,const struct file_operations *fops)

*cdev: cdev structure to be initialized/*fops: operation function set corresponding to the device

2.3 Registering Device Description Structure

    cdev_add(struct cdev *p,dev_t dev,unsignedcount)

p: the character device structure to be added to the kernel

dev: device number

count: the number of devices of this type of device

2.4 Hardware initialization

3 Device operation (device method)

3.1 int (*open) (struct inode *,struct file *) Open the device and respond to the open system

3.1.1 structfile:

3.1.1.1 In the linux system, each open file is associated with a structfile, which is created by the kernel when the file is opened and released after the file is closed

3.1.1.2 Important members

loff_t f_pos //File read and write pointer

struct file_operation*f_op //The operation corresponding to the file

3.1.2 structinode

3.1.2.1 Each file existing in the file system is associated with an inode structure that records the physical information of the file.

3.1.2.2 Important members:

dev_t i_rdev //device number

3.2 int (*release) (struct inode *,struct file*) Close the device and respond to the close system

3.3 loff_t (*llseek) (struct file *,loff_t,int) Relocate the read and write pointers and respond to the lseek system call

3.4 ssize_t(*read) (struct file *,char _user *,size_t,loff_t *) Read data from the device and respond to the read system call

3.4.1 Parameter analysis:

filp: The file structure pointer associated with the character device file, created by the kernel

buff: The location where the data read from the device needs to be saved, provided by the read system call

count: The amount of data requested to be transferred, provided by the read system call

offp: file read and write position, taken from the file structure by the kernel and passed in

3.4.2 Reading data from the device (hardware access operation)

3.4.3 Return the read data to the application

3.5 ssize_t(*write) (struct file *,const char _user *,size_t,loff_t *) Write data to the device and respond to the write system call

3.5.1 Parameter analysis:

filp: The file structure pointer associated with the character device file, created by the kernel

buff: The location where the data read from the device needs to be saved, provided by the read system call

count: The amount of data requested to be transferred, provided by the read system call

offp: file read and write position, taken from the file structure by the kernel and passed in

3.5.2 Fetch data from the address provided by the application

3.5.3 Write data to the device (hardware access class operation)

4 Driver logout

4.1 Uninstall the driver with the cdev_del function

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324520454&siteId=291194637