早期字符设备注册

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了早期字符设备注册相关的知识,希望对你有一定的参考价值。

led驱动

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/io.h>

static unsigned int led_major;

//根据自己硬件写led驱动

#define GPM4_DAT_PHYADDR 0X110002E4
#define GPM4_CON_PHYADDR 0X110002E0

typedef struct GPIO{

  volatile unsigned long gpm4con;
  volatile unsigned long gpm4dat;

}GPIO_t ,*GP;
static GPIO_t *GPM4=NULL;

// 7 编写文件操作函数
static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t *offsets)
{
  unsigned char ledflag[2]={0};
//接收函数// 8 接收上层数据
  unsigned long ret = copy_from_user(ledflag,buf,count);

  printk(KERN_WARNING "driver ledflag :%d",ledflag[0]);
  printk(KERN_WARNING "driver ledflag :%d\n",ledflag[1]);

  if(ledflag[1]==1)
  {
    if (ledflag[0]==1)
      GPM4->gpm4dat &=~(1<<0);
    else if (ledflag[0]==2)
      GPM4->gpm4dat &=~(1<<1);
    else if (ledflag[0]==3)
      GPM4->gpm4dat &=~(1<<2);
    else if (ledflag[0]==4)
      GPM4->gpm4dat &=~(1<<3);
  }
  else
  {
    if (ledflag[0]==1)
      GPM4->gpm4dat |=(1<<0);
    else if (ledflag[0]==2)
      GPM4->gpm4dat |=(1<<1);
    else if (ledflag[0]==3)
      GPM4->gpm4dat |=(1<<2);
    else if (ledflag[0]==4)
      GPM4->gpm4dat |=(1<<3);
  }




  return ret;
}


// 4 构造file_operation文件操作集合
// 6 填充文件操作集合

struct file_operations led_fops =
{
  .owner = THIS_MODULE,

  .write = led_write,

};


// 2 编写驱动加载卸载函数
static int __init led_drv_init(void)
{

// 3 早期字符设备注册
// 参数1:主设备号 >0 静态注册 以写入的设备号注册
// =0 动态注册 自动分配一个设备号
// 参数2:名称 辅助识别
// 参数3:文件操作集合 驱动支持的上层操作接口
// 返回:静态注册 成功返回0 失败返回错误
// 动态注册 成功返回分配的主设备号

  led_major= register_chrdev(0,"leddrv",&led_fops);

  printk("led insmod....\n");

 

  GPM4 = ioremap(GPM4_CON_PHYADDR, 8);

//led初始化

  GPM4->gpm4con |=0X1111<<0;
  GPM4->gpm4dat |=0XF<<0;
  return 0;

}

 

 

static void __exit led_drv_exit(void)
{

  unregister_chrdev(led_major,"leddrv");

// 9 取消硬件映射
  iounmap(GPM4);

  printk("led rmmod....\n");

}


//指点加载程序入口
module_init(led_drv_init);
module_exit(led_drv_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("qw");

 

上层应用ledapp.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
  int led_fd;
  unsigned char ledflag[2]={0};

if(argc !=3)
{
  printf("Use: %s </dev/led> <11/10/21/20/31/30/41/40>\n",argv[0]);
}

led_fd = open(argv[1],O_WRONLY);

  ledflag[0] = argv[2][0]-48;
  ledflag[1] = argv[2][1]-48;
  write(led_fd,ledflag,2);


}

 

以上是关于早期字符设备注册的主要内容,如果未能解决你的问题,请参考以下文章

字符设备集中编程模型

Linux-标准字符设备

Linux-标准字符设备

register_chrdev_region/alloc_chrdev_region和cdev注册字符设备驱动

字符设备注册/注销

注册字符类设备-11