//头文件 #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/slab.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm-generic/ioctl.h>#define LED_NUM_ON _IOW('L',0x1122,int) #define LED_NUM_OFF _IOW('L',0x3344,int) #define LED_ALL_ON _IO('L',0x1234) #define LED_ALL_OFF _IO('L',0x5678) int unsigneds5pv210_led {structobject-oriented programming type of device design ----// Major; struct class * CLS; struct Device * dev; int Data; }; struct s5pv210_led * led_dev; volatile unsigned Long * gpco_conf; volatile unsigned Long * gpco_data; // implement operation of the interface device int led_open ( struct the inode the inode *, struct File * the filp) { the printk ( " -------- ^ _ ^ S ------------% \ n- " , __ FUNCTION__); // the corresponding output pin is set gpco_conf & = ~ * ( 0xff << 12 ); // 19--12 cleared 0 * gpco_conf | = 0x11 << 12 ; // 19 --- 12 Assignment: 00010001 return 0 ; } ssize_t led_write ( struct File * filp , const char __user * buf, size_t size, loff_t * the flags) { int RET; the printk ( " -------- ^ _ ^ S ------------% \ n- " , __FUNCTION__); // application space data into kernel space data RET = copy_from_user (& led_dev-> data, buf, size); IF (RET =!0){ printk("copy_from_user error!\n"); return -EFAULT; } if(led_dev->data){ //点灯 *gpco_data |= 0x3<<3; }else{ //灭灯 *gpco_data &= ~(0x3<<3); } return size; } long led_ioctl(struct file *filp, unsigned int cmd , unsigned long args) { int NUM = args + 2 ; the printk ( " -------- ^ _ ^ S ------------% \ n- " , __ FUNCTION__); Switch (cmd) { Case LED_NUM_ON: / / the lamp lighting an IF (NUM =! . 3 && NUM =! . 4 ) return - EINVAL; the else * gpco_data | = 0x1 << NUM; BREAK ; Case LED_NUM_OFF: // the lights to exterminate a IF (NUM ! = 3 && NUM! = 4) Return - EINVAL; the else * gpco_data & = ~ ( 0x1 << NUM); BREAK ; Case LED_ALL_ON: // two lamps simultaneously lit * gpco_data | = 0x3 << . 3 ; BREAK ; Case LED_ALL_OFF: // two lamps simultaneously off * gpco_data & = ~ ( 0x3 << . 3 ); BREAK ; default : the printk ( " unknow cmd \ n-!"); } return 0; } int led_close(struct inode *inode, struct file *filp) { printk("--------^_^ %s------------\n",__FUNCTION__); //灭灯 *gpco_data &= ~(0x3<<3); return 0; } static struct file_operations fops = { .open = led_open, .write = led_write, .unlocked_ioctl =led_ioctl, .release = led_close, }; // loading and unloading functions Functions static int the __init led_init ( void ) // load function executed when ----- is loaded driving { int RET; the printk ( " ----- % S ^ _ ^ --- ------------ \ n- " , __ FUNCTION__); // 0, instantiating the device object // ---- space to apply the size parameter 1 / / identification space parameter 2 ---- aPPLICATIONS led_dev = kzalloc ( the sizeof ( struct s5pv210_led), GFP_KERNEL); IF (IS_ERR (led_dev)) { the printk ( " ! kzalloc error \ n-" ); RET = PTR_ERR (led_dev); return - ENOMEM; } // . 1, the device application No. #if 0 // static master Application No. led_dev-> Major = 256 ; RET = the register_chrdev (led_dev-> Major, " led_drv " , & FOPS); IF (RET < 0 ) { the printk ( " the register_chrdev error \ n-! " ); return - EINVAL; } #else // dynamic master application No. led_dev->major = register_chrdev(0,"led_drv",&fops); if(led_dev->major < 0){ printk("register_chrdev error!\n"); ret = -EINVAL; goto err_kfree; } #endif //2,创建设备文件-----/dev/led1 led_dev->cls = class_create(THIS_MODULE,"led_cls"); if(IS_ERR(led_dev->cls)){ printk("class_create error!\n"); right= PTR_ERR(led_dev->cls); goto err_unregister; } led_dev->dev = device_create(led_dev->cls,NULL,MKDEV(led_dev->major,0),NULL,"led"); if(IS_ERR(led_dev->dev)){ printk("device_create error!\n"); ret = PTR_ERR(led_dev->dev); goto err_class; } //3,硬件初始化----地址映射 gpco_conf = ioremap(0xE0200060,8); gpco_data = Gpco_conf + . 1 ; return 0 ; err_class: class_destroy (led_dev -> CLS); err_unregister: unregister_chrdev (led_dev -> Major, " led_drv " ); err_kfree: kfree (led_dev); return RET; } static void The __exit led_exit ( void ) / / uninstall function executed when ----- is unloaded driving { the printk ( " -------- ^ _ ^ S ------------% \ n- " , __ FUNCTION__); device_destroy (led_dev -> CLS, mkdev (led_dev-> Major, 0 )); class_destroy(led_dev->cls); unregister_chrdev(led_dev->major,"led_drv"); kfree(led_dev); } //声明和认证 module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL");
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #define LED_NUM_ON _IOW('L',0x1122,int) #define LED_NUM_OFF _IOW('L',0x3344,int) #define LED_ALL_ON _IO('L',0x1234) #define LED_ALL_OFF _IO('L',0x5678) int main(void) { int fd; fd = open("/dev/led",O_RDWR); if(FD < 0 ) { perror ( " Open " ); Exit ( . 1 ); } // flash the while ( . 1 ) { // first lamp flashing the ioctl (FD, LED_NUM_ON, . 1 ); SLEEP ( . 1 ); the ioctl (FD, LED_NUM_OFF, . 1 ); SLEEP ( . 1 ); // second lamp flashes the ioctl (FD, LED_NUM_ON, 2 ); SLEEP ( . 1 ); the ioctl (FD, LED_NUM_OFF, 2 ); SLEEP ( . 1 ); // two lamps flashing simultaneously the ioctl (FD, LED_ALL_ON); SLEEP ( . 1 ); the ioctl (FD, LED_ALL_OFF); SLEEP ( . 1 ); } Close (FD); return 0 ; }
# Specify the kernel source path KERNEL_DIR = / Home / Farsight / S5PV210 / Kernel / linux- 3.0 . 8 CUR_DIR = $ (shell pwd) MYAPP = the Test All: # Let make enter the kernel source code compiler, while the c program in the current directory as compiled kernel module with the make -C $ (KERNEL_DIR should) M = $ (CUR_DIR) modules ARM -none-Linux-GCC-gnueabi - O $ (MYAPP) $ (MYAPP) .c Clean: # delete the file of compiled above the make - $ C (KERNEL_DIR) M = $ (CUR_DIR) Clean RM - the RF $ (MYAPP) install: cp * .ko $ (MYAPP) / opt / rootfs / drv_module # specify which file in the current directory as a kernel module compiled obj-m = led_drv.o