天天看點

H3 Linux4.11核心裝置樹裝置驅動開發2

參考:

linux核心device-tree基礎

在裝置樹裡描述platform_device

在裝置樹裡描述一個mydt的裝置,此裝置有多種屬性及兩個子節點,每個子節點也有多種屬性.

修改裝置樹的文本檔案: arch/arm/boot/dts/sun8i-h3-orangepi-lite.dts

/ {
      model = "Xunlong Orange Pi Lite";
      compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3";
  
      mydt@11223344{
          compatible = "mydt,test";
          hello = "hello", "world";
          what = "shift";
          hehe = <>, <>;
          haha = <>;
          mymac = [     ];
  
          dt1 {
              hello = "hello", "dt1";
              what = "what dt1";
              hehe = <>, <>;
              haha = <>;
              mymac = [     ];
          };
          dt2 {
              hello = "hello", "dt2";
              what = "what dt2";
              hehe = <>, <>;
              haha = <>;
              mymac = [     ];
          };
      };
           

修改完成後,重編譯并更新使用裝置樹檔案:

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[];
    int  n, n2[];
    char mymac[];

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

    //取屬性hello的字元串數組值
    if (device_property_read_string_array(&pdev->dev, "hello", p2, ) < )
        return -ENODEV;

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

    //取屬性hehe的整型數組  
    if (device_property_read_u32_array(&pdev->dev, "hehe", n2, ) < )
        return -ENODEV;

    //取屬性mymac的位元組數組
    if (device_property_read_u8_array(&pdev->dev, "mymac", mymac, ) < )
        return -ENODEV;


    printk(KERN_ERR"in myprobe ...%s\n", p);
    printk(KERN_ERR"%s,%s\n", p2[], p2[]);
    printk(KERN_ERR"n = %d\n", n);
    printk(KERN_ERR"n2: %d, %d\n", n2[], n2[]);
    printk(KERN_ERR"mymac=%x,%x,%x,%x,%x,%x\n", mymac[], mymac[], mymac[], mymac[],
                mymac[], mymac[]);    
    printk(KERN_ERR"######################################\n");
///////////////////////////////////////////////////////////////////
//擷取裝置子節點的屬性值


    //循環擷取每個子節點的屬性值
    device_for_each_child_node(&pdev->dev, child)
    {
        //取子節點的屬性what的值
        if ( <= fwnode_property_read_string(child, "what", &p))
            printk(KERN_ERR"child what=%s\n", p);

        //取子節點的屬性hello的字元串數組值
        if ( <= fwnode_property_read_string_array(child, "hello", p2, ))
            printk(KERN_ERR"child hello=%s, %s\n", p2[], p2[]);

        //取子節點的屬性haha的整型值
        if ( <= fwnode_property_read_u32_array(child, "haha", &n, ))
            printk(KERN_ERR"child haha=%d\n", n);

        //取子節點的屬性hehe的整型數組  
        if ( <= fwnode_property_read_u32_array(child, "hehe", n2, ))
            printk(KERN_ERR"child hehe=%d,%d\n", n2[], n2[]);

        //取子節點屬性mymac的位元組數組
        if ( <= fwnode_property_read_u8_array(child, "mymac", mymac, ))
            printk(KERN_ERR"child mymac=%x,%x,%x,%x,%x,%x\n", mymac[], mymac[], mymac[], mymac[],
                mymac[], mymac[]);    
        printk(KERN_ERR"---------------------\n");
    }

    return ;
}

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


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] ---------------------

           

繼續閱讀