当前位置:网站首页>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闪烁:
边栏推荐
- Telephone encryption, middle 4 is replaced by * * * *
- Numpy vstack and column_ stack
- El tree combined with El table, tree adding and modifying operations
- Compréhension approfondie du symbole [langue C]
- QT—双缓冲绘图
- Lambdaquerywrapper usage
- CloudCompare&Open3D DBSCAN聚类(非插件式)
- 解决异步接口慢导致的数据错乱问题
- 283. 移动零-c与语言辅助数组法
- What is business intelligence (BI), just look at this article is enough
猜你喜欢
Interpreting the development of various intelligent organizations in maker Education
Application practice | Shuhai supply chain construction of data center based on Apache Doris
[public class preview]: basis and practice of video quality evaluation
MP3是如何诞生的?
QT—双缓冲绘图
Flutter TextField示例
Analyzing the maker space contained in steam Education
Nat. Commun.| 机器学习对可突变的治疗性抗体的亲和力和特异性进行共同优化
What is business intelligence (BI), just look at this article is enough
Enlightenment of maker thinking in Higher Education
随机推荐
案例分享|金融业数据运营运维一体化建设
[optimtool.unconstrained] unconstrained optimization toolbox
AcWing 2022 每日一题
Golang面试整理 三 简历如何书写
开户哪家券商比较好?网上开户安全吗
Redis03 - network configuration and heartbeat mechanism of redis
Which securities company is better to open an account? Is online account opening safe
ArcGIS 10.2.2 | solution to the failure of ArcGIS license server to start
GTEST from ignorance to proficiency (3) what are test suite and test case
Analyzing the maker space contained in steam Education
时空预测3-graph transformer
并列图的画法,多排多列
一文掌握数仓中auto analyze的使用
关系型数据库
文件读取写入
How is the entered query SQL statement executed?
File read write
Shutter textfield example
Cadre WebGIS - kalrry
Master the use of auto analyze in data warehouse