Linux serial port cross compile

OP #5056652
Lesenswert?

Guten Tag,

versuche über die serielle Schnittstelle (c Code) einen Sensor 
anzusprechen.
Dieser liefert mir anschließend seine Messdaten zurück.

Starte ich den Code auf dem Linux Laptop funktioniert die Verbindung 
einwandfrei.
Nun mache ich ein cross compile für meinen Embedded Linux Controller. 
Code ist der gleiche nur Port ändert sich.

Der recv buffer bleibt jedoch leer. Daten werden gesendet. Verkabelung 
stimmt ebenfalls.
1
#include <errno.h>
2
#include <fcntl.h> 
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <termios.h>
7
#include <unistd.h>
8
#include <sys/select.h>
9
#include <sys/time.h>
10
#include <sys/types.h>
11
#include <sys/ioctl.h>
12

13
int set_interface_attribs(int fd, int speed)
14
{
15
    struct termios tty;
16

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

22
    cfsetospeed(&tty, (speed_t)speed);
23
    cfsetispeed(&tty, (speed_t)speed);
24

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

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

37
    /* fetch bytes as they become available */
38
    tty.c_cc[VMIN] = 49;
39
    tty.c_cc[VTIME] = 10;
40

41
    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
42
        printf("Error from tcsetattr: %s\n", strerror(errno));
43
        return -1;
44
    }
45
  sleep(2);
46
  if (tcsetattr(fd, TCSAFLUSH, &tty) != 0) {
47
        printf("Error from tcsetattr: %s\n", strerror(errno));
48
        return -1;
49
    }
50
    return 0;
51
}
52

53
int main()
54
{
55
    char *portname = "/dev/ttyS1";
56
    int fd = 0;
57
    int wlen;
58
    unsigned char send_bytes[] ={0xde,0x01,0x05,0x59,0x83};
59

60
    fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
61
    if (fd < 0) {
62
        printf("Error opening %s: %s\n", portname, strerror(errno));
63
        return -1;
64
    }
65
    set_interface_attribs(fd, B115200);
66

67
  //wlen = write(fd, send_bytes, 5);
68

69
  int maxfd,n;
70
  maxfd = fd + 1;
71

72
    struct timeval timeout;
73
    fd_set readSet;
74
  unsigned char buf[254];
75
  int rdlen;
76

77
  do {
78
    /*
79
  wlen = write(fd,"\xde\x01\x05\x59\x83", 5);
80

81
  if (wlen != 5) {
82
    printf("Error from write: %d, %d\n", wlen, errno);
83
  }
84
  */
85
  printf("-->\n");
86

87
  timeout.tv_usec = 0;  // milliseconds
88
  timeout.tv_sec  = 1;  // seconds
89

90
  FD_ZERO(&readSet);
91
  FD_SET(fd,&readSet);
92
  
93
  n = select(maxfd,&readSet, NULL, NULL,&timeout);
94
  if (n>0)
95
  {
96
    if (FD_ISSET(fd, &readSet))
97
    {
98
    printf("--reading--->\n");
99
    rdlen = read(fd, buf, sizeof(buf) - 1);
100
    printf("length: %i\n",rdlen);
101

102
    if (rdlen > 1) {
103
      unsigned char   *p;
104
      printf("Read %d:", rdlen);
105
      for (p = buf; rdlen-- > 0; p++)
106
        printf(" 0x%x", *p);
107
      printf("\n");
108
    } else if (rdlen <= 0) {
109
      printf("Error from read: %d: %s\n", rdlen, strerror(errno));
110
    }
111
    }
112
  }
113
  else if(n<=0)
114
  {
115
    printf("FEHLER\n");
116
  }
117
  }while (1);
118
close(fd);
119
}
#5056672
Lesenswert?

Laß' dir mal fd und FD_SETSIZE ausgeben (fd muß kleiner sein, sonst 
tut's nicht).

select() kann auf den "großen" Linuxen normalerweise bis zum 
File-Deskriptor 255 benutzt werden, es kann aber durchaus sein, daß das 
beim embedded Linux beschnitten wurde.

Dann bliebe nur, stattdessen poll() zu benutzen (ist wahrscheinlich 
sowieso die bessere Idee).
OP #5056684
Lesenswert?

