Thread: Raspberry Pi totaly freezes, runs fine on ubuntu laptop

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    52

    Raspberry Pi totaly freezes, runs fine on ubuntu laptop

    Dear users,

    I've got a problem witch is driving me crazy. I have a RS-485 connection with a platform. I use a FTDI chip in my usb port to connect to it. I get the data with open, read and write. This all works good, and does not make any problem.
    After that, I push everything in a file (with only a write, because later on I send it to the next pi, witch is a server)

    So, the program function is quit simple:
    -Get the data from the platform
    -Write it ins a file

    On my Ubuntu laptop there is absolutely no problem, it runs smoothly.

    This all works fine, but sometimes my raspberry freezes. It wan't do anything, and i need a hard reset. It's is not on a fixed time: the first time it runned for 1 hour, the second time for 5 minutes.

    I already tried to:
    1. Flush all the buffers
    2. Searched for a memory leak (with top, and nothing appears to be)
    3. A lot witch I don't remember now.

    Can anyone please help me? It's giving me really big headaches!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <fcntl.h>
    
    #define MY_ID_H         0x01
    #define MY_ID_L         0x00
    #define Try_Again_Max   0x04
    #define Timout_Sec      0x04
    /* This is made by Libpgeak. */
    
    static unsigned char output[9];
    static unsigned char input[100];
    
    static int Create_file(long long unsigned ntptime, int Power, float Rotation);
    static int Serial_to_int(unsigned char *input, char NumberOfBytes);
    static long long unsigned ntp_time(void);
    static unsigned char Get_Checksum(int NumberOfBytes);
    static int my_itoa(int val, char* buf);
    
    int main()
    {
     int PSERIAL;
     int i,j;
     int TimeNow=0;
     int TimeSo=0;
     int TryCount=0;
     char succes=0;
     long long unsigned ntptime=0;
     unsigned char TargetID[2];
     float Rotation=0;
     int Power=0;
    
     system("stty -F /dev/ttyUSB0 9600 -parenb -parodd cs8 -hupcl -cstopb cread clocal -crtscts"
        " ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff"
        " -iuclc -ixany -imaxbel -iutf8"
        " -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0"
        " -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt"
        " -echoctl -echoke time 1");
     while(1)
     {
      usleep(50000);
    
       usleep(50000);
     PSERIAL = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
     if(PSERIAL ==-1)
        {
        printf("Could not open write connection with FTDI-chip, closing program\n\r");
        return 100;
        }
     printf("Connected to FTDI chip\n\r");
     fcntl(PSERIAL, F_SETFL, FNDELAY);
     //Get the slave ID.
     output[0] = 0x00;
     output[1] = 0x00;
     output[2] = MY_ID_L;
     output[3] = MY_ID_H;
     output[4] = 0xA1;
     output[5] = 0xB0;
     output[6] = 0xC0;
     output[7] = 0x00;
     output[8] = Get_Checksum(8);
     succes=0;
     while(!succes)
        {
        i=write (PSERIAL, output, 9);
            if (i < 0)
                {
                printf("write() of C1 command failed!\n\r");
                succes=0;
                TryCount++;
                }
            if(TryCount==Try_Again_Max)
                {
                printf("Error at sending, Errorcode 0x01\n\r");
                close(PSERIAL);
                return 0x01;
                }
            else
                {
                printf("RS485 send was succesfull \n\r");
                succes=1;
                }
        }
       usleep(50000);
    
     i=0;
     TimeNow =ntp_time();
     TimeSo = TimeNow+Timout_Sec;
     while(i<1) //Timeout after a several secconds?
        {
        i=read(PSERIAL, input, sizeof(input));
        TimeNow =ntp_time();
        if(TimeNow==TimeSo)
            {
            printf("Timeout at receiving, Errorcode 0x20\n\r");
            return 0x20;
            }
        }
     for(j=0; j<i; j++)
         printf("%x ",input[j]);
     printf("\n\r");
    
      usleep(50000);
     TargetID[0] = input[2];
     TargetID[1] = input[3];
     // Now we know the ID, we can ask for monitordata
     output[0] = TargetID[0];
     output[1] = TargetID[1];
     output[2] = MY_ID_L;
     output[3] = MY_ID_H;
     output[4] = 0x07;
     output[5] = 0x10;
     output[6] = 0xA4;
     output[7] = 0x00;
     output[8] = Get_Checksum(8);
    
     i=0;
     TryCount=0;
     succes=0;
     while(!succes)
        {
        i=write (PSERIAL, output, 9);
            if (i < 0)
                {
                printf("write() of B6 command failed!\n\r");
                succes=0;
                TryCount++;
                }
            if(TryCount==Try_Again_Max)
                {
                printf("Error at sending, Errorcode 0x02\n\r");
                close(PSERIAL);
                return 0x02;
                }
            else
                {
                printf("RS485 send was succesfull \n\r");
                succes=1;
                }
        }
       usleep(50000);
     printf("reading information\n\r");
     i=0;
     TimeNow =ntp_time();
     TimeSo = TimeNow+Timout_Sec;
     while(i<1) //Timeout after a several seconds?
        {
        i=read(PSERIAL, input, sizeof(input));
        TimeNow = ntp_time();
        if(TimeNow==TimeSo)
            {
            printf("Timeout at receiving, Errorcode 0x20\n\r");
            close(PSERIAL);
            return 0x20;
            }
        }
    
     //for(j=0; j<i; j++)
        //printf("%x ",input[j]);
     //printf("\n\r");
    
     close(PSERIAL);                            //Done, and close the connection
     Power = Serial_to_int(&input[18], 2);
      //printf("Actual Power is %d\n\r", Power);
     Rotation = Serial_to_int(&input[20], 3);
     //printf("Actual Rotation is %f\n\r", Rotation);
    
     ntptime=ntp_time();
     ntptime= ntptime << 32;
     Create_file(ntptime, Power, Rotation);                  //this function has to be more complete
       usleep(50000);
     fflush(stdout);
     fflush(stdin);
     printf("C-code is finished %\n\r");
     }
     return 1;
    }
    
    static  long long unsigned ntp_time(void)
    {
     time_t sec=0;
     sec = time(NULL) + 2208988800;
     return sec;
    }
    
    static  int Create_file(long long unsigned ntptime, int Power, float Rotation)
     {
     int errorhandler;
     FILE *PFILE;
     char buffer[10];
     int lenght;
     int i=0;
     Rotation = Rotation / 100;
    
     printf("the timestamp is %llu\n\r",ntptime);
     lenght = my_itoa(Power, buffer);
     PFILE = fopen ("jsondata","w");
     if (PFILE==NULL)
        {
        printf("Could not make JSONDATA, closing program\n\r");
        return 200;
        }
     printf("Creating File\n\r");
     errorhandler=fprintf(PFILE,"The Power is %d \n\r"
                                 "The Rotation is %F \n\r"
                                 "Timestamp is %llu\n\r",Power, Rotation, ntptime);
     if(errorhandler<1)
    	{
    	printf("fprintf failed, Errorcode 0x63\n\r");
    	fflush(PFILE);
            fclose(PFILE);
    	return 0x63;
     	}
      usleep(50000);
     errorhandler=fflush (PFILE);
     if(errorhandler !=0)
    	{
    	printf("failure 0x64\n\r");
    	return 0x64;
    	}
     errorhandler=fclose (PFILE);
     if(errorhandler != 0)
     	{
    	printf("failure 0x65\n\r");
    	return 0x65;
    	}
     printf("Done Filewriting \n\r");
     return 1;
     }
    //Addres first byte from input string, and number of bytes
    static  int Serial_to_int(unsigned char *SerialBytes, char NumberOfBytes)
    {
     int i=0;
     int j=0;
     int output=0;
     while(NumberOfBytes>0)
        {
        output+= (SerialBytes[j] << i);
        printf("byte is %x\n\r",SerialBytes[j]);
        i+=8;
        j++;
        NumberOfBytes--;
        }
     return output;
    }
    
    static  unsigned char Get_Checksum(int NumberOfBytes)
    {
     int j=0;
     int i=0;
     unsigned char outputt=0;
     while(NumberOfBytes>0)
        {
        i += output[j];
        j++;
        NumberOfBytes--;
        }
     outputt = (i & 0xff);
     return outputt;
    }
    
    static int my_itoa(int val, char* buf)
    {
     const unsigned int radix = 10;
     char* p;
     unsigned int a;        //every digit
     int len;
     char* b;            //start of the digit char
     char temp;
     unsigned int u;
    
     p = buf;
     if (val < 0)
        {
        *p++ = '-';
        val = 0 - val;
        }
     u = (unsigned int)val;
     b = p;
     do
        {
        a = u % radix;
        u /= radix;
        *p++ = a + '0';
         }
        while (u > 0);
     len = (int)(p - buf);
     *p-- = 0;
     //swap
     do
         {
         temp = *p;
         *p = *b;
         *b = temp;
         --p;
         ++b;
         }
         while (b < p);
     return len;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Just some general thoughts.

    1. Indentation could be better.

    2. main() is far too long. The "connection" "request" and "response" phases of the communication should be done as separate functions.

    3. i=write (PSERIAL, output, 9); and the next 20 or so lines is copy/pasted. Another candidate for making into a separate function.

    4. When you run it on your laptop, consider running it as
    valgrind ./myprog
    just to make sure you're not doing anything dodgy with memory.

    I assume you have a keyboard and monitor plugged into your PI.
    Opening a second terminal window is always a good idea, just so you can type in "kill -9" and aim it at your errant process.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    Thanks Salem,
    1, 2 & 3. Yes, that is right, it's not the most beautiful code I ever made.
    4. valgrind is a memory checker? I thought when you do something nasty, you will get a segmentation error(and no full freeze)
    What does kill -9 do?

    Thanks!

    Libpgeak

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > 4. valgrind is a memory checker? I thought when you do something nasty, you will get a segmentation error(and no full freeze)
    Yes, it's a memory checker.
    One thing to check is that even on your laptop, you may be just "lucky" with your memory errors, even though everything seems to work.
    If valgrind complains about things when running your code on the laptop, then you need to fix those issues.

    > What does kill -9 do?
    kill(1): terminate process - Linux man page
    -9 is the extreme "do not pass GO, do not collect $200" option for ending a process.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    Well, I can't jsut open another terminal, because when it freezes, the whole Pi is totaly gone. I would not react on the mouse / keyboard, so there is no way to type the kill command. That is the weirdest thing of the code: it hangs the whole machine...

  6. #6
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Then it's unlikely to be the code unless you're running as root and doing something incredibly stupid.

    The RPi isn't the greatest device I've ever used and has had a couple of problems with USB etc. in its history. The SD-card and the USB bus share a chip, for instance, and without the latest kernel you get a LOT of weirdness when trying to use both simultaneously (from lockups to lost USB data transactions, etc.). This could easily be the cause of your problem, and nothing to do with C at all.

    Are you monitoring memory, disk space, the logs (which can be pushed over a network over USB-serial connection, for example, so you can read them live as the RPi is crashing)? Are you doing crazy amounts of data gathering which could be swamping the SD/USB bus? Are you using the latest drivers and kernel?

    I gave up programming on the RPi because of such issues (a simple serial connection to an AT-modem would often die once you went past certain bauds and had a busy machine, but it would not only die silently, but drop USB packets which caused all sorts of messes in the drivers). It also suffers from a lot of stability issues if you don't have a very stable and quite powerful PSU powering it.

    This is a problem with your hardware, I would hazard, not your programming.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  7. #7
    Registered User
    Join Date
    Sep 2011
    Posts
    52
    @ledow Thanks for your reaction. I searched on the internet for this weird thing but you wan't find that much crash story's, perhaps people love it to much... I use the USB port for a FTDI chip, and I write the data on the SD-card. When I look at the system calls, it alway's crashes in the sleep() function. So I thought nanosleep() was the troublemaker, and I skiped it out the code (with a realy ugly wait loop)... After I had done this, it crashed in the write to the SD-card... So there was something else going on. When I isolate the USB function or the SD-card write, it al goes fine... Gues you're right. I never had a embedded device witch had so much crashes witch I can not explain. First I thought the pi would be a great device to build the POC. Now, I go back to the TI sitara....

    Libpgeak

  8. #8
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    For reference:

    https://github.com/raspberrypi/firmware/issues/19

    Been going on for over 7 months now, and was ignored for a while before that on the forums.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program runs fine, then crashes 5% of the time
    By mat1z in forum C++ Programming
    Replies: 5
    Last Post: 01-30-2011, 04:28 AM
  2. Runs in Windows but not un Linux (Ubuntu)
    By Joelito in forum C++ Programming
    Replies: 5
    Last Post: 07-29-2009, 06:49 PM
  3. Compiles fine, freezes when Run?
    By Mahdi123 in forum C Programming
    Replies: 7
    Last Post: 04-10-2007, 12:36 PM
  4. Replies: 5
    Last Post: 08-05-2002, 07:14 PM
  5. Runs fine in IDE but crashes normally!
    By Hunter2 in forum Windows Programming
    Replies: 5
    Last Post: 05-07-2002, 03:47 PM

Tags for this Thread