Включение и тестирование обратного локального шлейфа для UART

Я пытаюсь выполнить обратное тестирование внутренней петли UART и придумать следующие изменения

 #include <fcntl.h>
 #include <stdio.h>
 #include <termios.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/errno.h>
 #include <sys/types.h>
 #include <unistd.h>


 #define CCSR_BASE  0xfe000000
 #define UART1_BASE 0x11c000
 #define UART1_LEN  0x1000

 static volatile unsigned long  *uartReg = MAP_FAILED;

/* Map in registers. */
static unsigned long  *initMapMem(int fd, unsigned long addr, unsigned long len)
{
     return (unsigned long *) mmap(0, len,
            PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED|MAP_LOCKED, fd, addr);
}

int uartInitialise(void)
{
    int fd;
    int i;

    fd = open("/dev/mem", O_RDWR | O_SYNC) ;

    if (fd < 0)
       {
           fprintf(stderr,"This program needs root privileges.Try sudo /n");
           return -1;
       }

   uartReg  = initMapMem(fd, ((CCSR_BASE) + (UART1_BASE))  , UART1_LEN);

   /* In local loop back mode, data written to UTHR(8 bit) can be read from the 
      receiver buffer register(URBR 8 bit) of the same UART. */

 //    *(uartReg + 0x605 )  = 0x0;

       *(uartReg + (0x600)) = 0xf;

       printf("UART_REG : %#x\n", *(int *)(uartReg + (0x600)); /*Expecting 0xf to read here if loop back mode is set */

       close(fd);

  if (uartReg == MAP_FAILED)
     {
        fprintf(stderr,"Bad, mmap failed\n");
        return -1;
     }

    return 0;
}

 int main()
 {
    int pins;
    int f = open( "/dev/ttyS1", O_RDWR);

    if (f< 0)
    {
        printf("\nout");
        close(f);
     }   

    ioctl( f, TIOCMGET, &pins);
    ioctl( f, TIOCMSET, pins | TIOCM_LOOP);

    if (uartInitialise() < 0) return 1;

    sleep(5);

   ioctl( f, TIOCMGET, &pins);
   ioctl( f, TIOCMSET, pins & ~ TIOCM_LOOP);

 }

root@amit:~# ./loop_back

UART_РЕГ: 0

Но я не получаю ожидаемого результата, может ли кто-нибудь указать мне, что нужно сделать, чтобы проверить внутреннюю петлю UART?


person Amit Singh Tomar    schedule 19.03.2015    source источник
comment
Вы делаете это неправильно; вы не должны вмешиваться в регистры устройства, пока драйвер также активен. Вместо этого вы должны проверить, поддерживает ли драйвер последовательного порта вызов ioctl() TIOCM_LOOP, а затем просто write() и read().   -  person sawdust    schedule 19.03.2015
comment
Хорошо, я проверил, что ioctl( f, TIOCMSET, pins | TIOCM_LOOP) возвращает из lxr.free-electrons.com/source/drivers/tty/tty_io.c#L2725, значит ли это, что драйвер последовательного порта не поддерживает TIOCM_LOOP, если да, то что мне делать :(   -  person Amit Singh Tomar    schedule 19.03.2015
comment
tty_io.c не является драйвером последовательного порта; это часть tty или терминального уровня. Драйверы последовательного порта находятся в папке drivers/tty/serial/. По-видимому, вы не включаете предупреждения компилятора или игнорируете их, потому что ваш вызов ioctl( f, TIOCMSET, pins | TIOCM_LOOP) неверен. Третий аргумент для TIOCMSET ioctl(), согласно справочной странице Linux, равен const int *argp.   -  person sawdust    schedule 19.03.2015
comment
Хорошо, но тогда что-то, за чем я следовал, должно быть неправильным, stackoverflow.com/questions/22059104/ :)   -  person Amit Singh Tomar    schedule 19.03.2015
comment
Мое общее правило — доверять справочной странице чьему-то примеру. Затем я проверял исходный код Linux. Или выполните тест: выполните TIOCMGET, а затем TIOCSGET. Выполните еще один TIOCMGET для проверки (и всегда проверяйте коды возврата).   -  person sawdust    schedule 19.03.2015
comment
Я только что заглянул в файл DTS моей машины github.com/torvalds/linux/blob/master/arch/powerpc/boot/dts/fsl/ и соответствующий драйвер последовательного порта должен быть drivers/tty/serial/of_serial.c и смотрит на me loop back test отключен, этот драйвер поддерживает вызов ioctl TIOCM_LOOP, пожалуйста, подтвердите !!!   -  person Amit Singh Tomar    schedule 19.03.2015
comment
of_serial.c является универсальным для нескольких драйверов, особенно совместимых с 8250/16xxx UART, которые должны поддерживать обратную связь. Используйте dmesg для просмотра журнала загрузки и cat /proc/tty/driver/serial для получения более точной информации о последовательном порте и драйвере.   -  person sawdust    schedule 19.03.2015
comment
Спасибо, сработало :). Кроме того, поток будет похож на код приложения --> tty_io.c ---> драйвер последовательного порта ---> 8250_core.c, верно?   -  person Amit Singh Tomar    schedule 20.03.2015