Forum: PC-Programmierung Raspberry Pi Programmierung C - nach 15 Minuten kein Dateizugriff möglich


von David T (Gast)


Lesenswert?

Hi,

ich programmiere gerade ein Raspberry (mit Minibian) in C. Dieser soll 
mittels SPI, I2C, GPIO und einem UnixSocket verschiedene Aufgaben 
ausführen.

Dabei wird pro Sekunde ungefähr 100 mal auf SPI, 100 mal auf GPIO, 200 
mal auf TWI zugegriffen. Nach ziemlich genau 15 Minuten ist jedoch kein 
Zugriff mehr möglich, auf keine dieser Schnittstellen. Ich kann sie 
weder öffnen, schließen oder etwas hineinschreiben. Erst ein 
Programmneustart bringt Abhilfe (für 15 Minuten).

Mein Zugriff auf die Dateien ist immer gleich :
1
int i2c_start(uint8_t deviceadress)
2
{
3
  int result;
4
  int fd;
5
  char error_code[100];
6
7
  fd = open(I2C_FILE, O_RDWR);
8
9
  if(fd < 0) {
10
    output_error("I2C: Failed to open file\n");
11
    snprintf(error_code, 100, "i2c_start : Failed to open file, Code : %d",fd);
12
    output_error_detail(error_code, "i2cfox.c");
13
    return -1;
14
  }
15
16
  result = ioctl(fd,I2C_SLAVE,deviceadress);
17
18
  if(result<0)
19
  {
20
    output_error("I2C Error: ioctl \n");
21
    return -1;
22
  }
23
24
  return fd;
25
}
26
27
int i2c_close(int fd)
28
{
29
  int result;
30
31
  result = close(fd);
32
33
  if(result < 0)
34
  {
35
    output_error("I2C Error: error by closing file\n");
36
  }
37
38
  return result;
39
40
}

Hat dazu jemand eine Idee wie ich an die Fehlerfindung herangehe ?

von Andreas E. (hismastersvoice)


Lesenswert?

Im Fehlerfall von ioctl solltest Du den Descriptor schliessen, da sonst 
ein Ressourcenleck entsteht (bei ioctl hat Dein Programm diese Ressource 
schon, gibt sie im Fehlerfall aber nicht zurück => Ressourcenleck).

Ob es das war, kann man nicht sagen, da das drumherum fehlt.

Die Stelle ist aber auf jeden Fall problematisch und sollte korrigiert 
werden.

von Florian (Gast)


Lesenswert?

File descriptor limit erricht war auch mein erster Gedanke.

von Andreas E. (hismastersvoice)


Lesenswert?

Nochmal zu Deiner Frage:

Wenn der Fehler auftritt und das Programm noch läuft, schaue im 
Verzeichnis /proc/<pid>/fd nach, ob das zugemüllt mit Eintragen ist.

<pid> ist die Pid Deines Prozesses.

Mit ulimit -n  kannst Du sehen, wieviele Deskriptoren Dein Prozess haben 
darf. Ist meist auf 1024 limitiert.

Mit 'ls /proc/<pid>/fd | wc -l' siehst Du, ob Dein Prozess den Wert 
erreicht hat.

Wenn ja, war das oben beschriebene wahrscheinlich Dein Problem.

Wenn nicht, solltest Du den Code drumherum zeigen.

: Bearbeitet durch User
von David T (Gast)


Lesenswert?

Danke, das war's. Habe mir die Nummer der Filediscriptoren ausgeben 
lassen und die steigen an. In dem Verzeichnis sind nach 8 Minuten über 
25000 Einträge und es wurde mehr.

Hab den Fehler gefunden (auf einmal ganz einfach wenn man einen Ansatz 
hat), hatte vergessen die SPI Schnittstelle nach Verwendung zu 
schließen.

Werde dein Hinweis zwecks itoa berücksichtigen, muss ich mir nur noch 
Gedanken um's Fehlermanagment machen.

Nochmals Vielen Dank, da wäre ich selber wohl nicht so schnell drauf 
gekommen.

von Karl H. (kbuchegg)


Lesenswert?

Ich denke du solltest auch in die Richtung überlegen, nicht jedesmal die 
Schnittstellen zu öffnen, ein bischen was raus/rein zu schieben und dann 
alles wieder zu schliessen.
Spricht irgend etwas dagegen, die entsprechenden Devices bei 
Programmstart zu öffnen und dann ganz einfach die ganze Zeit während des 
Programmlaufs offen zu halten? Mit ständigem File auf / File zu kann man 
nämlich auch eine Maschine ganz wunderbar ausbremsen.

von David T. (Gast)


Lesenswert?

Es bringt mir keine Vorteile die Schnittstellen offen zu halten da mein 
Messgerät nur mit 100Hz misst. Ein ständiges offen halten der SPI und 
I2C Schnittstelle ändert daran nichts.
Das einzige was sich ändern könnte wäre die Last auf dem System, das 
könnte ich mal untersuchen wenn ich noch Zeit habe.

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.