Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80400
  • 博文数量: 15
  • 博客积分: 346
  • 博客等级: 一等列兵
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-14 17:20
文章分类
文章存档

2012年(15)

分类: LINUX

2012-05-21 22:32:18

练习定时器
--led.c

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/errno.h>
  5. #include <linux/mm.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <linux/device.h>
  10. #include <linux/gpio.h>
  11. #include <linux/timer.h>
  12. #include <linux/types.h>
  13. #include <asm/io.h>
  14. #include <asm/module.h>
  15. #include <asm/uaccess.h>
  16. #include <mach/regs-gpio.h>
  17. #include <mach/hardware.h>


  18. #define DEVICE_NAME "leds"
  19. #define LEDDEV_MAJOR 0
  20. #define LED_NR_DEVS 1
  21. #define LEDON 0
  22. #define LEDOFF 1

  23. struct led_dev
  24. {
  25.     struct cdev dev;
  26.     atomic_t index;
  27.     struct timer_list timer;
  28. };
  29. struct led_dev *devp;
  30. struct class *my_class;

  31. static int led_major = LEDDEV_MAJOR;

  32. static unsigned long led_table[] =
  33. {
  34.     S3C2410_GPB(5),
  35.     S3C2410_GPB(6),
  36.     S3C2410_GPB(7),
  37.     S3C2410_GPB(8),
  38. };

  39. static unsigned int led_cfg_table[] =
  40. {
  41.     S3C2410_GPIO_OUTPUT,
  42.     S3C2410_GPIO_OUTPUT,
  43.     S3C2410_GPIO_OUTPUT,
  44.     S3C2410_GPIO_OUTPUT,
  45. };

  46. static void s3c2440_timer_handle(unsigned long arg)
  47. {
  48.     int i;
  49.     mod_timer(&devp->timer, jiffies + HZ);
  50.     atomic_inc(&devp->index);
  51.     i = devp->index.counter;
  52.     if (atomic_sub_and_test(4, &devp->index))
  53.         atomic_set(&devp->index, 0);
  54.     else
  55.         atomic_set(&devp->index, i);

  56.     for (i = 0; i < 4; ++i)
  57.         s3c2410_gpio_setpin(led_table[i], 1);
  58.     s3c2410_gpio_setpin(led_table[devp->index.counter], 0);
  59. }

  60. static int s3c2440_leds_open(struct inode *inode, struct file *filp)
  61. {
  62.     int i;
  63.     for(i = 0; i < 4; ++i)
  64.     {
  65.         s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  66.         s3c2410_gpio_setpin(led_table[i], 1);
  67.     }
  68.     init_timer(&devp->timer);
  69.     devp->timer.function = &s3c2440_timer_handle;
  70.     devp->timer.expires = jiffies + HZ;

  71.     add_timer(&devp->timer);
  72.     atomic_set(&devp->index, 0);
  73.     return 0;
  74. }


  75. static int s3c2440_leds_release(struct inode *inode, struct file *filp)
  76. {
  77.     del_timer(&devp->timer);
  78.     return 0;
  79. }

  80. static struct file_operations dev_fops =
  81. {
  82.     .owner = THIS_MODULE,
  83.     .open = s3c2440_leds_open,
  84.     .release = s3c2440_leds_release,
  85. };


  86. static int __init s3c2440_led_init(void)
  87. {
  88.     int result;
  89.     struct device *devxx;
  90.     dev_t devno = MKDEV(led_major, 0);

  91.     if (led_major)
  92.         result = register_chrdev_region(devno, 1, DEVICE_NAME);
  93.     else
  94.     {
  95.         result = alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);
  96.         led_major = MAJOR(devno);
  97.         printk("Major-->%d\n", led_major);
  98.     }

  99.     if (result < 0)
  100.         return result;

  101.     devp = kmalloc(sizeof(struct led_dev), GFP_KERNEL);
  102.     if (!devp)
  103.     {
  104.         result = -ENOMEM;
  105.         goto fail_malloc;
  106.     }

  107.     cdev_init(&devp->dev, &dev_fops);
  108.     devp->dev.owner = THIS_MODULE;
  109.     devp->dev.ops = &dev_fops;

  110.     cdev_add(&devp->dev, devno, LED_NR_DEVS);

  111.     my_class = class_create(THIS_MODULE, "my_class");
  112.     if (IS_ERR(my_class))
  113.         return -1;
  114.     devxx = device_create(my_class, NULL, devno, NULL, DEVICE_NAME);
  115.     if (IS_ERR(devxx))
  116.     {
  117.         printk("create device node fail!\n");
  118.         return -1;
  119.     }
  120.     printk("create device node sucess!\n");
  121.     return 0;

  122. fail_malloc:
  123.     unregister_chrdev_region(MKDEV(led_major, 0), LED_NR_DEVS);
  124.     return result;
  125. }

  126. static void __exit s3c2440_led_exit(void)
  127. {
  128.     cdev_del(&devp->dev);
  129.     device_destroy(my_class, MKDEV(led_major, 0));
  130.     class_destroy(my_class);
  131.     unregister_chrdev_region(MKDEV(led_major, 0), LED_NR_DEVS);
  132. }

  133. MODULE_LICENSE("GPL");
  134. MODULE_AUTHOR("Domod");
  135. module_init(s3c2440_led_init);
  136. module_exit(s3c2440_led_exit);
--app-led.c

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/ioctl.h>

  5. int main(int argc, char **argv)
  6. {
  7.     int fd;
  8.     fd = open("/dev/leds", 0);
  9.     while(1);
  10. }
--Makefile

点击(此处)折叠或打开

  1. CFILE=app-led.c
  2. TFILE=led.ko
  3. ifneq ($(KERNELRELEASE),)

  4. obj-m := led.o

  5. else
  6.     
  7. KDIR := /home/domod/arm/kernel/src/linux-2.6.32.2
  8. all:
  9.     make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
  10. app:
  11.     arm-linux-gcc $(CFILE) -o app
  12. sub:
  13.     cp $(TFILE) ../rootfs
  14. clean:
  15.     rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*

  16. endif

阅读(1549) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~