首页 > 其他分享 >韦东山2440-学习笔记-platform

韦东山2440-学习笔记-platform

时间:2023-03-01 15:12:36浏览次数:51  
标签:2440 led 东山 dev platform static device include

1. 简介

platform是 设备驱动总线模型

2. 示例

#include <linux/platform_device.h>
#include <linux/module.h>

static struct platform_device *led_dev;

static struct resource led_dev_resource[] = {
        {
                // gpfcon gpfdat
                .start  = 0x56000050,
                .end    = 0x56000050 + 8,
                .flags  = IORESOURCE_MEM,
        },
        {
                // pin
                .start  = 5,
                .end    = 5,
                .flags  = IORESOURCE_IRQ,
        }
};

static int __init
led_dev_init(void)
{
        led_dev = platform_device_alloc("led", -1);

        platform_device_add_resources(led_dev,
                        led_dev_resource,
                        sizeof(led_dev_resource)/sizeof(*led_dev_resource));

        platform_device_add(led_dev);

        return 0;
}


static void __exit
led_dev_exit(void)
{
        platform_device_unregister(led_dev);
        platform_device_put(led_dev);
}

module_init(led_dev_init);
module_exit(led_dev_exit);

MODULE_LICENSE("GPL");
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/bootmem.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/module.h>

static unsigned int *gpfcon;
static unsigned int *gpfdat;
static unsigned int pin;
static struct class *led_class;
static dev_t dev;

static ssize_t
led_write (struct file *fp, const char __user *user,
                size_t sz, loff_t *offset)
{
        unsigned int val, ret;

        ret = copy_from_user(&val, user, sz);
        if (val == 1)
                *gpfdat &= ~(1 << pin);
        else
                *gpfdat |= (1 << pin);

        return 0;
}

static int
led_open (struct inode *inode, struct file *fp)
{
        printk("led open\n");
        *gpfcon &= ~(0x3 << 2 * pin);
        *gpfcon |= (1 << 2*pin);

        return 0;
}

static const struct file_operations led_ops = {
        .owner = THIS_MODULE,
        .open = led_open,
        .write = led_write,
};

// 当总线的match匹配时,调用
static int
led_drv_probe(struct platform_device *pdev)
{
        struct resource *res;
        struct cdev *cdev;

        printk("led match.\n");

        // 获得硬件资源
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        gpfcon = ioremap(res->start, res->end - res->start);
        gpfdat = gpfcon + 1;

        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        pin = res->start;

        // cdev
        alloc_chrdev_region(&dev, 0, 1, "led");
        cdev = cdev_alloc();
        cdev->owner = THIS_MODULE;
        cdev->ops = &led_ops;
        cdev_add(cdev, dev, 1);
        printk("major : %d\n", MAJOR(dev));

        // 自动创建设备节点
        led_class = class_create(THIS_MODULE, "led");

        device_create(led_class, NULL, dev, "led%d", pin);

        return 0;
}

// 当已经匹配的 dev 或 drv  调用 platform_xxx_unregister 时,调用此函数
static int
led_drv_remove(struct platform_device *pdev)
{
        printk("led remove.\n");

        device_destroy(led_class, dev);
        class_destroy(led_class);
        unregister_chrdev(MAJOR(dev), "led"); // 释放设备号 和 cdev
        iounmap(gpfcon);

        return 0;
}

static struct platform_driver led_drv = {
        .probe  = led_drv_probe,
        .remove = led_drv_remove,
        .driver = {
                .name   = "led",
        },
};

static int __init
led_init(void)
{
        platform_driver_register(&led_drv);
        return 0;
}

static void __exit
led_exit(void)
{
        platform_driver_unregister(&led_drv);
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");

标签:2440,led,东山,dev,platform,static,device,include
From: https://www.cnblogs.com/yangxinrui/p/17168212.html

相关文章