Эксперимент с драйвером последовательного порта Linux RS232/485/GPS (пересадка minicom)

Последовательный порт является очень часто используемым периферийным устройством.В Linux он обычно связывается с другими устройствами или датчиками через последовательный порт.В соответствии с различными
уровнями последовательный порт делится на TTL и RS232. Независимо от уровня интерфейса программа драйвера одна и та же.Последовательный
порт может быть преобразован в сигнал RS485 путем подключения внешнего чипа, такого как RS485, что
и делает плата разработки I.MX6U-ALPHA компании punctual Atom. Для платы разработки I.MX6U-ALPHA от Zhengdian Atom все интерфейсы модуля RS232, RS485 и GPS
подключены к интерфейсу UART3 I.MX6U, поэтому эти периферийные устройства в конечном итоге относятся к драйверу последовательного порта UART3
. В этой главе мы узнаем, как управлять последовательным портом UART3 на макетной плате I.MX6U-ALPHA, а затем реализуем
драйверы RS232, RS485 и GSP.

Каркас драйверов UART под Linux

1. Регистрация и отмена регистрации uart_driver
Подобно I2C и SPI, Linux также предоставляет структуру драйвера последовательного порта, нам нужно только написать
программу драйвера в соответствии с соответствующей структурой последовательного порта. В драйвере последовательного порта нет различий между концом хоста и концом устройства, есть только один драйвер последовательного порта, и этот драйвер был официально
написан NXP.Что нам действительно нужно сделать, так это добавить информацию об узле последовательного порта. для использования в дереве устройств
. При запуске системы драйвер последовательного порта успешно сопоставляется с устройством, и соответствующий последовательный порт будет задействован для создания файла
/dev/ttymxcX(X=0….n).
Хотя драйвер последовательного порта не требует от нас написания, нам все же необходимо понять структуру драйвера последовательного порта.Структура uart_driver
представляет драйвер UART.uart_driver определен в файле include/linux/serial_core.h, а содержимое следующее:

示例代码63.1.1 uart_driver 结构体
295 struct uart_driver {
    
    
296 struct module *owner; /* 模块所属者*/
297 const char *driver_name; /* 驱动名字*/
298 const char *dev_name; /* 设备名字*/
299 int major; /* 主设备号*/
300 int minor; /* 次设备号*/
301 int nr; /* 设备数*/
302 struct console *cons; /* 控制台*/
303
304 /*
305 * these are private; the low level driver should not
306 * touch these; they should be initialised to NULL
307 */
308 struct uart_state *state;
309 struct tty_driver *tty_driver;
310 };


Каждый драйвер последовательного порта должен определить uart_driver.При загрузке драйвера зарегистрируйте этот uart_driver в системе через функцию uart_register_driver.Прототип этой функции выглядит следующим образом:

int uart_register_driver(struct uart_driver *drv)

Значения параметров функции и возвращаемых значений следующие:
drv: uart_driver для регистрации.
Возвращаемое значение: 0 — успех, отрицательное значение — сбой.
При отмене регистрации драйвера также необходимо отменить регистрацию ранее зарегистрированного uart_driver.Нужно использовать функцию uart_unregister_driver.Прототип
функции выглядит следующим образом:

void uart_unregister_driver(struct uart_driver *drv)

Значения параметров функции и возвращаемых значений следующие:
drv: uart_driver не регистрируется.
Возвращаемое значение: нет.
2. Добавление и удаление uart_port
uart_port представляет конкретный порт, uart_port определен в файле include/linux/serial_core.h, его содержимое выглядит следующим образом
(некоторые опущены):

示例代码63.1.2 uart_port 结构体
117 struct uart_port {
    
    
118 spinlock_t lock; /* port lock */
119 unsigned long iobase; /* in/out[bwl] */
120 unsigned char __iomem *membase; /* read/write[bwl] */
......
235 const struct uart_ops *ops;
236 unsigned int custom_divisor;
237 unsigned int line; /* port index */
238 unsigned int minor;
239 resource_size_t mapbase; /* for ioremap */
240 resource_size_t mapsize;
241 struct device *dev; /* parent device */
......
250 };

Самая важная вещь в uart_port — это ops в строке 235. ops содержит специфические функции драйвера последовательного порта, которые мы
рассмотрим позже. У каждого UART есть uart_port, так как же uart_port сочетается с uart_driver? Здесь
используется функция uart_add_one_port , и прототип функции выглядит следующим образом:

int uart_add_one_port(struct uart_driver *drv,
struct uart_port *uport)

Значения параметров функции и возвращаемых значений следующие:
drv: uart_driver, соответствующий этому порту.
upport: порт, который нужно добавить в uart_driver.
Возвращаемое значение: 0 — успех, отрицательное значение — сбой.
При удалении драйвера UART также необходимо удалить uart_port из соответствующего uart_driver.Необходимо использовать
функцию uart_remove_one_port.Прототип функции выглядит следующим образом:

int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)

Значения параметров функции и возвращаемых значений следующие:
drv: uart_driver, соответствующий удаляемому порту.
upport: uart_port для удаления.
Возвращаемое значение: 0 — успех, отрицательное значение — сбой.
3. Реализация uart_ops
Как упоминалось выше при объяснении uart_port, переменная-член ops в uart_port очень важна, поскольку ops содержит
специальные функции драйвера для UART, а функции в ops, наконец, вызываются системой Linux для отправки и получения данных. ops —
переменная указателя структуры типа uart_ops, uart_ops определена в файле include/linux/serial_core.h, содержание следующее:

