Strom fließt auch durch krumme Drähte !
Dürfen die Parameter die man übergibt nur eine bestimmte Länge haben?
Weil wenn ich z.B. eintippe
"IchbineinHund"
kommt im Terminal:
IchbineinHundˆ@
[ 3720.868847] Unhandled fault: alignment exception (0x011) at 0x00000001
Bei dem Text "Ich" kommt das nicht, egal wie oft ich das sende.
Schaut ruhig mal auf meiner Homepage vorbei:
http://kampis-elektroecke.de
Oder folge mir auf Google+:
Daniel Kampert
Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.
Gruß
Daniel
Das sieht nach einer zu klein dimensionierten Variable aus. Ist die char groß genug dimensioert, dann fehlt das String-Abschlußzeichen "\0"
Wie ist denn der Quellcode?
Edit:
Ich nutze bis 76 Zeichen in einem Rutsch. Es können auch mehr sein, jedoch breche ich dann halt ab.
Wenn das Herz involviert ist, steht die Logik außen vor! \/
Der Quellcode lautet:
Die Länge für strncpy ist variabel und richtet sich nach der Länge des ersten Argumentes.Code:// Compile with: GCC /var/scripte/senden.c -o /var/scripte/senden //#include <iostream> //using namespace std; #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h> #define BAUDRATE B115200 // Baudrate char MODEMDEVICE[]= "/dev/ttyAMA0"; // Device zum Senden struct termios newtio={}; // Variable für "termios.h" volatile int fd; // File descriptor unsigned char Send_UART(char c[]) // Gibt ein einzelnes Zeichen über UART (als fd geöffnet) aus. { int res; char Counter; char lenght = 0x00; lenght = strlen(c); // Länge des Strings feststellen while(Counter < lenght) { res = write(fd, &c[Counter], 1); Counter++; } Counter = 0x00; // Counter reseten res = write(fd, &"\r", 1); // CR senden res = write(fd, &"\n", 1); // LF senden } int UART_Init() //Schnittstelle öffnen und parametrieren { /*** Init ***/ //O_RDONLY, O_WRONLY or O_RDWR - //O_NDELAY (geht weiter, wenn keine Daten da sind und gibt "-1" zurueck) // man 2 open fuer mehr Infos - see "man 2 open" for more info // O_NOCTTY No ControllTeleType fd = open(MODEMDEVICE, O_WRONLY | O_NOCTTY); if (fd < 0) { printf("Fehler beim öffnen von %s\n", MODEMDEVICE); exit(-1); } memset(&newtio, 0, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; // Setzt die neuen Porteinstellungen newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; newtio.c_lflag = 0; /* set input mode (non-canonical, no echo, ...) */ newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */ tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &newtio); return fd; } int main(int argc, char** argv) //Programmstart { // Variablen für das Hauptprogramm char buffer[] = ""; int Laenge = 0x00; UART_Init(); // Schnittstelle öffnen und parametrieren Laenge = strlen(argv[1]); strncpy(buffer, argv[1], Laenge); // Kopiert den zweiten Parameter der übergeben wurde in den String "Buffer if (argc >= 1) { printf("Text empfangen\n"); // Empfangsbestätigung senden Send_UART(buffer); } close (fd); return 0; }
Schaut ruhig mal auf meiner Homepage vorbei:
http://kampis-elektroecke.de
Oder folge mir auf Google+:
Daniel Kampert
Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.
Gruß
Daniel
Zu deinem Code läßt sich eine Menge sagen, hier nur einiges.
"volatile" hat in einem Anwenderprogramm nichts zu suchen.
Zeichen sind chars, alles andere, Zähler etc sind ints. Und was soll die Hex-Notation?
char lenght = 0x00;
Also:
int length = 0;
nicht:
unsigned char Send_UART(char c[])
sondern
int Send_UART(char *c)
Und wenn man einer Funktion einen Returnwert verpasst, sollte man ihn auch liefern.
Und statt
length = strlen(c); // Länge des Strings feststellen
while(Counter < lenght)
{
res = write(fd, &c[Counter], 1);
Counter++;
}
einfach
res = write(fd, c, strlen(c));
Dann auch noch res bearbeiten und feststellen, ob auch alles geschrieben wurde.
Und in main()
char buffer[] = "";
Das ist ein array mit der Länge 1, das mit einem Null-Byte gefüllt ist. Ist es das, was du willst?
UART_init() liefert den Filedescriptor als Rückgabewert, keiner sieht ihn an. Das funktioniert, weil fd global ist. Wenn man das will, warum dann als Returnwert?
Laenge = strlen(argv[1]);
strncpy(buffer, argv[1], Laenge);
Warum kopierst du eigentlich argv[1] in einen Buffer und sendest es nicht gleich?
char LineEnd[] = "\r\n";
write(fd, argv[1], strlen(argv[1]);
write(fd, LineEnd, 2);
Ich hoffe, das ist nicht allzu schlimm ausgefallen
MfG Klebwax
[/CODE]
Strom fließt auch durch krumme Drähte !
Huu danke für die ganzen Anregungen.
Zu dem Thema "Warum kopierst du eigentlich argv[1] in einen Buffer und sendest es nicht gleich?"
Ich habe es probiert aber es wollte nie klappen. Ich probiere dann mal das was du vorgeschlagen hast.
Das mit dem Hex habe ich mir so angewöhnt
Bin halt recht neu in C und ich programmiere damit nicht ganz so viel von daher weiß ich nicht wie man was vereinfachen kann
Aber danke für die Tipps. Ich setze sie direkt mal um!
Warum hat volatile nichts in einem Anwenderprogramm zu suchen?
Edit: Habe es jetzt mal gemacht. Jetzt erscheint auch der Fehler nicht mehr wenn ich einen längeren Text sende.
Im Endeffekt hat das Programm ja nun zwei Möglichkeiten zu senden oder? Einmal mit
write(fd, argv[1], strlen(argv[1]));
write(fd, LineEnd, 2);
und einmal mit
int Send_UART(char *c)
{
int res;
char LineEnd[] = "\r\n";
res = write(fd, c, strlen(c));
write(fd, LineEnd, 2);
}
Geändert von Kampi (15.09.2012 um 23:23 Uhr)
Schaut ruhig mal auf meiner Homepage vorbei:
http://kampis-elektroecke.de
Oder folge mir auf Google+:
Daniel Kampert
Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.
Gruß
Daniel
volatile bedeutet, daß eine Variable auch von außerhalb eines Programmkontextes geändert werden kann, ohne daß das Programm etwas dazu tut. Dies soll der Compiler berücksichtigen. Das kann nicht vorkommen, alle Variablen eines Userprogramms gehören nur diesem Programm.
Ja, mit den Angewohnheiten ist das so eine Sache. Die Hexnotation heißt, das ist nicht als Zahl gemeint, sondern als Bitmuster. Darauf wendet man typischerweise Bitoperationen an.
Es geht nicht so sehr um vereinfachen, sondern darum, klar und gradlinig Anweisungen an den Rechner zu formulieren, die man selbst (auch noch in ein paar Wochen) und der Rechner verstehen.
Du willst die Parameter für /dev/ttyx setzen und argv[1] mitangehängtem CR/LF dahin schreiben. Das ist nicht wirklich viel, alles in allem ein 10-Zeiler. Funktionen sind da eigentlich nicht nötig, sie stören nur den Lesefluß. Je mehr Zeilen, desto mehr potentielle Fehler.
Du müßtest auch einige Warnings beim Übersetzen bekommen haben. Nimm sie ernst und stell sie ab. 0 Warnings und 0 Errors ist das Ziel.
MfG Klebwax
Strom fließt auch durch krumme Drähte !
Lesezeichen