“手把手教你学linux驱动开发”OK6410系列之03---LED字符设备驱动

来源:互联网 发布:群智能算法 编辑:程序博客网 时间:2024/04/28 01:03

上一篇文章我们介绍了字符设备驱动程序的框架,本篇文章我们将操作真实的硬件---LED。

       作者:沧海猎人   出处:http://blog.csdn.net/embedded_hunter  转载请注明出处   嵌入式技术交流QQ群:179012822

 

 一、实验环境 

开发机环境

          操作系统:ubuntu 9.10

          交叉编译环境:arm-linux-gcc 4.2.2 ,安装位置 /usr/local/arm/4.3.2/

          6410板子内核源码路径:/work/linux-2.6.36.2-v1.05/     

目标板环境:OK6410-A     linux2.6.36

 

二、实验原理

         控制LED是最简单的一件事情,我们学习LED驱动程序,就相当于学习其他编程语言是的“hello world”程序一样,是一个入门的程序。

         学习驱动程序,必须要对硬件有所了解,接下来看几个与硬件相关的材料。

 

     

                                           OK6410  LED原理图

 

     

                                              OK6410  LED原理图

 

从上面的原理图可以得知,LED与CPU引脚的连接方法如下,低电平点亮。

     LED1 -GPM0

     LED2 -GPM1

     LED3 -GPM2

     LED4 -GPM3

    

从数据手册可以找到相应的控制方法。这里我们以LED1为例,介绍一下LED1的操作方法,其他的类似,请大家自行分析。

通过上面可以得知,需要先将GPM0设置为输出方式。将相应的寄存器进行配置。

 

然后将GPMDAT寄存器的第0位置0灯亮,置1灯灭。

 

三、实验步骤

1、编写驱动程序

driver_led.c

[plain] view plaincopy
  1. #include <linux/module.h>  
  2.   
  3. #include <linux/kernel.h>  
  4. #include <linux/fs.h>  
  5. #include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
  6. #include <linux/miscdevice.h>    
  7. #include <linux/pci.h>    
  8. #include <mach/map.h>    
  9. #include <mach/regs-gpio.h>    
  10. #include <mach/gpio-bank-m.h>    
  11. #include <plat/gpio-cfg.h>  
  12.   
  13. #define LED_MAJOR 240  
  14.   
  15. int led_open (struct inode *inode,struct file *filp)  
  16.   
  17. {  
  18.     unsigned tmp;     
  19.          tmp = readl(S3C64XX_GPMCON);     
  20.     tmp = (tmp & ~(0x7U<<1))|(0x1U);     
  21.          writel(tmp, S3C64XX_GPMCON);   
  22.     printk("#########open######\n");  
  23.     return 0;  
  24. }  
  25.   
  26. ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  
  27. {  
  28.     printk("#########read######\n");  
  29.     return count;  
  30. }  
  31.   
  32.   
  33. ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
  34. {  
  35.     char wbuf[10];  
  36.     unsigned tmp;     
  37.     printk("#########write######\n");  
  38.     copy_from_user(wbuf,buf,count);  
  39.     switch(wbuf[0])  
  40.     {  
  41.         case 0:  //off  
  42.             tmp = readl(S3C64XX_GPMDAT);     
  43.                           tmp |= (0x1U);     
  44.                           writel(tmp, S3C64XX_GPMDAT);  
  45.             break;  
  46.         case 1:  //on  
  47.             tmp = readl(S3C64XX_GPMDAT);     
  48.                           tmp &= ~(0x1U);     
  49.                           writel(tmp, S3C64XX_GPMDAT);  
  50.             break;  
  51.         default :  
  52.             break;  
  53.     }  
  54.     return count;  
  55. }  
  56.   
  57. int led_release (struct inode *inode, struct file *filp)  
  58. {  
  59.     printk("#########release######\n");  
  60.     return 0;  
  61. }  
  62.   
  63. struct file_operations led_fops ={  
  64.     .owner = THIS_MODULE,  
  65.     .open = led_open,  
  66.     .read = led_read,  
  67.     .write = led_write,  
  68.     .release = led_release,  
  69. };  
  70.   
  71. int __init led_init (void)  
  72. {   int rc;  
  73.     printk ("Test led dev\n");  
  74.     rc = register_chrdev(LED_MAJOR,"led",&led_fops);  
  75.     if (rc <0)  
  76.     {  
  77.         printk ("register %s char dev error\n","led");  
  78.         return -1;  
  79.     }  
  80.     printk ("ok!\n");  
  81.     return 0;  
  82. }  
  83.   
  84. void __exit led_exit (void)  
  85. {  
  86.     unregister_chrdev(LED_MAJOR,"led");  
  87.     printk ("module exit\n");  
  88.     return ;  
  89. }  
  90.   
  91. module_init(led_init);  
  92. module_exit(led_exit);  

 

