Forum: Mikrocontroller und Digitale Elektronik Posix Thread Fehler bei Übergabe mehrerer Parameter?


von Tuxi (Gast)


Lesenswert?

Hallo Forum,

ich habe hier ein kleines Problem:
1
//In der main
2
int
3
main (void)
4
{
5
  Config * Config_PTR = NULL;
6
  SPI_Par * SPI_Param = NULL;
7
  //Initialisierung
8
  init_Soft (&Config_PTR, &SPI_Param); //Hiernach sind Zeiger mit Structs belegt!!
9
  Thread Thread_Struct =
10
    { Config_PTR, SPI_Param };
11
  pthread_t threads[5];
12
//Bis hierhin stimmt alles!!
13
14
while (pthread_create (&threads[5], NULL, state_get_Mess_Data, &Thread_Struct)
15
      != 0)
16
    printf ("Fehler Thread state_get_Mess_Data!");
17
.
18
.
19
.
20
21
//Hier Thread Anfang
22
void *
23
state_get_Mess_Data (void * Give_Thread_Struct)
24
{
25
  Thread * Thread_Struct = (Thread *) Give_Thread_Struct;//Diese Adresse stimmt noch!
26
27
  Config * Config_PTR = (Config *) (Thread_Struct->Config_PTR); //Die Adresse Stimmt plötzlich nicht mehr!
28
  SPI_Par * SPI_Param = (SPI_Par *) (Thread_Struct->SPI_Param); //Diese Adresse stimmt noch!
29
  int_fast8_t ret;
30
  while (1)
31
    {

In der main werden die Pointer mit structs belegt worin Parameter stehen 
die innerhalb des Threads benötigt werden.

Nach dem start des Threads stimmt auf einmal die Adresse für den 
Config_PTR nicht mehr und die Daten innerhalb dieses structs sind Müll. 
Komischweise stimmt aber die Adresse das SPI_Param structs noch.

Wo liegt denn hier mein Fehler?

von Tuxi (Gast)


Lesenswert?

Achja ich habe noch einen 2. Thread der dieses struct übergeben bekommt:
1
//In der main()
2
    while (pthread_create (&threads[4], NULL, state_Flash_Firm,
3
           &Thread_Struct) != 0)
4
  printf ("Fehler Thread state_Flash_Firm!");
5
6
7
//Thread Anfang
8
void *
9
state_Flash_Firm (void * Give_Thread_Struct)
10
{
11
  Thread * Thread_Struct = (Thread *) Give_Thread_Struct;
12
  Config * Config_PTR =  (Config *) (Thread_Struct->Config_PTR);
13
  SPI_Par * SPI_Param = (SPI_Par *) (Thread_Struct->SPI_Param);
14
  int status = 0;
15
  while (1)

Hier stimmt aber alles und Config_PTR zeigt auf die richtige Adresse!

von Peter II (Gast)


Lesenswert?

Tuxi schrieb:
> Thread Thread_Struct =
>     { Config_PTR, SPI_Param };
>   pthread_t threads[5];

kann es sein, das du den Gültigkeitsbereich der Variablen verlässt?

Leist zeigst du nicht wie der code weiter geht.

von Tuxi (Gast)


Lesenswert?

1
int
2
main (void)
3
{
4
  Config * Config_PTR = NULL;
5
  SPI_Par * SPI_Param = NULL;
6
  //Initialisierung
7
  init_Soft (&Config_PTR, &SPI_Param);
8
  Thread Thread_Struct =
9
    { Config_PTR, SPI_Param };
10
  pthread_t threads[5];
11
12
   //TESTS
13
   //system("wvdial pin");
14
   //state_feed_Watchdog(&WD_feeding_time);
15
   //state_SD_mount_umount(NULL);
16
   //flash_dsp(Config_PTR ,SPI_Param);
17
   //state_get_Mess_Data(&Thread_Struct);
18
   //state_Flash_Firm(&Thread_Struct);
19
   //state_Transfer_Data( Config_PTR);
20
21
   //exit(0);
22
   //TESTS OFF
23
24
  //Threads starten
25
  //while (pthread_create (&threads[1], NULL, state_SD_mount_umount, NULL) != 0)
26
   // printf ("Fehler Thread state_SD_mount_umount!");
27
  //while (pthread_create (&threads[2], NULL, state_SD_copy, Config_PTR) != 0)
28
   // printf ("Fehler Thread state_SD_copy!");
29
/*
30
  if (!(Config_PTR->SD_Only))
31
    {
32
      while (pthread_create (&threads[3], NULL, state_Transfer_Data, Config_PTR)
33
    != 0)
34
  printf ("Fehler Thread state_Transfer_Data!");
35
      while (pthread_create (&threads[4], NULL, state_Flash_Firm,
36
           &Thread_Struct) != 0)
37
  printf ("Fehler Thread state_Flash_Firm!");
38
   }
39
*/
40
  //DSP Reset für definierten Anfangszustand
41
  dsp_reset ();
42
43
  while (pthread_create (&threads[5], NULL, state_get_Mess_Data, &Thread_Struct)
44
      != 0)
45
    printf ("Fehler Thread state_get_Mess_Data!");
46
while(1)
47
  sleep(1000);
48
  //Start / feed Watchdog
49
  size_t WD_feeding_time = 20; //in s
50
  state_feed_Watchdog (&WD_feeding_time);
51
52
  //Close bzw. sollte niemals hierhin kommen!
53
  deinit_Soft (&Config_PTR, &SPI_Param);
54
  exit (0);
55
}

von Tuxi (Gast)


Lesenswert?

So sieht die Gesamte main() momentan aus.

Ich habe einmal nur den einen Thread (4) gestartet und dort passt alles.
Dann habe ich einmal nur Thread (5) gestartet und da ist dann der Zeiger 
auf Config_PTR innerhalb des Thread_Struct ganz woanders wo natürlich 
nur mist drin steht..

Obwohl ja beides mal der Code sehr ähnlich bzw. gleich ist.

Läuft übrigens unter Embedded Linux.

von Achim K. (aks)


Lesenswert?

Mit oder ohne Optimierung compiliert?

von Karl H. (kbuchegg)


Lesenswert?

Tuxi schrieb:

Zeig mal deine init_Soft.

Bei so etwas

>
1
>   Config * Config_PTR = NULL;
2
>   SPI_Par * SPI_Param = NULL;
3
>   //Initialisierung
4
>   init_Soft (&Config_PTR, &SPI_Param);
5
6
>

hab ich ein ganz schlechtes Bauchgefühl. Wozu die Adressen der Pointer 
übergeben? Normalerweise würde man in main einfach Strukturobjekte 
anlegen, deren Adressen an init_Soft übergeben, die dann die relevanten 
Informationen in die Strukturobjekte schreibt und gut ists. Wenn 
init_Soft aber die Adresse der Pointer kriegt, dann murmelt mein 
Bauchgefühl 'Der hat da sicher die Adresse von funktionslokalen 
Variablen in die Pointer geschrieben und wundert sich, dass die Objekte 
nicht mehr regulär existieren, nachdem die Funktion verlassen wurde'.

von Tuxi (Gast)


Lesenswert?

1
//Struct mit allen nötigen Konfigurations Parametern!
2
struct Config_Var
3
{
4
  volatile int_least8_t SD_Only; //Flag wenn nur auf SD-Card
5
.
6
.
7
.
8
. 
9
  volatile char Junk_Folder[MAX];
10
  volatile char time_buffer[MAX];
11
  volatile char Flashed_Firmware[MAX];
12
  volatile pid_t UMTS_PID;
13
};
14
typedef struct Config_Var Config;
15
16
struct SPI_Parameter
17
{
18
  volatile char device[MAX];
19
  volatile int fd;
20
  volatile uint_least8_t mode;
21
  volatile uint_least8_t bits;
22
  volatile uint32_t speed;
23
  volatile uint16_t delay;
24
  volatile uint_least8_t cs;
25
};
26
typedef struct SPI_Parameter SPI_Par;
27
28
struct thread_data
29
{
30
  volatile Config * Config_PTR;
31
  volatile SPI_Par * SPI_Param;
32
};
33
typedef struct thread_data Thread;

von Peter II (Gast)


Lesenswert?

> pthread_t threads[5];
> &threads[5]

was stimmt hier wohl nicht?

von Achim K. (aks)


Lesenswert?

Peter II schrieb:
>> pthread_t threads[5];
>> &threads[5]
>
> was stimmt hier wohl nicht?

Sehr gut gesehen! Dann muss man das mit der Optimierung nicht mehr 
untersuchen ;-).

von Tuxi (Gast)


Lesenswert?

1
void
2
init_Soft (Config ** Config_PTR, SPI_Par ** SPI_Param)
3
{
4
  
5
  *Config_PTR = start_param ();
6
  init_param (*Config_PTR);
7
  *SPI_Param = init_SPI ("/dev/spidev1.0", SPI_MODE_1, 16, 10000, 0, 1);
8
  //Not send Data?
9
  Config * TMP = *Config_PTR;
10
  if (not_send_Data_there ())
11
    TMP->Not_send_Data = 1;
12
  else
13
    TMP->Not_send_Data = 0;
14
}
1
Config *
2
start_param ()
3
{
4
  Config * Config_PTR = NULL;
5
  Config_PTR = (Config *) malloc (sizeof(Config));
6
  while (Config_PTR == NULL)
7
    {
8
      printf ("No Space left in RAM!");
9
      Config_PTR = (Config *) malloc (sizeof(Config));
10
    }
11
  load_default_param (Config_PTR);
12
  return (Config_PTR);
13
}
14
15
int_fast8_t
16
init_param (Config * const Config_PTR)
17
{
18
  int_fast8_t Loaded = 0;
19
  char * Param_Target = build_target (Config_PTR->ParamFile_Path,
20
                                      Config_PTR->ParamFile_File);
21
  FILE * Start_Param = NULL;
22
  Start_Param = fopen (Param_Target, "r");
23
  free (Param_Target);
24
  Param_Target = NULL;
25
  if (Start_Param == NULL) load_default_param (Config_PTR);
26
  else
27
    {
28
      while (Loaded == 0)
29
        {
30
          Loaded = load_param_file (Config_PTR, Start_Param);
31
          if (Loaded == 0)
32
            {
33
              load_default_param (Config_PTR);
34
              break;
35
            }
36
        }
37
    }
38
  if (Start_Param != NULL)
39
    {
40
      fclose (Start_Param);
41
      Start_Param = NULL;
42
    }
43
  return (Loaded);
44
}
45
46
void
47
load_default_param (Config * const Config_PTR)
48
{
49
  Config_PTR->SD_Only = Default_SD_Only_INT;
50
  Config_PTR->Clean_SD_Messdata = Default_Clean_SD_Messdata_INT;
51
  Config_PTR->Time_Lap = Default_Time_Lap;
52
.
53
.
54
.
55
}
56
57
int_fast8_t
58
load_param_file (Config * const Config_PTR, FILE* Start_Param)
59
{
60
  int8_t OPTSDONLY = 0, OPTSDCLEAN = 0, OPTTIMELAP = 0, OPTHOSTPORT = 0,
61
      OPTHOSTIP = 0, OPTUSERSFTP = 0, OPTPWSFTP = 0, OPTMESSPATH = 0,
62
      OPTFIRMPATH = 0, OPTFIRMFILE = 0, OPTFIRMFILESHA1 = 0, OPTPARAMPATH = 0,
63
      OPTPARAMFILE = 0, OPTPARAMFILESHA1 = 0,/* OPTPARNAM = 0,*/OPTFIRMNAM = 0;
64
  const char delim[] =
65
    { '=', ';' };
66
  volatile char * TMP = NULL;
67
  volatile char * TMP2 = NULL;
68
  volatile char * tok_buf;
69
  TMP = malloc (sizeof(char) * MAX);
70
  while (TMP == NULL)
71
    {
72
      printf ("No Space left in RAM!");
73
      TMP = malloc (sizeof(char) * MAX);
74
    }
75
  /*tok_buf = malloc(sizeof(char) * MAX);
76
   while (tok_buf == NULL) {
77
   printf("No Space left in RAM!");
78
   tok_buf = malloc(sizeof(char) * MAX);
79
   }*/
80
  /* TMP2 = malloc (sizeof(char) * MAX);
81
   while(TMP"" == NULL)
82
   {
83
   printf("No Space left in RAM!");
84
   TMP2 = malloc (sizeof(char) * MAX);
85
   }*/
86
  while (!OPTOK)
87
    {
88
      if ((fgets (TMP, (sizeof(char) * MAX), Start_Param) == NULL) && !OPTOK)
89
        {
90
          free (TMP);
91
          TMP = NULL;
92
          TMP2 = NULL;
93
          return (0);
94
        }
95
      del_n (TMP);
96
      TMP2 = strtok_r (TMP, delim, &tok_buf);
97
      if (TMP2 == NULL && !OPTOK)
98
        {
99
          printf ("Nothing in Token!\n");
100
          free (TMP);
101
          TMP = NULL;
102
          TMP2 = NULL;
103
          return (0);
104
        }
105
      if (!(strncmp (TMP2, "SDOnly", (sizeof(char) * strnlen ("SDOnly", NMAX)))))
106
        {
107
          TMP2 = strtok_r (NULL, delim, &tok_buf);
108
          if (!(strncmp (TMP2, "YES", (sizeof(char) * strnlen ("YES", NMAX))))) Config_PTR->SD_Only =
109
              1;
110
          else if (!(strncmp (TMP2, "NO", (sizeof(char) * strnlen ("NO", NMAX))))) Config_PTR->SD_Only =
111
              0;
112
          else Config_PTR->SD_Only = Default_SD_Only_INT;
113
          OPTSDONLY = 1;
114
          continue;
115
        }
116
      else if (!strncmp (TMP2, "CleanSDMessdata",
117
                         (sizeof(char) * strnlen ("CleanSDMessdata", NMAX))))
118
        {
119
          TMP2 = strtok_r (NULL, delim, &tok_buf);
120
          if (!(strncmp (TMP2, "YES", (sizeof(char) * strnlen ("YES", NMAX))))) Config_PTR->Clean_SD_Messdata =
121
              1;
122
          else if (!(strncmp (TMP2, "NO", (sizeof(char) * strnlen ("NO", NMAX))))) Config_PTR->Clean_SD_Messdata =
123
              0;
124
          else Config_PTR->Clean_SD_Messdata = Default_Clean_SD_Messdata_INT;
125
          OPTSDCLEAN = 1;
126
          continue;
127
        }
128
      else if (!strncmp (TMP2, "TimeLap",
129
                         (sizeof(char) * strnlen ("TimeLap", NMAX))))
130
        {
131
          TMP2 = strtok_r (NULL, delim, &tok_buf);
132
          Config_PTR->Time_Lap = (uint32_t) atoi (TMP2);
133
          OPTTIMELAP = 1;
134
          continue;
135
        }
136
.
137
.
138
.
139
}

von Peter II (Gast)


Lesenswert?

Achim K. schrieb:
>>> &threads[5]
>>
>> was stimmt hier wohl nicht?
>
> Sehr gut gesehen! Dann muss man das mit der Optimierung nicht mehr
> untersuchen ;-).

ist mir nur aufgefallen weil
1
&threads[5]
schon selber merkwürdig ist.

von Tuxi (Gast)


Lesenswert?

Okay.... habs verrafft...

Danke..

von Peter II (Gast)


Lesenswert?

> volatile char * TMP = NULL;

funktionslokale variabel als volatile ist auch wenig sinn.

von Tuxi (Gast)


Lesenswert?

Das mit init_Soft und so ist später dazugekommen... Daher ist es leider 
mittlerweile etwas unübersichtlicher geworden...

von Tuxi (Gast)


Lesenswert?

Jap, das mit volatile sagt mir mein Compiler bereits.. aber er schluckt 
es..
Werde ich vll irgendwann überall noch rausnehmen.

von Karl H. (kbuchegg)


Lesenswert?

Tuxi schrieb:

<C Code für init_Soft und weitere Funktionen>

ein bischen ein malloc Fetischist bist du zwar schon, aber das sieht 
erst mal in Ordnung aus.

von Tuxi (Gast)


Lesenswert?

Läuft auch nachdem ich die Thread nochmal korrekt durchnummerriert habe.

Danke für die schnelle Hilfe, das hätte ich wahrscheinlich die nächsten 
3 Stunden überlesen..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.