arm驱动程序——点亮led(韦东山的视频总结及针对linux-2.6.30)

上面两节只是驱动程序的框架,下面就是点亮led了。

目的:点亮led

步骤:

    1.写框架。

    2.完善硬件相关操作。

a.看原理图

b.看2440手册

c.写代码

下面是所用到的函数及结构:

/*由于用户空间中的指针,数据不能直接使用要用下面两个函数进行操作*/

/* 从用户空间得到数据,to:内核空间;from:用户空间;n:复制的数据长度*/

copy_from_user(void *to, const void __user *from, unsigned long n)

/* 传数据到用户空间,to:内核空间;from:用户空间;n:复制的数据长度*/

copy_to_user(void __user *to, const void *from, unsigned long n)


/*地址映射,把物理地址转化为虚拟地址。

 *cookie:物理地址的首地址,size:映射的大小,字节的大小

 */

ioremap(cookie,size)

/*注销虚拟地址的映射 cookie:物理地址的首地址*/

iounmap(cookie)

驱动程序: 

 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/device.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <linux/poll.h>
 
 static int major;

 /*定义class结构体*/
 static struct class *first_led_class;

 /*定义一个class_device结构体*/

 /*此定义也是可以的:static struct class_device *first_led_device;*/
 static struct class_device *first_led_device;

 
 volatile unsigned long *GPBCON = NULL;
 volatile unsigned long *GPBDAT = NULL;
 
 static int first_led_open (struct inode *inode, struct file *file)
 {
    *GPBCON &= ~((3<<10)|(3<<12)|(3<<14)|(3<<16));
    *GPBCON |= (1<<10)|(1<<12)|(1<<14)|(1<<16);
    return 0;
 }
 static ssize_t first_led_write(struct file *file, 

                  const char __user *user_buffer, size_t count, loff_t * loff)
 {
    int ret;

    /*从用户空间得到数据*/
    copy_from_user(&ret,user_buffer,count);
    if(0 == ret)

         /*点亮led*/
        *GPBDAT &=  ~((1<<5)|(1<<6)|(1<<7)|(1<<8));
    else

        /*熄灭led*/

        *GPBDAT |= ((1<<5)|(1<<6)|(1<<7)|(1<<8));
    return count;
 }

   /*定义一个file_operations结构体*/
 static struct file_operations first_led_fops = {
     .owner = THIS_MODULE,
     .open  = first_led_open,
     .write = first_led_write,
 };

   /*入口函数*/
 static int first_led_init(void){

        /*注册,主设备的位置为0,代表自动分配主设备号*/
       major = register_chrdev(0,"first_dev_led",&first_led_fops);

        /*创建一个类,可在/sys/class目录下查看到*/
  first_led_class = class_create(THIS_MODULE,"fisrst_led_class");

        /*类下创建一个设备,可在/sys/class/fisrst_led_class目录下查看到*/
  first_led_device = device_create(first_led_class,NULL,
                                MKDEV(major,0),NULL,"first_led");

      /*地址映射*/
      GPBCON = (volatile int *)ioremap(0x56000010,16);
      GPBDAT = GPBCON + 1;

      return 0; 
 }
 static void first_led_exit(void){

        /*注销*/
       unregister_chrdev(major,"first_dev_led");

        /*注销设备*/
       device_unregister(first_led_device);

        /*销毁类*/
       class_destroy(first_led_class);

        /*注销虚拟地址的映射*/
       iounmap(GPBCON);
 }
 MODULE_LICENSE("GPL");
 module_init(first_led_init);
 module_exit(first_led_exit);


测试程序:

//usage< file on | off >

#include<unistd.h>

#include<fcntl.h>
#include<stdio.h>
int main(int argc,char **argv){
   int fd;
   int val=1;
   fd=open("/dev/first_led",O_RDWR);
   if(fd<0)
       printf("can't open!\n");
   if(argc != 2)

   {
        printf("usage:\n");
        printf("first_devdritest <on|off>\n");
        return 0;
   }
   if(strcmp(argv[1],"on")==0)
        val=0;
   else
        val=1;
   write(fd,&val,4);
   return 0;
}


下面就是测试了。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值