点亮GT2440开发板上的led(基于IO内存实现)

来源:互联网 发布:软件销售招聘 编辑:程序博客网 时间:2024/06/05 02:13

首先的感谢这微博主:http://blog.csdn.net/jianchi88/article/details/6848035

我在这先粘下我的开发版的数据手册的led截图,毕竟涉及到硬件知识,也是为了让大家读更加容易明白:



驱动程序源码:

#include <linux/module.h> //内核模块头文件  #include <linux/moduleparam.h>  //内核模块参数头文件  #include <linux/kernel.h>  //printk头文件    #include<asm/io.h>//ioremap需要  //包含有可装载模块需要的大量符合和函数的定义;  #include <linux/init.h>  //指定初始化和清除函数;    //struct file_operactions 相关头文件  #include <linux/fs.h>  #include <asm/uaccess.h>    //struct cdev 相关头文件  #include <linux/types.h>  #include <linux/cdev.h>    //定义设备名称  #define DEVICE_NAME "led"    //定义主次设备号  static unsigned int LedMajor=0;  static unsigned int LedMinor=0;    /* 注册字符设备 */  static struct cdev *led_cdev;  static dev_t dev;  //设备号    volatile unsigned int long *gpb_con = NULL;    volatile unsigned int long *gpb_data = NULL;        static int led_ioctl(struct inode *inode, struct file *file,                        unsigned int cmd, unsigned long arg)    {                  if((cmd>1) | (cmd<0) | (arg>3) | (arg<0))                       return -EINVAL;                                   switch(cmd)             {                       case 0:                                *gpb_data|= (1<<(arg+5));  //0                            break;                       case 1:                                *gpb_data&= ~(1<<(arg+5));  //1                               break;                                                      default:                                return -EINVAL;                                            }                         return 0;    }        /*static int led_open(struct inode *inode, struct file *file)  {      printk("led_open\n");            //映射I/O内存        gpb_con = (volatile unsigned long *)ioremap(0x56000010,16); //0x56000010为GPIOB控制寄存器的物理地址        gpb_data = gpb_con+1;  //这里+1是加了4个字节,因为指针+1是以指针的长度为单位的(unsigned long *)        // 配置GPB5,6,7,8为输出      *gpb_con &= ~((1<<(5)) & (1<<(6)) & (1<<(7)) & (1<<(8)));      // 初始化为灭     *gpb_data |=(1<<5) | (1<<6) | (1<<7) | (1<<8);         printk("leaving led_open\n");      return 0;    }    *//*static int led_release(struct inode *inode,struct file *file)  {            printk("close major=%d, minor=%d\n", imajor(inode), iminor(inode));      return 0;  }    */static struct file_operations chardev_fops={      .owner = THIS_MODULE,      //.open = led_open,      //.release = led_release,      .ioctl = led_ioctl,  };      static int __init dev_init(void)  {      int result;  /*分配设备编号*/      if(LedMajor)      {          dev=MKDEV(LedMajor,LedMinor);//创建设备编号          result=register_chrdev_region(dev,1,DEVICE_NAME);      }       else       {          result=alloc_chrdev_region(&dev,LedMinor,1,DEVICE_NAME);          LedMajor=MAJOR(dev);      }      if(result<0)      {          printk(KERN_WARNING"LED: cannot get major %d \n",LedMajor);          return result;      }  /* 注册字符设备 */      led_cdev=cdev_alloc();//为struct cdev 分配空间        cdev_init(led_cdev,&chardev_fops);//初始化struct cdev            led_cdev->owner=THIS_MODULE;            result=cdev_add(led_cdev,dev,1);            if(result)          printk("<1>Error %d while register led device!\n",result);                printk("initialzed.\n");          //映射I/O内存        gpb_con = (volatile unsigned long *)ioremap(0x56000010,16); //0x56000010为GPIOB控制寄存器的物理地址        gpb_data = gpb_con+1;  //这里+1是加了4个字节,因为指针+1是以指针的长度为单位的(unsigned long *)        // 配置GPB5,6,7,8为输出      *gpb_con &= ~((1<<(5)) & (1<<(6)) & (1<<(7)) & (1<<(8)));      // 初始化为灭     *gpb_data |=(1<<5) | (1<<6) | (1<<7) | (1<<8);       return 0;  }    static void __exit dev_exit(void)  {      unregister_chrdev_region(MKDEV(LedMajor,LedMinor),1);      cdev_del(led_cdev);  }    module_init(dev_init);  module_exit(dev_exit);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Bai");  

测试程序就补贴出来了,我想大家都不会感到有难度。

运行结果:



原创粉丝点击