Blog: Http://blog.csdn.net/muyang_ren
This is compared with the device driver programmed into the kernel.
Led.h
#ifndef _head_h#define _head_h#define MAGIC ' H ' #define LED_ON _iow (magic,1,int) #define Led_off _iow (magic,0,int) struct led_device{dev_t devno;unsigned int led_major;struct Cdev *led_cdev;struct class *led_class;struct device *led_device;}; #endif
Platform Equipment
Dev_led.c
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include " Led.h "static void Led_release (struct device *dev) {}static struct Platform_device s5pv210_led_device_lhy = {. Name=" S5pv210_led_lhy ",. id= 1,.dev={.release = led_release, //dev mode, this really can't be less!},};static int __init dev_led_init (void) { Platform_device_register (&s5pv210_led_device_lhy); return 0;} static void __exit dev_led_exit (void) {platform_device_unregister (&s5pv210_led_device_lhy);} Module_init (Dev_led_init); Module_exit (Dev_led_exit); Module_license ("GPL");
Platform-driven
Led_drv.c
#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h>//register_chrled#include <linux/device.h>//class_create/ledice_create#include<linux/slab.h>//kmalloc#include<asm/ Uaccess.h>//copy_to_user/copy_from_user#include<asm/io.h>//ioremap#include<linux/gpio.h>//gpio_ Request#include <plat/gpio-cfg.h>//s3c_gpio_cfgpin#include <linux/cdev.h>//cdev_alloc#include < linux/platform_device.h> #include "led.h" static struct led_device *led_drv;static int led_open (struct inode *inode, struct file *file) {PRINTK (kern_info "%s ()-%d\n", __func__, __line__); S3c_gpio_cfgpin (S5PV210_GPC0 (3), S3c_gpio_ OUTPUT); S3c_gpio_cfgpin (S5PV210_GPC0 (4), s3c_gpio_output); return 0;} Static ssize_t led_read (struct file *file, char __user *buf, size_t count, loff_t *offset) {PRINTK (kern_info "%s ()-%d\n", __ func__, __line__); return count;} ssize_t led_write (struct file *file, const char __user *buf, size_t count, loff_t *offset) {PRINTK (kern_info "%s ()-%d\N ", __func__, __line__); return 0;} Static long led_ioctl (struct file *file, unsigned int cmd, unsigned long val) {PRINTK (kern_info "%s ()-%d\n", __func__, __lin e__);p rintk (kern_info "cmd=%d arg=%ld\n", CMD, Val); switch (cmd) {case Led_on:gpio_set_value (S5pv210_gpc0 (Val), 1); Break;case Led_off:gpio_set_value (S5pv210_gpc0 (Val), 0); break;default:break;} return 0;} Hardware operating methods static struct file_operations led_fops={.owner= This_module,.open = led_open,.write = Led_write,.read = Led_r EAD,.UNLOCKED_IOCTL = led_ioctl,};static int s5pv210_led_probe (struct platform_device *pdrv) {int ret;led_drv = Kmalloc ( sizeof (struct led_device), gfp_kernel); if (led_drv==null) {PRINTK (kern_err "No memory malloc for fs210_led\n"); return- Enomem;} /*1. Dynamic Registration/Application of Master device */ret=alloc_chrdev_region (&led_drv->devno,0,1, "dev_module"); if (Ret < 0) {PRINTK (kern_err ") Unable to get major\n "); Return-efault;goto out_err_1;} Detach the main device number from the device number Led_drv->led_major = major (LED_DRV->DEVNO);/* Allocate space for Cdev */led_drv->led_cdev = Cdev_alloc ();/* Register hardware operation method/Initialize Cdev*/cdev_init (led_drv->led_cdev,&led_fops);/* Register character device */cdev_add (led_drv->led_cdev,led _drv->devno,1);/*2. Create the device class */led_drv->led_class=class_create (This_module, "Led_class"), if (Is_err (Led_drv->led_class)) {PRINTK ( Kern_err "Class_create () failed for led_class\n"); ret =-enodata;goto out_err_2;} /*3. Create a Device file */led_drv->led_device=device_create (Led_drv->led_class,null,mkdev (led_drv->led_major,0), NULL, " Led "); /led/xxxif (Is_err (Led_drv->led_device)) {PRINTK (kern_err "Device_create failed for led_device\n"); ret =-enodev; Goto Out_err_3;} /* Apply for gpc0_3,4 pin resource */gpio_request (S5PV210_GPC0 (3), "LED1"), Gpio_request (S5PV210_GPC0 (4), "LED2"), return 0;out_err_3: Class_destroy (Led_drv->led_class); Out_err_2:unregister_chrdev (Led_drv->led_major, "Led_module"); out_err_1 : Kfree (LED_DRV); return ret;} static int s5pv210_led_remove (struct platform_device *pdrv) {Unregister_chrdev (led_drv->led_major, "led_module"); Device_destroy (Led_drv->led_class,mkdev (led_drv->led_major,0)); Class_destroy (Led_drv->led_class); Gpio_free (S5PV210_GPC0 (3)); Gpio_free (S5PV210_GPC0 (4)); Kfree (led_drv); return 0;} struct platform_device_id led_ids[]={[0]={.name = "S5pv210_led_lhy",. driver_data = 0,},};static struct platform_driver S5pv210_led_driver = {. probe= S5pv210_led_probe,.remove = S5pv210_led_remove,.driver = {. Name = "S5pv210_led_lhy",. Owner = This_module,},.id_table = Led_ids,}; static int __init led_init (void) {platform_driver_register (&s5pv210_led_driver); return 0;} static void __exit led_exit (void) {platform_driver_unregister (&s5pv210_led_driver);} Module_init (Led_init); Module_exit (Led_exit); Module_license ("GPL");
Test procedure:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <sys/ioctl.h> #include "led.h"/***./ Led_test onnum lit led1/2**./led_test offnum off led1/2*/int main (int argc, char *argv[]) {if (argc! = 3) printf ("input:<%s O N led_num >or<%s off led_num>\n ", argv[0],argv[0]); int fd;unsigned int cmd=0;unsigned long Val=0;fd=open ("/dev/ Led ", O_RDWR), if (fd<0) {perror (" open failed!\n "); exit (1);} if (strcmp (argv[1], "on") ==0) {cmd=led_on;} else if (strcmp (argv[1], "off") ==0) {Cmd=led_off;} else{printf ("Err input!\n");} val = atoi (argv[2]), if (IOCTL (fd,cmd,val) <0) {perror ("ioctl failed!\n"); exit (1);} Close (FD); return 0;}
Makefile
Ifeq ($ (kernelrelease),) Kerneldir =/home/farsight/work/kernel/linux-3.0.8pwd =$ (shell pwd) modules:$ (make)-C $ ( Kerneldir) m=$ (PWD) modulesarm-none-linux-gnueabi-gcc led_test.c-o led_testcp Led_drv.ko Dev_led.ko led_test/opt/ filesystem/s5pv210modules_install:$ (make)-C $ (Kerneldir) m=$ (PWD) modules_installclean:rm-rf *.so *.o *.ko *test . tmp_versions *.mod.c *.order *.symvers elseobj-m: =LED_DRV.O dev_led.oendif
Pleasant Goat Series "Device-drive dynamic loading into the kernel"