OS版本:RT-Thread 4.0.0

芯片:STM32F407

RT-Thread的串口驱动框架与Linux相识,分成 I/O设备框架 + 设备底层驱动;

1. serial设备初始化及使用

将配置使能的 uart_obj[ ] 进行设备注册

rtthread_startup --> rt_hw_usart_init() --> rt_hw_serial_register --> rt_device_register

设备注册之后就可使用设备操作方式来使用串口

rt_device_find("uart3") -->  rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX) -->  rt_device_set_rx_indicate(serial, uart_dma_rx_handle)

2. serial设备

设备层 rt_device 注册及 ops 实现

const static struct rt_device_ops serial_ops ={

rt_serial_init,

rt_serial_open,

rt_serial_close,

rt_serial_read,

rt_serial_write,

rt_serial_control

};

而serial设备 rt_serial_device 为 rt_device 的一个子类

structrt_serial_device

{structrt_device parent;const struct rt_uart_ops *ops;structserial_configure config;void *serial_rx;void *serial_tx;

};

其中 rt_serial_device 中的 ops 通过 stm32_uart_ops 实现,这样 rt_device、rt_serial_device 和 uart底层就都关联起来了

硬件驱动层文件

drv_usart.c

drv_usart.h

stm32f4xx_hal_msp.c

主要内容 ops 实现,中断处理

static const struct rt_uart_ops stm32_uart_ops ={

.configure=stm32_configure,  //默认配置

.control=stm32_control,

.putc=stm32_putc,

.getc=stm32_getc,

};

串口硬件初始化  HAL_UART_MspInit  对串口引脚和时钟的初始化 在 stm32f4xx_hal_msp.c 中,通过配置CubeMX生成;

3. 驱动分析

serial 的 control 操作 设计成 不能设置中断,即缺少 RT_DEVICE_CTRL_SET_INT 和 RT_DEVICE_CTRL_CLR_INT 操作, 这样可以避免误设置;

同时也是由于串口接收已经设计成三选一方式:中断、DMA、轮询;

说一下DMA,因为这也是我们最常用的串口数据接收处理方式;

RTT的 serial 的DMA接收,采用的 IDLE 中断来控制DMA接收数据的,

在 drv_usart.c 中

static void stm32_dma_config(struct rt_serial_device *serial)

{

....../*enable interrupt*/__HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE);  //使能了空闲中断和DMA中断/*enable rx irq*/HAL_NVIC_SetPriority(uart->config->dma_rx->dma_irq, 0, 0);

HAL_NVIC_EnableIRQ(uart->config->dma_rx->dma_irq);

HAL_NVIC_SetPriority(uart->config->irq_type, 1, 0);

HAL_NVIC_EnableIRQ(uart->config->irq_type);

....

}

在中断处理函数 uart_isr 中 实现了

static void uart_isr(struct rt_serial_device *serial)

{

....

#ifdef RT_SERIAL_USING_DMAelse if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) !=RESET))  //IDLE空闲中断

{

level=rt_hw_interrupt_disable();

recv_total_index= serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma.handle));

recv_len= recv_total_index - uart->dma.last_index;

uart->dma.last_index =recv_total_index;

rt_hw_interrupt_enable(level);if(recv_len)

{

rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE| (recv_len << 8));

}

__HAL_UART_CLEAR_IDLEFLAG(&uart->handle);

}#endif.....

}

void rt_hw_serial_isr(struct rt_serial_device *serial, int event)

{caseRT_SERIAL_EVENT_RX_DMADONE:

{intlength;

rt_base_t level;/*get DMA rx length*/length= (event & (~0xff)) >> 8;if (serial->config.bufsz == 0)

{struct rt_serial_rx_dma*rx_dma;

rx_dma= (struct rt_serial_rx_dma*) serial->serial_rx;

RT_ASSERT(rx_dma!=RT_NULL);

RT_ASSERT(serial->parent.rx_indicate !=RT_NULL);

serial->parent.rx_indicate(&(serial->parent), length);

rx_dma->activated =RT_FALSE;

}else{/*disable interrupt*/level=rt_hw_interrupt_disable();/*update fifo put index*/rt_dma_recv_update_put_index(serial, length);/*calculate received total length*/length=rt_dma_calc_recved_len(serial);/*enable interrupt*/rt_hw_interrupt_enable(level);/*invoke callback*/

if (serial->parent.rx_indicate !=RT_NULL)

{

serial->parent.rx_indicate(&(serial->parent), length);  //应用回调接收处理函数

}

}break;

}

}

如果进行大数据传输,发现默认缓存(64字节)不够用 可修改 RT_SERIAL_RB_BUFSZ 值

#define RT_SERIAL_CONFIG_DEFAULT \{ \

BAUD_RATE_115200,/*115200 bits/s*/\

DATA_BITS_8,/*8 databits*/\

STOP_BITS_1,/*1 stopbit*/\

PARITY_NONE,/*No parity*/\

BIT_ORDER_LSB,/*LSB first sent*/\

