led驱动.docx

上传人:b****2 文档编号:17389846 上传时间:2023-07-24 格式:DOCX 页数:10 大小:16.92KB
下载 相关 举报
led驱动.docx_第1页
第1页 / 共10页
led驱动.docx_第2页
第2页 / 共10页
led驱动.docx_第3页
第3页 / 共10页
led驱动.docx_第4页
第4页 / 共10页
led驱动.docx_第5页
第5页 / 共10页
led驱动.docx_第6页
第6页 / 共10页
led驱动.docx_第7页
第7页 / 共10页
led驱动.docx_第8页
第8页 / 共10页
led驱动.docx_第9页
第9页 / 共10页
led驱动.docx_第10页
第10页 / 共10页
亲,该文档总共10页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

led驱动.docx

《led驱动.docx》由会员分享,可在线阅读,更多相关《led驱动.docx(10页珍藏版)》请在冰点文库上搜索。

led驱动.docx

led驱动

第一个驱动程序:

点灯

 编写驱动函数

 1)定义file_operation结构体,填充(用户定义什么接口,结构体对应有什么成员)

 2)在内核中注册设备

   早期的办法:

register_chrdev(unsignedintmajor,constchar*name,structfile_operations*fops)

 3)驱动的入口函数

  intfirst_drv_init(void){

   上面定义的注册设备驱动程序的方法

   return0;

  }

  内核如何区分入口函数

 4)修饰入口函数

  module_init(first_drv_init);

   

  示例代码如下:

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  

  staticintfirst_drv_open(structinode*inode,structfile*file)

  {

   printk("first_drv_open!

\n");

   return0;

  }

  

  staticssize_tfirst_drv_write(structfile*file,constchar__user*buf,size_tcount,loff_t*ppos)

  {

   printk("first_drv_write!

\n");

   return0;

  }

  

  staticstructfile_operationsfirst_drv_fops={

   .owner=THIS_MODULE,/*这是一个宏,推向编译模块时自动创建__this_module*/

   .open=first_drv_open,

   .write=first_drv_write,

  };

  /*入口函数,注册驱动徎序,早期的办法*/

  intfirst_drv_init(void)

  {

   /*major设备的主设备号,name是驱动程序的名称,fops默认的是file_operations结构*/

   //如果主设备号为0,系统会自动分配

   register_chrdev(111,"first_drv",&first_drv_fops);

   return0;

  }

  /*出口函数,卸载驱动*/

  voidfirst_drv_exit()

  {

   /*major和name必须和注册时的值一致*/

   unregister_chrdev(111,"first_drv");

  }

  

  /*修饰入口函数*/

  module_init(first_drv_init);

  /*修饰出口函数*/

  module_exit(first_drv_exit);

  

 5)编译makefile文件

 示例代码如下:

 

 KERN_DIR=/mnt/sda3/FriendlyARM/mini6410/linux/linux-2.6.38

 all:

  make-C$(KERN_DIR)M=`pwd`modules 

 

 clean:

  make-C$(KERN_DIR)M=`pwd`modulesclean

  rm-rfmodules.order

 

 obj-m +=first_drv.o

  

 6)测试驱动模块

  查看系统设备号cat/proc/devices

  上传模块到开发板

   在开发板上先进入/tmp目录,然后输入rz。

先择文件后上传

  装载到系统中 

   insmodfirst_drv.ko

  查看

   方法一:

lsmod|grepword_count

    [root@FriendlyARM/tmp]#lsmod|grepfirst_drv

      first_drv11560-Live0xbf006000(P)

   方法二:

cat/proc/devices

    [root@FriendlyARM/tmp]#cat/proc/devices 

      Characterdevices:

      ...

      108ppp

      111first_drv

      ...

