当前位置:网站首页>i.MX6ULL驱动开发 | 24 - 基于platform平台驱动模型点亮LED
i.MX6ULL驱动开发 | 24 - 基于platform平台驱动模型点亮LED
2022-07-04 21:34:00 【Mculover666】
一、编写基本设备驱动模块
编写驱动模块源码:
#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闪烁:
边栏推荐
- Redis has three methods for checking big keys, which are necessary for optimization
- Relational database
- 输入的查询SQL语句,是如何执行的?
- How to remove the black dot in front of the title in word document
- 使用 BlocConsumer 同时构建响应式组件和监听状态
- How to implement Devops with automatic tools
- Flink1.13 SQL basic syntax (I) DDL, DML
- Which securities company is better to open an account? Is online account opening safe
- Shutter textfield example
- 网上开户哪家证券公司佣金最低,我要开户,网上开户安全吗
猜你喜欢

如何使用ConcurrentLinkedQueue做一个缓存队列

做BI开发,为什么一定要熟悉行业和企业业务?

【C语言进阶篇】数组&&指针&&数组笔试题

Redis has three methods for checking big keys, which are necessary for optimization

Daily question -leetcode1200- minimum absolute difference - array - sort

MP3是如何诞生的?

玩转gRPC—深入概念与原理

Analyzing the maker space contained in steam Education

【LeetCode】17、电话号码的字母组合

Super detailed tutorial, an introduction to istio Architecture Principle and practical application
随机推荐
HUAWEI nova 10系列发布 华为应用市场筑牢应用安全防火墙
HDU - 1078 FatMouse and Cheese(记忆化搜索DP)
开户哪家券商比较好?网上开户安全吗
历史最全混合专家(MOE)模型相关精选论文、系统、应用整理分享
置信区间的画法
Cadre WebGIS - kalrry
Arcgis 10.2.2 | arcgis license server无法启动的解决办法
【C语言进阶篇】数组&&指针&&数组笔试题
LambdaQueryWrapper用法
The drawing method of side-by-side diagram, multi row and multi column
Shutter textfield example
Open3d surface normal vector calculation
Spatiotemporal prediction 3-graph transformer
From repvgg to mobileone, including mobileone code
How to remove the black dot in front of the title in word document
Cadeus has never stopped innovating. Decentralized edge rendering technology makes the metauniverse no longer far away
Bookmark
How is the entered query SQL statement executed?
1807. 替换字符串中的括号内容
283. 移动零-c与语言辅助数组法