Linux下LED跑马灯驱动

 一.驱动程序代码:

      #include <linux/config.h>
      #include <linux/module.h>
      #include <linux/kernel.h>
      #include <linux/fs.h>
      #include <linux/init.h>
      #include <linux/devfs_fs_kernel.h>
      #include <linux/miscdevice.h>
      #include <linux/delay.h>
      #include <asm/irq.h>
      #include <asm/arch/regs-gpio.h>
      #include <asm/hardware.h>

      #define DEVICE_NAME "leds"

     #define LED_MAJOR 231


      static unsigned long led_table [] = {
       S3C2410_GPF4,
       S3C2410_GPF5,
        S3C2410_GPF6,
       S3C2410_GPF7,
      };


      static unsigned int led_cfg_table [] = {
       S3C2410_GPF4_OUTP,
      S3C2410_GPF5_OUTP,
      S3C2410_GPF6_OUTP,
      S3C2410_GPF7_OUTP,
      };


      static int s3c2440_leds_ioctl(
       struct inode *inode,
       struct file *file,
       unsigned int cmd,
      unsigned long arg)
      {
      switch(cmd)
      {
      case 0:
      case 1:
       if (arg > 4)
       {
       return -EINVAL;
       }
       s3c2410_gpio_setpin(led_table[arg], !cmd);
       return 0;
      default:
       return -EINVAL;
      }
   }

      static struct file_operations s3c2440_leds_fops = {
      .owner = THIS_MODULE,
      .ioctl = s3c2440_leds_ioctl,
      };


      static int __init s3c2440_leds_init(void)
      {
       int ret;
       int i;

       ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2440_leds_fops);

       if (ret < 0)
       {
       printk(DEVICE_NAME " can't register major number\n");
       return ret;
      }

       devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR |
         S_IRGRP,DEVICE_NAME);

     for (i = 0; i < 4; i++)
      {
       s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
       s3c2410_gpio_setpin(led_table[i], 1);
      }

      printk(DEVICE_NAME " initialized\n");

      return 0;
     }


      static void __exit s3c2440_leds_exit(void)
      {
        devfs_remove(DEVICE_NAME);
        unregister_chrdev(LED_MAJOR, DEVICE_NAME);
      }

       module_init(s3c2440_leds_init);
       module_exit(s3c2440_leds_exit);

       编译的方式参考:“如何在Linux下添加自己驱动”一文。

   二.应用程序测试代码:

       #include <stdio.h>
       #include <stdlib.h>
      #include <unistd.h>
       #include "stdio.h"
       #include "sys/types.h"
       #include "sys/ioctl.h"
       #include "stdlib.h"
       #include "termios.h"
       #include "sys/stat.h"
       #include "fcntl.h"
       #include "sys/time.h"
        int main()
        {
          int on=1;
           int led;
          int fd;
          fd = open("/dev/leds", 0);
          if (fd < 0) {
                           perror("open device leds");
                              exit(1);
                           }
           printf("leds test show. press ctrl+c to exit \n");
          while(1)
              {
                for(led=0;led<4;led++)
                  {
                       ioctl(fd, on, led);
                       usleep(50000);
                  }
               on=!on;
             }
        close(fd);
         return 0;
     }

    编辑完成,命一个名,如led_test.c, 然后该目录下进行静态编译:arm-linux-gcc -static led_test.c -o led_test

     最后,在目标板上找到存放led_test.c的文件,执行./led_test,便可以看到想要的结果...


你可能感兴趣的:(c,linux,struct,Module,cmd,table)