Hello,
I try to communicate between 2 Apalis evaluation board through rs422 at 4Mbaud.
linux kernel version : 4.1.44-2.7.4+gb1555bf
I have the 4Mbaud with termios and this work.
But the problem come from the time occupation.
Take a look at this image :
It appears that I have a link of 4mbaud, but used only 1/3 of the time.
How can i use the uartin a better way? maybe DMA or others function to control uart…
In my main i open the uart like that (function detailled bellow) :
// open uart
data.fd = open("/dev/ttymxc1", O_RDWR | O_NOCTTY | O_NONBLOCK);
set_interface_attribs (data.fd, B4000000, 0); // set speed to 4 Mbps, 8n1 (no parity)
The function called when a new buffer arrive: (from gstreamer pipeline)
// The appsink has received a buffer
static GstFlowReturn new_sample (GstElement *sink, CustomData *data) {
GstSample *sample;
GstBuffer *buffer;
GstMapInfo info;
int wlen;
/* Retrieve the buffer */
g_signal_emit_by_name (sink,
"pull-sample", &sample);
if (sample)
{
buffer = gst_sample_get_buffer (sample);
gst_buffer_map (buffer,&info,GST_MAP_READ);
// write on uart
wlen = write(data->fd, info.data, info.size);
tcdrain(data->fd);
gst_buffer_unmap(buffer,&info);
gst_buffer_unref (buffer);
}
return GST_FLOW_OK;
}
serials functions:
int set_interface_attribs (int fd, int speed, int parity) {
struct termios tty;
if (tcgetattr (fd, &tty) != 0)
{
printf ("error %d from tcgetattr", errno);
return EXIT_FAILURE;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 5;
if (tcsetattr (fd, TCSANOW, &tty) != 0)
{
printf ("error %d from tcsetattr", errno);
return EXIT_FAILURE;
}
return 0; }
EDIT 21/03/2018 11:54
I tried to bypass the tcdrain function using ioctl functions :
while(nbbytes!=0){
ioctl(data->fd, TIOCOUTQ, &nbbytes);
printf("ioctl => %d\n",nbbytes);
usleep(1);
}
but the result return buffer max size and directly 0. Nothing change on the rs422 link…
I don’t understand why my buffer is not decremented slowly.
Any idea?
EDIT 2 21/03/2018 15h45 :
thank you jaski.tx for updating my post.
Here, I may have found a solution but i don’t understand what to do to deactivate DMA…:
To prevent this issue you can disable the RX-DMA of the desired UART by changing the uart block of your DTS file (this example works for ttymxc4):
&uart5 {
status = "okay";
dma-names = "","tx";
};
EDIT 3 22/03/2018 08:18 :
can someone could give me a linux image without DMA on uart in this list :
https://developer.toradex.com/files/toradex-dev/uploads/media/Colibri/Linux/Images/old/
I’m currently use this one :
Apalis-iMX6_LXDE-Image_2.7-20180104.tar.bz2