福州网站建设制作首选荧光信息,花瓣网网站模板,邯郸有做网站的吗,网站首页结构怎么写错误1#xff1a;我一直找不到为什么我的minicom用不了#xff0c;编译啥的都通过了#xff0c;原来是我的密码文件命名错了#xff0c;我就习以为常的命名为password#xff0c;谁知道应该是passwd#xff0c;所以以后该复制的还是复制#xff0c;不然就容易找不到源头…错误1我一直找不到为什么我的minicom用不了编译啥的都通过了原来是我的密码文件命名错了我就习以为常的命名为password谁知道应该是passwd所以以后该复制的还是复制不然就容易找不到源头在哪。 
串口是很常用的一个外设在 Linux 下通常通过串口和其他设备或传感器进行通信根据 电平的不同串口分为 TTL 和 RS232。不管是什么样的接口电平其驱动程序都是一样的通 过外接 RS485 这样的芯片就可以将串口转换为 RS485 信号正点原子的 I.MX6U-ALPHA 开发 板就是这么做的。对于正点原子的 I.MX6U-ALPHA 开发板而言 RS232、RS485 以及 GPS 模 块接口通通连接到了 I.MX6U 的 UART3 接口上因此这些外设最终都归结为 UART3 的串口驱 动。本章我们就来学习一下如何驱动 I.MX6U-ALPHA 开发板上的 UART3 串口进而实现 RS232、 RS485 以及 GSP 驱动。 
1Linux 下 UART 驱动框架 
1.1uart_driver 注册与注销 
同 I2C、SPI 一样Linux 也提供了串口驱动框架我们只需要按照相应的串口框架编写驱 动程序即可。串口驱动没有什么主机端和设备端之分就只有一个串口驱动而且这个驱动也 已经由 NXP 官方已经编写好了我们真正要做的就是在设备树中添加所要使用的串口节点信 息。当系统启动以后串口驱动和设备匹配成功相应的串口就会被驱动起来生成 /dev/ttymxcX(X0….n)文件。 虽然串口驱动不需要我们去写但是串口驱动框架我们还是需要了解的uart_driver 结构 体表示 UART 驱动uart_driver 定义在 include/linux/serial_core.h 文件中内容如下 
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_register_driver 函数向 系统注册这个 uart_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。 返回值无。 
1.2uart_port 的添加与移除 
uart_port 表示一个具体的 portuart_port 定义在 include/linux/serial_core.h 文件内容如下 (有省略) 
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 中最主要的就是第 235 行的 opsops 包含了串口的具体驱动函数这个我们稍后 再看。每个 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此 port 对应的 uart_driver。 
uport要添加到 uart_driver 中的 port。 
返回值0成功负值失败。 
卸载 UART 驱动的时候也需要将 uart_port 从相应的 uart_driver 中移除需要用到 uart_remove_one_port 函数函数原型如下 
int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport) 
函数参数和返回值含义如下 drv要卸载的 port 所对应的 uart_driver。 
uport要卸载的 uart_port。 
返回值0成功负值失败。 
1.3uart_ops 实现 
在上面讲解 uart_port 的时候说过uart_port 中的 ops 成员变量很重要因为 ops 包含了针 对 UART 具体的驱动函数Linux 系统收发数据最终调用的都是 ops 中的函数。ops 是 uart_ops 类型的结构体指针变量uart_ops 定义在 include/linux/serial_core.h 文件中内容如下 
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 驱动框架大概就是这些接下来我们理论联系实际看一下 NXP 官方的 UART 驱动文件是如何编写的。 
2I.MX6U UART 驱动分析 
2.1UART 的 platform 驱动框架 
打开 imx6ull.dtsi 文件找到 UART3 对应的子节点子节点内容如下所示 
1 uart3: serial021ec000 {
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 }; 
重点看一下第 23 行的 compatible 属性这里一共有三个值“fsl,imx6ul-uart”、“fsl,imx6q-uar”和“fsl,imx21-uart”。在 linux 源码中搜索这三个值即可找到对应的 UART 驱动文件此文 件为 drivers/tty/serial/imx.c在此文件中可以找到如下内容 
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); 
可以看出 I.MX6U 的 UART 本质上是一个 platform 驱动 
第 267~280 行imx_uart_devtype 为传统匹配表。 
第 283~288 行设备树所使用的匹配表第 284 行的 compatible 属性值为“fsl,imx6q-uart”。 
第 2071~2082 行platform 驱动框架结构体 serial_imx_driver。 
第 2084~2096 行驱动入口函数 
第 2086 行调用 uart_register_driver 函数向 Linux 内核注 册 uart_driver在这里就是 imx_reg。 
第 2098~2102 行驱动出口函数 
第 2101 行调用 uart_unregister_driver 函数注销掉前面注 册的 uart_driver也就是 imx_reg。 
2.2uart_driver 初始化 
在 imx_serial_init 函数中向 Linux 内核注册了 imx_regimx_reg 就是 uart_driver 类型的结 构体变量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 };  
2.3uart_port 初始化与添加 
当 UART 设备和驱动匹配成功以后 serial_imx_probe 函数就会执行此函数的重点工作就 是初始化 uart_port然后将其添加到对应的 uart_driver 中。在看 serial_imx_probe 函数之前先来 看一下 imx_port 结构体imx_port 是 NXP 为 I.MX 系列 SOC 定义的一个设备结构体此结构 体内部就包含了 uart_port 成员变量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 成员变量 port。 接下来看一下 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 类型的结构体指针变量 sport。 
第 1977 行为 sport 申请内存。 
第 1987~1988 行从设备树中获取 I.MX 系列 SOC UART 外设寄存器首地址对于 I.MX6ULL 的 UART3 来说就是 0X021EC000。得到寄存器首地址以后对其进行内存映射得到 对应的虚拟地址。 
第 1992~1994 行获取中断信息。 第 1996~2034 行初始化 sport我们重点关注的就是第 2003 行初始化 sport 的 port 成员变 量也就是设置 uart_ops 为 imx_popsimx_pops 就是 I.MX6ULL 最底层的驱动函数集合稍后 再来看。 
第 2040~2055 行申请中断。 
第 2061 行使用 uart_add_one_port 向 uart_driver 添加 uart_port在这里就是向 imx_reg 添 加 sport-port。 
2.4imx_pops 结构体变量 
imx_pops 就是 uart_ops 类型的结构体变量保存了 I.MX6ULL 串口最底层的操作函数 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 中的函数基本都是和 I.MX6ULL 的 UART 寄存器打交道的这里就不去详细的 分析了。简单的了解了 I.MX6U 的 UART 驱动以后我们再来学习一下如何驱动正点原子 I.MX6U-ALPHA 开发板上的 UART3 接口。 
3RS232 驱动编写 
前面我们已经说过了I.MX6U 的 UART 驱动 NXP 已经编写好了所以不需要我们编写。我们要做的就是在设备树中添加 UART3 对应的设备节点即可。打开 imx6ull-alientek-emmc.dts 文件在此文件中只有 UART1 对应的 uart1 节点并没有 UART3 对应的节点因此我们可以 参考 uart1 节点创建 uart3 节点。 
3.1UART3 IO 节点创建 
UART3 用到了 UART3_TXD 和 UART3_RXD 这两个 IO因此要先在 iomuxc 中创建 UART3 对应的 pinctrl 子节点在 iomuxc 中添加如下内容 
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切记 
3.2添加 uart3 节点 
默认情况下 imx6ull-alientek-emmc.dts 中只有 uart1 和 uart2 这两个节点如图 63.4.1 所示 uart1 是 UART1 的在正点原子的 I.MX6U-ALPHA 开发板上没有用到 UART2而且 UART2 默认用到了 UART3 的 IO因此需要将 uart2 这个节点删除掉然后加上 UART3 对应的 uart3 uart3 节点内容如下 
1 uart3 {
2 pinctrl-names  default;
3 pinctrl-0  pinctrl_uart3;
4 status  okay;
5 }; 
完成以后重新编译设备树并使用新的设备树启动 Linux如果设备树修改成功的话系统 启动以后就会生成一个名为“/dev/ttymxc2”的设备文件ttymxc2 就是 UART3 对应的设备文 件应用程序可以通过访问 ttymxc2 来实现对 UART3 的操作 
4移植 minicom 
minicom 类似我们常用的串口调试助手是 Linux 下很常用的一个串口工具将 minicom 移植到我们的开发板中这样我们就可以借助 minicom 对串口进行读写操作。 
4.1移植 ncurses 
minicom 需要用到 ncurses依次需要先移植 ncurses如果前面已经移植好了 ncurses那么 这里就不需要再次移植了只需要在编译 minicom 的时候指定 ncurses 库和头文件目录 即可。 
首先在 ubuntu 中 创 建 一 个 目 录 来 存 放 我 们 要 移 植 的 文 件  比 如 我 在 /home/zuozhongkai/linux/IMX6ULL 目录下创建了一个名为“tool”的目录来存放所有的移植文 件。然后下载 ncurses 源码我们已经将 ncurses 源码放到了开发板光盘中路径为1、例程源 码-》7、第三方库源码-》ncurses-6.0.tar.gz将 ncurses-6.0.tar.gz 拷贝到 Ubuntu 中创建的 tool 目 录下然后进行解压解压命令如下 
tar -vxzf ncurses-6.0.tar.gz 
解压完成以后就会生成一个名为“ncurses-6.0”的文件夹此文件夹就是 ncurese 的源码文 件夹。在 tool 目录下新建名为“ncurses”目录用于保存 ncurses 编译结果一切准备就绪以后 就可以编译 ncureses 库了。进入到 ncureses 源码目录下也就是刚刚解压出来的 ncurses-6.0 目 录中首先是配置 ncureses输入如下命令 
./configure --prefix/home/zuozhongkai/linux/IMX6ULL/tool/ncurses --hostarm-linuxgnueabihf --targetarm-linux-gnueabihf --with-shared --without-profile --disable-stripping --without-progs --with-manpages --without-tests 
configure 就是配置脚本--prefix 用于指定编译结果的保存目录这里肯定将编译结果保存 到我们前面创建的“ncurses”目录中。--host 用于指定编译器前缀这里设置为 “arm-linuxgnueabihf”--target 用于指定目标这里也设置为“arm-linux-gnueabihf”。配置命令写好以后点 击回车键等待配置完成配置成功以后如图 63.5.1 所示 配置成功以后输入“make”命令开始编译编译成功以后如图 63.5.2 所示 pfefix 指定的目录里面去。安装成功以后如图 63.5.3 所示 安装成功以后查看一下前面创建的“ncurses”文件夹会发现里面多了一些东西如图 63.5.4 所示 我们需要将图 63.5.4 中 include、lib 和 share 这三个目录中存放的文件分别拷贝到开发板根 文件系统中的/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(没有的话自己创建一个)文件中添加如下所示内容 
1 #!/bin/sh
2 LD_LIBRARY_PATH/lib:/usr/lib:$LD_LIBRARY_PATH
3 export LD_LIBRARY_PATH
4
5 export TERMvt100
6 export TERMINFO/usr/share/terminfo 
4.2:移植 minicom 
继续移植 minicom获取 minicom 源码我们已经放到了开发板光盘中了路径为1、例 程源码-》7、第三方库源码-》minicom-2.7.1.tar.gz。将 minicom-2.7.1.tar.gz 拷贝到 ubuntu 中的 /home/zuozhongkai/linux/IMX6ULL/tool 目录下然后在 tool 目录下新建一个名为“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 CCarm-linux-gnueabihf-gcc --prefix/home/zuozhongkai/linux/IMX6ULL/tool/
minicom --hostarm-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 所示 将 minicom 目录中 bin 子目录下的所有文件拷贝到开发板根目录中的/usr/bin 目录下命令 如下 sudo cp bin/* /home/zuozhongkai/linux/nfs/rootfs/usr/bin/ 
完成以后在开发板中输入“minicom -v”来查看 minicom 工作是否正常结果如图 63.5.7 所 示 从图 63.5.7 可以看出此时 minicom 版本号为 2.7.1minicom 版本号查看正常。输入如下 命令打开 minicom 配置界面 
minicom -s结果是打不开 minicom 配置界面提示如图 63.5.8 所示信息 从图 63.5.8 可以看出minicom 异常嚣张竟然让我们“Go away”这能容忍必须要 治一下。解决方法很简单新建/etc/passwd 文件然后在 passwd 文件里面输入如下所示内容 
1 root:x:0:0:root:/root:/bin/sh完成以后重启开发板 
完成以后重启开发板 
完成以后重启开发板 
开发板重启以后再执行“minicom -s”命令此时 minicom 配置界面就可以打开了如图 63.5.9 所示 如果能出现图 63.5.9 所示界面那么就说明 mincom 工作正常了。 
当然mini板子没有232好像只有485和can 
5RS232 驱动测试 
5.1RS232 连接设置 
在测试之前要先将 I.MX6U-ALPHA 开发板的 RS232 与电脑连接起来首先设置 JP1 跳线 帽如图 63.6.1.1 所示 跳线帽设置好以后使用 RS232 线将开发板与电脑连接起来这里建议使用 USB 转 DB9(RS232)数据线比如正点原子售卖的 CH340 方案的 USB 转公头 DB9 数据线如图 63.6.1.2 所示 图 63.6.1.2 中所示的数据线是带有 CH340 芯片的因此当连接到电脑以后就会出现一个 COM 口这个 COM 口就是我们要使用的 COM 口。比如在我的电脑上就是 COM9在 SecureCRT 上新建一个连接串口为 COM9波特率为 115200。 
5.2minicom 设置 
在开发板中输入“minicom -s”打开 minicom 配置界面然后选中“Serial port setup”如 图 63.6.2.1 所示 选中“Serial port setup”以后点击回车进入设置菜单如图 63.6.2.2 所示 图 63.6.2.2 中有 7 个设置项目分别对应 A、B……G比如第一个是选中串口UART3 的 串口文件为/dev/ttymxc2因此串口设置要设置为/dev/ttymxc2。设置方法就是按下键盘上的‘A’ 然后输入“/dev/ttymxc2”即可如图 63.6.2.3 所示 设置完以后按下回车键确认确认完以后就可以设置其他的配置项。比如 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按下 CTRLA然后再按下 Z 就可以打开 minicom 帮助信息界面如图 63.6.2.6 所示 从图 63.6.2.6 可以看出minicom 有很多快捷键本实验我们打开 minicom 的回显功能 回显功能配置项为“local Echo on/off..E”因此按下 E 即可打开/关闭回显功能。 
5.3RS232 收发测试 
5.3.1发送测试 
首先测试开发板通过 UART3 向电脑发送数据的功能需要打开 minicom 的回显功能(不打 开也可以但是在 minicom 中看不到自己输入的内容)回显功能打开以后输入“AAAA”如 图 63.6.3.1 所示 图 63.6.3.1 中的“AAAA”相当于开发板通过 UART3 向电脑发送“AAAA”那么 COM9 就会接收到“AAAA”SecureCRT 中 COM9 收到的数据如图 63.6.3.2 所示 5.3.2接收测试 
接下来测试开发板的 UART3 接收功能同样的要先打开 SecureCRT 上 COM9 的本地回 显否则的话你在 COM9 上输出的内容会看不到但是实际上是已经发送给了开发板。选中 SecureCRT 的 Options-Session Options-Adavnced打开回话配置界面然后选中“Local echo” 如图 63.6.3.3 所示 SecureCRT设置好以后向开发板发送一个“BBBB”在SecureCRT的COM9上输入“BBBB” 如图 63.6.3.3 所示 此时开发板的 minicom 就会接收到发送过来的“BBBB”如图 63.6.3.4 所示 UART3 收发测试都没有问题说明我们的 UART3 驱动工作正常。如果要退出 minicom 的 话在 minicom 通信界面按下 CRTLA然后按下 X 来关闭 minicom。关于 minicom 的使用我 们这里讲的很简单大家可以在网上查找更加详细的 minicom 使用教程。  
总而言之这个串口3的驱动不用我们写只需配置设备树和配置一些其他文件。驱动程序及测试APP都是我们移植的minicom来完成那我们做了什么呢。我们做的工作就是配置设备树和移植软件。这个硬件也不是我们操心的地方硬件由硬件工程师来做。串口同信的驱动是一致的区别在于电平转换芯片上。 
6RS485 测试 
前面已经说过了I.MX6U-ALPHA 开发板上的 RS485 接口连接到了 UART3 上因此本质 上就是个串口。RS232 实验我们已经将 UART3 的驱动编写好了所以 RS485 实验就不需要编 写任何驱动程序可以直接使用 minicom 来进行测试。 
6.1RS485 连接设置 
首先是设置 JP1 跳线帽将 3-5、4-6 连接起来如图 63.7.1.1 所示 mini板子上有这个485但为了485又去买一个转接器是不是有点为了一口醋去饱一顿饺子的嫌疑。 
一个板子是不能进行 RS485 通信测试的还需要另一个 RS485 设备比如另外一块 I.MX6UALPHA开发板。这里推荐大家使用正点原子出品的USB三合一串口转换器支持USB转TTL、 RS232 和 RS485如图 63.7.1.2 所示 使用杜邦线将 USB 串口转换器的 RS485 接口和 I.MX6U-ALPHA 开发板的 RS485 连接起 来A 接 AB 接 B不能接错了连接完成以后如图 63.7.1.3 所示 串口转换器通过 USB 线连接到电脑上我用的是 CH340 版本的因此就不需要安装驱动 的如果使用的是 FT232 版本的就需要安装相应的驱动。连接成功以后电脑就会有相应的 COM 口比如我的电脑上就是 COM10接下来就是测试。 
6.2RS485 收发测试 
RS485 的测试和 RS232 一模一样USB 多合一转换器的 COM 口为 10因此使用 SecureCRT 创建一个 COM10 的连接。开发板使用 UART3对应的串口设备文件为/dev/ttymxc2因此开发 板使用 minicom 创建一个/dev/ttymxc2 的串口连接。串口波特率都选择 1152008 位数据位1 位停止位关闭硬件和软件流控。 
6.2.1RS485 发送测试 
首先测试开发板通过 RS485 发送数据设置好 minicom 以后同样输入“AAAA”也就是 通过 RS485 向电脑发送一串“AAAA”。如果 RS485 驱动工作正常的话那么电脑就会接收到 开发板发送过来的“AAAA”如图 63.7.2.1 所示 从图 63.7.2.1 可以看出开发板通过 RS485 向电脑发送“AAAA”成功说明 RS485 数据数 据发送正常 
6.2.2RS485 接收测试 
接下来测试一下 RS485 数据接收电脑通过 RS485 向开发板发送“BBBB”然后观察 minicom 是否能接收到“BBBB”。结果如图 63.7.2.2 所示 从图 63.7.2.1 可以看出开发板接收到电脑通过 RS485 发送过来的“BBBB”说明 RS485 数 据接收也正常。 
7:GPS 测试 
7.1:GPS 连接设置 
GPS 模块大部分都是串口输出的这里以正点原子出品的 ATK1218-BD 模块为例这是 一款 GSP北斗的定位模块模块如图 63.8.1.1 所示 首先要将 I.MX6U-ALPHA 开发板上的 JP1 跳线帽拔掉不能连接 RS232 或 RS485否则 会干扰到 GSP 模块。UART3_TX 和 UART3_RX 已经连接到了开发板上的 ATK MODULE 上 直接将 ATK1218-BD 模块插到开发板上的 ATK MODULE 接口即可开发板上的 ATK MODULE 接口是 6 脚的而 ATK1218-BD 模块是 5 脚的因此需要靠左插然后 GPS 需要接上天线天 线的接收头一定要放到户外因此室内一般是没有 GPS 信号的。连接完成以后如图 63.8.1.2 所 示 7.2:GPS 数据接收测试  
原子哥没用北斗我是有点疑问的听说北斗的模块才几块钱是不是程序复杂啊不晓得 
GPS 我们都是被动接收定位数据的因此打开 minicom设置/dev/ttymxc2串口设置要求 如下 ①、波特率设置为 38400因为正点原子的 ATK1218-BD 模块默认波特率就是 38400。 ②、8 位数据位1 位停止位。 ③、关闭硬件和软件流控。 设置好以后如图 63.8.2.1 所示 设置好以后就可以静静的等待 GPS 数据输出GPS 模块第一次启动可能需要几分钟搜星 等搜到卫星以后才会有定位数据输出。搜到卫星以后 GPS 模块输出的定位数据如图 63.8.2.2 所 示 咱不买alpha板子因为咱省钱咱不买串口转换器因为咱省钱咱不买GPS定位模块因为咱省钱但是该移植这个minicom还是要做的 本文仅在记录学习正点原子imx6ull-mini开发板的过程不做他用。