# STM32 Circular DMA with Timeout Event
This example presents how to implement performance-efficient DMA timeout mechanism for peripheral DMA configured in circular mode.
## Table of contents
- [Description](#description)
- [Implementation](#implementation)
- [Source code organization](#source-code-organization)
- [How it works](#how-it-works)
- [References](#references)
## Description
Implementing DMA for peripherals (e.g. UART) can significantly boost performance while reducing workload on the MCU (microcontroller) core [[1]](#references), therefore configuring the DMA controller in circular mode can be straightforward for peripherals. However, in time-critical systems or hard real-time systems it is crucial to perform the required actions within specified deadlines. A DMA controller is only able to issue interrupts when its buffer is either full or halfway full, however considering UART communication, in most cases the received amount of data is not known in advance and the end of transfer cannot be detected. Consequently, when a transmission from a peripheral ends with a partially filled DMA buffer, and no further data is received over a certain period, a DMA timeout has to be implemented in order to process the remaining data. A DMA timeout means that a detectable event (e.g. interrupt) is generated when the following conditions are met: 1) DMA buffer is not full, and 2) no further data is received after a certain period.
ST suggests two methods for implementing DMA timeout in Section 2 of AN3019 [[2]](#references). The first method utilizes a timer in input capture mode. While this method is effective, it requires an available hardware timer and additional wiring. The second method requires no hardware changes and additional peripherals, instead it uses the system timer and utilizes the UART receive interrupt. The drawback of this method is that the UART interrupt service routine is called often during transmission, especially when the configured timeout period is short. This adds significant overhead to the system and affects performance and efficiency negatively.
In this demonstration, a more efficient idea is presented to implement DMA timeout. The UART peripheral can be configured to generate an interrupt when the UART module detects an idle line (end of transmission). After generating an idle line interrupt, it is not generated again until there is new data received. (For more information about how idle line detection and interrupt generation works, please refer to [[3]](#references).) After detecting an idle line, a software timer is started with user-defined period. If no DMA transfer complete interrupt is generated within this period, a DMA timeout event is generated and new data in DMA buffer can be processed. This method provides an efficient way to implement DMA timeout and minimizing overhead by generating a single additional interrupt (UART idle line interrupt) after the end of transmission.
## Implementation
The method is implemented and demonstrated on a 32L476G Discovery [[4]](#references) kit equipped with a STM32L476VG MCU [[5]](#references). The on-board ST-Link provides an USB VCP (Virtual COM Port) to UART interface for the microcontroller. The UART lines are connected to PD5 and PD6 pins of the MCU. The DMA controller is initialized to receive data from this UART line. In this demonstration, the USB peripheral of the MCU is initialized in CDC VCP mode, therefore the received data is forwarded back to the PC via USB. The demonstration software uses the official HAL library of ST [[6]](#references) and is compiled with IAR EWARM.
![System overview](system-overview.png)
*Figure 1: System overview*
## Source code organization
```
stm32-dma-uart/
|—— Drivers/
|—— EWARM/
|—— Inc/
|—— Middlewares/
`—— Src/
```
`Drivers` and `Middlewares` folder contain the CMSIS, HAL libraries and USB libraries for the microcontroller. The software source code and corresponding header files can be found in `Src` and `Inc` folders respectively.
## How it works
The `DMA_Event_t` structure type defined in `main.h` holds the required variables for the DMA timeout implementation. The DMA buffer size and timeout duration can be configured in `main.h`. When a UART idle interrupt occurs, the timer is set to the configured duration and decreased in the SysTick interrupt handler. After timeout, the flag is set and the DMA transfer complete callback is executed. The prevCNDTR stores the previous value of the DMA CNDTR register value, thus only the relevant, newly received data chunk can be extracted and processed from the DMA buffer.
When a DMA transfer complete interrupt or DMA timeout occurs, the DMA transfer complete callback is executed. Based on timeout state; current and previous state of DMA (stored in the `DMA_Event_t` structure), the newly received data (which can be the entire DMA buffer or only a part of it) is copied from the DMA buffer to a new buffer. Then the data can be processed without being corrupted or overwritten by further incoming data. In this demonstration the received data is simply forwarded back to the computer via USB.
## References
[1] Wikipedia, “Direct Memory Access”, https://en.wikipedia.org/wiki/Direct_memory_access
[2] AN3019, “Communication peripheral FIFO emulation with DMA and DMA timeout in STM32F10x microcontrollers”, http://www.st.com/resource/en/application_note/cd00256689.pdf
[3] RM0351, “STM32L4x5 and STM32L4x6 advanced ARM®-based 32-bit MCUs Reference Manual”, http://www.st.com/resource/en/reference_manual/dm00083560.pdf
[4] 32L476G Discovery, http://www.st.com/en/evaluation-tools/32l476gdiscovery.html
[5] STM32L476VG, http://www.st.com/en/microcontrollers/stm32l476vg.html
[6] UM1884, “Description of STM32L4 HAL and Low Layer drivers”, www.st.com/resource/en/user_manual/dm00173145.pdf
没有合适的资源?快使用搜索试试~ 我知道了~
在 STM32微控制器 上演示了用于以循环模式配置的外设 DMA 的高效 DMA 超时机制_C语言_代码_相关文件_下载
共90个文件
h:50个
c:28个
icf:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 200 浏览量
2022-07-07
17:02:18
上传
评论
收藏 660KB ZIP 举报
温馨提示
此示例介绍如何为配置为循环模式的外设 DMA 实现高效的 DMA 超时机制。 目录 描述 执行 源代码组织 这个怎么运作 参考 描述 为外设(例如 UART)实施 DMA 可以显着提高性能,同时减少 MCU(微控制器)内核的工作负载[1],因此在循环模式下配置 DMA 控制器对于外设来说非常简单。但是,在时间关键型系统或硬实时系统中,在指定期限内执行所需操作至关重要。DMA 控制器只能在其缓冲区已满或半满时发出中断,但考虑到 UART 通信,在大多数情况下,预先不知道接收到的数据量,也无法检测到传输结束。因此,当来自外设的传输以部分填充的 DMA 缓冲区结束时,并且在某个时间段内没有接收到更多数据时,必须实现 DMA 超时以处理剩余数据。DMA 超时意味着当满足以下条件时会产生可检测事件(例如中断): 1) DMA 缓冲区未满, ST 在 AN3019 [2]的第 2 节中提出了两种实现 DMA 超时的方法。 更多详情、使用方法,请下载后阅读README.md文件
资源推荐
资源详情
资源评论
收起资源包目录
stm32-dma-uart-master.zip (90个子文件)
stm32-dma-uart-master
Src
stm32l4xx_hal_msp.c 2KB
main.c 10KB
usbd_cdc_if.c 6KB
usbd_desc.c 11KB
usb_device.c 4KB
usbd_conf.c 23KB
stm32l4xx_it.c 3KB
system_stm32l4xx.c 13KB
Middlewares
ST
STM32_USB_Device_Library
Class
CDC
Src
usbd_cdc.c 28KB
Inc
usbd_cdc.h 5KB
Core
Src
usbd_ioreq.c 5KB
usbd_ctlreq.c 17KB
usbd_core.c 12KB
Inc
usbd_ctlreq.h 3KB
usbd_core.h 5KB
usbd_ioreq.h 3KB
usbd_def.h 11KB
Drivers
STM32L4xx_HAL_Driver
Src
stm32l4xx_hal.c 21KB
stm32l4xx_ll_usb.c 68KB
stm32l4xx_hal_dma.c 29KB
stm32l4xx_hal_flash_ramfunc.c 5KB
stm32l4xx_hal_pwr_ex.c 40KB
stm32l4xx_hal_flash_ex.c 41KB
stm32l4xx_hal_pcd.c 47KB
stm32l4xx_hal_rcc_ex.c 95KB
stm32l4xx_hal_rcc.c 55KB
stm32l4xx_hal_pwr.c 26KB
stm32l4xx_hal_gpio.c 20KB
stm32l4xx_hal_uart.c 89KB
stm32l4xx_hal_cortex.c 20KB
stm32l4xx_hal_flash.c 27KB
stm32l4xx_hal_pcd_ex.c 15KB
stm32l4xx_hal_uart_ex.c 16KB
Inc
stm32l4xx_hal_uart.h 71KB
stm32l4xx_hal_rcc.h 197KB
stm32l4xx_hal_flash.h 44KB
stm32l4xx_ll_usb.h 27KB
stm32l4xx_hal_uart_ex.h 34KB
stm32l4xx_hal_flash_ramfunc.h 4KB
Legacy
stm32_hal_legacy.h 171KB
stm32l4xx_hal_def.h 8KB
stm32l4xx_hal.h 31KB
stm32l4xx_hal_gpio_ex.h 29KB
stm32l4xx_hal_flash_ex.h 3KB
stm32l4xx_hal_pwr_ex.h 34KB
stm32l4xx_hal_dma.h 27KB
stm32l4xx_hal_cortex.h 19KB
stm32l4xx_hal_pcd.h 36KB
stm32l4xx_hal_rcc_ex.h 110KB
stm32l4xx_hal_gpio.h 14KB
stm32l4xx_hal_pcd_ex.h 5KB
stm32l4xx_hal_pwr.h 16KB
CMSIS
Include
core_cm0.h 36KB
core_cm3.h 100KB
arm_common_tables.h 7KB
core_cm4.h 110KB
cmsis_gcc.h 39KB
cmsis_armcc_V6.h 52KB
core_cm7.h 134KB
cmsis_armcc.h 23KB
core_sc000.h 43KB
core_cm0plus.h 43KB
arm_const_structs.h 4KB
arm_math.h 239KB
core_cmSimd.h 3KB
core_cmFunc.h 3KB
core_cmInstr.h 3KB
core_sc300.h 99KB
Device
ST
STM32L4xx
Include
stm32l476xx.h 1.51MB
stm32l4xx.h 7KB
system_stm32l4xx.h 4KB
system-overview.png 18KB
LICENSE.md 1KB
.gitignore 38B
Inc
usbd_conf.h 5KB
usb_device.h 3KB
stm32l4xx_it.h 908B
usbd_desc.h 3KB
stm32l4xx_hal_conf.h 14KB
main.h 2KB
usbd_cdc_if.h 524B
README.md 6KB
EWARM
stm32-dma-uart.dep 41KB
Project.eww 151B
stm32l476xx_flash.icf 2KB
stm32-dma-uart.ewd 42KB
startup_stm32l476xx.s 22KB
stm32-dma-uart.ewp 29KB
stm32l476xx_sram.icf 2KB
stm32-dma-uart.ewt 69KB
共 90 条
- 1
资源评论
快撑死的鱼
- 粉丝: 1w+
- 资源: 9156
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功