| 
 有了上一节的基础,就可以很轻松的用register_chrdev函数实现LED驱动了。编写LED驱动及相应的应用程序,实现LED灯每一秒闪烁一次。 参考驱动源码如下: - #include <linux/init.h>
 
 - #include <linux/module.h>
 
 - #include <asm/uaccess.h>
 
 - #include <plat/gpio-cfg.h>
 
 - #include <mach/gpio.h>
 
 - #include <linux/fs.h>
 
 - #include <linux/device.h> 
 
 -  
 
 - #define LED_ON 0x11
 
 - #define LED_OFF 0x22
 
 - #define LED_MAJOR 97 //主设备号
 
 - static struct class *led_class;
 
 -  
 
 - long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 - {
 
 -          switch(cmd)
 
 -          {
 
 -          case LED_ON:
 
 -                    gpio_set_value(EXYNOS4_GPX1(6), 0);
 
 -                    gpio_set_value(EXYNOS4_GPX1(7), 0);
 
 -                    gpio_set_value(EXYNOS4_GPX2(6), 0);
 
 -                    gpio_set_value(EXYNOS4_GPX2(7), 0);
 
 -          break;
 
 -          case LED_OFF:
 
 -                    gpio_set_value(EXYNOS4_GPX1(6), 1);
 
 -                    gpio_set_value(EXYNOS4_GPX1(7), 1);
 
 -                    gpio_set_value(EXYNOS4_GPX2(6), 1);
 
 -                    gpio_set_value(EXYNOS4_GPX2(7), 1);
 
 -          break;
 
 -          default:break;
 
 -          }
 
 -          return 0;
 
 - }
 
 -  
 
 - ssize_t led_open(struct inode * inode,struct file * file)
 
 - {
 
 -          return 0;
 
 - }
 
 -  
 
 - ssize_t led_release(struct inode * inode, struct file * file)
 
 - {
 
 -          return 0;
 
 - }
 
 -  
 
 - static const struct file_operations
 
 - x4412_ibox_ctl_ops={
 
 -          .owner = THIS_MODULE,
 
 -          .open = led_open,
 
 -          .unlocked_ioctl = led_ioctl,
 
 -          .release = led_release,
 
 - };
 
 -  
 
 - static int led_init(void)
 
 - {
 
 -          int ret = -ENODEV;
 
 -          //初始化端口,GPX1_6,GPX1_7,GPX2_6,GPX2_7
 
 -          ret = gpio_request(EXYNOS4_GPX1(6), "GPX1");
 
 -          if(ret)
 
 -                    printk("x4412-led: request gpio GPX1(6) fail\n");
 
 -          s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
 
 -          gpio_direction_output(EXYNOS4_GPX1(6), 1);
 
 -  
 
 -          ret = gpio_request(EXYNOS4_GPX1(7), "GPX1");
 
 -          if(ret)
 
 -                    printk("x4412-led: request gpio GPX1(7) fail\n");
 
 -          s3c_gpio_setpull(EXYNOS4_GPX1(7), S3C_GPIO_PULL_UP);
 
 -          gpio_direction_output(EXYNOS4_GPX1(7), 1);
 
 -  
 
 -          ret = gpio_request(EXYNOS4_GPX2(6), "GPX2");
 
 -          if(ret)
 
 -                    printk("x4412-led: request gpio GPX2(6) fail\n");
 
 -          s3c_gpio_setpull(EXYNOS4_GPX2(6), S3C_GPIO_PULL_UP);
 
 -          gpio_direction_output(EXYNOS4_GPX2(6), 1);
 
 -  
 
 -          ret = gpio_request(EXYNOS4_GPX2(7), "GPX2");
 
 -          if(ret)
 
 -                    printk("x4412-led: request gpio GPX2(7) fail\n");
 
 -          s3c_gpio_setpull(EXYNOS4_GPX2(7), S3C_GPIO_PULL_UP);
 
 -          gpio_direction_output(EXYNOS4_GPX2(7), 1);
 
 -  
 
 -          /*静态方式注册驱动*/
 
 -          ret = register_chrdev(LED_MAJOR, "x4412_ibox_led", &x4412_ibox_ctl_ops);
 
 -          if (ret < 0)
 
 -          {
 
 -                    printk(KERN_ERR "x4412_ibox_led: unable to get major %d\n", ret);
 
 -                    return ret;
 
 -          }
 
 -          //创建class
 
 -          led_class = class_create(THIS_MODULE, "x4412_ibox_led");
 
 -          if (IS_ERR(led_class))
 
 -          {
 
 -                    unregister_chrdev(LED_MAJOR, "x4412_ibox_led");
 
 -                    return PTR_ERR(led_class);
 
 -          }
 
 -          //创建节点
 
 -          device_create(led_class, NULL, MKDEV(LED_MAJOR, 0), NULL, "x4412-led");
 
 -          return 0;
 
 - }
 
 -  
 
 - static int __init x4412_ibox_LED_init(void)
 
 - {
 
 -          int ret = -ENODEV; //调用函数
 
 -          printk("x4412_ibox_LED_init\n");
 
 -          ret = led_init();
 
 -          if(ret)
 
 -          {
 
 -                    printk("x4412_ibox_LED_init fail!\n");
 
 -                    return ret;
 
 -          }
 
 -          return 0;
 
 - }
 
 -  
 
 - static void __exit x4412_ibox_LED_exit(void)
 
 - {
 
 -          //注销设备
 
 -          device_destroy(led_class, MKDEV(LED_MAJOR, 0));
 
 -          class_destroy(led_class);
 
 -          unregister_chrdev(LED_MAJOR, "x4412_ibox_led");
 
 - }
 
 -  
 
 - MODULE_LICENSE("GPL");
 
 - MODULE_DESCRIPTION("liu qiming");
 
 - MODULE_ALIAS_CHARDEV(LED_MAJOR, 0);
 
 - module_init(x4412_ibox_LED_init);
 
 - module_exit(x4412_ibox_LED_exit);
 
  复制代码参考应用程序源码如下: - #include <stdio.h>
 
 - #include <stdlib.h>
 
 - #include <fcntl.h>
 
 - #define DEVICE_NAME  "/dev/x4412-led"
 
 - #define LED_ON 0x11
 
 - #define LED_OFF 0x22
 
 - int main(int argc,char **argv)
 
 - {
 
 -          int fd;
 
 -          int ret;
 
 -          char *i;
 
 -          printf("\n x4412/ibox:start led test \r\n");
 
 -          fd = open(DEVICE_NAME,O_RDWR);//Open device ,get the handle
 
 -          printf("fd = %d \n",fd);
 
 -          if(fd == -1)
 
 -          {
 
 -                    printf("open device %s error \n",DEVICE_NAME);
 
 -          }
 
 -          else
 
 -          {
 
 -                    while(1)
 
 -                    {
 
 -                             ioctl(fd,LED_OFF);
 
 -                             sleep(1);//wait 1 second
 
 -                             ioctl(fd,LED_ON);
 
 -                             sleep(1);
 
 -                    }
 
 -                    ret = close(fd);
 
 -          }
 
 -          return 0;
 
 - }
 
  复制代码       编译测试,注意观察/proc/devices文件的内容,以及/dev下生成的节点,主次设备号等。  
附:做好的LED应用映像: 
 
led
(6.14 KB, 下载次数: 18)
 |