Markus F. schrieb:
> Laß' dir mal fd und FD_SETSIZE ausgeben (fd muß kleiner sein, sonst
> tut's nicht).
>
> select() kann auf den "großen" Linuxen normalerweise bis zum
> File-Deskriptor 255 benutzt werden, es kann aber durchaus sein, daß das
> beim embedded Linux beschnitten wurde.
>
> Dann bliebe nur, stattdessen poll() zu benutzen (ist wahrscheinlich
> sowieso die bessere Idee).

Ich bin noch sehr am Anfang mit meinen Kenntnissen.
Habe nun folgendes versucht:

Führe den Sende Code auf dem Rechner aus und den Empfangscode auf dem 
Embedded Controller. -> Daten werden auf dem Controller empfangen.

Nun das gleiche anders herum. Und die Daten werden auf dem Rechner 
empfangen.
Der Code müsste als soweit stimmen.
Nur wenn Senden und Empfangen auf dem Controller läuft kackt er ab.
#5056711
Lesenswert?

Abgesehen von der potentiellen select() Problematik: Dir ist bewußt, daß 
Du Software-Handshake eingeschaltet hast (IXON)?

Das schließt eigentlich Binärdatenübertragung (die wohl - wie die 
auskommentierte Senderoutine zu implizieren scheint - gewünscht ist?) 
aus...
OP #5056751
Lesenswert?

Markus F. schrieb:
> Abgesehen von der potentiellen select() Problematik: Dir ist bewußt, daß
> Du Software-Handshake eingeschaltet hast (IXON)?
>
> Das schließt eigentlich Binärdatenübertragung (die wohl - wie die
> auskommentierte Senderoutine zu implizieren scheint - gewünscht ist?)
> aus...

Nein das war mir nicht bewusst. Habe es nun auf OFF
fd liefert mir eine 3.
Trotzdem läuft es auf dem Controller nicht.
OP #5057617
Lesenswert?

Hallo,

wie schon erwähnt funktioniert die Schnittstelle schon. Und der Port ist 
ebenfalls richtig.

Wenn ich den Code nur auf die Read Funktion reduziere und dann auf dem 
Embedded ausführe werden Daten empfangen. (PC<-->EmbController).

Wenn ich den Code nur auf die Write Funktion reduziere und auf dem 
Embedded ausführe werden Hex Daten(Binär) 
gesendet.(PC<-->EmbController).

Wenn der Code vollständig ist. Also write dann anschließend read. 
Funktioniert es nicht.

Mit der shell habe ich es auch schon probiert. Dies funktioniert 
ebenfalls.
OP #5057771
Lesenswert?

Chris schrieb:
> Und mit einem normalen Terminalprogramm auf der seriellen Schnittstelle
> funktioniert alles?
> Es könnte auch am Treiber der seriellen Schnittstelle liegen.

ich kann über diese Schnittstelle Daten empfangen. Also Daten (binär) 
die ich vom PC sende.

wenn ich rein diesen code Ausführe
1
dlen = read(fd, buf, sizeof(buf) - 1);

das gleiche auch in die andere Richtung.
Habe es noch zusätzlich mit dem Oszi überprüft. Stimmt soweit alles.

habe es auch über das Terminal versucht:

cat /dev/ttyS2

Daten werden empfangen vom PC.


Sobald write and read (Code erster Post) ausgeführt wird bleibt der 
Buffer leer.
Ich habe das schon an einer 2ten ser Schnittstelle versucht. Gleiches 
Ergebnis.

Habe etwas gelesen über die poll Funktion. Kann mir da jmd eine Hilfe 
dazu geben.
OP #5057855
Lesenswert?

Habe das alles nun auch über das Terminal versucht.

echo -ne "\xde\x01..usw." > /dev/ttyS2

über 2tes Terminal Fenster

cat /dev/ttyS2

Gesendet und empfangen wird etwas (Oszi). Jedoch zeigt die cat Funktion 
nichts an.

Führe ich rein cat /dev/ttyS2 aus. Und sende die Daten über den PC 
funktioniert es.

So habe alles nochmal als python script getestet. Auf dem Rechner läufts 
wieder und auf dem Controler nicht (buffer LEER)
1
import serial
2

3
ser = serial.Serial('/dev/ttyS2', 115200, timeout=1)
4

5
if(ser.isOpen()):
6
    print'serial is not open'
7

8

9
while True:
10
    
11

12
    ser.write([0xde, 0x01, 0x05, 0x59, 0x83]) 
13
    reply = ser.read(100)
14

15
    if len(reply) == 0:
16
        print'length = LEER'
17
        #break
18
    print len(reply)
19

20
print'Serial close'
21
ser.close()

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren