i.MX6ULL驱动开发 | 24 - 基于platform平台驱动模型点亮LED

Posted Mculover666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了i.MX6ULL驱动开发 | 24 - 基于platform平台驱动模型点亮LED相关的知识,希望对你有一定的参考价值。

一、编写基本设备驱动模块

编写驱动模块源码:

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

编写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

编译:

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

二、编写platform驱动框架

添加platform驱动框架:

#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   设备树匹配列表
*/
static const struct of_device_id plat_led_of_match[] = 
     .compatible = "atk,plat_led" ,
     ,
;

/**
 * @brief   传统id方式匹配列表
*/
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");

三、编写字符设备驱动

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

    //分配cdev设备号
    ret = alloc_chrdev_region(&led_dts_dev, 0, 1, "led_dts");
    if (ret != 0) 
        printk("alloc_chrdev_region fail!");
        return -1;
    

    //初始化cdev
    led_dts_cdev = cdev_alloc();
    if (!led_dts_cdev) 
        printk("cdev_alloc fail!");
        return -1;
    

    //设置fop操作函数
    led_dts_cdev->owner = THIS_MODULE;
    led_dts_cdev->ops = &led_dts_fops;

    //注册cdev
    cdev_add(led_dts_cdev, led_dts_dev, 1);

    // 创建设备类
    led_dts_class = class_create(THIS_MODULE, "led_dts_class");
    if (!led_dts_class) 
        printk("class_create fail!");
        return -1;
    

    //创建设备节点
    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");

    // 将设备从内核删除
    cdev_del(led_dts_cdev);

    // 释放设备号
    unregister_chrdev_region(led_dts_dev, 1);

    // 删除设备节点
    device_destroy(led_dts_class, led_dts_dev);

    // 删除设备类
    class_destroy(led_dts_class);

    return 0;

四、编写LED驱动

i.MX6ULL驱动开发 | 08 -基于pinctrl子系统和gpio子系统点亮LED一样。

五、测试结果

1. 加载驱动模块


查看platform总线是否注册:

ls /sys/bus/platform/drivers


查看总线设备是否注册(因为有设备树节点的描述):

ls /sys/bus/platform/devices/


注意,这里驱动加载的时候,内核会去匹配对应的设备,所以设备树节点描述的兼容性要与驱动中的兼容性一致:

2. led测试

查看设备节点:

ls /dev/


运行测试程序,可以看到led闪烁:

以上是关于i.MX6ULL驱动开发 | 24 - 基于platform平台驱动模型点亮LED的主要内容,如果未能解决你的问题,请参考以下文章

i.MX6ULL驱动开发 | 08 -基于pinctrl子系统和gpio子系统点亮LED

i.MX6ULL驱动开发 | 09 -基于Linux自带的LED驱动点亮LED

i.MX6ULL驱动开发 | 34 - 基于SPI框架驱动spi lcd(st7789)

i.MX6ULL驱动开发 | 03-基于字符设备驱动框架点亮LED

i.MX6ULL驱动开发 | 34 - 基于SPI框架驱动spi lcd(st7789)

i.MX6ULL驱动开发 | 16 - 基于 UART 驱动框架发送/接收串口数据