暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

linux中led驱动(设备树)编程笔记

开源519 2020-07-05
275

1.模块三要素

用到的头文件

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

(1)初始化模块

int __init led_init(void)
{
 printk("led_init!!!\n");
 return 0;
}

module_init(led_init);

(2)退出模块

void __exit led_exit(void)
{
 printk("led_exit!!!\n");
}

module_exit(led_exit);

(3)模块签证

MODULE_LICENSE("GPL"):

2.platform总线三个步骤

用到的头文件

#include <linux/platform_device.h>
#include <linux/of.h> //of_match_ptr

① 实例化platform_driver结构体probe成员
② 实例化platform_driver结构体remove成员
③ 选择一种方式匹配(设备树,ACPI,名字,ID四选一)

(1)构建platform_driver结构体

const struct of_device_id led_dt_table[]={
 {
    .compatible = "dt,led",
 },
 {
 },
};

struct platform_driver pdev{
 .probe = led_probe,
 .remove = led_remove,
 .driver = {
    .name = "led_platform",//名字必须加不然会报错误(血的教训T_T)
    .of_match_table = of_match_ptr(led_dt_table),
 },
};

(2)注册

//在led_init中注册
platform_driver_register(&pdev);

(3)注销

//在led_exit中注销
platform_driver_unregister(&pdev);

3.字符设备框架流程

用到的头文件

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

(1)申请设备号

#define DEV_MAJOR 500
#define DEV_MINOR 0
#define DEV_NUM   1
#define DEV_NAME  "ledx"

dev_t devno;

devno = MKDEV(DEV_MAJOR,DEV_MINOR);

(2) 注册设备号

ret = register_chrdev_region(devno,DEV_NUM,DEV_NAME);

if(ret < 0)
{
 printk("register_chrdev_region fail!!!\n");

 ret = alloc_chrdev_region(&devno,DEV_MINOR,DEV_NUM,DEV_NUM);
 if (ret < 0)
 {
   printk("alloc_chrdev_region fail!!!\n");

   return -1;
 }

} else {
 printk("register_chrdev_region success!!!\n");
}

printk("MAJOR=%d MINOR=%d\n",MAJOR(devno),MINOR(devno));

(3)实例化cdev结构体

struct cdev led_cdev;

(4)实例化file_operations结构体,并初始化

int led_open(struct inode *inode, struct file *file)
{
 printk("led_open!!!\n");

 return 0;
}

int led_close(struct inode *inode, struct file *file)
{
 printk("led_close!!!\n");

 return 0;
}

long led_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
 printk("led_ioctl!!!\n");

 return 0;
}

struct file_operations fops = {

 .owner = THIS_MODULE,

 .open = led_open,

 .release = led_close,

 .unlocked_ioctl = led_ioctl,

};

(5)初始化cdev结构体

cdev_init(&led_cdev, &fops);

led_cdev.owner = THIS_MODULE;

(6)注册cdev结构体

cdev_add(&led_cdev, devno, DEV_NUM);

(7)注销cdev结构体

cdev_del(&led_cdev);

(8)注销设备号

unregister_chrdev_region(devno, DEV_NUM);

4.自动创建设备节点

用到的头文件

#include <linux/device.h>

(1)创建class

#define   CLS_NAME  "cls_led"

struct class *cls;

cls = class_create(THIS_MODULE, CLS_NAME);

if(IS_ERR(cls))
{
 printk("class_create fail!!!\n");

 return -1;

}

(2)创建设备节点

#define   NODE_LED "led"

device_create(cls, NULL, devno, NULL, NODE_LED);

(3)注销设备节点

device_destroy(cls, devno);

(4)注销class

class_destroy(cls);

5.设备树

/ {
……
 leds {
       compatible = "dt,led";
       pinctrl-names = "default";
       pinctrl-0 = <&pinctrl_leds>;
       status = "ok";
 };
……
};
&iomuxc_snvs {
   pinctrl-names = "default_snvs";
   pinctrl-0 = <&pinctrl_hog_2>;
……
      pinctrl_leds: ledgrp {
           fsl,pins = <
                 MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03        0x000110A0
           >;
       };
……
};

2020-06-28

点击这里,等你留言!


文章转载自开源519,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论