示例代码63.1.3 uart_ops 结构体
49 struct uart_ops {
    
    
50 unsigned int (*tx_empty)(struct uart_port *);
51 void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
52 unsigned int (*get_mctrl)(struct uart_port *);
53 void (*stop_tx)(struct uart_port *);
54 void (*start_tx)(struct uart_port *);
55 void (*throttle)(struct uart_port *);
56 void (*unthrottle)(struct uart_port *);
57 void (*send_xchar)(struct uart_port *, char ch);
58 void (*stop_rx)(struct uart_port *);
59 void (*enable_ms)(struct uart_port *);
60 void (*break_ctl)(struct uart_port *, int ctl);
61 int (*startup)(struct uart_port *);
62 void (*shutdown)(struct uart_port *);
63 void (*flush_buffer)(struct uart_port *);
64 void (*set_termios)(struct uart_port *, struct ktermios *new,
65 struct ktermios *old);
66 void (*set_ldisc)(struct uart_port *, struct ktermios *);
67 void (*pm)(struct uart_port *, unsigned int state,
68 unsigned int oldstate);
69
70 /*
71 * Return a string describing the type of the port
72 */
73 const char *(*type)(struct uart_port *);
74
75 /*
76 * Release IO and memory resources used by the port.
77 * This includes iounmap if necessary.
78 */
79 void (*release_port)(struct uart_port *);
80
81 /*
82 * Request IO and memory resources used by the port.
83 * This includes iomapping the port if necessary.
84 */
85 int (*request_port)(struct uart_port *);
86 void (*config_port)(struct uart_port *, int);
87 int (*verify_port)(struct uart_port *, struct serial_struct *);
88 int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
89 #ifdef CONFIG_CONSOLE_POLL
90 int (*poll_init)(struct uart_port *);
91 void (*poll_put_char)(struct uart_port *, unsigned char);
92 int (*poll_get_char)(struct uart_port *);
93 #endif
94 };

Разработчикам драйверов UART необходимо реализовать uart_ops, потому что uart_ops — это интерфейс драйвера UART самого низкого уровня, который фактически
имеет дело с регистрами UART. Конкретное значение этих функций в структуре uart_ops см. в
Documentation/serial/driver.
Структура драйвера UART, вероятно, такова.Далее мы объединим теорию с практикой, чтобы увидеть, как написан официальный файл драйвера UART от NXP.

Анализ драйвера UART I.MX6U

1. Структура драйвера платформы UART
Откройте файл imx6ull.dtsi и найдите подузел, соответствующий UART3.Содержимое подузла следующее:

示例代码63.2.1 uart3 设备节点
1 uart3: serial@021ec000 {
    
    
2 compatible = "fsl,imx6ul-uart",
3 "fsl,imx6q-uart", "fsl,imx21-uart";
4 reg = <0x021ec000 0x4000>;
5 interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
6 clocks = <&clks IMX6UL_CLK_UART3_IPG>,
7 <&clks IMX6UL_CLK_UART3_SERIAL>;
8 clock-names = "ipg", "per";
9 dmas = <&sdma 29 4 0>, <&sdma 30 4 0>;
10 dma-names = "rx", "tx";
11 status = "disabled";
12 };

Сосредоточьтесь на совместимом атрибуте в строках 2 и 3. Здесь есть три значения: «fsl,imx6ul-uart», «fsl,imx6q-uar»
и «fsl,imx21-uart». Найдите эти три значения в исходном коде Linux, чтобы найти соответствующий файл драйвера UART, этот
файл — drivers/tty/serial/imx.c, в этом файле вы можете найти следующее содержимое:

示例代码63.2.2 UART platform 驱动框架
267 static struct platform_device_id imx_uart_devtype[] = {
    
    
268 {
    
    
269 .name = "imx1-uart",
270 .driver_data = (kernel_ulong_t) &imx_uart_devdata[IMX1_UART],
271 }, {
    
    
272 .name = "imx21-uart",
273 .driver_data = (kernel_ulong_t)
&imx_uart_devdata[IMX21_UART],
274 }, {
    
    
275 .name = "imx6q-uart",
276 .driver_data = (kernel_ulong_t)
&imx_uart_devdata[IMX6Q_UART],
277 }, {
    
    
278 /* sentinel */
279 }
280 };
281 MODULE_DEVICE_TABLE(platform, imx_uart_devtype);
282
283 static const struct of_device_id imx_uart_dt_ids[] = {
    
    
284 {
    
     .compatible = "fsl,imx6q-uart", .data =
&imx_uart_devdata[IMX6Q_UART], },
285 {
    
     .compatible = "fsl,imx1-uart", .data =
&imx_uart_devdata[IMX1_UART], },
286 {
    
     .compatible = "fsl,imx21-uart", .data =
&imx_uart_devdata[IMX21_UART], },
287 {
    
     /* sentinel */ }
288 };
......
2071 static struct platform_driver serial_imx_driver = {
    
    
2072 .probe = serial_imx_probe,
2073 .remove = serial_imx_remove,
2074
2075 .suspend = serial_imx_suspend,
2076 .resume = serial_imx_resume,
2077 .id_table = imx_uart_devtype,
2078 .driver = {
    
    
2079 .name = "imx-uart",
2080 .of_match_table = imx_uart_dt_ids,
2081 },
2082 };
2083
2084 static int __init imx_serial_init(void)
2085 {
    
    
2086 int ret = uart_register_driver(&imx_reg);
2087
2088 if (ret)
2089 return ret;
2090
2091 ret = platform_driver_register(&serial_imx_driver);
2092 if (ret != 0)
2093 uart_unregister_driver(&imx_reg);
2094
2095 return ret;
2096 }
2097
2098 static void __exit imx_serial_exit(void)
2099 {
    
    
2100 platform_driver_unregister(&serial_imx_driver);
2101 uart_unregister_driver(&imx_reg);
2102 }
2103
2104 module_init(imx_serial_init);
2105 module_exit(imx_serial_exit);

