H3 Linux4.11内核设备树设备驱动开发2

参考:
linux内核device-tree基础

在设备树里描述platform_device


在设备树里描述一个mydt的设备,此设备有多种属性及两个子节点,每个子节点也有多种属性.

修改设备树的文本文件: arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts

 51 / {
 52     model = "Xunlong Orange Pi Lite";
 53     compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3";
 54 
 55     mydt@11223344{
 56         compatible = "mydt,test";
 57         hello = "hello", "world";
 58         what = "shift";
 59         hehe = <88>, <99>;
 60         haha = <33>;
 61         mymac = [11 22 33 44 55 66];
 62 
 63         dt1 {
 64             hello = "hello", "dt1";
 65             what = "what dt1";
 66             hehe = <22>, <88>;
 67             haha = <99>;
 68             mymac = [11 22 33 44 55 66];
 69         };
 70         dt2 {
 71             hello = "hello", "dt2";
 72             what = "what dt2";
 73             hehe = <11>, <44>;
 74             haha = <55>;
 75             mymac = [11 22 33 44 55 66];
 76         };
 77     };

修改完成后,重编译并更新使用设备树文件:

make dtbs ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
编译完成后: arch/arm/boot/dts/sun8i-h3-orangepi-lite.dtb就是所需的设备树文件。

使用新的设备树文件启动系统后,可查看到:

/ # ls /sys/bus/platform/devices/mydt@11223344/
driver/          modalias         power/           uevent
driver_override  of_node/         subsystem/
/ # ls /sys/bus/platform/devices/mydt@11223344/of_node/
compatible  dt2/        hehe        mymac       what
dt1/        haha        hello       name
/ # ls /sys/bus/platform/devices/mydt@11223344/of_node/dt1/
haha   hehe   hello  mymac  name   what
/ # ls /sys/bus/platform/devices/mydt@11223344/of_node/dt1/


编写一个与mydt平台设备匹配的平台驱动对象,并获取设备的属性及它的子节点属性值.


#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>

int myprobe(struct platform_device *pdev)
{
    struct fwnode_handle *child;    
    const char *p, *p2[2];
    int  n, n2[2];
    char mymac[6];

    //取属性what的值
    if (device_property_read_string(&pdev->dev, "what", &p) < 0)
        return -ENODEV;

    //取属性hello的字符串数组值
    if (device_property_read_string_array(&pdev->dev, "hello", p2, 2) < 0)
        return -ENODEV;

    //取属性haha的整型值
    if (device_property_read_u32_array(&pdev->dev, "haha", &n, 1) < 0)
        return -ENODEV; 

    //取属性hehe的整型数组  
    if (device_property_read_u32_array(&pdev->dev, "hehe", n2, 2) < 0)
        return -ENODEV;

    //取属性mymac的字节数组
    if (device_property_read_u8_array(&pdev->dev, "mymac", mymac, 6) < 0)
        return -ENODEV;


    printk(KERN_ERR"in myprobe ...%s\n", p);
    printk(KERN_ERR"%s,%s\n", p2[0], p2[1]);
    printk(KERN_ERR"n = %d\n", n);
    printk(KERN_ERR"n2: %d, %d\n", n2[0], n2[1]);
    printk(KERN_ERR"mymac=%x,%x,%x,%x,%x,%x\n", mymac[0], mymac[1], mymac[2], mymac[3],
                mymac[4], mymac[5]);    
    printk(KERN_ERR"######################################\n");
///////////////////////////////////////////////////////////////////
//获取设备子节点的属性值


    //循环获取每个子节点的属性值
    device_for_each_child_node(&pdev->dev, child)
    {
        //取子节点的属性what的值
        if (0 <= fwnode_property_read_string(child, "what", &p))
            printk(KERN_ERR"child what=%s\n", p);

        //取子节点的属性hello的字符串数组值
        if (0 <= fwnode_property_read_string_array(child, "hello", p2, 2))
            printk(KERN_ERR"child hello=%s, %s\n", p2[0], p2[1]);

        //取子节点的属性haha的整型值
        if (0 <= fwnode_property_read_u32_array(child, "haha", &n, 1))
            printk(KERN_ERR"child haha=%d\n", n);

        //取子节点的属性hehe的整型数组  
        if (0 <= fwnode_property_read_u32_array(child, "hehe", n2, 2))
            printk(KERN_ERR"child hehe=%d,%d\n", n2[0], n2[1]);

        //取子节点属性mymac的字节数组
        if (0 <= fwnode_property_read_u8_array(child, "mymac", mymac, 6))
            printk(KERN_ERR"child mymac=%x,%x,%x,%x,%x,%x\n", mymac[0], mymac[1], mymac[2], mymac[3],
                mymac[4], mymac[5]);    
        printk(KERN_ERR"---------------------\n");
    }

    return 0;
}

int myremove(struct platform_device *pdev)
{
    printk(KERN_ERR"in myremove ...\n");
    return 0;
}


struct of_device_id ids[] = {
    {.compatible = "mydt,test"},
    {},
};

struct platform_driver pdrv = {
    .driver = {
        .name = "mydrv",
        .owner = THIS_MODULE,
        .of_match_table = ids,
    },

    .probe = myprobe,
    .remove = myremove,
};

module_platform_driver(pdrv);
MODULE_LICENSE("GPL");

执行结果:

/mnt/kernel_coding/30device_tree/01mydrv # insmod test.ko 
[ 1930.702739] in myprobe ...shift
[ 1930.705891] hello,world
[ 1930.708362] n = 33
[ 1930.710372] n2: 88, 99
[ 1930.712728] mymac=11,22,33,44,55,66
[ 1930.716210] ######################################
[ 1930.721005] child what=what dt1
[ 1930.724142] child hello=hello, dt1
[ 1930.727553] child haha=99
[ 1930.730170] child hehe=22,88
[ 1930.733048] child mymac=11,22,33,44,55,66
[ 1930.737057] ---------------------
[ 1930.740367] child what=what dt2
[ 1930.743503] child hello=hello, dt2
[ 1930.746898] child haha=55
[ 1930.749521] child hehe=11,44
[ 1930.752398] child mymac=11,22,33,44,55,66
[ 1930.756399] ---------------------
### 回答1: Linux字符设备驱动开发是指在Linux系统中编写驱动程序,使得用户可以通过字符设备接口来访问硬件设备。这种驱动程序通常用于控制串口、并口、USB设备等。开发Linux字符设备驱动需要掌握Linux内核的基本知识,包括进程管理、内存管理、中断处理、设备驱动等方面。此外,还需要了解字符设备驱动的编写流程、驱动程序的结构和接口等。开发Linux字符设备驱动需要使用C语言和Linux内核编程接口。 ### 回答2Linux字符设备驱动开发Linux系统中的一部分,它允许开发人员在Linux系统上使用字符设备,这些字符设备可以包括串口、USB口、网卡等。Linux字符设备驱动开发可帮助开发人员实现各种各样的设备驱动,从而增强Linux系统的功能。 在Linux字符设备驱动开发过程中,需要注意以下几点: 1. 实现设备驱动的一个基本框架,包括注册设备、设备的初始化,以及对设备进行读写操作等。 2. 开发人员不仅需要熟悉驱动程序开发技术,还需要了解Linux内核系统的相关知识,例如进程、中断、内存管理等。 3. 应该在代码注释中提供详细的文档,以方便其他开发人员进行维护和修改。 4. 在实现字符设备驱动过程中,必须保证安全性和可靠性,防止设备出现故障或者损坏用户的数据。 5. 在测试和维护设备驱动时,需要使用一些常见的工具和技术,例如devfs、udev等。 总之,Linux字符设备驱动开发是一个需要熟练技能和丰富经验的过程。开发人员需要有足够的专业知识和经验来确保设备驱动的高效和稳定性。通过精心设计和开发Linux字符设备驱动可以提供高性能、高可靠性、易于使用的设备驱动,从而大大增强了Linux系统的功能和灵活性。 ### 回答3Linux字符设备驱动开发Linux系统中的一个重要领域。其主要任务是开发一些支持字符设备的驱动程序,从而使用户能够在Linux系统中使用各种不同类型的字符设备,例如串口、打印机、读卡器和磁盘等。同时,这些驱动程序还要保证设备完全可靠和高效地工作,确保系统的安全性和性能。 Linux字符设备驱动开发需要掌握以下基本知识: 1.了解Linux系统体系结构和内核架构 Linux系统由内核和用户空间组成,内核作为系统的核心组件,是实现系统功能的主要部分,因此了解内核体系结构和架构是开发Linux字符设备驱动所必须掌握的知识。 2.熟悉字符设备的相关知识 字符设备是Linux系统中的一种重要的设备类型,它与其他类型设备不同之处在于它只能逐个字符地进行读写操作。因此需要深入了解字符设备的相关知识,例如驱动的主要功能、驱动程序与设备的交互方式、设备控制结构等。 3.熟练掌握C语言及Linux内核编程技术 编写Linux字符设备驱动程序需要掌握良好的C语言编程知识以及熟练的Linux内核编程技术,包括内存管理、进程管理、文件系统、中断处理等。同时,还需要了解Linux内核代码的结构和代码的编写规范,以便于编写出符合内核标准的驱动程序。 4.掌握Linux驱动框架的使用方法 为了简化Linux驱动的开发流程,Linux提供了一些驱动框架,这些框架定义了一些驱动程序中常用的接口和函数,能够方便驱动程序的开发和调试。因此,Linux字符设备驱动开发者需要掌握其中的一些驱动框架,如字符驱动框架。 5.熟悉Linux字符设备驱动开发过程 Linux字符设备驱动开发过程主要包括驱动程序的初始化、驱动程序的主要功能实现、驱动程序的卸载等环节。在开发过程中,需要合理使用系统提供的工具和调试手段,如gdb、strace、make等,以便于分析和排查驱动程序出现的问题,确保驱动程序的稳定和可靠性。 总之,在Linux字符设备驱动开发过程中,开发者需要掌握相关的知识和技能,以实现对字符设备的编程和调试,开发出满足用户需求的高质量驱动程序。同时,Linux字符设备驱动开发也是一项长期持续的工作,开发者需要时刻关注最新的技术发展和硬件设备变化,才能更好地适应市场需求。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值