<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > OK6410A學(xué)習(xí)筆記四:嵌入式Linux驅(qū)動之LED驅(qū)動進階

          OK6410A學(xué)習(xí)筆記四:嵌入式Linux驅(qū)動之LED驅(qū)動進階

          作者: 時間:2016-11-21 來源:網(wǎng)絡(luò) 收藏
          作為上一篇介紹的LED驅(qū)動的續(xù)篇,主要的改動之處在于實現(xiàn)了利用Linux系統(tǒng)支持的mdev機制在驅(qū)動加載的過程中自動創(chuàng)建設(shè)備節(jié)點的功能,另外,對write函數(shù)有了比較大的改進。

          //s3c6410_led.c – driver file
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include

          #define DEV_MAJOR 176
          #define DEV_NAME "s3c6410_leds"



          #define GPMCON 0x7F008820
          #define GPMDAT 0x7F008824
          #define GPMPUD 0x7F008828


          volatile unsigned long *gpmcon = NULL;
          volatile unsigned long *gpmdat = NULL;
          volatile unsigned long *gpmpud = NULL;

          static struct class *s3c6410_led_class;
          static struct class_device *s3c6410_led_class_dev;


          static int s3c6410_led_open(struct inode *inode, struct file *filp)
          {
          //int ret;

          printk(KERN_ALERT "This is open function of s3c6410 led driver.n");

          *gpmpud &= 0xffffffaa; //set GPM0~3 as pull up enabled
          *gpmcon &= 0xffff1111; //set GPM0~3 as output
          *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds

          return 0;

          }

          static ssize_t s3c6410_led_write(struct file *filp, const char __user *buf,
          size_t count, loff_t *ppos)
          {
          char val;

          copy_from_user(&val,buf,count);

          //printk("val is %cn",val);

          printk(KERN_ALERT "This is write function of s3c6410 led driver.n");

          *gpmpud &= 0xffffffaa;
          *gpmcon &= 0xffff1111;

          if((int)val){
          //turn on leds
          printk(KERN_ALERT "Turn on the leds.n");
          *gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds

          }else{
          printk(KERN_ALERT "Turn off the leds.n");
          *gpmdat |= 0x0000000f; //set GPM0~3 to low level, which turn off leds
          }

          return count;
          }


          struct file_operations s3c6410_led_flops = {
          .owner = THIS_MODULE,
          .open = s3c6410_led_open,
          .write = s3c6410_led_write,
          };

          static int __init s3c6410_led_init(void)
          {
          int ret;

          //register led device driver into kernel
          ret = register_chrdev(DEV_MAJOR,DEV_NAME,&s3c6410_led_flops);

          //retriver the vritual address by ioremap
          gpmcon = (volatile unsigned long *)ioremap(GPMCON,4); //32-bit reg
          gpmdat = gpmcon + 1;
          gpmpud = gpmcon + 2;

          //create led device node
          s3c6410_led_class = class_create(THIS_MODULE,"s3c6410_led");
          s3c6410_led_class_dev = device_create(s3c6410_led_class,NULL,MKDEV(DEV_MAJOR,0),
          NULL,DEV_NAME);

          return 0;
          }

          static void __exit s3c6410_led_exit(void)
          {
          //unregister led device dirver from kernel
          unregister_chrdev(DEV_MAJOR,DEV_NAME);

          //iounmap
          iounmap(gpmcon);

          //delete led driver node
          device_unregister(s3c6410_led_class_dev);
          class_destroy(s3c6410_led_class);
          }

          module_init(s3c6410_led_init);
          module_exit(s3c6410_led_exit);

          MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
          MODULE_VERSION("1.0");
          MODULE_AUTHOR("");
          MODULE_LICENSE("Dual BSD/GPL");

          //s3c6410_led_test.c – test file
          #include
          #include
          #include
          #include

          int main(int argc,char* argv[])
          {
          int fd;
          int val;

          if(argc != 2){
          printf("Usage: n");
          printf("%s n",argv[0]);
          return 0;
          }
          else{
          if(strcmp(argv[1],"on") == 0) val = 1;
          else if(strcmp(argv[1],"off") == 0) val = 0;
          else{
          printf("Usage: n");
          printf("%s ",argv[0]);
          return 0;
          }
          }

          fd = open("/dev/s3c6410_leds",O_RDWR);

          write(fd,&val,1);

          return 0;
          }

          操作過程:





          評論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();