zoukankan      html  css  js  c++  java
  • Linux驱动开发—— of_property_read_u8

    在使用設備樹的時候, 有時會遇到下面的問題.

    在設備樹中配置的屬性如下:

    fusb301,init-mode = <0x20>;

    但是在驅動中讀出的卻是:

        rc = of_property_read_u8(dev_node,
                    "fusb301,init-mode", &data->init_mode);

    加打印發現, 讀出的值是0, 並不是0x20.

    使用下面的命令將對應的節點從內存中pull出來:

    adb pull "/sys/firmware/devicetree/base/soc/i2c@7af6000/fusb301@25/fusb301,init-mode"

    這是一個二進制文件, 使用二進制閱讀工具打開:

    可以看到, 0x20存放在高字節, 即設備樹編譯工具是按大端格式組織數據的, 但是使用of_property_read_u8卻是按小端格式.

    然後做了如下實驗:

    添加屬性:

    fusb301,test = <0x12345678>;

    在驅動中解析這個字段:

        u8 value8;
        u16 value16;
        u32 value32;
    
        of_property_read_u8(dev_node,"fusb301,test", &value8);
        of_property_read_u16(dev_node,"fusb301,test", &value16);
        of_property_read_u32(dev_node,"fusb301,test", &value32);
    
        printk("%s: value8: %x, value16: %x, value32: %x
    ", __func__, value8, value16, value32);

    輸出的log如下:

    fusb301_parse_dt: value8: 12, value16: 1234, value32: 12345678

    可以驗證我們的猜想.

    那麼如何解決這個問題呢?

    通過閱讀內核代碼發現, 內核中其實有說明:

     1 /**
     2  * of_property_read_u8_array - Find and read an array of u8 from a property.
     3  *
     4  * @np:        device node from which the property value is to be read.
     5  * @propname:    name of the property to be searched.
     6  * @out_values:    pointer to return value, modified only if return value is 0.
     7  * @sz:        number of array elements to read
     8  *
     9  * Search for a property in a device node and read 8-bit value(s) from
    10  * it. Returns 0 on success, -EINVAL if the property does not exist,
    11  * -ENODATA if property does not have a value, and -EOVERFLOW if the
    12  * property data isn't large enough.
    13  *
    14  * dts entry of array should be like:
    15  *    property = /bits/ 8 <0x50 0x60 0x70>;
    16  *
    17  * The out_values is modified only if a valid u8 value can be decoded.
    18  */
    19 int of_property_read_u8_array(const struct device_node *np,
    20             const char *propname, u8 *out_values, size_t sz)
    21 {
    22     const u8 *val = of_find_property_value_of_size(np, propname,
    23                         (sz * sizeof(*out_values)));
    24 
    25     if (IS_ERR(val))
    26         return PTR_ERR(val);
    27 
    28     while (sz--)
    29         *out_values++ = *val++;
    30     return 0;
    31 }
    32 EXPORT_SYMBOL_GPL(of_property_read_u8_array);

    然後我做了如下實驗:

    添加如下幾個屬性:

            fusb301,test8 = /bits/ 8 <0x12>;
            fusb301,test16 = /bits/ 16 <0x1234>;
            fusb301,test32 = <0x12345678>;

    修改驅動, 解析這些字段:

        u8 value8;
        u16 value16;
        u32 value32;
    
        of_property_read_u8(dev_node,"fusb301,test8", &value8);
        of_property_read_u16(dev_node,"fusb301,test16", &value16);
        of_property_read_u32(dev_node,"fusb301,test32", &value32);
    
        printk("%s: value8: %x, value16: %x, value32: %x
    ", __func__, value8, value16, value32);

    輸出的log如下:

    fusb301_parse_dt: value8: 12, value16: 1234, value32: 12345678

    完.

  • 相关阅读:
    求二叉树的层次遍历
    求二叉树的先序遍历
    数据结构实验之二叉树一:树的同构
    list列表操作
    汉罗塔问题
    expected an indented block
    42步进阶学习—让你成为优秀的Java大数据科学家!
    MVC 3.0错误 HTTP 404您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。
    判断浏览器版本
    VisualStudio2012编辑器错误
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/6044418.html
Copyright © 2011-2022 走看看