Видно, что UART I.MX6U по сути является драйвером платформы, строки 267–280, imx_uart_devtype
— это традиционная таблица соответствия.
Строки 283–288, таблица соответствия, используемая деревом устройств, значение совместимого атрибута строки 284 — «fsl,imx6q-uart».
Строки 2071~2082, структура кадра драйвера платформы serial_imx_driver.
Строки 2084~2096 — это функции ввода драйвера Строка 2086 вызывает функцию uart_register_driver для регистрации
uart_driver в ядре Linux, которая здесь imx_reg.
Строки 2098~2102 являются функциями выхода драйвера, а строка 2101 вызывает функцию uart_unregister_driver для отмены регистрации ранее зарегистрированного
uart_driver, то есть imx_reg.
2. Инициализация uart_driver
В функции imx_serial_init imx_reg регистрируется ядром Linux imx_reg является структурной
переменной типа uart_driver imx_reg определяется следующим образом:

示例代码63.2.3 imx_reg 结构体变量
1836 static struct uart_driver imx_reg = {
    
    
1837 .owner = THIS_MODULE,
1838 .driver_name = DRIVER_NAME,
1839 .dev_name = DEV_NAME,
1840 .major = SERIAL_IMX_MAJOR,
1841 .minor = MINOR_START,
1842 .nr = ARRAY_SIZE(imx_ports),
1843 .cons = IMX_CONSOLE,
1844 };

3. Инициализация и добавление uart_port
После успешного сопоставления устройства UART и драйвера будет выполнена функция serial_imx_probe.Основная работа этой функции заключается в
инициализации uart_port, а затем добавлении его к соответствующему uart_driver. Прежде чем рассматривать функцию serial_imx_probe, давайте взглянем
на структуру imx_port. imx_port — это структура устройства, определенная NXP для SOC серии I.MX. Эта структура
содержит переменную-член uart_port. Содержание структуры imx_port выглядит следующим образом ( с аббревиатурой):

示例代码63.2.4 imx_port 结构体
216 struct imx_port {
    
    
217 struct uart_port port;
218 struct timer_list timer;
219 unsigned int old_status;
220 unsigned int have_rtscts:1;
221 unsigned int dte_mode:1;
222 unsigned int irda_inv_rx:1;
223 unsigned int irda_inv_tx:1;
224 unsigned short trcv_delay; /* transceiver delay */
......
243 unsigned long flags;
245 };

Строка 217, порт переменной-члена uart_port.
Далее посмотрите на функцию serial_imx_probe, содержание функции следующее:

示例代码63.2.5 serial_imx_probe 函数
1969 static int serial_imx_probe(struct platform_device *pdev)
1970 {
    
    
1971 struct imx_port *sport;
1972 void __iomem *base;
1973 int ret = 0;
1974 struct resource *res;
1975 int txirq, rxirq, rtsirq;
1976
1977 sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL);
1978 if (!sport)
1979 return -ENOMEM;
1980
1981 ret = serial_imx_probe_dt(sport, pdev);
1982 if (ret > 0)
1983 serial_imx_probe_pdata(sport, pdev);
1984 else if (ret < 0)
1985 return ret;
1986
1987 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1988 base = devm_ioremap_resource(&pdev->dev, res);
1989 if (IS_ERR(base))
1990 return PTR_ERR(base);
1991
1992 rxirq = platform_get_irq(pdev, 0);
1993 txirq = platform_get_irq(pdev, 1);
1994 rtsirq = platform_get_irq(pdev, 2);
1995
1996 sport->port.dev = &pdev->dev;
1997 sport->port.mapbase = res->start;
1998 sport->port.membase = base;
1999 sport->port.type = PORT_IMX,
2000 sport->port.iotype = UPIO_MEM;
2001 sport->port.irq = rxirq;
2002 sport->port.fifosize = 32;
2003 sport->port.ops = &imx_pops;
2004 sport->port.rs485_config = imx_rs485_config;
2005 sport->port.rs485.flags =
2006 SER_RS485_RTS_ON_SEND | SER_RS485_RX_DURING_TX;
2007 sport->port.flags = UPF_BOOT_AUTOCONF;
2008 init_timer(&sport->timer);
2009 sport->timer.function = imx_timeout;
2010 sport->timer.data = (unsigned long)sport;
2011
2012 sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
2013 if (IS_ERR(sport->clk_ipg)) {
    
    
2014 ret = PTR_ERR(sport->clk_ipg);
2015 dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret);
2016 return ret;
2017 }
2018
2019 sport->clk_per = devm_clk_get(&pdev->dev, "per");
2020 if (IS_ERR(sport->clk_per)) {
    
    
2021 ret = PTR_ERR(sport->clk_per);
2022 dev_err(&pdev->dev, "failed to get per clk: %d\n", ret);
2023 return ret;
2024 }
2025
2026 sport->port.uartclk = clk_get_rate(sport->clk_per);
2027 if (sport->port.uartclk > IMX_MODULE_MAX_CLK_RATE) {
    
    
2028 ret = clk_set_rate(sport->clk_per, IMX_MODULE_MAX_CLK_RATE);
2029 if (ret < 0) {
    
    
2030 dev_err(&pdev->dev, "clk_set_rate() failed\n");
2031 return ret;
2032 }
2033 }
2034 sport->port.uartclk = clk_get_rate(sport->clk_per);
2035
2036 /*
2037 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
2038 * chips only have one interrupt.
2039 */
2040 if (txirq > 0) {
    
    
2041 ret = devm_request_irq(&pdev->dev, rxirq, imx_rxint, 0,
2042 dev_name(&pdev->dev), sport);
2043 if (ret)
2044 return ret;
2045
2046 ret = devm_request_irq(&pdev->dev, txirq, imx_txint, 0,
2047 dev_name(&pdev->dev), sport);
2048 if (ret)
2049 return ret;
2050 } else {
    
    
2051 ret = devm_request_irq(&pdev->dev, rxirq, imx_int, 0,
2052 dev_name(&pdev->dev), sport);
2053 if (ret)
2054 return ret;
2055 }
2056
2057 imx_ports[sport->port.line] = sport;
2058
2059 platform_set_drvdata(pdev, sport);
2060
2061 return uart_add_one_port(&imx_reg, &sport->port);
2062 }

Строка 1971 определяет переменную указателя структуры типа imx_port.
Линия 1977 года, применяется на память для спорта.
Строки 1987–1988 получают первый адрес периферийного регистра SOC UART серии I.MX из дерева устройств, который
равен 0X021EC000 для UART3 I.MX6ULL. После получения первого адреса регистра он отображается в память для получения
соответствующего виртуального адреса.
Строки 1992~1994, получить информацию о прерывании.
Строки 1996–2034, инициализируем sport, мы фокусируемся на строке 2003, чтобы инициализировать переменную-член порта sport
, то есть установить uart_ops в imx_pops, imx_pops — это набор функций драйвера нижнего уровня I.MX6ULL,
см. его позже.
Строки 2040~2055, подать заявку на прерывание.
Строка 2061, используйте uart_add_one_port для добавления uart_port к uart_driver, здесь для добавления
sport->port в imx_reg.
4. Структурная переменная imx_pops
imx_pops — это структурная переменная типа uart_ops, которая сохраняет функцию работы нижнего уровня последовательного порта I.MX6ULL.Определение
imx_pops следующее:

示例代码63.2.6 imx_pops 结构体
1611 static struct uart_ops imx_pops = {
    
    
1612 .tx_empty = imx_tx_empty,
1613 .set_mctrl = imx_set_mctrl,
1614 .get_mctrl = imx_get_mctrl,
1615 .stop_tx = imx_stop_tx,
1616 .start_tx = imx_start_tx,
1617 .stop_rx = imx_stop_rx,
1618 .enable_ms = imx_enable_ms,
1619 .break_ctl = imx_break_ctl,
1620 .startup = imx_startup,
1621 .shutdown = imx_shutdown,
1622 .flush_buffer = imx_flush_buffer,
1623 .set_termios = imx_set_termios,
1624 .type = imx_type,
1625 .config_port = imx_config_port,
1626 .verify_port = imx_verify_port,
1627 #if defined(CONFIG_CONSOLE_POLL)
1628 .poll_init = imx_poll_init,
1629 .poll_get_char = imx_poll_get_char,
1630 .poll_put_char = imx_poll_put_char,
1631 #endif
1632 };

Функции в imx_pops в основном имеют дело с регистрами UART I.MX6ULL, поэтому я не буду
подробно их анализировать. После краткого понимания драйвера UART I.MX6U давайте узнаем, как управлять
интерфейсом UART3 на макетной плате punctual Atom I.MX6U-ALPHA.

Аппаратный схематический анализ

Интерфейс UART3 модуля I.MX6U, используемый в этом эксперименте,
три интерфейса RS232, RS485 и GPS на макетной плате I.MX6U-ALPHA подключены к UART3.Давайте по очереди рассмотрим принципиальные схемы этих трех модулей. .
1. Принципиальная схема RS232
Принципиальная схема RS232 показана на рисунке 63.3.1:
вставьте сюда описание изображения
Из рисунка 63.3.1 видно, что уровень RS232 реализован через микросхему SP3232, а RS232 подключен к интерфейсу
UART3 I. MX6U, но его нужно подключать через JP1 Этот колпачок перемычки установлен. После подключения 1-3 и 2-4 JP1, SP3232
и UART3 соединяются вместе.
2. Принципиальная схема RS485
Схематическая диаграмма RS485 показана на рис. 63.3.2:
вставьте сюда описание изображения
RS485 реализуется микросхемой SP3485, RO — клемма вывода данных, RI — клемма ввода данных, RE —
сигнал разрешения приема (активный низкий уровень) , DE — сигнал разрешения передачи (активный высокий уровень). На рис. 63.3.2 RE и DE проходят через серию
цепей и, наконец, управляются RS485_RX, так что мы можем сохранить ввод-вывод управления приемопередатчиком RS485 и
использовать RS485 в качестве последовательного порта, который нам удобен для написания драйверов. .
3. Принципиальная схема GPS
Zhengdian Atom имеет модуль позиционирования GPS + Beidou, модель ATK1218-BD, а макетная плата I.MX6U-ALPHA зарезервировала интерфейс
этого модуля позиционирования GPS Принципиальная схема интерфейса показана на рисунке 63.3. .3:
вставьте сюда описание изображения
Из рисунка 63.3.3 видно, что модуль GPS также использует UART3, поэтому
данные модуля GPS можно считать сразу после успешного запуска UART3.

Написание драйвера RS232

Как мы уже говорили ранее, драйвер UART для I.MX6U был написан NXP, поэтому нам не нужно его писать.
Все, что нам нужно сделать, это добавить узел устройства, соответствующий UART3, в дерево устройств. Откройте файл imx6ull-alientek-emmc.dts
, в этом файле есть только узел uart1, соответствующий UART1, и нет узла, соответствующего UART3, поэтому мы можем
обратиться к узлу uart1 для создания узла uart3.
1. Узел ввода-вывода UART3 При создании UART3 используются два ввода-вывода UART3_TXD и UART3_RXD, поэтому сначала создайте подузел pinctrl, соответствующий
UART3, в iomuxc и добавьте следующее содержимое в iomuxc:

示例代码63.4.1 UART3 引脚pinctrl 节点
1 pinctrl_uart3: uart3grp {
    
    
2 fsl,pins = <
3 MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0X1b0b1
4 MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0X1b0b1
5 >;
6 };

Наконец, проверьте, используются ли два контакта UART3_TX и UART3_RX для других функций, и если да,
защитите их, чтобы убедиться, что эти два IO используются только как UART3, помните! ! !
2. Добавьте узел uart3.
По умолчанию в файле imx6ull-alientek-emmc.dts имеется только два узла uart1 и uart2, как показано на рис. 63.4.1:
вставьте сюда описание изображения
uart1 — это UART1, на плате разработки I.MX6U-ALPHA точечного атома UART2. не используется, а UART2
использует IO UART3 по умолчанию, поэтому вам нужно удалить узел uart2, а затем добавить uart3, соответствующий UART3,
содержимое узла uart3 следующее:

示例代码63.4.2 UART3 对应的uart3 节点
1 &uart3 {
    
    
2 pinctrl-names = "default";
3 pinctrl-0 = <&pinctrl_uart3>;
4 status = "okay";
5 };

После завершения перекомпилируйте дерево устройств и используйте новое дерево устройств для запуска Linux. Если дерево устройств изменено успешно,
после запуска системы будет создан
файл программа может реализовать операцию на UART3, обратившись к ttymxc2.

Портирование миникома

Minicom похож на нашего широко используемого помощника по отладке последовательного порта.Это очень часто используемый инструмент последовательного порта в Linux.Мы переносим minicom
на нашу плату разработки, чтобы мы могли использовать minicom для чтения и записи в последовательный порт.
1. Пересадка ncurses
minicom нуждается в ncurses, поэтому сначала нужно пересадить ncurses.Если ncurses уже пересаживался ранее, то
здесь пересаживать заново не нужно.Только при компиляции minicom нужно указать библиотеку ncurses и директорию заголовочного файла.
Сначала создайте каталог в Ubuntu для хранения файлов, которые мы хотим пересадить.Например, я
создал каталог с именем «tool» в каталоге /home/zuozhongkai/linux/IMX6ULL для хранения всех пересаженных файлов
. Затем загрузите исходный код ncurses, мы поместили исходный код ncurses на компакт-диск платы разработки, путь: 1,
исходный код сторонней библиотеки -" ncurses-6.0.tar.gz , ncurses-6.0.tar Скопируйте файл .gz в каталог инструментов, созданный в Ubuntu
, а затем распакуйте его.Команда распаковки выглядит следующим образом:

tar -vxzf ncurses-6.0.tar.gz

После завершения распаковки будет создана папка с именем «ncurses-6.0», которая является папкой с исходным кодом ncurse
. Создайте новый каталог с именем «ncurses» в каталоге инструментов, чтобы сохранить результаты компиляции ncurses.После того, как все будет готово, вы
можете скомпилировать библиотеку ncurses. Войдите в каталог исходного кода ncureses, то есть каталог ncurses-6.0, который был только что распакован
, сначала настройте ncureses и введите следующую команду:

./configure --prefix=/home/zuozhongkai/linux/IMX6ULL/tool/ncurses --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --with-shared --without-profile --disable-stripping --without-progs --with-manpages --without-tests

configure — это скрипт конфигурации, а --prefix используется для указания каталога сохранения результата компиляции, а результат компиляции должен быть сохранен
в созданном нами ранее каталоге «ncurses».
–host используется для указания префикса компилятора, который здесь установлен как «arm-linux- gnueabihf», а –target используется для указания цели, которая здесь также имеет значение «arm-linux-gnueabihf». После того, как команда конфигурации написана, нажмите
клавишу Enter и дождитесь завершения конфигурации.После того, как конфигурация будет успешной, это показано на рисунке 63.5.1: После того, как конфигурация будет успешной, введите
вставьте сюда описание изображения
команду «make», чтобы начать компиляцию. После успешной компиляции это показано на Рисунке 63.5.2: Компиляция прошла успешно
вставьте сюда описание изображения
Затем введите команду «make install» для установки, смысл установки заключается в копировании скомпилированного результата в каталог, указанный параметром –pfefix. После успешной установки, как показано на рисунке 63.5.3:

вставьте сюда описание изображения
После успешной установки проверьте созданную ранее папку «ncurses», и вы обнаружите, что в ней есть еще кое-что, как показано на рис. 63.5.4
:
вставьте сюда описание изображения
нам нужно хранить файлы в трех каталогах include, lib и share на рисунке 63.5.4 Скопируйте файлы в
три каталога /usr/include, /usr/lib и /usr/share в корневой файловой системе макетной платы.Если какой-либо каталог не существует, создайте его самостоятельно
! ! Команда копирования выглядит следующим образом:

