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");