• 正文
    • 示例源码
    • 编译
    • 修改设备树
    • 测试
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard ELF 1板卡-platform总线驱动简单示例

04/01 14:45
202
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

例程代码路径:ELF 1开发板资料包3-例程源码3-2 驱动例程源码6_platformplatform

示例源码

#include <linux/init.h>

#include <linux/module.h>

#include <linux/platform_device.h>

static int my_platform_probe(struct platform_device *pdev)

{

printk(KERN_INFO "my_platform_probe: Platform device probedn");

return 0;

}

static int my_platform_remove(struct platform_device *pdev)

{

printk(KERN_INFO "my_platform_remove: Platform device removedn");

return 0;

}

static const struct of_device_id of_platform_match[] = {

{ .compatible = "platform", },

{},

};

static struct platform_driver my_platform_driver = {

.driver = {

.name = "my_platform_driver",

.owner = THIS_MODULE,

.of_match_table = of_platform_match,

},

.probe = my_platform_probe,

.remove = my_platform_remove,

};

module_platform_driver(my_platform_driver);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Your Name");

MODULE_DESCRIPTION("Platform Driver Example");

上述示例定义了一个名为 "my_platform_driver" 的平台驱动程序。驱动程序中的 my_platform_probe() 函数是探测函数,my_platform_remove() 函数是移除函数。还定义了一个platform_driver类型的结构体,结构体定义如下:

struct platform_driver {

int (*probe)(struct platform_device *);

int (*remove)(struct platform_device *);

void (*shutdown)(struct platform_device *);

int (*suspend)(struct platform_device *, pm_message_t);

int (*resume)(struct platform_device *);

struct device_driver driver;

const struct platform_device_id *id_table;

bool prevent_deferred_probe;

};

定义说明:

(一)probe:驱动探测函数指针,当设备与驱动匹配时调用。它接收一个指向structplatform_device的指针作为参数,返回一个整数类型的值。

(二)remove:驱动移除函数指针,当设备被移除时调用。它接收一个指向structplatform_device的指针作为参数,返回一个整数类型的值。

(三)shutdown:关机回调函数指针,当系统关机时调用。它接收一个指向struct platform_device的指针作为参数,无返回值。

(四)suspend:挂起回调函数指针,当系统进入挂起状态时调用。它接收一个指向struct platform_device的指针和pm_message_t类型的参数作为输入,返回一个整数类型的值。

(五)resume:恢复回调函数指针,当系统从挂起状态恢复时调用。它接收一个指向struct platform_device的指针作为参数,返回一个整数类型的值。

(六)driver:包含了驱动的名称、拥有者等信息的 struct device_driver 结构体。

(七)id_table:一个指向平台设备ID表的指针,用于与设备匹配。它可以为空,或者指向一个以NULL结尾的数组。

(八)prevent_deferred_probe:一个布尔值,用于指示是否禁止推迟的探测。如果设置为true,则在设备匹配时不会推迟探测过程。

通过使用module_platform_driver宏,我们可以将驱动程序的注册和注销过程简化为一行代码。宏会自动为驱动程序注册和注销函数,并处理必要的初始化和清理工作。

需要注意的是,驱动程序中的probe和remove回调函数必须与平台驱动程序的结构体字段对应,以正确地处理设备的探测和移除。

of_platform_match[]数组中定义了设备兼容性匹配项,当内核在设备初始化过程中加载驱动时,会遍历设备树中的设备节点,并将每个设备节点的compatible属性与驱动中的兼容属性进行匹配。只有当匹配成功时,才会执行相应的probe函数。

编译

复制上一节驱动中的Makefile文件,将其中的myirq_key.o修改为platform.o,效果如下:

. /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

elf@ubuntu:~/work/test/06_platform/platform$ make

将编译生成的platform.ko模块拷贝到开发板中

修改设备树

在设备树根节点下添加设备,否则无法进行匹配。打开arch/arm/boot/dts/imx6ull-elf1-emmc.dts添加如下内容:

my_device {

compatible = "platform";

};

添加后效果如下:

编译设备树,单独替换设备树并重启。

测试

root@ELF1:~# insmod platform.ko

my_platform_probe: Platform device probed

root@ELF1:~# rmmod platform.ko

my_platform_remove: Platform device removed

可以看到在驱动加载时,进入到了probe函数,在驱动卸载时进入到了remove函数。从上面示例中可以了解到使用 module_platform_driver 宏可以大大简化平台驱动程序的编写过程,并提高代码的可读性和可维护性。

相关推荐