13 Replies Latest reply on Feb 20, 2015 11:35 AM by KurtE

    How to test if i2c hardware is there without segmentation fault

    allene

      I have a project that may or may not have a i2c device connected.  It is optional.  I would like to detect if it is there or not so I don't crash the system making calls that won't work.

       

      I tried looking at the result code of the init function like this:

       

      int main(){

      ...

      if (ADDON == 0) addon = 0;

      int error_code = 0;

      error_code = init_heel();

      printf("MRAA Exit Code is %d\n",error_code);

      if(error_code == -1)addon = 0;

      ...

      }

       

      int init_heel(){

      if (addon == 0 )return -1;

      //printf("Initializing Heel Sensor\n");

      int rtv;

          rtv = mraa_init();

          if (rtv != MRAA_SUCCESS && rtv != MRAA_ERROR_PLATFORM_ALREADY_INITIALISED)

            {

              printf( "MRAA Init Failed,Return Value is %d\n",rtv);

              return -1;

            }

      ....

      }

       

      This causes Edison to crash.

       

      Note that if I define ADDON to 0, the code runs fine so it I am getting an error code other than 0 or 12 out of init, the code should set addon to 0 and run fine.

       

      Next I tried just reading an address before the init.

       

          uint8_t buf[2] = {0,0};

          mraa_i2c_address(i2c, ADXL345_I2C_ADDR);

          mraa_i2c_write_byte(i2c, 0x00);

          mraa_i2c_address(i2c, ADXL345_I2C_ADDR);

          mraa_i2c_read(i2c, buf, 1);

          printf("chip is is %u",buf[0]);

       

      This causes a segmentation fault.  If placed after init, the above code prints 229, which is correct. In fact, just having the single line address causes a segmentation fault.

       

      How can I detect if the i2c device is on the buss or not?

       

      Allen

        • 1. Re: How to test if i2c hardware is there without segmentation fault
          Intel_Peter

          Hello allene,

           

          What do you mean when you say that the Edison crashes? Does the compiler you're using return an error message or does the completely Edison freezes?

           

          Peter.

          • 2. Re: How to test if i2c hardware is there without segmentation fault
            allene

            This message is not from my program but is on the terminal as soon as the program is run.  Notice that the exit code is not printed out.

             

            root@username~# /home/root/program

            Railed to write to export

            Intel Edison failed to initialize Arduino board Tristate

            Railed to write to export

            Intel Edison failed to initialize Arduino board Tristate

            Platform not initialized

            Segmentation Fault


            I should point out I do not have the Arduino board version, I have the mini breakout board.

             

            I also forgot to mention that when the program runs successfully, with the i2c board installed, the exit code is always 12, never 0 even from a cold boot.

             

            Allen

            • 3. Re: How to test if i2c hardware is there without segmentation fault
              Intel_Peter

              Hello allene,

               

              Did you enable I2C before you tried to run your sketch?

              If you didn't these are the steps you have to take to enable it:

               

              # echo 28 > /sys/class/gpio/export
              # echo 27 > /sys/class/gpio/export
              # echo 204 > /sys/class/gpio/export
              # echo 205 > /sys/class/gpio/export
              # echo 236 > /sys/class/gpio/export
              # echo 237 > /sys/class/gpio/export
              # echo 14 > /sys/class/gpio/export
              # echo 165 > /sys/class/gpio/export
              # echo 212 > /sys/class/gpio/export
              # echo 213 > /sys/class/gpio/export
              # echo 214 > /sys/class/gpio/export
              # echo low > /sys/class/gpio/gpio214/direction
              # echo high > /sys/class/gpio/gpio204/direction
              # echo high > /sys/class/gpio/gpio205/direction
              # echo in > /sys/class/gpio/gpio14/direction
              # echo in > /sys/class/gpio/gpio165/direction
              # echo low > /sys/class/gpio/gpio236/direction
              # echo low > /sys/class/gpio/gpio237/direction
              # echo in > /sys/class/gpio/gpio212/direction
              # echo in > /sys/class/gpio/gpio213/direction
              # echo mode1 > /sys/kernel/debug/gpio_debug/gpio28/current_pinmux
              # echo mode1 > /sys/kernel/debug/gpio_debug/gpio27/current_pinmux
              # echo high > /sys/class/gpio/gpio214/direction
              

               

              Peter.

              • 4. Re: How to test if i2c hardware is there without segmentation fault
                allene

                Two issues with this. 

                 

                One is that it everything works just fine when the i2c hardware is there so I would think I am enabling things OK.  My question was that I can't detect that it is not there without the program crashing.  Just running nraa_init() crashes Edison.

                 

                Second is that the above code given by the echo statements gives a string of error messages the first being on the third line with 204.  I get a no such device error.

                • 5. Re: How to test if i2c hardware is there without segmentation fault
                  KurtE

                  Note: Assuming your code is like above,  where you are calling mraa init and and I2c init, MRAA should be setting this up.

                   

                  First thing is to make sure your MRAA is up to date.  Also do you have simple program that illustrates this?

                  Might be interesting to try it out.  Could simply be a bug in MRAA where some init fails, so some pointer is NULL and then

                  someone uses pointer...

                   

                  Kurt

                  • 6. Re: How to test if i2c hardware is there without segmentation fault
                    allene

                    Here is a simple program:

                    int main(){

                        mraa_init();

                    }


                    Result:

                    root@username~# /home/root/program

                    Failed to write to export

                    Intel Edison failed to initialize Arduino board Tristate

                    Railed to write to export

                    Intel Edison failed to initialize Arduino board Tristate

                    Platform not initialized

                    Segmentation Fault

                     

                    Actually, I can't run this as my breadboard is apart and when it goes back together it will have the i2c chip installed so it will not crash.  But I have run this enough to know that this is what would happen.

                     

                    Also, I know that mraa_init() always returns 12 even the first time.  I think it should return 0.

                     

                    Allen

                    • 7. Re: How to test if i2c hardware is there without segmentation fault
                      KurtE

                      It did not fault with simple program.  But I am running current mraa, which I just built.  If you have not done so, update your mraa libraries.  If using eclipse also update on dev machine as well.  Also to verify, would be good to print out mraa version

                      • 8. Re: How to test if i2c hardware is there without segmentation fault
                        allene

                        Mine is 3 weeks old, Jan 17 it was updated.  I will have to update it.

                        • 9. Re: How to test if i2c hardware is there without segmentation fault
                          Intel_Peter

                          Hello allene,

                           

                          Has anything changed after the update?

                           

                          Peter.

                          • 10. Re: How to test if i2c hardware is there without segmentation fault
                            allene

                            I just got my second Edison a few days ago and flashed the new image to it.  I still get exit code 12 but it doesn't give a segmentation fault.  I have not updated my mraa file though.  I need to set up another development environment to do that as I don't want to take a chance on breaking the production system.  I have a work around that works for me so I have limited motivation to work on this.  I just have the user create a file if the i2c hardware is installed and I look for the file before loading the i2c code.

                             

                            Allen

                            • 11. Re: How to test if i2c hardware is there without segmentation fault
                              Intel_Peter

                              I'm glad to hear that you found a workaround for your issue, maybe you could share it with the community, I believe it could help other users on their projects.

                               

                              Peter.

                              • 12. Re: How to test if i2c hardware is there without segmentation fault
                                allene

                                My solution  is simple although not elegant.  If the user has i2c hardware installed they do this from the root directory #touch addon.

                                 

                                Then my main routine runs this code

                                 

                                if (access("/home/root/addon",F_OK) == 0) addon = 1;

                                else addon = 0;

                                 

                                My init code starts like this as do all routines dealing with i2c

                                 

                                int init_heel(){

                                  if (addon == 0 )return -1;

                                  ...

                                }

                                1 of 1 people found this helpful
                                • 13. Re: How to test if i2c hardware is there without segmentation fault
                                  KurtE

                                  Note: I still wonder if something else is going on.  For example, I have the following test program, for reading a davenport CMPS03 and I have it on my Edison with mini breakout board:

                                  #include "mraa.h"
                                  #include "math.h"
                                  #include <unistd.h>
                                  #define ADDRESS 0x60 //defines address of compass
                                  
                                  #define MAX_BUFFER_LENGTH 6
                                  
                                  int
                                  main(int argc, char **argv)
                                  {
                                      mraa_init();
                                      uint16_t direction = 0;
                                      uint8_t rx_tx_buf[MAX_BUFFER_LENGTH];
                                  
                                      mraa_i2c_context i2c;
                                      i2c = mraa_i2c_init(0);
                                      mraa_result_t result;
                                  
                                      result = mraa_i2c_address(i2c, ADDRESS);
                                      if (result != MRAA_SUCCESS)
                                          printf("Addres result: %d\n\r", result);
                                      uint8_t bVer = mraa_i2c_read_byte_data(i2c, 0);   // read one byte
                                      printf("CMPS03 Version: %d\n\r", bVer);
                                      
                                  
                                      for(;;) {
                                          mraa_i2c_address(i2c, ADDRESS);
                                          result = mraa_i2c_write_byte(i2c, 2);    // start read at byte 2
                                          if (result != MRAA_SUCCESS)
                                              printf("write result: %d ", result);
                                          mraa_i2c_address(i2c, ADDRESS);
                                          int cb = mraa_i2c_read(i2c, rx_tx_buf, 2);
                                          if (cb != 2)
                                              printf("read cb: %d ", cb);
                                  
                                          direction = (rx_tx_buf[0] << 8) + rx_tx_buf[1];
                                  //        direction = mraa_i2c_read_word_data(i2c,  2);
                                          printf("Heading : %d\n", direction) ;
                                          usleep(250000);
                                      }
                                  }
                                  
                                  

                                   

                                  I ran the program and it shows:

                                  root@edison_MP2:~/Raspberry_Pi/testCMPS03# ./testCMPS03

                                  CMPS03 Version: 0

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                  write result: 5 read cb: 0 Heading : 1032

                                   

                                  So from the above, it appears you can check for a write returning an error condition (invalid handle in this case) or you can check if read does not read.