serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array zu S

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array zu S

Beitrag von Sallos » 30.05.2013 19:38:16

Moin,

ich habe ein PC mit RS485 Schnittstelle der Chip ist ein "serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A".

Ich habe diese Test Programm ausprobiert:

Code: Alles auswählen

/* 485-example.c : Basic example of RS485 half duplex transmission */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>

#include <sys/ioctl.h>
#include <asm/ioctls.h>

#include <linux/serial.h>

int main(void)
{
   char dev[] = "/dev/ttyS0";
   char tosend[] = {'A', 'B', 'C'};
   struct serial_rs485 ctrl485;
   int status;
   int fd;

   struct termios ti;
   speed_t speed;

   /* Open the port */
   fd = open(dev, O_RDWR);
   if (fd < 0) {
      printf("%s: Unable to open.\n", dev);
      return -1;
   }

   /* Set the port in 485 mode */
   ctrl485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
   ctrl485.delay_rts_before_send = 0;
   ctrl485.delay_rts_after_send = 0;

   status = ioctl(fd, TIOCSRS485, &ctrl485);
   if (status) {
      printf("%s: Unable to configure port in 485 mode, status (%i)\n", dev, status);
      return -1;
   }

   /* Set the port speed */
   speed = B9600;
   tcgetattr(fd, &ti);
   cfsetospeed(&ti, speed);
   cfsetispeed(&ti, speed);
   tcsetattr(fd, TCSANOW, &ti);

   /* Send content to RS485 */
   if (write(fd, tosend, sizeof(tosend)) != sizeof(tosend)) {
      printf("%s: write() failed\n", dev);
   }

   return 0;
}

