Blog: Http://blog.csdn.net/muyang_ren
this and device-driven dynamic loading into the kernel for comparison
* for different platforms. may not be put in the following documents, only to do the reference
1. header file
Put in: Linux-3.0.8\arch\arm\plat-samsung\include\plat
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
=============================================================================================================== =====================
2. Equipment files
Method One: Add the device resources directly into the/linux-3.0.8/arch/arm/mach-s5pv210 under the MACH-SMDKV210.C
① struct Platform_device s5pv210_led_device_lhy = {. Name= "S5pv210_led_lhy",. id= 1,};static struct Platform_device *smdkv210_devices[] __initdata = {..。。。
。
。。。
。。。
。
。。
。。
。。。
。。。
。。。。 }
② Add device information to bus <span style= "white-space:pre" ></span> change arch/arm/mach-s5pv210/mach-smdkv210.c file static struct Platform_device *smdkv210_devices[] __initdata = {.../* Add for example the following code */&s5pv210_led_device_lhy, //New Added}
Method Two:
① put the device file dev-led.c into the Linux-3.0.8/arch/arm/plat-samsung
Led_dev.c
#include <linux/platform_device.h> #include <plat/led.h> #include <plat/devs.h> #include <plat/ Cpu.h>struct Platform_device s5pv210_led_device_lhy = {. Name= "S5pv210_led_lhy",. id= 1,};
② to ARCH/ARM/MACH-S5PV210/MACH-SMDKV210.C (with platform architecture-related files)
static struct Platform_device *smdkv210_devices[] __initdata = {.... &s5pv210_led_device_lhy, //New addition};
③ to Linux-3.0.8/arch/arm/plat-samsung/makefile to join
obj-$ (config_s3c_dev_led) + = LED_DEV.O
④Join the Linux-3.0.8/arch/arm/plat-samsung/kconfig
Config s3c_dev_led bool "s5pv210 led driver Support" help s5pv210 led device support
⑤ Add external declarations Arch/arm/plat-samsung/include/plat/devs.h
extern struct Platform_device s5pv210_led_device_lhy;
=============================================================================================================== =====================
3. Platform-driven
① put LED_DRV.C in linux-3.0.8/drivers/my_led
Led_drv.c
#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>//The following are the # include <linux/that you need to add when porting module.h> #include <linux/kernel.h> #include <linux/init.h> #include <plat/cpu.h> #include < plat/led.h> #include <plat/devs.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", __fun c__, __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 Register/Application Master Equipment */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;}//separate the main device number from the device number Led_drv->led_major = major (LED_DRV->DEVNO);/* Allocate Space Cdev = */led_drv->led_cdev () for Cdev_alloc; * Manual hardware Operation method/initialization 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");d Evice_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 __devinit s5pv210_led_init (void) {return platform_driver_register (&s5pv210_led_driver);} static void __devexit s5pv210_led_exit (void) {platform_driver_unregister (&s5pv210_led_driver);} Module_init (S5pv210_led_init); Module_exit (S5pv210_led_exit); Module_description ("LED Driver for Marvell pm860x"); Module_author ("Kiron"); Module_license ("GPL"); Module_alias ("platform:s5pv210-led"); ② after the kconfig of the current folder, no new
Config s5pv210_led_drv tristate "Led_dev for fs210 device" help LED driver was for s5pv210, choose Y /m/n
③ after the makefile of the current folder, no new
<span style= "White-space:pre" ></span>obj-$ (config_s5pv210_led_drv) = LED_DRV.O
④ change the makefile and Kconfig of the parent folder
Join the Linux-3.0.8/drivers/kconfig
SOURCE "Drivers/my_led/kconfig"
Join the Linux-3.0.8/drivers/makefile
<span style= "White-space:pre" ></span>obj-y + = mydriver/
Finally, it's your own make menuconfig configuration option.
=============================================================================================================== =====================
4, test program compiled test to use the cross-tool connection
<span style= "White-space:pre" ></SPAN>ARM-NONE-LINUX-GNUEABI-GCC led_test.c-o led_test
Report:
Add a running file to boot, change the root filesystem filesystem
VI filesystem/etc/init.d/rcs./star_app/led_test
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 <unistd.h > #define MAGIC ' h ' #define LED_ON _iow (magic,1,int) #define Led_off _iow (magic,0,int) static void my_sleep (int n) {int J; for (j=0; j<10000000*n; j + +);} int main (void) {printf ("-------------------------------\ n" <span style= "White-space:pre" ></span> "| | Start: Twinkle Sparkle | | \ n ""-------------------------------\ n "); My_sleep (1); 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);} int i;for (i=0; i<10; i++) {if (i%2==0) cmd=led_off;elsecmd=led_on;val=3; Bright Led3if (IOCTL (fd,cmd,val) <0) {perror ("ioctl failed!\n"); exit (1);} val=4; Bright Led4if (IOCTL (fd,cmd,val) <0) {perror ("ioctl failed!\n"); exit (1);} My_sleep (1);} Close (FD); return 0;}
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
Hi-Goat Series "device-drive compiler into kernel"