【问题标题】:APQ-8016 Snapdragon 410c: non-standard UART baudrate in LinaroAPQ-8016 Snapdragon 410c:Linaro 中的非标准 UART 波特率
【发布时间】:2017-01-18 16:39:46
【问题描述】:

运行 Linux (linaro) 的 Snapdragon 410c ttyMSM1 (msm_serial) 是否能够原生提供 250,000 波特率的 DMX 协议?

    root@linaro-developer:~# stty -F /dev/ttyMSM1 cs8 -parenb cstopb 250000

stty: invalid argument ‘250000’ 

Try 'stty --help' for more information.

250000 不在 kernel/drivers/tty/tty_ioctl.c:baud_table[] 中支持的波特率列表中,setserial 自定义 38400 波特率命令无法正确覆盖波特率。

root@linaro-developer:~# setserial -av /dev/ttyMSM1 spd_cust
[  491.312449] msm_serial 78af000.serial: setserial sets custom speed on ttyMSM1. This is deprecated.

在此处交叉发布(在我努力寻找答案时,我将保持两个板同步): http://www.96boards.org/forums/topic/linaro-ttymsm1-uart0-dmx-250000-baudrate/#post-17264

【问题讨论】:

  • 您必须使用支持BOTHER 的应用程序。 AFAIK picocom 可以在这种支持下编译。不过没试过。

标签: linux linux-kernel serial-port linux-device-driver uart


【解决方案1】:

我遇到了类似的问题,无法为我的案例找到正确的工具,所以我决定自己编写代码会更快。下一个代码使用termios2 API(和BOTHER 标志,Andy Shevchenko 在他的评论中提到)为串口设置自定义波特率。

从未查看过您的串行驱动程序代码,但您可以先尝试此代码:

ma​​in.c

#include "termios2.h"

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc, char *argv[])
{
    struct termios2 tio;
    int fd, ret, speed;

    if (argc != 3) {
        printf("%s device speed\n\n"
                "Set speed for a serial device.\n"
                "For instance:\n    %s /dev/ttyUSB0 75000\n",
                argv[0], argv[0]);
        return EXIT_FAILURE;
    }

    fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open() error");
        return EXIT_FAILURE;
    }

    speed = atoi(argv[2]);

    ret = ioctl(fd, TCGETS2, &tio);
    if (ret == -1) {
        perror("TCFETS2 error");
        close(fd);
        return EXIT_FAILURE;
    }

    /* Speed settings */
    tio.c_cflag &= ~CBAUD;
    tio.c_cflag |= BOTHER;
    tio.c_ispeed = speed;
    tio.c_ospeed = speed;

    /* Ignore CR (\r) characters */
    tio.c_iflag |= IGNCR;

    ret = ioctl(fd, TCSETS2, &tio);
    if (ret == -1) {
        perror("TCSETS2 error");
        close(fd);
        return EXIT_FAILURE;
    }

    close(fd);
    return 0;
}

termios2.h

/* The content for this file was borrowed from:
 * /usr/include/asm-generic/termbits.h
 *
 * We can't just include <asm/termios.h>, because it will interfere with
 * regular <termios.h> (compiler will give some errors).
 * So it's better to copy needed stuff here instead.
 */

#ifndef TERMIOS2_H
#define TERMIOS2_H

#include <termios.h>

/* termios.h defines NCCS as 32, but for termios2 we need it to be 19 */
#undef NCCS
#define NCCS        19

#define BOTHER      0010000

struct termios2 {
    tcflag_t c_iflag;       /* input mode flags */
    tcflag_t c_oflag;       /* output mode flags */
    tcflag_t c_cflag;       /* control mode flags */
    tcflag_t c_lflag;       /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
    speed_t c_ispeed;       /* input speed */
    speed_t c_ospeed;       /* output speed */
};

#endif /* TERMIOS2_H */

构建:

$ gcc -Wall -O2 main.c -o set-tty-speed

用法:

$ ./set-tty-speed /dev/ttyMSM1 250000

另请参阅此问题:How to set a custom baud rate on Linux?

【讨论】:

  • 感谢您的回复。我看过这篇文章并且一直在努力解决编译器错误。 AFAICT 这不适用于金鱼草。我担心硬件不支持 250000 波特率,或者至少需要调整系统时钟。我将在本周晚些时候深入了解驱动程序,届时将更新问题。
  • 诀窍是手动描述termios2,而不是包含asm/termios.h。尝试使用我提供的代码。它对我来说就像一个魅力。除此之外,如果问题实际上出在驱动程序 (msm_serial) 中,那么仅此代码当然不会帮助您。但我可以确认它适用于我的 PL2303。因此,至少您可以使用它来验证实际问题出在您的驱动程序中。
猜你喜欢
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 2019-12-08
相关资源
最近更新 更多