LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-31-2018, 12:46 PM   #1
yudopplyr
LQ Newbie
 
Registered: Jun 2012
Posts: 9

Rep: Reputation: Disabled
High Latency for real time application with hardware serial


I have a project where I receive data from the serial port and then send a response. I have noticed that my system (NanoPi NEO core 2) has a latency of 1 millisecond. I want to reduce it to at least 0.3 milliseconds when receiving interrupts.

I would like to know if I am setting correctly the serial port options or if I am missing something. I have a digital scope (see image), when the interrupt happens I enable a GPIO to measure the time it takes for the interrupt to be called.



Code:
#include <stdint.h>
#include <fcntl.h>          //Used for UART
#include <termios.h>                    //Used for UART
#include <sys/signal.h>                 //Used for UART interrupt
#include <wiringPi.h>       //GPIO for debug
#include <linux/serial.h>    //Serial struct
#define TIMING_UART_PIN 4

int uart_port;
#define SERIALPORT "/dev/ttyS1"   //Physical UART
void usartRX_interrupt (int status);   /* definition of signal handler */

void init_UART(void){
    printf("Init UART\n");
    uart_port = open(SERIALPORT, O_RDWR | O_NOCTTY | O_NDELAY);

    fcntl(uart_port, F_SETFL, FNDELAY);
    fcntl(uart_port, F_SETOWN, getpid());
    fcntl(uart_port, F_SETFL,  O_ASYNC );

    struct termios options;
    tcgetattr(uart_port, &options);
    options.c_cflag = B38400 |PARENB | CS8 | CLOCAL | CREAD;  //UART PORT 38400kb/s even parity 8 bits
    cfsetispeed(&options,38400);
    cfsetospeed(&options,38400);
    options.c_iflag = IGNPAR | INPCK; //Ignore characters with parity error
    options.c_oflag = 0;
    options.c_lflag = 0;    
    tcsetattr(uart_port, TCSANOW, &options); //set options for UART

   //Set Interrupt handler for UART RX
    struct sigaction saio;  
    saio.sa_handler = usartRX_interrupt; //Handler for UART
    saio.sa_flags = 0;
    saio.sa_restorer = NULL; 
    sigaction(SIGIO,&saio,NULL);
    //Trying to set low latency
    struct serial_struct kernel_serial_settings;
    ioctl(uart_port, TIOCGSERIAL, &kernel_serial_settings);
    kernel_serial_settings.flags |= ASYNC_LOW_LATENCY;
    ioctl(uart_port, TIOCSSERIAL, &kernel_serial_settings);
}

int main(int argc, char** argv) {
        wiringPiSetup();
    pinMode(TIMING_UART_PIN,OUTPUT);
    digitalWrite(TIMING_UART_PIN,LOW);
    init_UART();

    while (1)
    {
    usleep(1); 
    }

    return 0;
}

void usartRX_interrupt (int status)
{
    uint8_t bufferData;
    digitalWrite(TIMING_UART_PIN,HIGH); //Debugging pin
    read( uart_port, &bufferData , sizeof bufferData ); //read data
    digitalWrite(TIMING_UART_PIN,LOW);

}
 
Old 11-01-2018, 12:57 PM   #2
business_kid
LQ Guru
 
Registered: Jan 2006
Location: Ireland
Distribution: Slackware, Slarm64 & Android
Posts: 16,252

Rep: Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321Reputation: 2321
I'm not with your code, or your hardware. It strikes me that there are several points for latency. GPIO is not particularly fast, serial is dead slow, delays are possible in your external hardware. I would expect it to be faster also. Set up some sort of chain like this, deleting what doesn't apply and inserting missing items
  1. Software control signals to GPIO
  2. Software data signal to gpio
  3. Any further delay in pc
  4. Baud rate
  5. Signal received in external hardware
  6. Signal returned in external hardware
  7. Baud rate of return signal
  8. PC delays in processing result

You can find exactly where your delay appears. We couldn't guess.

Your controls from the pc end are increasing the baud rate and decreasing handshake time. Beware that your pc might be doing RS-232 but your hardware could be I^2C; I've seen guys caught by that before. RS-232 requires -5V/+5V; I^2C is 0-5V. Trickiest is where the thing works, somebody swaps a chip and nothing works.
 
1 members found this post helpful.
Old 11-01-2018, 06:43 PM   #3
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,219

Rep: Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309Reputation: 5309
Is there buffering involved?

If it's waiting for the buffer to fill up before it issues the interrupt, that could be a factor.

There's a flow control setting that sets the buffer size to one byte.
 
  


Reply

Tags
interrupt, latency, uart



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Real Time vs Low Latency Kernel on Xubuntu Cr0wb4r Linux - Kernel 1 05-24-2011 02:18 PM
[SOLVED] Serial Programming - Multiple interruptions for serial devices on real-time Linux. santiagocasti Programming 5 05-06-2010 04:34 AM
real time application khodeir Programming 10 12-02-2009 09:38 AM
real-time application quantt Programming 6 09-15-2009 03:58 PM
latency and audio programming in real-time tanoatlq Programming 2 08-12-2008 05:01 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:23 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration