RTT UART设备框架学习

UART简介

UART(Universal Asynchronous Receiver/Transmitter)通用异步收发传输器,UART 作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。是在应用程序开发过程中使用频率最高的数据总线。

UART串口的特点是将数据一位一位地顺序传送,只要2根传输线就可以实现双向通信,一根线发送数据的同时用另一根线接收数据。UART 串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用 UART 串口通信的端口,这些参数必须匹配,否则通信将无法正常完成。UART 串口传输的数据格式如下图所示:

起始位:表示数据传输的开始,电平逻辑为 "0" 。

数据位:可能值有 5、6、7、8、9,表示传输这几个 bit 位数据。一般取值为 8,因为一个 ASCII 字符值为 8 位。

奇偶校验位:用于接收方对接收到的数据进行校验,校验 "1" 的位数为偶数 (偶校验) 或奇数(奇校验),以此来校验数据传送的正确性,使用时不需要此位也可以。

停止位: 表示一帧数据的结束。电平逻辑为 "1"。

波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效位 (bit) 数来表示,其单位为每秒比特数 bit/s(bps)。常见的波特率值有 4800、9600、14400、38400、115200 等,数值越大数据传输的越快,波特率为 115200 表示每秒钟传输 115200 位数据。

访问串口设备

c 复制代码
#define SAMPLE_UART_NAME "uart1"
static rt_device_t serial;
serial = rt_device_find(SAMPLE_UART_NAME);

打开串口设备

通过设备句柄,应用程序可以打开和关闭设备,打开设备时,会检测设备是否已经初始化,没有初始化则会默认调用接口初始化设备。

c 复制代码
rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);

一般情况下,会选择使用发送阻塞模式以及接收非阻塞模式来进行开发。

c 复制代码
rt_device_open(dev,RT_DEVICE_FLAG_RX_NON_BLOCKING|RT_DEVICE_FLAG_TX_BLOCKING)

硬件工作模式选择

由于用户层使用串口时,只关心应用层操作模式,不再关心硬件工作模式,使得应用层开发变得更加便捷,也增加了应用程序的可移植性。倘若用户开发时比较关心硬件具体的工作模式,那么应该对其工作模式如何选择?

串口外设的遵循如下规则:

  1. 模式优先级:DMA>中断>轮询,当有DMA配置时,默认使用DMA模式,以此类推。
  2. 串口默认配置接收和发送缓冲区
  3. 默认使用阻塞发送、非阻塞接收模式

V1版本

通过设备句柄,应用程序可以打开和关闭设备,打开设备时,会检测设备是否已经初始化,没有初始化则会默认调用初始化接口初始化设备。通过如下函数打开设备:

oflags 参数支持下列取值 (可以采用或的方式支持多种取值):

c 复制代码
#define RT_DEVICE_FLAG_STREAM       0x040     /* 流模式      */
/* 接收模式参数 */
#define RT_DEVICE_FLAG_INT_RX       0x100     /* 中断接收模式 */
#define RT_DEVICE_FLAG_DMA_RX       0x200     /* DMA 接收模式 */
/* 发送模式参数 */
#define RT_DEVICE_FLAG_INT_TX       0x400     /* 中断发送模式 */
#define RT_DEVICE_FLAG_DMA_TX       0x800     /* DMA 发送模式 */

串口数据接收和发送数据的模式分为三种:中断模式、轮询模式、DMA模式。

在使用的时候,这 3 种模式只能选其一,若串口的打开参数 oflags 没有指定使用中断模式或者 DMA 模式,则默认使用轮询模式

DMA(Direct Memory Access)即直接存储器访问。 DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过 DMA 控制器为 RAM 与 I/O 设备开辟一条直接传送数据的通路,这就节省了 CPU 的资源来做其他操作。使用 DMA 传输可以连续获取或发送一段信息而不占用中断或延时,在通信频繁或有大段信息要传输时非常有用。

控制串口设备

通过控制接口,应用程序可以对串口设备进行配置,如波特率、数据位、校验位、接收缓冲区大小、停止位等参数的修改。

c 复制代码
rt_err_t rt_deivce_control(rt_device_t dev, rt_uint8_t cmd, void *arg);
c 复制代码
struct serial_configure
{
    rt_uint32_t baud_rate;            /* 波特率 */
    rt_uint32_t data_bits    :4;      /* 数据位 */
    rt_uint32_t stop_bits    :2;      /* 停止位 */
    rt_uint32_t parity       :2;      /* 奇偶校验位 */
    rt_uint32_t bit_order    :1;      /* 高位在前或者低位在前 */
    rt_uint32_t invert       :1;      /* 模式 */
    rt_uint32_t bufsz        :16;     /* 接收数据缓冲区大小 */
    rt_uint32_t reserved     :4;      /* 保留位 */
};

接收缓冲区:当串口使用中断接收模式打开时,串口驱动框架会根据 RT_SERIAL_RB_BUFSZ 大小开辟一块缓冲区用于保存接收到的数据,底层驱动接收到一个数据,都会在中断服务程序里面将数据放入缓冲区。

设置发送完成回调函数

c 复制代码
rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer));

设置接收回调函数

c 复制代码
rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size));

DMA接收及轮询发送

当串口收到一批数据后,会调用接收回调函数,接收回调函数会把此时缓冲区的数据大小通过消息队列发送给等待的数据处理线程。线程获取到消息后被激活,并读取数据。一般情况下 DMA 接收模式会结合 DMA 接收完成中断和串口空闲中断完成数据接收。

c 复制代码
#include <rtthread.h>

#define SAMPLE_UART_NAME       "uart3"      /* 串口设备名称 */

/* 串口接收消息结构*/
struct rx_msg
{
	rt_device_t dev;
    rt_size_t size;
};
/* 串口设备句柄 */
static rt_device_t serial;
}
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;
相关推荐
eybk2 小时前
Pytorch+Mumu模拟器+萤石摄像头实现对小孩学习的监控
学习
6.942 小时前
Scala学习记录 递归调用 练习
开发语言·学习·scala
qq_459730032 小时前
4-3 MCU中ARM存储器的作用
arm开发·单片机·嵌入式硬件
守护者1703 小时前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
学会沉淀。3 小时前
Docker学习
java·开发语言·学习
Rinai_R4 小时前
计算机组成原理的学习笔记(7)-- 存储器·其二 容量扩展/多模块存储系统/外存/Cache/虚拟存储器
笔记·物联网·学习
吃着火锅x唱着歌4 小时前
PHP7内核剖析 学习笔记 第四章 内存管理(1)
android·笔记·学习
ragnwang4 小时前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
Web阿成5 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript