grzanix
Posts: 2
Joined: Thu May 16, 2019 8:44 am

Problem with start program

Thu May 16, 2019 8:54 am

I wrote a program in c, the compilation ran OK, the program has to display pictures with a time delay, the start of the presentation follows after receiving "15" by UART. Library for displaying SDL_images. Unfortunately, I have 2 problems.
At the first start of the program, I pop out in the "Segmentation fault" terminal and I do not know what may be caused. Calling the program the second time does not start, it starts after using the CTRL + C command.
What could be the reason?

Code: Select all

#include <unistd.h>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <errno.h>
#include <fcntl.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <wiringPi.h>


	SDL_Surface *screen = NULL;
	SDL_Surface *image = NULL;
    const SDL_VideoInfo *videoInfo = NULL;
	
	
int set_interface_attribs(int fd, int speed)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        return -1;
    }

    cfsetospeed(&tty, (speed_t)speed);
    cfsetispeed(&tty, (speed_t)speed);

    tty.c_cflag |= (CLOCAL | CREAD);    /* ignore modem controls */
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8;         /* 8-bit characters */
    tty.c_cflag &= ~PARENB;     /* no parity bit */
    tty.c_cflag &= ~CSTOPB;     /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS;    /* no hardware flowcontrol */

    /* setup for non-canonical mode */
    tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
    tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tty.c_oflag &= ~OPOST;

    /* fetch bytes as they become available */
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 1;

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

void set_mincount(int fd, int mcount)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) < 0) {
        printf("Error tcgetattr: %s\n", strerror(errno));
        return;
    }

    tty.c_cc[VMIN] = mcount ? 1 : 0;
    tty.c_cc[VTIME] = 5;        /* half second timer */

    if (tcsetattr(fd, TCSANOW, &tty) < 0)
        printf("Error tcsetattr: %s\n", strerror(errno));
}

void play(int n)
{
	switch(n){
		case 0:
		{
				image = IMG_Load("start.jpg");
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);
		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		SDL_Delay(2000);
		}
		break;
		case 1:
		{
				image = IMG_Load("1.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 2:
		{
				image = IMG_Load("2.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 3:
		{
				image = IMG_Load("3.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 4:
		{
				image = IMG_Load("4.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 5:
		{
				image = IMG_Load("5.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 6:
		{
				image = IMG_Load("6.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 7:
		{
				image = IMG_Load("7.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		case 8:
		{
				image = IMG_Load("8.jpg");
		
		screen = SDL_SetVideoMode(image->w,
								  image->h,
								  videoInfo->vfmt->BitsPerPixel,
								  SDL_HWSURFACE);

		SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
		//SDL_Delay(6000);
		}
		break;
		
		
}
}




int main(void)
{
	int time_delay = 100;
	char *portname = "/dev/ttyS0";
    int fd;
    //int wlen;
	wiringPiSetup () ;
	pinMode (1, INPUT) ;
	pullUpDnControl (1, PUD_UP) ;
		
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
		{
			fprintf(stderr, "SDL_Init failed - %s\n", SDL_GetError());
			//return 1;
		}

		/////////////////////////////////////////////////////////

		videoInfo = SDL_GetVideoInfo();

		if (videoInfo == 0)
		{
			fprintf(stderr, "SDL_GetVideoInfo failed - %s\n", SDL_GetError());
			SDL_Quit();
			//return 1;
		}

		
    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd < 0) {
        printf("Error opening %s: %s\n", portname, strerror(errno));
        return -1;
    }
    set_interface_attribs(fd, B19200);
	
    	
int zdjecie_nr;
int licznik_czasu = 0;

    play(0);

	do {
		unsigned char buf[80];
        int rdlen;
		
	
		rdlen = read(fd, buf, sizeof(buf) - 1);
        if (rdlen > 0) {
            if(buf[0]==15)
				
			for(zdjecie_nr = 1; zdjecie_nr<9; zdjecie_nr++){
				
				play(zdjecie_nr);
				
				licznik_czasu=0;
				
				
				do{		
					if ( digitalRead(1) == 0 ) break; 
					SDL_Delay(time_delay);
					
					++licznik_czasu;
				}while( (licznik_czasu < 100) );
		
				SDL_Delay(100);
				SDL_FreeSurface(image);
				} // koniec for	
			} // koniec if 1
		
			play(0);
			
   
	}while(1);

    
	
    SDL_Quit();
    return 0;
}

User avatar
Paeryn
Posts: 2516
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Problem with start program

Thu May 16, 2019 11:27 am

To know where the program crashes (and to debug it) compile with debugging info -g and run it with gdb

Code: Select all

[email protected]:~/Programming/sdl $ gcc -g sdltest.c -o sdltest $(pkg-config --cflags --libs sdl) -lSDL_image  -lwiringPi
[email protected]:~/Programming/sdl $ gdbtui sdltest
When in gdb run the program with run, when it segfaults gdb will show you the line where it happened (you may need to press CTRL-L to redraw the screen if the program printed anything)

Code: Select all

   ┌──sdl.c────────────────────────────────────────────────────────────────────┐
   │68      void play(int n)                                                   │
   │69      {                                                                  │
   │70        switch (n) {                                                     │
   │71        case 0:                                                          │
   │72          {                                                              │
   │73            image = IMG_Load("start.jpg");                               │
  >│74            screen = SDL_SetVideoMode(image->w,                          │
   │75                                      image->h,                          │
   │76                                      videoInfo->vfmt->BitsPerPixel, SDL_│
   │77            SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie    │
   │78            SDL_Delay(2000);                                             │
   │79          }                                                              │
   │80          break;                                                         │
   │81        case 1:                                                          │
   └───────────────────────────────────────────────────────────────────────────┘
multi-thre Thread 0x75db75f0 ( In: play                       L74   PC: 0x10d78
(gdb) run
Starting program: /home/pi/Programming/sdl/sdltest
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
play (n=0) at sdl.c:74
(gdb) quit
You aren't checking if the images you are trying to load are actually being loaded (e.g. the images aren't in the current working directory), that would giver you a NULL pointer which you proceed to try and dereference in the next line which will cause a segfault.

Code: Select all

    case 0:
    {
      image = IMG_Load("start.jpg");
      screen = SDL_SetVideoMode(image->w,
                                image->h,
                                videoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE);
      SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
      SDL_Delay(2000);
    }
    break;
Add in a check that the image loaded :-

Code: Select all

    case 0:
    {
      image = IMG_Load("start.jpg");
      if (image) {
        screen = SDL_SetVideoMode(image->w,
                                  image->h,
                                  videoInfo->vfmt->BitsPerPixel, SDL_HWSURFACE);
        SDL_BlitSurface(image, 0, screen, 0); // wyswietl zdjecie
        SDL_Delay(2000);
      }
      else {
        printf("Failed to load start.jpg\n");
      }
    }
    break;

She who travels light — forgot something.

grzanix
Posts: 2
Joined: Thu May 16, 2019 8:44 am

Re: Problem with start program

Thu May 16, 2019 12:03 pm

Thanks for the response. I started with gdb,

Code: Select all

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
SDL_Init failed - Unable to open a console terminal
(gdb) tVideoInfo failed - Unable to open a console terminal
Error opening /dev/ttyS0: Permission denied
[Inferior 1 (process 922) exited with code 0377]
I wonder why he has a problem with opening the UART port, after receiving the porgram he receives this data .. :shock:
I can not solve the error with functions from the SDL library

You know why after each launch of the program using sudo ./main the program does not start, only after pressing in the CTRL-C terminal?

Return to “C/C++”