字符型驱动程序的编写

https://img-blog.csdn.net/20130911223403218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTkyMDIzNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center[插入]

图1.   read 函数的整个过程


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <asm/io.h>

dev_t devid;
struct cdev dev;
struct class *cls;
struct device *device;
volatile unsigned int *gpmcon;
volatile unsigned int *gpmdat;


ssize_t led_read(struct file *file, char __user *user, size_t size, loff_t *offset)
{
//LED ON
*gpmdat &= ~0xf;
return 0;
}


ssize_t led_write(struct file *file, const char __user *user, size_t size, loff_t *offset)
{
//LED OFF
*gpmdat |= 0xf;
return 0;
}

//驱动需要实现的操作函数。
struct file_operations ops = {
.read = led_read,
.write = led_write,
};


int __init led_init(void)
{
int ret;


//1.动态申请主次设备号,通过&devid返回。
ret = alloc_chrdev_region(&devid, 0, 1, "led_6410");
if(ret)
{
printk("alloc_chrdev_region failed %d\n", ret);
goto err_alloc;
}

//2.初始化cdev 结构体,关联cdev和file_operations 初始化kObject结构
cdev_init(&dev, &ops);


//3。将cdev 结构注册到系统中
ret = cdev_add(&dev, devid, 1);
if(ret)
{
printk("cdev_add failed %d\n", ret);
goto err_add;
}


//4。创建管理设备的类(/dev/class/led_class)

cls = class_create(THIS_MODULE, "led_class");

if(IS_ERR(cls))
{
printk("class_create failed %d\n", (int)cls);
goto err_cls;
}


//5。创建设备(并不是在"/dev / "下面创建设备文件) 而是将其注册到SYS文件系统中。

device = device_create(cls, NULL, devid, NULL, "led%d", 0);
if(IS_ERR(device))
{
printk("device_create failed %d\n", (int)device);
goto err_device;
}


//6.ioremap 标志硬件初始化的开始

// ioremap 将物理地址映射到虚拟地址。

gpmcon = ioremap(0x7f008820, 4);
*gpmcon = 0x1111;
gpmdat = ioremap(0x7f008824, 4);


return 0;
err_device:
class_destroy(cls);
err_cls:
cdev_del(&dev);
err_add:
unregister_chrdev_region(devid, 1);
err_alloc:
return ret;
}


void __exit led_exit(void)
{
iounmap(gpmcon);
iounmap(gpmdat);
device_destroy(cls, devid);
class_destroy(cls);
cdev_del(&dev);
unregister_chrdev_region(devid, 1);
}


module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值