当前位置:网站首页>i. Mx6ull driver development | 24 - platform based driver model lights LED

i. Mx6ull driver development | 24 - platform based driver model lights LED

2022-07-04 22:04:00 Mculover666

One 、 Write basic device driver module

Write driver module source code :

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

static int __init platform_led_init(void)
{
    
    return 0;
}

static void __exit platform_led_exit(void)
{
    

}

module_init(platform_led_init);
module_exit(platform_led_exit);

MODULE_AUTHOR("Mculover666");
MODULE_LICENSE("GPL");

To write Makefile:

KERNEL_DIR = /home/mculover666/develop/imx6ull/linux-imx6ull
obj-m := platform_led.o

build: kernel_module

kernel_module:
	$(MAKE)	-C $(KERNEL_DIR) M=$(CURDIR) modules

clean:
	$(MAKE)	-C $(KERNEL_DIR) M=$(CURDIR) clean

compile :

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make

Two 、 To write platform Drive frame

add to platform Drive frame :

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

static int led_probe(struct platform_device *dev)
{
    
    return 0;
}

static int led_remove(struct platform_device *dev)
{
    
    return 0;
}

/** * @brief  Device tree matching list  */
static const struct of_device_id plat_led_of_match[] = {
    
    {
     .compatible = "atk,plat_led" },
    {
     },
};

/** * @brief  Tradition id Method matching list  */
static const struct platform_device_id plat_led_id[] = {
    
    {
     "atk,plat_led", 0 },
    {
     },
};

static struct platform_driver led_driver = {
    
    .probe = led_probe,
    .remove = led_remove,
    .driver = {
    
        .name = "platform_led",
        .owner = THIS_MODULE,
        .of_match_table = plat_led_of_match,
    },
    .id_table = plat_led_id,
};

static int __init platform_led_init(void)
{
    
    int ret;

    ret = platform_driver_register(&led_driver);
    if (ret < 0) {
    
        printk("platform_driver_register fail!\n");
        return -1;
    }
    return 0;
}

static void __exit platform_led_exit(void)
{
    
    platform_driver_unregister(&led_driver);
}

module_init(platform_led_init);
module_exit(platform_led_exit);

MODULE_AUTHOR("Mculover666");
MODULE_LICENSE("GPL");

3、 ... and 、 Write character device driver

#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>

dev_t led_dts_dev;
struct cdev *led_dts_cdev;
struct class *led_dts_class;
struct device *led_dts_device0;

static int led_dts_open(struct inode *inode, struct file *fp)
{
    
    return 0;
}

static int led_dts_read(struct file *fp, char __user *buf, size_t size, loff_t *off)
{
    
    return 0;
}

static int led_dts_write(struct file *fp, const char __user *buf, size_t size, loff_t *off)
{
    
    return 0;
}

static int led_dts_release(struct inode *inode, struct file *fp)
{
    
    return 0;
}

static struct file_operations led_dts_fops = {
    
    .owner = THIS_MODULE,
    .open = led_dts_open,
    .read = led_dts_read,
    .write = led_dts_write,
    .release = led_dts_release,
};

static int led_probe(struct platform_device *dev)
{
    
    int ret;

    printk("led probe called!\n");

    // Distribute cdev Device number 
    ret = alloc_chrdev_region(&led_dts_dev, 0, 1, "led_dts");
    if (ret != 0) {
    
        printk("alloc_chrdev_region fail!");
        return -1;
    }

    // initialization cdev
    led_dts_cdev = cdev_alloc();
    if (!led_dts_cdev) {
    
        printk("cdev_alloc fail!");
        return -1;
    }

    // Set up fop Operation function 
    led_dts_cdev->owner = THIS_MODULE;
    led_dts_cdev->ops = &led_dts_fops;

    // register cdev
    cdev_add(led_dts_cdev, led_dts_dev, 1);

    //  Create device classes 
    led_dts_class = class_create(THIS_MODULE, "led_dts_class");
    if (!led_dts_class) {
    
        printk("class_create fail!");
        return -1;
    }

    // Create device nodes 
    led_dts_device0 = device_create(led_dts_class, NULL, led_dts_dev, NULL, "led0");
    if (IS_ERR(led_dts_device0)) {
    
        printk("device_create led_dts_device0 fail!");
        return -1;
    }

    return 0;
}

static int led_remove(struct platform_device *dev)
{
    
    printk("led remove called!\n");

    //  Remove the device from the kernel 
    cdev_del(led_dts_cdev);

    //  Release the device number 
    unregister_chrdev_region(led_dts_dev, 1);

    //  Delete device node 
    device_destroy(led_dts_class, led_dts_dev);

    //  Delete device class 
    class_destroy(led_dts_class);

    return 0;
}

Four 、 To write LED drive

and i.MX6ULL Drive development | 08 - be based on pinctrl Subsystem and gpio Subsystem on LED equally .

5、 ... and 、 test result

1. Load driver module


see platform Whether the bus is registered :

ls /sys/bus/platform/drivers


Check whether the bus device is registered ( Because there is a description of the device tree node ):

ls /sys/bus/platform/devices/


Be careful , When the driver loads , The kernel will match the corresponding device , Therefore, the compatibility described in the device tree node should be consistent with that in the driver :

2. led test

View device nodes :

ls /dev/


Run the test program , You can see led flashing :

原网站

版权声明
本文为[Mculover666]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/185/202207042133541452.html