编写测试程序

  示例代码如下:

  #include

  #include

  #include

  #include

  //测试

  intmain(intargc,char**argv){

   intfd;

   intval=1;

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

   if(fd<0){

    printf("cannotopen!

\n");

   }  

   write(fd,&val,4);

   return0;

  } 

  运行程序查看结果如下:

       

  [root@FriendlyARM/tmp]#./Firstdrvtest 

  -/bin/sh:

./Firstdrvtest:

Permissiondenied

  [root@FriendlyARM/tmp]#chmodu+xFirstdrvtest 

  [root@FriendlyARM/tmp]#./Firstdrvtest 

  cannotopen!

  

  创设备:

  [root@FriendlyARM/tmp]#mknod/dev/xxxc1110

  [root@FriendlyARM/tmp]#./Firstdrvtest 

  first_drv_open!

  first_drv_write!

  

  

自动创建设备文件

  示例代码如下:

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  #include

  

  

  staticstructclass*firstdrv_class;

  staticstructdevice *firstdrv_class_dev;

  

  staticintfirst_drv_open(structinode*inode,structfile*file)

  {

   printk("first_drv_open!

\n");

   return0;

  }

  

  staticssize_tfirst_drv_write(structfile*file,constchar__user*buf,size_tcount,loff_t*ppos)

  {

   printk("first_drv_write!

\n");

   return0;

  }

  

  staticstructfile_operationsfirst_drv_fops={

   .owner=THIS_MODULE,/*这是一个宏,推向编译模块时自动创建__this_module*/

   .open=first_drv_open,

   .write=first_drv_write,

  };

  /*入口函数,注册驱动徎序,早期的办法*/

  intmajor;

  intfirst_drv_init(void)

  {

   /*major设备的主设备号,name是驱动程序的名称,fops默认的是file_operations结构*/

   //设备号写0由系统自动分配

   major=register_chrdev(0,"first_drv",&first_drv_fops);

   firstdrv_class=class_create(THIS_MODULE,"firstdrv");

   //创建设备节点

   firstdrv_class_dev=device_create(firstdrv_class,firstdrv_class_dev,MKDEV(major,0),NULL,"firstdrv-%s","firstdrv");

   return0;

  }

  /*出口函数,卸载驱动*/

  voidfirst_drv_exit()

  {

   /*major和name必须和注册时的值一致*/

   unregister_chrdev(major,"first_drv");

   //删除设备节点

   //class_device_unregister(firstdrv_class_dev);

   device_destroy(major,firstdrv_class_dev);

   class_destroy(firstdrv_class);

  }

  

  /*修饰入口函数*/

  module_init(first_drv_init);

  /*修饰出口函数*/

  module_exit(first_drv_exit);

  MODULE_LICENSE("GPL");

重新装载,显示如下内容

[root@FriendlyARM/tmp]#insmodfirst_drv.ko 

first_drv:

Unknownsymbol__class_create(err0)

first_drv:

Unknownsymbolclass_destroy(err0)

first_drv:

Unknownsymboldevice_create(err0)

first_drv:

Unknownsymboldevice_destroy(err0)

insmod:

can'tinsert'first_drv.ko':

unknownsymbolinmoduleorinvalidparameter

在代码中添加

MODULE_LICENSE("GPL");

重新加载,查看已生成设备节点

[root@FriendlyARM/tmp]#ls/dev/firstdrv-firstdrv 

/dev/firstdrv-firstdrv 

 

完善点灯程序

看原理图

 GPK4-7

查看芯片手册

GPKCON00x7F008800R/WPortKConfigurationRegister00x22222222

GPKDAT0x7F008808R/WPortKDataRegisterUndefined

GPK4[19:

16] 0000=Input           0001=Output  

       0010=HostI/FDATA[4]0011=HSITXREADY 

       0100=Reserved        0101=DATA_CF[4] 

       0110=Reserved        0111=Reserved 

                                                           0010 

编写代码:

  单板的物理地址

  驱动中操作的是虚拟地址(ioremap映射)

配置引角:

GPKCON0

设置(高低电平):

GPKDAT

示例代码如上:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

staticstructclass*firstdrv_class;

staticstructdevice *firstdrv_class_dev;

volatileunsignedlong*gpkcon=NULL;

volatileunsignedlong*gpkdat=NULL;

staticintfirst_drv_open(structinode*inode,structfile*file)

{

 printk("first_drv_open!

\n");

 /*配置GPK4-7为输出*/

 /*清零*/

 *gpkcon&=~(0xFFFF);

 *gpkcon|=0x11110000;

 printk("gpkcon:

%u",gpkcon);

 return0;

}

staticssize_tfirst_drv_write(structfile*file,constchar__user*buf,size_tcount,loff_t*ppos)

{

 intval;

 copy_from_user(&val,buf,count);

 if(val==1){

  //点灯

  *gpkdat&=~((1<<4)|(1<<5)|(1<<6)|(1<<7));

  printk("ongpkdat:

%u",gpkdat);

 }else{

  //灭灯

  *gpkdat|=(1<<4)|(1<<5)|(1<<6)|(1<<7);

  printk("offgpkdat:

%u",gpkdat);

 }

 printk("first_drv_write!

\n");

 return0;

}

staticstructfile_operationsfirst_drv_fops={

 .owner=THIS_MODULE,/*这是一个宏,推向编译模块时自动创建__this_module*/

 .open=first_drv_open,

 .write=first_drv_write,

};

/*入口函数,注册驱动徎序,早期的办法*/

intmajor;

intfirst_drv_init(void)

{

 /*major设备的主设备号,name是驱动程序的名称,fops默认的是file_operations结构*/

 //设备号写0由系统自动分配

 major=register_chrdev(0,"first_drv",&first_drv_fops);

 firstdrv_class=class_create(THIS_MODULE,"firstdrv");

 //创建设备节点

 firstdrv_class_dev=device_create(firstdrv_class,firstdrv_class_dev,MKDEV(major,0),NULL,"firstdrv-%s","firstdrv");

 

 /*映射虚拟地址*/

 gpkcon=(volatileunsignedlong*)ioremap(0x7F008800,32);

 gpkdat=(volatileunsignedlong*)ioremap(0x7F008808,32);

 printk("initmethodofgpkcon:

%u,gpkdata:

%u",gpkcon,gpkdat);

 return0;

}

/*出口函数,卸载驱动*/

voidfirst_drv_exit()

{

 /*major和name必须和注册时的值一致*/

 unregister_chrdev(major,"first_drv");

 //删除设备节点

 //class_device_unregister(firstdrv_class_dev);

 device_destroy(major,firstdrv_class_dev);

 class_destroy(firstdrv_class);

 /*取消映射*/

 iounmap(gpkcon);

 iounmap(gpkdat);

}

/*修饰入口函数*/

module_init(first_drv_init);

/*修饰出口函数*/

module_exit(first_drv_exit);

MODULE_LICENSE("GPL");

重新编译,下载到开发板

装载驱动,检查是否安装成功

编写测试程序:

示例代码如下:

#include

#include

#include

#include

/**

 *firstdrvteston点灯

 *firstdrvtestoff灭灯

 **/

intmain(intargc,char**argv){

 intfd;

 intval=1;

 fd=open("/dev/firstdrv-firstdrv",O_RDWR); 

 if(fd<0){

  printf("cannotopen!

\n");

 }  

 if(argc!

=2){

  printf("Usage:

\n");

  printf("%s",argv[0]);

 }

 if(strcmp(argv[1],"on")==0){

  val=1;

 }else{

  val=0;

 }

 write(fd,&val,4);

 return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 学科竞赛

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2