티스토리 뷰

ARM Cortex-M

DMA - UART

Just4Fun 2017. 5. 22. 20:40

이전 글에서는 memory to memory 방식의 간단한 예제를 만들어서, DMA가 무엇인지, 어떻게 동작되는지 설명하였다.  

그러나, MCU에서는 memory to memory 방식보다는, 주로 주변장치를 통한 데이터 송수신을 위하여 DMA를 사용하므로, 이번 글에서는 UART 송신 기능을 DMA를 이용하여 구현하는 방법을 설명하도록 하겠다.

Memory to memory DMA의 경우에는 임의의 DMA 채널을 마음대로 지정해서 사용할 수 있으나, 주변 장치와의 통신을 위하여 DMA를 사용할 경우에는 지정된 DMA 채널을 사용하여야 한다.

이러한 내용은 reference manual을 보면 자세히 알 수 있다.

위의 그림과 표를 보면 DMA의 각 채널별로 연결된 주변 장치가 어떤 것들이 있는지 알 수 있다.

이번 글에서는 UART 송신 기능을 DMA를 이용할 것이므로 채널4번을 사용하여야 된다는것을 알 수 있게 된다.

DMA를 이용하여 UART 송신 기능을 수행하기 위한 절차는 다음과 같다.

그리고, 실제 UART와 DMA controller가 서로 어떤 타이밍으로 동작되는지는 다음과 같다.

위의 내용을 바탕으로 코드를 만들어 보도록 하겠다.

먼저 uart_init() 함수에 아래와 같이 한줄을 추가해준다.

19번째 줄이 새로 추가된 코드이다.  이 코드를 추가한 이유의 위의 타이밍도를 보면 이해할 수 있다.

Memory to memory 방식에서는 source address에서 데이터를 읽어서 곧바로 destination address로 데이터를 써주면 되었지만,

주변 장치는 그런식으로 무작정 데이터를 연속해서 써주면 안된다.

UART의 data register(DR)가 비었을때에만 새로운 데이터를 쓸수 있다.  하지만 DMA는 이러한 사실을 알 수 없으므로 UART에서 DMA로 data register가 비어 있음을 알려주어야 한다.  그 신호가 바로 DMA request 신호이다.  이러한 DMA request 신호를 생성하기 위하여 CR3 register에서 DMAT 비트를 설정해 주어야 하는 것이다.

UART TX를 위한 DMA 초기화 코드는 다음과 같다.

3번 줄에서 UART TX를 위하여 DMA4 채널을 선택하였다.

5번 줄은 destination 주소를 UART의 data register 주소값으로 설정하였다.

7번 줄은 source address는 데이터 전송이 될때마다 증가될 수 있도록 하지만 UART DR은 고정 시켜주어야 하므로 메모리 주소만 증가 시키도록 하였다.

9,10번줄은 1바이트 단위로 전송이 되도록 해준다.

11번줄은 메모리 복사 방향을 memory에서 peripheral로 되도록 설정해주고, DMA 동작이 완료될때와 에러가 발생할 때 이를 알려주기 위한 플래그 설정을 해주었다.

UART 데이터를 내 보내기 위한 코드는 다음과 같다.

송신할 데이터가 있는 메모리 주소와 내보낼 데이터 크기를 설정해 준다.  이때 반드시 DMA는 disable 상태에서 설정해 주어야 한다.  설정이 끝난후 DMA를 enable 해주면 위의 타이밍도에 나온 절차대로 한 바이트씩 데이터를 UART를 통해 내보내게 된다.

인터럽트를 사용하지 않는 구조이므로 DMA 동작이 완료 되었는지 DMA의 ISR레지스터를 polling한다.

14번 줄에서 DMA를 이용해서 배너 메시지를 출력한다.

DMA를 통해서 UART 데이터를 내 보내므로 CPU는 그 동안 다른 일을 할 수 있다.  이번 글에서는 count라는 변수값을 계속 증가 시키는 단순한 일을 수행하고 있다.

UART 데이터 송신이 모두 완료되면 새로운 데이터를 내 보낸다.  그 사이에 CPU는 또다시 count 값을 증가 시킨다.

UART 데이터 송신은 10번 반복하도록 한다.

위의 코드를 실행 시키면 다음과 같은 결과를 볼 수 있다.

배너 메시지를 출력하는 동안 count 값을 8천번 정도 증가 시킨것을 확인할 수 있다.

그리고, count값을 출력하기 위한 메시지를 내보내는 동안 약 3천번 정도의 count 값을 증가 시킬수 있는 것도 볼 수 있다.

DMA를 이용하게 되면 그만큼 CPU가 다른일을 할 수 있다는 말이 되고, 반대로 얘기하면 DMA를 이용하지 않을 경우 CPU가 그 일을 직접 수행하여야 하므로 성능이 낮아진다고 볼 수 있다.

위의 결과는 CPU 동작 클럭을 48MHz이고, UART baudrate를 115200으로 설정하였을 때의 결과이다.

만약 CPU 동작 주파수를 72MHz로 설정하고 UART baudrate를 9600으로 설정했을때는 다음과 같은 결과가 나왔다.

배너 메시지 한줄 출력하는 동안 CPU는 count 값을 11만번 증가 시켰다.  count 값을 하나 증가하기 위하여 필요한 명령어는 어셈블리 코드를 분석하면 정확하게 알겠지만, 그냥 대충따져도 20개 정도의 명령어가 필요할 것 같다.

그렇다는 얘기는 한줄의 UART 데이터를 출력하는 동안 100만번 이상의 명령어를 cpu가 처리 가능하다는 뜻이다.



dma_uart.zip



'ARM Cortex-M' 카테고리의 다른 글

DMA - ADC  (0) 2017.05.28
DMA - SPI  (2) 2017.05.27
DMA  (2) 2017.05.13
SPI  (3) 2017.05.03
I2C  (0) 2017.04.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함