色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 字符設(shè)備驅(qū)動-LED實驗

          字符設(shè)備驅(qū)動-LED實驗

          作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          驅(qū)動源碼:
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          int major;
          static struct class *leddrv_class;
          static struct class_device *leddrv_class_dev;
          volatile unsigned long *gpfcon = NULL;
          volatile unsigned long *gpfdat = NULL;
          static int led_drv_open(struct inode *inode, struct file *file)
          {
          //printk("first_drv_openn");
          *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2)));
          *gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2)));
          return 0;
          }
          static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
          {
          char val = 0;
          copy_from_user(&val,buf,count);
          if(val == 1)
          *gpfdat &= ~((1<<4) | (1<<5) | (1<<6));
          else if(val == 0)
          *gpfdat |= ((1<<4) | (1<<5) | (1<<6));
          //printk("first_drv_writen");
          return 0;
          }
          static struct file_operations led_drv_fops = {
          .owner = THIS_MODULE,
          .open = led_drv_open,
          .write = led_drv_write,
          };
          static int led_drv_init(void)
          {
          major = register_chrdev(0, "led_drv", &led_drv_fops); // 注冊, 告訴內(nèi)核
          leddrv_class = class_create(THIS_MODULE, "leddrv");
          leddrv_class_dev = class_device_create(leddrv_class, NULL, MKDEV(major, 0), NULL, "xxx");
          gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);
          gpfdat = gpfcon + 1;
          return 0;
          }
          static void led_drv_exit(void)
          {
          unregister_chrdev(major, "led_drv"); // 卸載
          class_device_unregister(leddrv_class_dev);
          class_destroy(leddrv_class);
          iounmap(gpfcon);
          }
          module_init(led_drv_init);
          module_exit(led_drv_exit);
          MODULE_LICENSE("GPL");
          ==================================================================================================
          測試程序:
          #include
          #include
          #include
          #include
          int main(int argc, char **argv)
          {
          int fd;
          int val = 1;
          fd = open("/dev/xxx",O_RDWR);
          if(fd < 0)
          {
          printf("cant open!n");
          }
          if(argc != 2)
          {
          printf("Usage:n");
          printf("%s ",argv[0]);
          return 0;
          }
          if(strcmp(argv[1],"on") == 0)
          val = 1;
          else
          val = 0;
          write(fd,&val,4);
          return 0;
          }
          ==================================================================================================
          注:在調(diào)用write(fd,&val,4);時根據(jù)不同的val值在調(diào)用驅(qū)動程序時做出判斷:關(guān)閉、打開led燈
          copy_from_user(&val,buf,count); //從用戶空間buf拷貝count長度的數(shù)據(jù)到內(nèi)核空間val中
          copy_to_user(buf,&val,,count); //從內(nèi)核空間val拷貝count長度的數(shù)據(jù)到用戶空間buf中
          內(nèi)核空間不能直接訪問物理地址,故要映射:
          gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16);


          評論


          技術(shù)專區(qū)

          關(guān)閉