RT-Thread之UART设备驱动开发教程

uart介绍
uart(universal asynchronous receiver/transmitter,通用异步收发传输器)也常被称为串口。uart作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。uart是在应用程序开发过程中使用频率最高的数据总线。在嵌入式设计中,uart常用于主机与辅助设备通信,如嵌入式设备与外接模块(wi-fi、蓝牙模块等)的通信,嵌入式设备与pc监视器的通信,或用于两个嵌入式设备之间的通信。
uart串口属于字符设备的一种,它的硬件连接也比较简单,只要两根传输线就可以实现双向通信:一根线(tx)发送数据,另一根线(rx)接收数据。
uart串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用uart串口通信的端口,这些参数必须匹配,否则通信将无法正常完成。
数据格式包含起始位、数据位、奇偶校验位、停止位。
起始位:表示数据传输的开始,电平逻辑为“0”。
数据位:数据位通常为8bit的数据(一个字节),但也可以是其他大小,例如5bit、6bit、7bit,表示传输数据的位数。
奇偶校验位:用于接收方对接收到的数据进行校验,校验一个二进制数中“1”的个数为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性,使用时也可以不需要此位。
停止位:表示一帧数据的结束,电平逻辑为“1”。
波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效位数来表示,其单位为bit/s。常见的波特率值有4800、9600、14400、38400、115200等,数值越大数据传输越快,波特率为115200表示每秒传输115200位数据。
uart v2.0版本的uart框架和驱动讲解
uart层级结构
1)i/o设备管理层向应用层提供rt_device_read/write等标准接口,应用层可以通过这些标准接口访问uart设备。
2)uart设备驱动框架源码文件为serial_v2.c,位于rt-thread源码的componentsdriversserial文件夹中。抽象出的uart设备驱动框架和平台无关,是一层通用的软件层。uart设备驱动框架提供以下功能。
①对接上层的i/o设备管理层,以让应用层调用i/o设备管理层提供的统一接口对uart进行操作。
②uart设备驱动框架向uart设备驱动层提供uart设备操作方法接口struct rt_uart_ops(如configure、control、putc、getc、transmit),驱动开发者需要实现这些接口。
③提供设备注册管理接口rt_hw_serial_register和中断处理接口rt_hw_serial_isr。4929.html
3)uart设备驱动源码文件为drv_usartv2.c,放在具体bsp目录下,v2表示对接在串口v2版本的设备驱动框架上。uart设备驱动的实现与平台相关,它操作具体的mcu uart控制器。uart设备驱动需要实现uart设备的操作方法struct rt_uart_ops,以提供访问和控制uart硬件的能力。这一层也负责调用rt_hw_serial_register函数将uart设备注册到操作系统。最后还需调用中断处理接口rt_hw_serial_isr,通知uart设备驱动框架层处理数据。
4)最下面一层是mcu外接的uart模块,如uart通信模块、rs-232芯片或者rs-485芯片电路模块等,这样mcu就可以与外接模块进行数据通信了。
uart设备驱动开发的主要任务就是实现串口设备操作方法接口struct rt_uart_ops,然后注册串口设备。
查看代码,串口初始化:
int rt_hw_usart_init(void)
{
rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct stm32_uart);
struct serial_configure config = rt_serial_config_default;
rt_err_t result = 0;
stm32_uart_get_dma_config();
for (int i = 0; i name,
rt_device_flag_rdwr
| rt_device_flag_int_rx
| rt_device_flag_int_tx
| uart_obj[i].uart_dma_flag
, null);
rt_assert(result == rt_eok);
}
return result;
}
创建uart设备。对uart设备来说,在驱动开发时需要先从struct rt_serial_device结构中派生出新的串口设备模型,然后根据自己的设备类型定义私有数据域。特别是在可能有多个类似设备的情况下(例如串口1、串口2),设备接口可以共用同一套接口,不同的只是各自的数据域(例如寄存器基地址)。
例如,stm32的uart设备模型从struct rt_serial_device派生,并增加了stm32uart的特有数据结构,如stm32串口句柄、串口配置信息、dma结构信息等。
/* stm32 uart dirver class */
struct stm32_uart
{
uart_handletypedef handle;
struct stm32_uart_config *config;
#ifdef rt_serial_using_dma
struct
{
dma_handletypedef handle;
rt_size_t last_index;
} dma_rx;
struct
{
dma_handletypedef handle;
} dma_tx;
#endif
rt_uint16_t uart_dma_flag;
struct rt_serial_device serial;
};
实现uart设备的操作方法
struct rt_uart_ops
{
rt_err_t (*configure)(struct rt_serial_device *serial,
struct serial_configure *cfg);
rt_err_t (*control)(struct rt_serial_device *serial,
int cmd,
void *arg);
int (*putc)(struct rt_serial_device *serial, char c);
int (*getc)(struct rt_serial_device *serial);
rt_size_t (*transmit)(struct rt_serial_device *serial,
rt_uint8_t *buf,
rt_size_t size,
rt_uint32_t tx_flag);
};
这些操作方法会完成串口的基本操作,例如:configure方法用于配置串口(波特率等);control方法用于控制串口;putc方法用于串口向外发送字符数据;getc方法用于串口获取字符数据;transmit方法用于数据发送,主要是进行多字节数据的发送。下面继续讲解如何实现这些操作方法。
注册uart设备
uart设备的操作方法实现后需要注册设备到操作系统,注册uart设备的接口是rt_err_t rt_hw_serial_register(struct rt_serial_device serial,const char name,rt_uint32_t flag, void *data)。
uart设备中断处理
增加dma模式
增加uart设备dma模式,需要首先对每个uart的dma进行配置,接着进行dma初始化和中断处理,最后完成dma发送。以下是dma配置代码。
驱动配置
rt-thread使用scons构建工程,使用基于kconfig机制的menuconfig工具配置工程。因此不仅要实现驱动,还要实现驱动相关的配置选项:一是kconfig配置,配置好的配置文件将会在menuconfig工具中形成对应的配置界面;二是进行sconscript配置,配置好后,相应的驱动文件将会被添加到工程中。后面各章的驱动相关配置选项与此类似,如无特殊配置将不再赘述。
1.kconfig配置
下面参考bsp/stm32/stm32f407-atk-explorer/board/kconfig文件配置串口驱动的相关选项,如下所示:
menuconfig bsp_using_uart
bool enable uart
default y
select rt_using_serial
if bsp_using_uart
config bsp_using_uart0
bool enable uart0
default y
config bsp_uart0_rx_using_dma
bool enable uart0 rx dma
depends on bsp_using_uart0
select rt_serial_using_dma
default n
config bsp_using_uart1
bool enable uart1
default n
config bsp_uart1_rx_using_dma
bool enable uart1 rx dma
depends on bsp_using_uart1
select rt_serial_using_dma
default n
config bsp_using_uart2
bool enable uart2
default n
config bsp_uart2_rx_using_dma
bool enable uart2 rx dma
depends on bsp_using_uart2
select rt_serial_using_dma
default n
config bsp_using_uart3
bool enable uart3
default n
config bsp_uart3_rx_using_dma
bool enable uart3 rx dma
depends on bsp_using_uart3
select rt_serial_using_dma
default n
config bsp_using_uart4
bool enable uart4
default n
config bsp_uart4_rx_using_dma
bool enable uart4 rx dma
depends on bsp_using_uart4
select rt_serial_using_dma
default n
config bsp_using_uart5
bool enable uart5
default n
config bsp_uart5_rx_using_dma
bool enable uart5 rx dma
depends on bsp_using_uart5
select rt_serial_using_dma
default n
config bsp_using_uart6
bool enable uart6
default n
config bsp_uart6_rx_using_dma
bool enable uart6 rx dma
depends on bsp_using_uart6
select rt_serial_using_dma
default n
config bsp_using_uart7
bool enable uart7
default n
config bsp_uart7_rx_using_dma
bool enable uart7 rx dma
depends on bsp_using_uart7
select rt_serial_using_dma
default n
endif
代码段中相关宏的说明如下所示。
bsp_using_uart:串口驱动代码对应的宏定义,这个宏控制串口驱动相关代码是否会添加到工程中。
rt_using_serial:串口驱动框架代码对应的宏定义,这个宏控制串口驱动框架的相关代码是否会添加到工程中。
bsp_using_uart1:串口设备1对应的宏定义,这个宏控制串口设备1是否会注册到系统中。
bsp_uart1_rx_using_dma:串口设备1使用dma接收数据。
2.sconscript配置
在hal_drivers/sconscript文件中为串口驱动添加判断选项,代码如下所示。这是一段python代码,表示如果定义了宏bsp_using_uart,则drv_uart.c会被添加到工程的源文件中。
if getdepend(['rt_using_serial']):
src += ['drv_usart.c']
注册设备之后,uart设备将以字符设备的形式在i/o设备管理器中存在。系统启动并开始运行后,可以在终端使用list_device命令看到注册的设备包含了uart设备,之后则可以使用uart设备驱动框架提供的统一api对uart设备进行操作。
小结
在rt-thread中,将uart外设抽象为uart设备,并结合uart设备的通用操作方法与驱动框架思想设计出uart设备驱动框架,这为开发者提供了更便利的设备控制方式。同时,这使基于uart设备编写出来的应用代码更具兼容性与通用性。开发者还需要注意以下两点。
1)操作方法的名称可以自定义,但不要脱离实际意义,并且需要遵守代码规范。所有的操作方法/函数都属于内部函数,在函数实现时,需要使用static进行修饰。本条注意事项对每种驱动都适用,后面章节将不再赘述。
2)在进入与退出中断时,需要调用中断进入和中断退出函数,如下所示。本条注意事项对每种驱动都适用,后面章节将不再赘述。

大型能源企业重点能耗在线监测系统
Cadence基于AI的Cadence Virtuoso Studio设计工具获得认证
中科曙光位列中国液冷数据中心基础设施市场规模第一
脸刷刷上市了吗
PLC在工业控制中的应用方向
RT-Thread之UART设备驱动开发教程
电感中闭合式铁芯与非闭合式铁芯的差异
玩和平精英推荐哪款蓝牙耳机?和平精英电竞蓝牙耳机榜单
国产机器人已实现80%零部件自我供应
荷兰某无线运营商工作人员爆料称,苹果可能会在10月13日推出iPhone 12
是德科技最新工具能帮助加速5g
PROFET Load Guard 12V通过可调节过流限制和容性负载开关模式为汽车ADAS和配电系统保驾护航
esp车身电子稳定系统,为安全而存在
首席执行官应该提出的十个云安全问题
区块链是什么它能做什么
冰箱线上均价首次下滑 线上开始“带不动”大盘
什么是军用机器人,都有哪些分类
三星突破LED技术 可用玻璃制超大尺寸显示屏
八角鼓筒ICI起毛起球测试仪——技术指导
JOLED携手Burning Core展现OLED显示优势