Linux I2C 总线驱动恢复机制!

       I2C是经常使用的一种bus方式,工程师们也经常调试I2C驱动设备;总会碰到各种各样的问题;

最令人头疼的一种问题,就是非常小概率I2C数据报错,又不好重现,怎么处理呢? 好在linux提供一种非常

牛逼的方法,可以在总线被挂住的情况下恢复,然后设备可以继续使用。下面就把相关的代码列举下。

但是你的平台是否配置此功能需要验证下,并打开相关的功能。

     Linux I2C 总线驱动恢复机制!从代码看,非常明确的解释了I2C的工作机制和原理

 

    #define RECOVERY_CLK_CNT    9
    static int i2c_generic_recovery(struct i2c_adapter *adap)
    {

        int i = 0, val = 1, ret = 0;

        if (bri->prepare_recovery)
                bri->prepare_recovery(adap);

        bri->set_scl(adap, val);
        ndelay(RECOVERY_NDELAY);

       /*
       * By this time SCL is high, as we need to give 9 falling-rising edges
       */
       while (i++ < RECOVERY_CLK_CNT * 2) {

          if (val) {
              /* Break if SDA is high */
              if  (bri->get_sda && bri->get_sda(adap))
                    break;


              /* SCL shouldn't be low here */
              if   (!bri->get_scl(adap))  {
                  dev_err(&adap->dev,  "SCL is stuck low, exit recovery\n");
                  ret = -EBUSY;
                  break;
              }
          }

          val = ! val;   /////  0  1 0 1 波形高低
          bri->set_scl(adap, val);
         ndelay(RECOVERY_NDELAY);
    }

 

            bri->get_sda = get_sda_gpio_value;

            bri->get_scl = get_scl_gpio_value;
            bri->set_scl = set_scl_gpio_value;

       文件: kernel-4.4/drivers/i2c/i2c-core.c

 

        虽然在非不得已情况下,可以使用此方法,当然开着这个功能也很实用;但是,最好的办法

还是把根本的问题解决好,这样不会留下什么后遗症。很多情况下是同一组I2C下,挂了多组设备,之间

没有协调好,另外上拉电阻硬件工程师没有算好,大部分他们也只是抄问厂商参考上拉电阻值,而不会

在统一大局下,协调所有同组I2C上设备调好匹配需求,多个上拉电阻就会造成并联,阻值就会变小。

这样就会出现同一路I2C下,有的设备不稳定,或者出现一些奇异的问题事件,低概率问题,

基本上很难查,一般这种问题的根因都是 基本原理没有过关。

你可能感兴趣的:(Linux I2C 总线驱动恢复机制!)