Mam bardzo podobnie napisany program ale niestety funkcja read czeka na znak \n konca linii. Funkcja write przesyła mi znaki bez \n na końcu (wygląda, że nie buforuje i jest ok).
Używam uart do wysyłania i odbierania danych binarnych i nie umiem przejść tego problemu.
Na płytce mam połączenie TX i RX. Tak więc to co wysyłam powinienem dostawać. I dzieje się tylko jak wyślę na końcu ramki \n.
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <string.h>
#include <linux/types.h>
#include <stdlib.h>
/* baudrate settings are defined in <asm/termbits.h>, which is
included by <termios.h> */
#define BAUDRATE B115200 // Change as needed, keep B
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
#define TIOCGRS485 0x542E
#define TIOCSRS485 0x542F
/* change this definition for the correct port */
//#define MODEMDEVICE "/dev/ttyO1" //COM1 STEROWANIE
//#define MODEMDEVICE "/dev/ttyO2" //COM2 STEROWANIE
#define MODEMDEVICE "/dev/ttyO4" //IO STEROWANIE
//#define RS485_RTS_GPIO_PIN 45 // 1.13 COM1 STEROWANIE
//#define RS485_RTS_GPIO_PIN 46 // 1.14 COM2 STEROWANIE
#define RS485_RTS_GPIO_PIN 60 // 1.28 IO STEROWANIE
struct serial_rs485 {
__u32 flags; /* RS485 feature flags */
#define SER_RS485_ENABLED (1 << 0) /* If enabled */
#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for
RTS pin when
sending */
#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for
RTS pin after sent*/
#define SER_RS485_RX_BEFORE_TX (1 << 3)
#define SER_RS485_USE_GPIO (1 << 5)
__u32 delay_rts_before_send; /* Delay before send (milliseconds) */
__u32 delay_rts_after_send; /* Delay after send (milliseconds) */
__u32 gpio_pin; /* GPIO Pin Index */
__u32 padding[4]; /* Memory is cheap, new structs
are a royal PITA .. */
};
main()
{
int fd, c, res, res1;
struct termios oldtio, newtio;
char buf[255];
char bufTx[32];
printf("Start: %d\n\r", '\n');
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd < 0) { perror(MODEMDEVICE); exit(-1); }
printf("open\n\r");
struct serial_rs485 rs485conf;
/* Set RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED|SER_RS485_USE_GPIO;
/* Set RS485 "1" when sending */
rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
/* Set RS485 "0" after sending */
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
/* Set delay: */
rs485conf.delay_rts_before_send = 0x000000005;
rs485conf.delay_rts_after_send = 0x000000005;
rs485conf.gpio_pin = RS485_RTS_GPIO_PIN;
rs485conf.padding[0] = 0;
rs485conf.padding[1] = 0;
rs485conf.padding[2] = 0;
rs485conf.padding[3] = 0;
ioctl (fd, TIOCSRS485, &rs485conf);
bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
/* BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
CRTSCTS : output hardware flow control (only used if the cable has
all necessary lines. See sect. 7 of Serial-HOWTO)
CS8 : 8n1 (8bit,no parity,1 stopbit)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters */
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
/* IGNPAR : ignore bytes with parity errors
otherwise make device raw (no other input processing) */
newtio.c_iflag = IGNPAR;
/* Raw output */
newtio.c_oflag = 0;
/* ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program */
newtio.c_lflag = ICANON;
/* now clean the modem line and activate the settings for the port */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
//sleep(1);
//setvbuf(fd, NULL, _IONBF, 0);
/* terminal settings done, now handle input*/
while (TRUE) { /* loop continuously */
bufTx[0] = '1'; // lub 0x01
bufTx[1] = '2'; // lub 0x02
bufTx[2] = '3'; // lub 0x03
//bufTx[3] = '\n';
write(fd, bufTx, 3);
sleep(1);
/* read blocks program execution until a line terminating character is
input, even if more than 255 chars are input. If the number
of characters read is smaller than the number of chars available,
subsequent reads will return the remaining chars. res will be set
to the actual number of characters actually read */
res = read(fd, buf, 255);
buf[res] = 0; /* set end of string, so we can printf */
printf("Odebrano %d znaki: \n\r%s\n\r", res, buf);
}
tcsetattr(fd, TCSANOW, &oldtio);
}
Wynik programu z \n na końcu to:
Odebrano 4 znaki:
123