linux 字符设备驱动实践

chardev.c

#include <linux/module.h>  //模块化的相关头文件
#include <linux/init.h>   //初始化的相关头文件
#include <linux/fs.h>     //文件操作集合
#include <linux/uaccess.h>//copy_to_user的头文件
#include <linux/kdev_t.h> //MKDEV所需要的头文件
#include <linux/cdev.h>   //cdev结构体以及cdev-init
#include <linux/device.h> //class_create,device_create
#include <linux/io.h>            //寄存器

#define GPIO5_DR 0x20AC000        //蜂鸣器Io物
unsigned int* gpio5_1;            //虚拟地址
#define SIZEBEY  4                //寄存器字节

#define GPIO3_DR 0x209C000        //LED2  Io物理地址
unsigned int* gpio3_3;            //虚拟地址


struct cdev class16_cdev;   //cdev结构体用来表示字符设备
struct class * class16;    //class类
struct device * class16device; //device 设备结构体

dev_t char_dev;

ssize_t chartest_read(struct file *file, char __user *ubuf, size_t size, loff_t *loff_t){
    char kbuf[]="Hello World!";
    if(copy_to_user(ubuf, kbuf, strlen(kbuf)) != 0)  //将内核数据复制到用户空间               kbuf 的数据复制到 ubuf 里
        {
        printk("chartest_read error\n");
        return 0;
        }
    printk("chartest_read success!\n");
    return 0;
}

ssize_t chartest_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff_t){
    char kbuf[64]={0};
    if(copy_from_user(kbuf,ubuf,size)!=0){    //将用户数据复制到内核空间               ubuf 的数据复制到 kbuf 里
        printk("chartest_write error\n");
        return 0;
    }

    if( kbuf[0] == 1 ){
        *gpio5_1 |= (1 << 1);
    }else if( kbuf[0] == 0 ){
        *gpio5_1 &= ~(1 << 1);
    }
    
    printk("chartest_write success\n");
    printk("chartest_write kbuf is %s",kbuf);
    return 0;
}

int chartest_open (struct inode *inode, struct file *file){
    printk("chartest_open\n");
    return 0;

}

int chartest_release (struct inode *inode, struct file *file){
    printk("chartest_release\n");
    return 0;
}

struct file_operations chartest_fops={
    .owner   =THIS_MODULE,
    .open    =chartest_open,
    .release =chartest_release,
    .read    =chartest_read,
    .write   =chartest_write,
};

static int chartest_init(void)
    {
    int ret;
    
    /*
    /*******************静态注册设备号***********************/
    char_dev = MKDEV(100,10);
    ret = register_chrdev_region(char_dev, 1, "class16");
    if(ret!=0)
        {
        printk("register_chrdev_region error\n");
        return 0;
        }*/

    /*******************动态注册设备号***********************/
    
    ret = alloc_chrdev_region(char_dev,0,1,class16);
    
    if( ret != 0 ){
    printk("alloc_chrdev_region: register_chrdev_region error!!\n");
    return ret;
    }
    
    printk("alloc_chrdev_region: register_chrdev_region ok!!\n");
    printk("MAJOR %d\n\n",MAJOR(char_dev));
    printk("MINOR %d\n\n",MINOR(char_dev));
    


    /*内存映射*/
    gpio5_1 = ioremap(GPIO5_DR, SIZEBEY);
    if( gpio5_1 == NULL ){
        printk("ioremap error!!\n");
        return 0;
    }
    /*内存映射*/
    gpio3_3 = ioremap(GPIO3_DR, SIZEBEY);
    if( gpio3_3 == NULL ){
        printk("ioremap error3!!\n");
        return 0;
    }

    
    //初始化cdev
    class16_cdev.owner=THIS_MODULE;
    cdev_init(&class16_cdev,&chartest_fops);
    //向内核注册设备
    cdev_add(&class16_cdev,char_dev,1);
    //创建类,在sys/class下
    class16=class_create(THIS_MODULE,"LCDchar");
    //自动创建设备,在/dev下生成设备节点
    class16device=device_create(class16,NULL,char_dev,NULL,"LCDdevice");
    printk("chartest_init!!!\n");
    return 0;
    }

static void chartest_exit(void)
{
    iounmap(gpio5_1);
    iounmap(gpio3_3);
    unregister_chrdev_region(char_dev,1);  //注销设备号
    cdev_del(&class16_cdev);   //删除设备
    device_destroy(class16, char_dev);  //注销设备
    class_destroy(class16);    //删除类
    printk("bye!!!\n");
}

module_init(chartest_init);
module_exit(chartest_exit);
MODULE_LICENSE("GPL");


APP.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 fd;
    char buf[64] = {0};
    char writebuf[64]={0};
    fd = open("/dev/LCDdevice",O_RDWR);
    if(fd < 0)
    {
        perror("open error\n");
        return fd;
    }
    read(fd,buf,sizeof(buf));
    printf("read buf is %s\n",buf);

    writebuf[0] = atoi(argv[1]);
    write(fd,writebuf,sizeof(writebuf));
    close(fd);
    return 0;
}

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值