概述
1 设备树文件
1.1 引脚配置
硬件上采用了 CSI0_DAT10、CSI0_DAT11 做为串口 1 的 TX,RX,在设备树文件中,需要按照如下配置:
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
>;
};
#define MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x280 0x650 0x000 0x3 0x0
#define MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x284 0x654 0x920 0x3 0x1
参数 | 描述 |
---|---|
mux_reg | PAD MUX Register offset |
conf_reg | PAD Control Register offset |
input_reg | select input register offset |
mux_mode | value of PAD MUX Register |
input_val | value of select input Register |
config | value of PAD Control Register |
1.1.1 mux_reg:PAD MUX Register offset
mux_mode = 0x03
select signal UART1_TX_DATA
1.1.2 conf_reg:PAD Control Register offset
config = 0x1b0b1
1.2 串口资源描述
uart1: serial@02020000 {
compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
reg = <0x02020000 0x4000>;
interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_UART_IPG>,
<&clks IMX6QDL_CLK_UART_SERIAL>;
clock-names = "ipg", "per";
dmas = <&sdma 25 4 0>, <&sdma 26 4 0>;
dma-names = "rx", "tx";
status = "okay";
};
- 这个一般只需要改动 status 的值。okay,disabled。
- reg = <0x02020000 0x4000>,表示 uart1 寄存器的起始地址与大小
- interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>,中断号 26,高电平有效
- clocks = <&clks IMX6QDL_CLK_UART_IPG>, <&clks IMX6QDL_CLK_UART_SERIAL>; 未搞懂
- dmas = <&sdma 25 4 0>, <&sdma 26 4 0>; 未搞懂
2 系统调用 open、write、read 是如何操作串口
在 Linux 系统中,每个字符设备都由一个 struct cdev 结构表示:
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
其中,包含了文件操作的接口 struct file_operation *ops,编写串口驱动就是用串口的操作函数填充这些接口。如下图所示:
2.1 open 操作
open 函数经过层层调用,最后调用了 imx_startup 函数。
static int imx_startup(struct uart_port *port)
{
/*
使能时钟;
设置发送/接收 FIFO 触发字节数;
设置DMA;
注册DMA发送函数;
使能中断;
*/
}
2.2 write 操作
write 函数经过层层调用,最后调用了 imx_start_tx 函数。
static void imx_start_tx(struct uart_port *port)
{
/*
根据是否开启DMA,开启相应的发送中断;
*/
}
开启中断后,注册过的中断发送函数会自动将发送 buff 内的字节发送出去。
2.3 read 操作
接收中断会自动将接收到的字节搬运至接收缓冲区,所以串口不需要实现特定的 read 函数,调用 read 函数,最后会调用 tty_read 函数,将接收缓冲区的内容搬运至用户空间。
2.4 close 操作
close 函数经过层层调用,最后调用了 imx_shutdown 函数。
static void imx_shutdown(struct uart_port *port)
{
/*
等待DMA结束;
停止定时器;
失能所有中断;
*/
}
最后
以上就是冷艳紫菜为你收集整理的IMX6DL 串口篇的全部内容,希望文章能够帮你解决IMX6DL 串口篇所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复