#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
//设备资源(设备描述)
static struct resource led_resources[]={
[0]={
.start = 0x0,
.end = 0xA,
.flags = IORESOURCE_MEM
},
[1]={
.start = 0xB,
.end = 0xF,
.flags = IORESOURCE_IRQ
},
[2]={
.start = 0xAA,
.end = 0xAF,
.flags = IORESOURCE_IRQ
}
};
static void led_device_release(struct device *dev)
{
printk("led_device_release\n");
}
static struct platform_device led_device = {
.name = "led_device",
.id = -1,
.resource = led_resources,
.dev = {
.release = led_device_release,
},
};
static int led_module_init(void)
{
platform_device_register(&led_device);
printk("hello world\n");
return 0;
}
static void led_module_exit(void)
{
platform_device_unregister(&led_device);
printk("goodbye world\n");
}
module_init(led_module_init);
module_exit(led_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("WYL");
MODULE_DESCRIPTION("led device");
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <linux/uaccess.h>
dev_t dev_no; // 设备号
struct cdev cdev_test; // 字符设备结构体
struct class *class_test; // 类
struct device *device_test; // 设备
static int test_open(struct inode *inode,struct file *file)
{
printk("open\n");
return 0;
}
static ssize_t test_read(struct file *file,char __user *buf, size_t size,loff_t *off){
printk("read\n");
return 0;
}
static ssize_t test_write(struct file *file,const char __user *buf, size_t size,loff_t *off){
printk("write\n");
*off += size;
return size;
}
static int test_release(struct inode *inode,struct file *file)
{
printk("release\n");
return 0;
}
struct file_operations fops = {
.owner = THIS_MODULE,
.open = test_open,
.read = test_read,
.write = test_write,
.release = test_release,
};
int my_probe(struct platform_device * dev){
int ret;
ret = alloc_chrdev_region(&dev_no, 0, 1, "led_device");
if (ret<0) {
printk("alloc_chrdev_region failed\n");
return ret;
}
printk("major:%d, minor:%d\n", MAJOR(dev_no), MINOR(dev_no));
cdev_init(&cdev_test, &fops);
cdev_add(&cdev_test, dev_no, 1);
class_test = class_create(THIS_MODULE, "led_device"); //创建类
device_test = device_create(class_test, NULL, dev_no, NULL, "led_device");
printk("my_probe"); //device和driver匹配成功时调用
return 0;
}
int my_remove(struct platform_device * dev){
printk("my_remove"); //移除设备或这个驱动被rmmod时调用
return 0;
};
struct platform_driver driver_test= {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "led_device", //与device设备描述名字一致!!!
.owner = THIS_MODULE,
// const struct platform_device_id *id_table; //非必须,匹配时优先级最高比上面的name要高
}
};
static int platform_driver_init(void)
{
platform_driver_register(&driver_test);
printk("platform_driver_init");
return 0;
}
static void platform_driver_exit(void)
{
// 1. 先销毁设备节点
device_destroy(class_test, dev_no);
// 2. 销毁类 (原代码缺失此步,必须添加)
class_destroy(class_test);
// 3. 删除字符设备
cdev_del(&cdev_test);
// 4. 最后注销设备号
unregister_chrdev_region(dev_no, 1);
platform_driver_unregister(&driver_test);
printk("platform_driver_exit");
}
module_init(platform_driver_init);
module_exit(platform_driver_exit);
// 模块许可证声明,必须是 GPL 兼容的许可证才能加载到内核中
MODULE_LICENSE("GPL");
// 模块作者信息
MODULE_AUTHOR("wyl");
// 模块描述
MODULE_DESCRIPTION("A simple Hello World Linux Driver");