Как установить низкую задержку для обработчика прерываний Serial RX (Linux / C ++) - PullRequest
0 голосов
/ 30 октября 2018

У меня есть проект, в котором я получаю данные из последовательного порта, а затем отправляю ответ. Я заметил, что моя система (NanoPi NEO core 2) имеет задержку в 1 миллисекунду. Я хочу уменьшить его как минимум до 0,3 миллисекунд при получении прерываний.

Я хотел бы знать, правильно ли я настраиваю параметры последовательного порта или что-то не хватает. У меня есть цифровая область, когда происходит прерывание, я позволяю GPIO измерить время, которое требуется для вызова прерывания.

Serial debugging of interrupt handler

#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);

}
...