Makefile文件

[plain] view plaincopy
  1. obj-m := driver_led.o  
  2. KDIR :=/work/linux-2.6.36.2-v1.05/  
  3. all:  
  4.     make -C $(KDIR) M=$(shell pwd) modules  
  5. install:  
  6.     cp driver_led.ko /tftpboot/  
  7. clean:  
  8.     make -C $(KDIR) M=$(shell pwd) clean  

 

2、编写测试程序

test.c

[plain] view plaincopy
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. int main (void)  
  6. {  
  7.     int fd;  
  8.     char buf[10]={0,1};  
  9.     fd = open("/dev/my_led",O_RDWR);  
  10.     if (fd < 0)  
  11.     {  
  12.         printf ("Open /dev/my_led file error\n");  
  13.         return -1;  
  14.     }     
  15.     while(1)  
  16.     {  
  17.         write(fd,&buf[0],1);  
  18.         sleep(1);  
  19.         write(fd,&buf[1],1);  
  20.         sleep(1);  
  21.     }  
  22.     close (fd);  
  23.     return 0;  
  24.   
  25. }  

 

 

3、编译驱动程序与测试程序

      编译驱动程序

      #make

      将驱动程序放到tftp的工作目录 /tftpboot

      #make install

      编译测试程序

      #arm-linux-gcc  test.c  -o  test

      将测试程序放到tftp的工作目录 /tftpboot

       #cp  test  /tftpboot

 

4、将程序下载到开发板

       将开发板的IP地址修改,与主机在同一个网段。确保PC的tftp服务开启。

      下载程序到开发板

        SMDK6410#   tftp -l /lib/modules/2.6.36.2/driver_led.ko -r driver_led.ko  -g  192.168.1.111        192.168.1.111为服务器IP

        SMDK6410#   tftp -l test  -r test  -g  192.168.1.111        

 

5、测试

        加载驱动   #insmod  /lib/modules/2.6.36.2/driver_led.ko

        创建设备文件   #mknod  /dev/my_led  c   240  0

        测试  ./test

        [root@FORLINX6410]# ./test
      此时可以看到OK6410板子上的LED0在闪烁。

       卸载驱动  #rmmod   driver_led

       从上面的结果我们可以看到,当用户调用相应的文件操作函数时,驱动程序中的相应的函数也会被调用。

        大家可以修改相应程序,测试一下其他的情况。

 

作者:沧海猎人   出处:http://blog.csdn.net/embedded_hunter  转载请注明出处   嵌入式技术交流QQ群:179012822

 

备注: 本驱动使用了最基本的内核函数,可能操作方法与你看过的其他驱动程序不太一样,尤其注册字符设备的函数。  没关系,我们会一步一步介绍相关的其他函数。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天然气热水器风口一封闭怎么办 热水器着火后火变大怎么办? 人如果没有天魂怎么办 被鬼魂附体了该怎么办 被吸血蠓咬了怎么办 股份公司大股东占用资金怎么办 抱小孩抱的胳膊疼怎么办 一个月好几个性伴侣怎么办 惹了势力大的人怎么办 给佛像换新法器旧的怎么办 cad填充图案拾取不了点怎么办 cad填充图案太密怎么办 桃木葫芦挂件裂口了怎么办 皮肤被太阳晒伤变黑怎么办 皮肤又粗又黑该怎么办 盆栽红薯长疯了怎么办 四叶草叶子发黄怎么办 美篇不想让别人看到怎么办 黑魂3暗灵入侵怎么办 问道手游账号忘了怎么办 问道手游密码忘了怎么办 毒蚂蚁咬了红肿怎么办 电脑开机后有电流声怎么办 小学生阅读方面不会总结怎么办 天龙八部手游转职装备怎么办 投简历没回应该怎么办? 开车开的腰疼怎么办 开车腰疼怎么办吃什么 58简历投错了怎么办 开了一天车腰疼怎么办 开车腰疼怎么办怎么解决好 球球大作战找不到主界面怎么办 在QQ上找不到主界面怎么办 mac地址被过滤了怎么办 续贷声明含非法字符怎么办 辞职老板不给结工资怎么办 辞职后老板不发工资怎么办 联想手机不自带系统升级怎么办 苹果6玩崩坏3卡怎么办 机票名字打错了怎么办? 安装软件后显示名字乱码怎么办