s3c24xx_leds驱动

参考嵌入式Linux应用开发完全手册,出现一些问题并加以修改。用的版本是linux-2.6.32.2。

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <linux/device.h>
  7 #include <linux/gpio.h>
  8 #include <asm/irq.h>
  9 //#include <asm/arch/regs-gpio.h>
 10 #include <mach/regs-gpio.h>         //此处头文件修改
 11 //#include <asm/hardware.h>
 12 #include <mach/hardware.h>         //修改
 13 
 14 #define DEVICE_NAME     "leds"  /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
 15 #define LED_MAJOR       231     /* 主设备号 */
 16 
 17 /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
 18 #define IOCTL_LED_ON    0
 19 #define IOCTL_LED_OFF   1
 20 
 21 /* 用来指定LED所用的GPIO引脚 */
 22 static unsigned long led_table [] =
 23 {
 24     S3C2410_GPB(5),                         //修改
 25     S3C2410_GPB(6),
 26     S3C2410_GPB(7),
 27     S3C2410_GPB(8),
 28 };
 29 
 30 /* 用来指定GPIO引脚的功能:输出 */
 31 static unsigned int led_cfg_table [] =
 32 {
 33     S3C2410_GPIO_OUTPUT,               //修改
 34     S3C2410_GPIO_OUTPUT,
 35     S3C2410_GPIO_OUTPUT,
 36     S3C2410_GPIO_OUTPUT,
 37 };
 38 
 39 /* 应用程序对设备文件/dev/leds执行open(...)时,
 40  * 就会调用s3c24xx_leds_open函数
 41  */
 42 static int s3c24xx_leds_open(struct inode *inode, struct file *file)
 43 {
 44     int i;
 45 
 46     for (i = 0; i < 4; i++) {
 47         // 设置GPIO引脚的功能:本驱动中LED所涉及的GPIO引脚设为输出功能
 48         s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
 49     }
 50     return 0;
 51 }
 52 
 53 /* 应用程序对设备文件/dev/leds执行ioclt(...)时,
 54  * 就会调用s3c24xx_leds_ioctl函数
 55  */
 56 static int s3c24xx_leds_ioctl(
 57     struct inode *inode,
 58     struct file *file,
 59     unsigned int cmd,
 60     unsigned long arg)
 61 {
 62     if (arg > 4) {
 63         return -EINVAL;
 64     }
 65 
 66     switch(cmd) {
 67     case IOCTL_LED_ON:
 68         // 设置指定引脚的输出电平为0
 69         s3c2410_gpio_setpin(led_table[arg], 0);
 70         return 0;
 71 
 72     case IOCTL_LED_OFF:
 73         // 设置指定引脚的输出电平为1
 74         s3c2410_gpio_setpin(led_table[arg], 1);
 75         return 0;
 76 
 77     default:
 78         return -EINVAL;
 79     }
 80 }
 81 
 82 /* 这个结构是字符设备驱动程序的核心
 83  * 当应用程序操作设备文件时所调用的open、read、write等函数,
 84  * 最终会调用这个结构中指定的对应函数
 85  */
 86 static struct file_operations s3c24xx_leds_fops = {
 87     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
 88     .open   =   s3c24xx_leds_open,
 89     .ioctl  =   s3c24xx_leds_ioctl,
 90 };
 91 
 92 /*
 93  * 执行“insmod s3c24xx_leds.ko”命令时就会调用这个函数
 94  */
 95 static int __init s3c24xx_leds_init(void)
 96 {
 97     int ret;
 98 
 99     /* 注册字符设备驱动程序
100      * 参数为主设备号、设备名字、file_operations结构;
101      * 这样,主设备号就和具体的file_operations结构联系起来了,
102      * 操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数
103      * LED_MAJOR可以设为0,表示由内核自动分配主设备号
104      */
105     ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);
106     if (ret < 0) {
107       printk(DEVICE_NAME " can't register major number\n");
108       return ret;
109     }
110 
111     printk(DEVICE_NAME " initialized\n");
112     return 0;
113 }
114 
115 /*
116  * 执行”rmmod s3c24xx_leds.ko”命令时就会调用这个函数
117  */
118 static void __exit s3c24xx_leds_exit(void)
119 {
120     /* 卸载驱动程序 */
121     unregister_chrdev(LED_MAJOR, DEVICE_NAME);
122 }
123 
124 /* 这两行指定驱动程序的初始化函数和卸载函数 */
125 module_init(s3c24xx_leds_init);
126 module_exit(s3c24xx_leds_exit);
127 
128 /* 描述驱动程序的一些信息,不是必须的 */
129 MODULE_AUTHOR("Huang");             // 驱动程序的作者
130 MODULE_DESCRIPTION("S3C2410/S3C2440 LED Driver");   // 一些描述信息
131 MODULE_LICENSE("GPL");                              // 遵循的协议

 

将修改好的该文件放到编译好的 linux-2.6.32.2/drivers/char 目录下,修改该目录下的Makefile,增加 obj-m  +=s3c24xx_leds.o

返回该内核根目录执行make modules:

观察到生成了s3c24xx_leds,ko模块。

 

posted @ 2015-03-06 00:31  ht-beyond  阅读(355)  评论(0编辑  收藏  举报