NRZ_NORMAL,/*Normal mode*/\

RT_SERIAL_RB_BUFSZ,/*Buffer size*/\0\

}

#define RT_SERIAL_RB_BUFSZ              64

rtthread 串口dma接收_RT-Thread 设备驱动UART浅析相关推荐

  1. rtthread 串口dma接收_rtthread 添加串口 (uart3)

    1.查询uart配置过程 文件路径: /drivers/board.h 使能RTT uart驱动 2.使能usart3总线 打开 /drivers/board.h #define BSP_UART3_ ...

  2. rtthread 串口dma接收_RT-Thread 串口DMA使用笔记--STM32F207

    RT-Thread学习笔记八 --------USART DMA方式发送 老规矩,首先说一下我的配置 STM32F207IGT6   MDK   RTT 1.1.0 使用UART2作为finsh组件, ...

  3. RT-Thread (2) RTT SPI设备驱动流程 || LWIP + ENC28J60

    系列文章目录 RT-Thread (1) 添加外部内存到内存管理 RT-Thread (2) RTT SPI设备驱动流程 || LWIP + ENC28J60 RT-Thread (3) 为RTT增加 ...

  4. STM32 串口DMA接收 Openmv / K210 整数、小数字符串数据 (基于HAL库)

    目录 前言 一.工程配置 二.串口DMA部分代码 1.源文件UART_DMA.c 2.头文件UART_DMA.h 3.stm32f1xx_it.c的修改 4.串口收发DMA测试 三.字符串数字提取代码 ...

  5. 第九章 AT32F403A基于V2库串口 dma接收不定长数据

    目录 概述 硬件 DMA 软件 流程 初始化 初始化代码: 中断服务函数: DMA1通道5设置函数:(重新使能通道) DMA1通道4发送函数:(设置dma长度和内存地址) 测试 最后 概述 本文主要是 ...

  6. STM32 USART串口DMA 接收和发送的源码详解!

    硬件平台:STM32F103ZET6: 开发环境:KEIL 4: 先说说应用通讯模式,串口终端的工作方式和迪文屏差不多,终端被动接受MCU发的指令,终端会偶尔主动发送一些数据给MCU(像迪文屏的触摸信 ...

  7. android 串口一直打开_STM32之串口DMA接收不定长数据

    STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口 ...

  8. STM32 HAL库 串口DMA接收不定长数据

    STM32 HAL库 串口DMA接收不定长数据 整体思路:我是用的CUBEMX软件生成的工程,使能了两个串口,串口2用来接收不定长的数据,串口1用来发送串口2接收到的数据:串口2我找了一个UBLOX卫 ...

  9. linux 串口 dma,STM32 USART串口DMA 接收和发送流程详解

    1.dma发送流程 1.配置DMA发送中断 - NVIC_Init 2.配置串口中断 - NVIC_Init 3.GPIO配置 - GPIO_Init 4.DMA发送配置 -DMA_Init  DMA ...

最新文章

  1. mac mysql本地连接数_如何用command line链接mysql
  2. 【Excel技巧】如何批量去掉×××号前的单引号
  3. maven中jar下载失败
  4. MySQL学习笔记07【事务、用户管理和权限管理】
  5. Emacs之魂(三):列表,引用和求值策略
  6. 【LeetCode】3. Longest Substring Without Repeating Characters
  7. matlab 带有下标的赋值维度不匹配_远见另类资产管理体系下的核心系统搭建
  8. svn版利用什么技术实现_金葱粉涂料印花利用了什么技术?
  9. opencv 从原始的图像中找出ROI区域
  10. 基于图像的相机定位/SLAM分类
  11. C程序设计--排序(冒泡、选择、插入)--冒泡
  12. wps linux 在线安装程序,WPS Office 2019 For Linux下载及安装教程
  13. LINUX下三个内核文件详解(vmlinuz/initrd.img/System.map)
  14. Python爬取哔哩哔哩视频
  15. 会计科目类词汇(中英)
  16. 原生js实现购物车添加删除商品、计算价格功能
  17. Wireshark抓包实例诊断TCP连接问题
  18. 开机提示小娜无法在本计算机运行,win10 20h2提示此应用无法在你的电脑上运行解决方法...
  19. CCC之I类设备、II类设备、III类设备的对比
  20. 【CSDN问答】使用体验、产品BUG和改进建议

热门文章

  1. 计算dpi公式及各主流分辨率介绍
  2. 工业物联网异常检测技术综述
  3. 移动端前端框架UI库(Frozen UI、WeUI、SUI Mobile)
  4. open source 拼音排序函数库发布
  5. Android Studio中javac不是内部命令或外部命令——错误大全
  6. 日志收集系统loki+promtail+Grafana 部署
  7. 【tensorflow 深度学习】8.训练图片分类模型
  8. openlava-6.0,cde
  9. 信息收集之 端口扫描
  10. 无迹(损)卡尔曼滤波(UKF)理论讲解与实例