linux+驱动读写寄存器,驱动读写寄存器

#include

#include

#include

#include

#include

#include

#include

#include "reg.h"

static void *vbase;

static unsigned int vsize;

static void reg_unmap(void)

{

if(vbase){

iounmap(vbase);

}

vbase = NULL;

}

static long reg_set_map(struct file *file, unsigned long arg)

{

struct reg_base base;

if(copy_from_user(&base, (void*)arg, sizeof(base))){

return -EFAULT;

}

reg_unmap();

vbase = ioremap(base.base, base.size);

if(NULL == vbase){

return -EINVAL;

}

vsize = base.size;

return 0;

}

static long reg_read_value(struct file *file, unsigned long arg)

{

struct reg_value value;

if(copy_from_user(&value, (void*)arg, sizeof(value))){

return -EFAULT;

}

if(NULL == vbase || value.addr > vsize - 4){

return -EINVAL;

}

value.value = readl(vbase + value.addr);

if(copy_to_user((void*)arg, &value, sizeof(value))){

return -EFAULT;

}

return 0;

}

static long reg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

long ret = -ENOIOCTLCMD;

switch(cmd)

{

case REG_CMD_BASE:

ret = reg_set_map(file, arg);

break;

case REG_CMD_VALUE:

ret = reg_read_value(file, arg);

break;

default:

break;

}

return ret;

}

static struct file_operations fops =

{

.unlocked_ioctl = reg_ioctl,

};

static struct miscdevice reg_dev =

{

.name = "reg",

.fops = &fops,

.minor = MISC_DYNAMIC_MINOR,

};

static int __init reg_init(void)

{

if(misc_register(&reg_dev)){

printk(KERN_ERR "Failed to register reg\n");

return -1;

}

printk(KERN_INFO "Success to register reg\n");

return 0;

}

static void __exit reg_exit(void)

{

misc_deregister(&reg_dev);

reg_unmap();

printk(KERN_INFO "Success to remove reg\n");

}

module_init(reg_init);

module_exit(reg_exit);

MODULE_LICENSE("GPL v2");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值