复制代码- /**********************************************************
- *
- *
- *说明:本程序为一个基于Linux操作系的简单LED驱动模块,
- * 本模块主要应用内核定时器进行定时LED,由于
- * 比较简单,所以在此不再进行说明
- *
- **环境:
- * 1)操作系统:Linux
- * 2)内核版本:kernel-2.6.13
- * 3)CPU :S3C2440
- * 4)开发板 :Mini2440
- *
- *硬件连接:
- * 1):LED1 -- GPB5
- * 2):LED2 -- GPB6
- * 3):LED3 -- GPB7
- * 4):LED4 -- GPB8
- *
- *编译环境:arm-linux-gcc-3.4.1
- *
- *作者:soon
- *部门:长沙理工大学 计通学院 计算机07级04班
- *最后修改时间:2010.5.19
- *
- *
- **********************************************************/
- #ifndef _LED_C_
- #define _LED_C_
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/errno.h>
- #include <linux/types.h>
- #include <linux/fcntl.h>
- #include <linux/cdev.h>
- #include <linux/version.h>
- #include <linux/vmalloc.h>
- #include <linux/ctype.h>
- #include <linux/pagemap.h>
- #include <linux/ioctl.h>
- #include <linux/interrupt.h>
- #include <linux/time.h>
- #include <linux/timer.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/signal.h>
- #include <asm/hardware.h>
- #include <asm/uaccess.h>
- #include <asm/arch/regs-gpio.h>
- #include <asm/arch/regs-timer.h>
- #include <asm/mach/time.h>
- #include <asm/hardware/clock.h>
- #ifndef LED_MAJOR
- #define LED_MAJOR 240
- #endif
- #ifndef LED_MINOR
- #define LED_MINOR 0
- #endif
- MODULE_AUTHOR("soon");
- MODULE_LICENSE("Dual BSD/GPL");
- static unsigned int led_inc=0;
- static unsigned int led_count = 0;
- struct LED_dev
- {
- struct cdev cdev;
- };
- /*定义LED相应的CPU引脚*/
- static unsigned long led_table [] = {
- S3C2410_GPB5,
- S3C2410_GPB6,
- S3C2410_GPB7,
- S3C2410_GPB8,
- };
- /*相应引脚的工作方式*/
- static unsigned int led_cfg_table [] = {
- S3C2410_GPB5_OUTP,
- S3C2410_GPB6_OUTP,
- S3C2410_GPB7_OUTP,
- S3C2410_GPB8_OUTP,
- };
- static struct LED_dev *LED_devices;
- static struct timer_list *LED_TIMER;
- static void kerneltimer_timerover(unsigned long arg);
- static void
- kerneltimer_registertimer(void)
- {
- init_timer(LED_TIMER);
- LED_TIMER->expires = get_jiffies_64() + (5 * HZ/100);
- LED_TIMER->function = kerneltimer_timerover;
- add_timer(LED_TIMER);
- }
- static void
- kerneltimer_timerover(unsigned long arg)
- {
- unsigned int i;
-
- /*如果led_count > 3,则led_count = 0*/
- led_count &= 0x3;
-
- for(i = 0; i < led_count; i++)
- s3c2410_gpio_setpin(led_table[i],1);
-
- s3c2410_gpio_setpin(led_table[led_count],0);
-
- led_count ++;
- kerneltimer_registertimer();
-
- }
- static int
- LED_open(struct inode *inode, struct file *filp)
- {
- struct LED_dev *dev;
-
- if(led_inc > 0)return -ERESTARTSYS;
-
- LED_TIMER = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
-
- if(!LED_TIMER)
- return -ENOMEM;
-
- kerneltimer_registertimer();
-
- led_inc++;
-
- dev = container_of(inode->i_cdev, struct LED_dev, cdev);
- filp->private_data = dev;
-
- return 0;
- }
- static int
- LED_release(struct inode *inode, struct file *filp)
- {
- led_inc--;
- return 0;
- }
- static struct file_operations LED_fops = {
- .owner = THIS_MODULE,
- .open = LED_open,
- .release = LED_release,
- };
- static void
- LED_cleanup_module(void)
- {
- unsigned int i = 0;
- dev_t devno = MKDEV(LED_MAJOR, LED_MINOR);
- if (LED_devices) {
- cdev_del(&LED_devices->cdev);
- kfree(LED_devices);
- }
-
- if(LED_TIMER)
- kfree(LED_TIMER);
- for(; i < 4; i ++)
- s3c2410_gpio_setpin(led_table[i], 1);
- unregister_chrdev_region(devno,1);
- }
- static int
- LED_init_module(void)
- {
- int result;
- unsigned int i;
- dev_t dev = 0;
- dev = MKDEV(LED_MAJOR,LED_MINOR);
- result = register_chrdev_region(dev,1,"Led_Test");
-
- if (result < 0)
- return result;
-
- LED_devices = kmalloc(sizeof(struct LED_dev), GFP_KERNEL);
-
- if (!LED_devices){
- result = -ENOMEM;
- goto fail;
- }
-
- memset(LED_devices, 0, sizeof(struct LED_dev));
-
- cdev_init(&LED_devices->cdev, &LED_fops);
- LED_devices->cdev.owner = THIS_MODULE;
- LED_devices->cdev.ops = &LED_fops;
- result = cdev_add (&LED_devices->cdev, dev, 1);
- if(result)
- goto fail;
- for (i = 0; i < 4; i++) {
- s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
- s3c2410_gpio_setpin(led_table[i], 1);
- }
-
- return 0;
- fail:
- LED_cleanup_module();
- return result;
- }
- module_init(LED_init_module);
- module_exit(LED_cleanup_module);
- #endif
- /**********************************************************
- ||
- ||
- ||
- || END
- ||
- ||
- ||
- **********************************************************/
- 如果不方便,可以进行一下调试,MAJOR = 240;MINOR = 0; 驱动加载为: mknod /dev/Led_Test c 240 0
|