Und irgdnwie kann er diese TIOCSRS485 Eigenschaften nicht setzten....:-(

Kann der Chip das nicht? Ich steh da irgendwie auf dem Schlauch...........

Ich habe schon versucht mit minicon über RS485 zu kommunizieren aber ich kann irgdnwei nur sende....empfangen geht gar nicht :-(



Wäre nett wenn jemand einen Tip hat
Zuletzt geändert von Sallos am 02.06.2013 22:04:43, insgesamt 1-mal geändert.

Benutzeravatar
Jerry
Beiträge: 665
Registriert: 01.09.2006 08:36:45
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: /home

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von Jerry » 30.05.2013 21:05:40

ich kenne nur einen Chip der RS485 unterstützt und das ist die serielle Schnittstelle vom AT91RM92x. Der Standard-8250 unterstützt RS485 nicht.
Gruß Wolf
Selbst der längste Weg beginnt mit dem ersten Schritt Lao Tse (~ 600-400 v. Chr.)

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von cosmac » 30.05.2013 22:51:50

hi,

was ist denn das für eine Hardware? Gibt's dazu evt. ein Schaltbild? Wenn der UART "von innen" wie ein 16550 aussieht, benutzt er evt. den RTS-Ausgang für die RX/TX-Umschaltung. Dann könntest du mit dem Standard-Treiber und seinem ioctl() TIOCMSET TIOM_RTS arbeiten -- nicht perfekt, aber möglich.

Statt minicom würde ich in diesem Fall Debianpicocom benutzen. Bessere Fehlermeldungen + keine komplexe Config = weniger Stress.
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von Sallos » 02.06.2013 11:41:06

Moin,

so ich habes rausgefunden der Port muss umgeschaltet werden.....

Code: Alles auswählen

//Port auf Empfang
int portempfang(int fd)
{
	int sercmd, serstat;
	sercmd = TIOCM_RTS;
	ioctl(fd, TIOCMBIC, &sercmd); // Reset the RTS pin.
	// Read the RTS pin status.
		ioctl(fd, TIOCMGET, &serstat);
		if (serstat & TIOCM_RTS)
		printf("RTS pin is set.\n");
		else
		printf("RTS pin is reset.\n");

	return 0;
}

//Port auf Senden
int portsenden(int fd)
{
	int sercmd, serstat;
	sercmd = TIOCM_RTS;
	ioctl(fd, TIOCMBIS, &sercmd); // Set the RTS pin.
	// Read the RTS pin status.
		ioctl(fd, TIOCMGET, &serstat);
		if (serstat & TIOCM_RTS)
		printf("RTS pin is set.\n");
		else
		printf("RTS pin is reset.\n");

	return 0;
}


Das geht schon mal...nun hab ich nur noch das Problem das ich irgendwie die Daten die ich empfange verarbeiten muss......Und ich habe das mit dem Strings in C noch nicht verstanden.

Wenn ich so lese res = read(fd,(char *)buf,sizeof(buf)); wie bekomme ich da einen String raus um es mit der Lib String.h bearbeiten zu können??


Lars

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von cosmac » 02.06.2013 14:13:23

die Strings wären nicht das Problem:

Code: Alles auswählen

  res = read (fd, buf, sizeof(buf)-1);
  if (res == -1) {
    /* irgendwas ist schief gegangen */
  }
  else {
    buf[res] = '\0';  /* jetzt steht in buf ein null-terminierter String */
  }
aber: erstens darf in den empfangenen Daten keine binäre 0 auftauchen. Zweitens liefert read() meistens nur ein einzelnes Zeichen, weil es viel schneller ist, als die Zeichen emfangen werden (die Angabe "sizeof(buf)" ist ja nur eine obere Grenze). Du müsstest also einen String aus einzelnen Zeichen zusammenbauen.

Komplette Strings kannst du z.B. zeitgesteuert erreichen, d.h. du rufst read() erst auf, wenn alle Zeichen vom externen Gerät gesendet wurden. Oder du experimentierst mit den Flags aus termios(3), insbes. mit VMIN und VTIME. Oder, wenn die Daten keine Steuerzeichen enthalten und definiert mit newline enden, wäre ICANON interessant. Damit sollte read() dann komplette Textzeilen liefern.
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von Sallos » 02.06.2013 15:20:41

Moin,

ja also meine Empfangsdaten sehen so aus:

1-1:1.8.0*11(0002.7017)
1-1:1.8.0*10(0002.7017)
1-1:1.8.0*09(0002.7017)
1-1:1.8.0*08(0002.7017)
1-1:1.8.0*07(0002.3606)

Denn guck ich mir mal dieses ICANON.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von Sallos » 02.06.2013 15:54:25

Ok das mit dem ICANON scheint gut zu gehn, aber

wenn ich nun versuche :

Code: Alles auswählen

	do{
	
		res = read(fd,buf,sizeof(buf)-1);
		
		buf[res] = '\0';
	

		printf("read:%s\n",buf);
              

   		
  		printf("Hier ist ein W:%s\n",strchr(buf, (int)'W'));
		

	
		i++;
		
	}while(i < 10);
Auszuführen bleibt das Programm sehn.....

Ich muss ja nun irgendwie die ausgelesenen Zeilen bearbeiten?!

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler

Beitrag von Sallos » 02.06.2013 22:04:15

Mhhh ich versteh das leider nicht :-(

Ich scheine ja ein Char Array zu haben und keinen String...

Und daher kann ich die ganzen Strin.h lib nicht nutzen. Aber wie komm ich jetzt z.b:

1-1:1.8.0*11(0002.7017) in Buffer stehen habe wie kann das nun in Header(1-1:1.8.0*11) und Wert(0002.7017) zerschneiden??

Was für funktionen gibt es denn für Chars array?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von cosmac » 02.06.2013 22:13:21

Sallos hat geschrieben:Ich scheine ja ein Char Array zu haben und keinen String...
dumme Frage: was ist der Unterschied (mal abgesehen von wide chars oder unicode)? Oder anders rum: die Funktionen aus string.h sollten doch auch für ein Char Array funktionieren, jedenfalls in diesem Fall. Wir haben doch nur ASCII und eine '\0' am Ende?
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von Sallos » 02.06.2013 22:43:10

Mhh aber warum kann ich denn das gelesene aus dem Read

Code: Alles auswählen

      res = read(fd,buf,sizeof(buf)-1);
      
      buf[res] = '\0';
   

      printf("read:%s\n",buf);

buf nicht mit strchr() ioder oder bearbeiten?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von cosmac » 02.06.2013 22:57:49

funktioniert denn das printf() noch, auch mehrmals in der Schleife?

Code: Alles auswählen

printf("Hier ist ein W:%s\n",strchr(buf, (int)'W'));
verwirrt mich, in den Beispielen kommt ja nun wirklich kein W vor... Aber strchr() müsste trotzdem funktionieren und in dem Fall eben NULL liefern. Was printf() dann aus NULL macht, ist für %s zwar undefiniert, aber in der Praxis gibt es entweder "(null)" aus, oder das Programm wird mit "Segmentation fault" beendet.

Von solchen Feinheiten mal abgesehen, scheint mir strchr() durchaus ein Schritt in die richtige Richtung zu sein. Es liefert einen Zeiger auf den Anfang der Daten und damit praktisch einen String, der die Daten enthält.
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von Sallos » 02.06.2013 23:06:11

Also egal was ich so aus der string.h nutze wenn ich es mit dem buf versuche zu füllen bleibt das Programm genau an der stelle hängen....

Code: Alles auswählen

//lesen der Ports
void readserial_1(int fd)
{

	char buf[50];
	int res=0;
	int i=0;
	int summe;

	do{
	
		res = read(fd,buf,sizeof(buf)-1);
		
		buf[res] = '\0';
	

		printf("read:%s\n",buf);
              
printf("Hier:%s\n",strchr(buf, (int)':'));

 
		//sscanf(buf, "%s", &summe);
   		
  		//printf("Hier ist ein W:%s\n",strchr(buf, (int)'W'));
		

	
		i++;
		
	}while(i < 10);

Mhh ich komm da nicht hinter warum das so ist????

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von cosmac » 02.06.2013 23:26:55

wozu dient denn die 10-fach-Schleife? Du sendest doch etwas und rufst dann readserial_1() auf. Sollen da wirklich 10 Zeilen gelesen werden oder gehört die Schleife vielleicht weiter nach außen, so dass immer einmal gesendet wird und dann einmal gelesen wird?

"hängen bleiben" kann es eigentlich nur im read().
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von Sallos » 03.06.2013 00:08:34

Ne ich lese immer ganze Zeilen. Die 10 sind nur zum test..


So hab was rausgefunden.

also wenn ich ne neuen Void machen und in den die String bearbeitung machen geht ?!?!

Also neue Funktion "String bearbeiten" und die Funktion in den Schleife aufrufen, dann gehts

Wieso nur in einer Funktion und nicht direkt in der schleife?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von cosmac » 03.06.2013 00:15:20

faszinierend :(
Beware of programmers who carry screwdrivers.

Sallos
Beiträge: 28
Registriert: 10.02.2007 20:57:44

Re: serial8250 und RS485 .... TIOCSRS485 fehler/ Char Array

Beitrag von Sallos » 03.06.2013 16:28:09

Ja :-(

dieser Code geht auch nicht

//TEST
char string2[20]="red dwarf";
char string1[20]="";
strcpy(string1, string2);
//

Ich habe mit gdb geguckt und er hängt sich dabei an dem READ auf ?!?

Antworten