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

    完.

  • 相关阅读:
    permission 文档 翻译 运行时权限
    TabLayout ViewPager Fragment 简介 案例 MD
    Log 日志工具类 保存到文件 MD
    OkHttp 官方wiki 翻译 MD
    Okhttp 简介 示例 MD
    OkHttp 官方Wiki之【使用案例】
    DialogPlus
    倒计时 总结 Timer Handler CountDownTimer RxJava MD
    RecyclerView 判断滑到底部 顶部 预加载 更多 分页 MD
    CSS3的媒体查询(Media Queries)与移动设备显示尺寸大全
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/6044418.html
Copyright © 2011-2022 走看看