sudo cp lib/* /home/zuozhongkai/linux/nfs/rootfs/usr/lib/ -rfa
sudo cp share/* /home/zuozhongkai/linux/nfs/rootfs/usr/share/ -rfa
sudo cp include/* /home/zuozhongkai/linux/nfs/rootfs/usr/include/ -rfa

Затем добавьте следующее содержимое в файл /etc/profile (создайте его самостоятельно, если у вас его нет) в корневом каталоге макетной платы:

示例代码63.5.1 /etc/profile 文件
1 #!/bin/sh
2 LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
3 export LD_LIBRARY_PATH
4
5 export TERM=vt100
6 export TERMINFO=/usr/share/terminfo

2. Пересадка minicom.
Продолжайте пересадку minicom и получите исходный код minicom, который мы поместили на компакт-диск с макетной платой, по пути: 1. Обычный
исходный код — «7. Исходный код сторонней библиотеки — «minicom-2.7.1». .tar.gz. Скопируйте minicom-2.7.1.tar.gz в
каталог /home/zuozhongkai/linux/IMX6ULL/tool ​​в ubuntu, а затем создайте подкаталог с именем «minicom» в каталоге инструментов
для хранения результатов компиляции minicom. После того, как все будет готово, можно скомпилировать minicom, предварительно разархивировав minicom,
команда следующая:

tar -vxzf minicom-2.7.1.tar.gz

После завершения распаковки будет создана папка с именем minicom-2.7.1.Это исходный код minicom.Войдите в
этот каталог, а затем настройте minicom.Команда настройки выглядит следующим образом:

cd minicom-2.7.1/ //进入minicom 源码目录
./configure CC=arm-linux-gnueabihf-gcc --prefix=/home/zuozhongkai/linux/IMX6ULL/tool/
minicom --host=arm-linux-gnueabihf CPPFLAGS=-I/home/zuozhongkai/linux/IMX6ULL/tool/
ncurses/include LDFLAGS=-L/home/zuozhongkai/linux/IMX6ULL/tool/ncurses/lib -enable-cfg-dir=/etc/minicom //配置

CC указывает используемый кросс-компилятор gcc, а --prefix указывает каталог хранения скомпилированных файлов, которые должны храниться в каталоге
minicom, который мы создали ранее. –host указывает префикс кросс-компилятора, CPPFLAGS указывает путь к заголовочному файлу ncurses, а LDFLAGS указывает путь к библиотеке ncurses.
Если конфигурация выполнена успешно, как показано на рис. 63.5.5:

вставьте сюда описание изображения
После успешной настройки выполните следующую команду для компиляции и установки:

make
make install

После компиляции и установки содержимое ранее созданного каталога minicom показано на рисунке 63.5.6:
вставьте сюда описание изображения
скопируйте все файлы из подкаталога bin в каталоге minicom в каталог /usr/bin в корневом каталоге макетной платы и команда выглядит
следующим образом:

sudo cp bin/* /home/zuozhongkai/linux/nfs/rootfs/usr/bin/

После завершения введите «minicom -v» на макетной плате, чтобы проверить, нормально ли работает minicom, результат показан на рисунке 63.5.7: Из рисунка 63.5.7 видно,
что
вставьте сюда описание изображения
номер версии minicom — 2.7.1, а номер версии миникома 2.7.1.Вид нормальный. Введите следующую
команду, чтобы открыть интерфейс конфигурации minicom:

minicom -s

В результате интерфейс настройки minicom не может быть открыт, и выводится информация, показанная на рисунке 63.5.8:
вставьте сюда описание изображения
Из рисунка 63.5.8 видно, что minicom крайне самонадеян и просит нас «Уйти». терпеть? ! Это должно быть
вылечено. Решение очень простое: создайте новый файл /etc/passwd, а затем введите в него следующее содержимое:

示例代码63.5.2 /etc/passwd 文件
1 root:x:0:0:root:/root:/bin/sh

Перезагрузите плату, когда закончите!
Перезагрузите плату, когда закончите!
После перезапуска макетной платы выполните команду «minicom -s», после чего можно будет открыть интерфейс конфигурации minicom, как
показано на рисунке 63.5.9:
вставьте сюда описание изображения
Если появится интерфейс, показанный на рисунке 63.5.9, это означает, что mincom работает нормально. .

Тест привода RS232

Настройки подключения RS232

Перед тестом подключите RS232 отладочной платы I.MX6U-ALPHA к компьютеру, сначала установите перемычку JP1
, как показано на рис. 63.6.1.1:
вставьте сюда описание изображения
После установки перемычки используйте линию RS232 для подключения отладочной платы. к компьютеру. Здесь рекомендуется использовать
кабель передачи данных USB-DB9 (RS232) , например кабель передачи данных USB-вилка DB9 решения CH340, продаваемого Zhengdian Atom, как
показано на рисунке 63.6.1.2:
вставьте сюда описание изображения
кабель передачи данных, показанный на Рисунок 63.6.1.2 показан с чипом CH340, поэтому, когда он подключен к компьютеру, появится COM-порт
, и этот COM-порт является COM-портом, который мы хотим использовать. Например, на моем компьютере это COM9,
создайте новое соединение на SecureCRT, последовательный порт — COM9, а скорость передачи — 115200.

minicom-настройки

Введите «minicom -s» на макетной плате, чтобы открыть интерфейс конфигурации minicom, а затем выберите «Настройка последовательного порта», как показано на рисунке 63.6.2.1:
После
вставьте сюда описание изображения
выбора «Настройка последовательного порта» нажмите «Ввод», чтобы войти в меню настройки, как показано на Рисунке 63.6 Как показано на .2.2:
вставьте сюда описание изображения
На Рисунке 63.6.2.2 имеется 7 пунктов настройки, которые соответствуют A, B...G соответственно Например, первый – выбрать последовательный порт, а
последовательный файл порта UART3 — /dev/ttymxc2, поэтому устройство последовательного порта должно быть установлено как /dev/ttymxc2. Метод настройки состоит в том, чтобы нажать «A» на клавиатуре,
а затем ввести «/dev/ttymxc2», как показано на рисунке 63.6.2.3:
вставьте сюда описание изображения
После настройки нажмите клавишу Enter для подтверждения, после чего вы можете установить другие элементы конфигурации. Например, E задает скорость передачи данных,
биты данных и стоповые биты, а F задает аппаратное управление потоком.Методы настройки те же.После настройки это показано на рисунке 63.6.2.4: После того, как все настройки завершены, нажмите
вставьте сюда описание изображения
кнопку Введите ключ для подтверждения и выхода.В это время он вернется к интерфейсу, показанному на рисунке 63.6.2.1, нажмите
клавишу ESC, чтобы выйти из интерфейса конфигурации, показанного на рисунке 63.6.2.1, после выхода он будет показан на рисунке 63.6. .2.5: На рисунке 63.6.2.2
вставьте сюда описание изображения
показан наш интерфейс отладки последовательного порта. Можно увидеть, что текущий файл последовательного порта — /dev/ttymxc2, нажмите CTRL-
A, а затем нажмите Z, чтобы открыть интерфейс справочной информации minicom, как показано на Рисунок 63.6.2.6:
вставьте сюда описание изображения
Из рисунка 63.6.2.6 видно, что в minicom много сочетаний клавиш. В этом эксперименте мы включаем функцию эха minicom. Элементом конфигурации функции
эха является «локальное эхо вкл/выкл.. .E", поэтому нажмите E, чтобы включить/выключить функцию эха.

Тест приемопередатчика RS232

1. Отправка теста
Сначала проверьте функцию макетной платы для отправки данных на компьютер через UART3, вам нужно открыть функцию эха minicom (вы не можете
открыть ее ), после включения функции эха введите «AAAA», как
показано на рисунке 63.6.3.1:
вставьте сюда описание изображения

«AAAA» на рисунке 63.6.3.1 эквивалентно отправке отладочной платой «AAAA» на компьютер через UART3, затем COM9
получит «AAAA». Данные, полученные COM9 в SecureCRT, показаны на рисунке 63.6.3.2:
вставьте сюда описание изображения
их можно Видно, макетная плата обычно отправляет данные на компьютер через UART3, а затем проверяет
функцию приема данных на макетной плате.
2. Получение теста
Затем проверьте функцию приема UART3 платы разработки.Точно так же вы должны сначала включить локальное эхо COM9 на SecureCRT
, иначе вы не увидите вывод на COM9, но он фактически был отправлен на плату разработки . Выберите
Options->Session Options->Adavnced of SecureCRT, откройте интерфейс конфигурации сеанса, а затем выберите «Local echo»,
как показано на рисунке 63.6.3.3:
вставьте сюда описание изображения
После установки SecureCRT отправьте «BBBB» на плату разработки, на COM9 от SecureCRT Вход «BBBB»,
как показано на рисунке 63.6.3.3:
вставьте сюда описание изображения
В это время minicom платы разработки будет получать отправленный «BBBB», как показано на рисунке 63.6.3.4:
вставьте сюда описание изображения
Нет проблем с отправкой UART3 и получаем тест, указывающий, что наш драйвер UART3 работает нормально. Если вы хотите выйти из minicom
, нажмите CRTL+A на коммуникационном интерфейсе minicom, а затем нажмите X, чтобы закрыть minicom. Использовать minicom
здесь очень просто, и вы можете найти более подробные руководства по minicom в Интернете.

Тест RS485

Как упоминалось выше, интерфейс RS485 на макетной плате I.MX6U-ALPHA подключен к UART3, поэтому
по сути это последовательный порт. Для эксперимента с RS232 мы написали драйвер UART3, поэтому нет необходимости писать
какой-либо драйвер для эксперимента с RS485, и мы можем напрямую использовать minicom для тестирования.

Настройки подключения RS485

Во-первых, установить перемычку JP1 и соединить 3-5 и 4-6, как показано на рис. 63.7.1.1:
вставьте сюда описание изображения
одна плата не может выполнить тест связи RS485, и требуется другое устройство RS485, например I.MX6U-ALPHA. развивающая доска. Здесь мы рекомендуем вам использовать последовательный преобразователь USB «три в одном» производства Zhengdian Atom, который поддерживает USB в TTL,
RS232 и RS485, как показано на рисунке 63.7.1.2:
вставьте сюда описание изображения
используйте кабель Dupont для подключения интерфейса RS485 последовательного порта USB. Преобразователь в I.MX6U-ALPHA RS485 макетной платы подключен
, A подключается к A, B подключается к B, он не может быть неправильно подключен! После завершения подключения, как показано на рисунке 63.7.1.3:
вставьте сюда описание изображения
преобразователь последовательного порта подключается к компьютеру через кабель USB.Я использую версию CH340, поэтому нет необходимости устанавливать драйвер.Если
вы используете версию FT232 , вам необходимо установить соответствующий диск. После успешного подключения на компьютере появится соответствующий COM-
порт, например, на моем компьютере COM10, и следующим шагом будет проверка.

Тест приемопередатчика RS485

Тест RS485 точно такой же, как и у RS232! COM-порт универсального USB-конвертера — 10, поэтому используйте SecureCRT
для создания соединения COM10. Плата разработки использует UART3, а соответствующий файл устройства последовательного порта — /dev/ttymxc2, поэтому плата разработки
использует minicom для создания соединения последовательного порта /dev/ttymxc2. Скорость последовательного порта составляет 115200 бод, 8 бит данных, 1
стоповый бит, аппаратное и программное управление потоком данных отключено.
1. Тест отправки RS485.
Сначала проверьте, что макетная плата отправляет данные через RS485, после настройки minicom также введите «AAAA», то есть
отправьте строку «AAAA» на компьютер через RS485. Если драйвер RS485 работает нормально, компьютер получит сообщение
«AAAA», отправленное отладочной платой, как показано на рисунке 63.7.2.1.
вставьте сюда описание изображения
Из рисунка 63.7.2.1 видно, что отладочная плата успешно отправила «AAAA» на компьютер через RS485.Это означает, что данные RS485
отправляются нормально.
2. Тест приема RS485
Затем проверьте прием данных RS485.Компьютер отправляет «BBBB» на макетную плату через RS485, а затем смотрите,
может ли minicom принимать «BBBB». Результат показан на рисунке 63.7.2.2:
вставьте сюда описание изображения
Из рисунка 63.7.2.1 видно, что макетная плата получает «BBBB», отправленный компьютером через RS485, что указывает на то, что
прием данных RS485 также является нормальным.

GPS тест

Настройки подключения GPS

Большинство модулей GPS выводятся через последовательные порты. В качестве примера мы возьмем модуль ATK1218-BD производства Zhengdian Atom. Это
модуль позиционирования GSP+ Beidou. Модуль показан на рисунке 63.8.1.1
вставьте сюда описание изображения
. JP1 на макетной плате, не подключайте RS232 или RS485, иначе
это будет мешать модулю GSP. UART3_TX и UART3_RX были подключены к МОДУЛЮ ATK на макетной плате.Просто
подключите модуль ATK1218-BD непосредственно к интерфейсу ATK MODULE на макетной плате.Интерфейс ATK MODULE на макетной плате
является 6-контактным, а ATK1218- BD модуль 5-контактный, поэтому его нужно вставлять слева! Затем GPS необходимо подключить к антенне, а
приемную головку антенны необходимо разместить на открытом воздухе, чтобы в помещении обычно не было сигнала GPS. После завершения подключения, как показано на рисунке 63.8.1.2
:
вставьте сюда описание изображения

Проверка приема данных GPS

Мы все пассивно получаем данные о местоположении для GPS, поэтому откройте minicom, установите /dev/ttymxc2, и требования к настройке последовательного порта следующие
:
пунктуальный атом 38400.
②, 8 бит данных, 1 стоповый бит.
③ Отключите аппаратное и программное управление потоком.
После настройки, как показано на рисунке 63.8.2.1:
вставьте сюда описание изображения
После настройки вы можете спокойно дождаться вывода данных GPS.Модулю GPS может потребоваться несколько минут для первого поиска спутников, и данные позиционирования
будут выведены только после того, как спутники будут найдены. После того, как спутник найден, данные позиционирования, выдаваемые модулем GPS, показаны
на рисунке 63.8.2.2:
вставьте сюда описание изображения

рекомендация

отblog.csdn.net/zhuguanlin121/article/details/129894275
рекомендация