This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] Linux/ADC128D818SW-Linux:读数较慢、原因何在?

Guru**** 2521850 points
Other Parts Discussed in Thread: ADC128D818

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/807519/linux-adc128d818sw-linux-slow-a-d-reading-why

器件型号:ADC128D818SW-Linux
主题中讨论的其他器件:ADC128D818

工具/软件:Linux

尊敬的专家:

 我的 ADC128D818和标准 Linux 驱动程序有一个奇怪的问题。

该器件检测到并且看起来工作正常。 问题是、获得正确读数需要~ 1秒。

当我更改输入引脚上的电压并连续读取时、每秒无法检测一次以上的变化。

读取自身(从驱动程序的 sysfs 文件中)速度快、不会挂起。 但更新不会以我所需的速率发生。

有什么想法吗? 是否可以通过某种方式调整驱动程序以提高读取速度?

该计算机是 iMX6 Solo (ARM7)、Ubuntu 14.04 LTS、内核4.1.0

谢谢、

Pavel A.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Pavel、


    很抱歉、尽管我们在 TI 网站上提供了 Linux 驱动程序的链接、但我们没有开发这些驱动程序、并且无法支持它们。

    在这种情况下、我将使用逻辑分析仪来检查器件是否响应命令并定期提供数据、以确保器件正常运行。 但是、我不确定 Linux 驱动程序是如何监控新数据以及如何读取新数据的。


    吴约瑟
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph、

    我发现了更新缓慢的原因:

    Linux 驱动程序(drivers/hwmon/adc128d818/c)将从器件读取的频率限制为每秒一次、硬编码:

    静态结构 adc128_data * adc128_update_device (struct device * dev)
    {
    …………
    if (time_after (jiffies、data->last_updated + Hz)||!data->valid){
    //... 从设备读取
    }
    

    (链接)  

    驱动程序还将器件保留在默认更新速度下、从而导致更新周期时间 为728 ms、即~ 1秒

    主流内核中此驱动程序的所有版本都以这种方式运行。

    没有参数可以调整更新频率。 我们认为、用户知道这一点可能会很有用。

    我将修复驱动器源中的1Hz 限制并启用持续更新。 然后、可能会发布一个带有模块或器件树参数的补丁。

    此致、  

    帕维尔·A.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更新了:确认了连续模式有助于将信号更改的延迟至少减少到100ms。

    在驱动程序的早期版本(内核~ 4.1、仅支持模式0)中遵循快速版本的补丁

    通过取消对自动最小和最大限值检查的支持、可以选择使扫描速度更快。

    - Pavel A、


    --- a/drivers/hwmon/adc128d813.c
    ++ b/drivers/hwmon/adc128dlet.c
    @@-83、38 +74、42 @@
    struct i2c_client *客户机=数据->客户机;
    struct adc128_data *
    
    
    数据=数据;int i、rv;mutex_lock (&data->jib、
    
    if); DATA->LAST_Updated + Hz)||!DATA->VALID){
    +IF (TIME_after (jiffies、DATA->LAST_Updated +(Hz/11))||!DATA->VALID){
    for (i = 0;i < 7;i++){
    RV = i2c_smbus_read_word_switched (client、s&rv
    
    
    
    
    
    (client = 128
    );[smbit_rv_ine_rv <=0>_rv_rv_rv_ine_/i&rv_rv_rv (client<=<=<=<x_rv_rv_reg_rv_rv_&<=0<=<<<<<<=<x_r
    ADC128_REG_IN_MIN (I));
    IF (RV < 0)
    转至中止;
    DATA->IN[1][i]= RV << 4;
    
    RV = i2c_smbus_read_Byte_data (client、
    ADC128_REG_IN_MAX (I));
    如果(RV < 0)
    转至中止;
    DATA->IN[2][i]= RV << 4;
    +#else
    +DATA->IN[1][i]= 0;//虚拟
    +数据-> IN[2][i]= 0x7FFF;
    +#endif TEMP + DATA>IN[REG_REV_REV_REV_REV_REV_REV_REV_REV_REV_REV_REV_REV_REV_RETP_RESP= 0*
    
    
    
    
    
    
    
    ;+ MODEV_RETP_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_RESPON_128;#128 = 0*= 0*
    128;
    if (RV <0)
    转至中止;
    DATA->temp[1]= RV << 1;
    
    RV = i2c_smbus_read_Byte_data (client、ADC128_REG_TEMP_HYST);
    @@-123,13+118,16 @@
    data->RV <<1;
    
    = i128_smbus_temp_read_rv;+ temp_data=>rv <1
    
    ;temp_rv =>temp_rv =>temp_data<1;/>temp_abort (p_rv =/<1)
    += temp_rv =/<1);[temp_rv =>temp_data<=/<=>temp_rv <=>rv <=>temp_
    
    
    
    
    +#endif /*Wit_limits*/
    DATA->LAST_Updated = Jiffies;
    DATA->VALID = true;
    }
    转至完成;
    
    中止:
    @@-384,11+382,15 @@
    *这使得大多数其他初始化没有必要。
    //
    err = i2c_smbus_write_byte_data (client、ADC128_REG_config、0x80);
    if (err)
    return err;
    +
    
    
    
    
    config = i2c_smbus_write_byte_data (client、ADC128_REG_CONVRATE、0x01);+ if (err)+ return err;//开始监控* hwbus_write_byte_data (client
    
    
    
    @@
    = 0x13、hwmon_dev_err_r = 0x13 @@、hwmon_dev_device_groups、+ r = 0x4mr = 0x4mr、+ dev_dev_byte、+ r = 0x13、hwmon_dev_dev_register;
    data、adc128_groups);
    if (is_ERR (hwmon_dev)){
    err = ptr_ERR (hwmon_dev);
    goto error;
    }
    -
    +printk ("ADC128 at %2.2X - fast scan fix\n"、client->addr);
    return 0;
    
    error:
    if (data->regulator)
    regulator _disable;"diplode_driver"
    
    @@
    
    (+128_disable @@
    
    
    
    
    );"ategr 8、ather_module"(r_guidr)-ategr (v 1、128_reat %48c);"rm 2、ategr (v 1、atr)-rm Ω.atr (v 1、atr、atr、atr、atr、atr、atr、128
    +module_description ("适用于 ADC128D818/pa01快速扫描修复程序"的驱动程序);
    module_license ("GPL");