当前位置:编程学习 > C/C++ >>

挂接在/proc上的对LED灯控制的驱动

通过一天的学习总结一下挂接在/proc上的对LED灯控制的驱动开发,代码和过程
1.驱动代码
[cpp] 
#include <linux/module.h>   
#include <linux/init.h>   
#include <linux/version.h>   
#include <linux/proc_fs.h>   
#include <asm/uaccess.h> 
#include <linux/gpio.h> 
#include <mach/regs-gpio.h> 
MODULE_LICENSE("Dual BSD/GPL");     
              
#define USER_ROOT_DIR "led"   
#define USER_ENTRY1   "led_entry1" 
  
static struct proc_dir_entry *led_root;   
static struct proc_dir_entry *led_entry1; 
 
static char msg[255]; 
static unsigned long led_table [] =  

    S3C2410_GPB(5), 
    S3C2410_GPB(6), 
    S3C2410_GPB(7), 
    S3C2410_GPB(8), 
}; 
static unsigned int led_cfg_table[] = 
{  
    S3C2410_GPIO_OUTPUT,  
    S3C2410_GPIO_OUTPUT, 
    S3C2410_GPIO_OUTPUT, 
    S3C2410_GPIO_OUTPUT, 
}; 
 
//int proc_read_information(char *page, char **start, off_t off, int count, int *eof, void *data); 
int proc_write_information(struct file *file, const char *buffer, unsigned long count, void *data); 
   
static int proc_test_init(void)   
{   
    int i; 
    for( i=0;i<4;i++) 
    { 
        s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]); 
    } 
    // Create user root dir under /proc   
    led_root = proc_mkdir(USER_ROOT_DIR, NULL);   
    if (NULL==led_root)   
    {   
        printk(KERN_ALERT "Create dir /proc/%s error!\n",USER_ROOT_DIR);   
        return -1;   
    }   
    printk(KERN_INFO "Create dir /proc/%s\n", USER_ROOT_DIR);   
 
    // Create a test entry under USER_ROOT_DIR   
    led_entry1 = create_proc_entry(USER_ENTRY1,0666, led_root);   
    if (NULL == led_entry1)   
    {   
        printk(KERN_ALERT "Create entry %s under /proc/%s error!\n",USER_ENTRY1, USER_ROOT_DIR);   
        goto err_out;   
    }   
    printk(KERN_INFO "Create /proc/%s/%s\n",USER_ROOT_DIR, USER_ENTRY1);   
 
    //led_entry1->read_proc  = proc_read_information;  
    led_entry1->write_proc = proc_write_information; 
 
    return 0;   
 
    err_out: remove_proc_entry(USER_ROOT_DIR, led_root);   
    return -1;   
}   
 
static void proc_test_exit(void)   
{   
    // Remove all entries   
    remove_proc_entry(USER_ENTRY1, led_root);   
    remove_proc_entry(USER_ROOT_DIR, NULL);   
    printk(KERN_INFO "All Proc Entry Removed!\n");   

 
//int proc_read_information(char *page, char **start, off_t off, int count, int *eof, void *data) 
//{ 
 
//}  
int proc_write_information(struct file *file, const char *buffer, unsigned long count, void *data) 

    int  count2=0,i ; 
    if (copy_from_user((void *)msg, (const void __user *)buffer, count)) 
        return -EFAULT; 
    count2 = 易做图_strtoul(msg, NULL, 0); 
 
    //printk("information %d\n",count2); 
    switch(count2) 
    { 
        case 0: 
        case 1: 
            for(i=0; i<4; i++) 
            { 
                s3c2410_gpio_setpin(led_table[i],!count2); 
            } 
        break; 
        default: 
            return -EINVAL; 
    } 
 
    return 0; 

  
module_init(proc_test_init);   
module_exit(proc_test_exit);   

2.驱动Makefile
[cpp] 
obj-m:=led2.o   
   
CURRENT_PATH:=$(shell pwd)   
       
ARM_LINUX_KERNEL:=/opt/FriendlyARM/mini2440/linux-2.6.32.2   
       
all:   
         $(MAKE) -C $(ARM_LINUX_KERNEL) SUBDIRS=$(CURRENT_PATH) modules   
            
clean:   
    rm -rf *.cmd *.o *.ko  *.mod.c *.symvers *.order 
3.开发过程
编写好驱动代码和Makefile,在PC机上编译成功后通过FTP把led2.ko文件上传到开发板,加载驱动(insmod led2.ko),
执行echo 1 >/proc/led/led_entry1,灯全亮
执行echo 0 >/proc/led/led_entry1,灯全灭
注意:开发板缺省的文件系统已经有了led 测试程序,所以在开发板的命令行终端执行:

#/etc/rc.d/init.d/leds stop

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,