STM32_Study: #05-Working with DMA

#1
1- DMA là gì?

Khi viết chương trình, ta hay sử dụng giải thuật chờ một cờ báo, khi có tín hiệu cờ thì đọc dữ liệu vào bộ nhớ.
Mã:
while(flagBusy);
buf[i]= peripheralRegister;

Điển hình như USART receive Polling:
Mã:
/* Loop until RXNE = 1 */
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)== RESET);
USART_Buffer[pInx++]= USART_ReceiveData(USART1);

Hay USART Transmit Polling:
Mã:
void USART1_Write(uint8_t* buf, uint8_t len)
{
  uint8_t cnt =0;
  uint8_t* p =(uint8_t*) buf;
  /* Copy buf to p */
  while(cnt < len)
  {
  USART_SendData(USART1,*p++);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TC)== RESET)
  {}
  cnt++;
  }
}

Ta thấy rằng thi CPU thực thi receive data(USART_Buffer[pInx++]= USART_ReceiveData(USART1)) hay transmit data (USART_SendData(USART1,*p++)) thì CPU cũng phải tốn một vài câu lệnh – hay một vài chu kỳ máy để thực thi lệnh copy data từ thanh ghi ngoại vi USART tới memory (USART_Buffer; buf …).

Việc sử dụng các lệnh copy data có 3 điểm hạn chế lớn:

1. CPU phải tốn nhiều resource không cần thiết và làm giảm hiệu suất thực thi task khác. Chẳng hạn trong 100ms CPU thực thi 10 tasks sẽ tốt hơn rất nhiều chỉ thực thi 6-7 tasks (vì phải copy data qua lại).

2. Khi ta dùng polling cho các phần liên quan đến commnucation, trasnfer một số lương lớn data thì tốc độ thực thi hoặc truyền nhận dữ liệu bị giảm đáng kể.

3. Cuối cùng, không thể đảm bảo kết quả tốt nếu các project có liên quan đến giới hạn timing, chẳng hạn những project liên quan đến chất lượng âm thanh (audio); phụ thuộc vào tần suất lấy mẫu trong 1 khoảng thời gian cố định …


Direct memory access (DMA) được sử dụng như là một giải pháp truyền data tốc độ cao giữa ngoại vi và vùng nhớ hoặc giữa vùng nhớ với nhau (high-speed data transfer between peripherals and memory as well as memory to memory). Data được transfer qua lại mà CPU không cần thực thi câu lệnh nào cả, vì vậy CPU có thể dành resource để thực thi các nhiệm vụ khác. Như vậy ta có thể xem DMA là phương thức transfer data bằng hardware; còn các lệnh C lấy data, (vd: USART_Buffer[pInx++]=USART_ReceiveData(USART1)) là phương thức transfer data bằng software.
upload_2016-6-14_21-53-0.png

2-Ví dụ minh họa sự khác biệt
Ta có thể xem qua phần minh họa khi có sử dụng và khi không sử dụng DMA với project sử dụng SPI để full-fill toàn bộ màn hình LCD 7735. Về lý thuyết ta cần phải truyền 12x106/16 = 750, 000pixels/second nếu sử dụng SPI với tốc độ 12 MHz .
upload_2016-6-14_21-35-8.png

Khi không sử dụng DMA, tốc độ ta đo được là 1/20x10−6 = 50, 000 pixels/second.
Với DMA, tốc độ có thể đo được là 128/17x10−4 = 735, 000 pixels/second.

upload_2016-6-14_21-36-32.png

3-DMA và ngoại vi STM32
STM32 có 2 DMA với nhiều kênh (channels) độc lập: 7 kênh DMA1 và 5 kênh DMA2. Mỗi kênh DMA chỉ có thể kết hợp với một và chì một ngoại vi cụ thể.

Với DMA1, các ngoại vi support bao gồm:
upload_2016-6-14_21-39-49.png

Với DMA2, các ngoại vi support bao gồm:
upload_2016-6-14_21-41-9.png



4-Configure và sử dụng DMA

Để hiểu rõ hơn cách sử dụng DMA, ta xem qua ví dụ đọc ADC có sử sụng DMA
upload_2016-6-14_21-43-6.png

Quy trình cấu hình để sử dụng ADC với DMA như sau:

1. Configure ngoại vi cho phép sử dụng DMA
2. Khởi tạo DMA
3. Khởi tạo ngoại vi (ADC)
4. Cho phép sử dụng ngoại vi kết hợp với ADC
5. Thực thi lệnh như bình thường cho ngoại vi
upload_2016-6-14_21-45-3.png


5-Tìm hiểu về cách khởi tạo DMA
Thư viện Std define cho ta data type của DMA, chúng ta có thể tóm tắt cách khởi tạo DMA bằng hình dưới đây:

upload_2016-6-14_21-51-52.png


Các mode tranfer của DMA
DMA có 4 mode transfer data, đó là:
1. Peripheral-to-memory
2. memory-to-peripheral
3. peripheral-to-peripheral
4. memory-to-memory
Như ta thấy, system bus của STM32 có 2 bus Memory bus và Periperal bus, vì vậy ta có 4 mode để transfer data qua lại giữa 2 bus này, trong đó 3 mode đầu(Peripheral-to-memory, memory-to-peripheral, peripheral-to-peripheral) thì cần một tín hiệu trigger của ngoại vi để DMA thực thi thao tác. Mode thứ 4 (memory -to-memory) thì không cần tín hiệu trigger của ngoại vi gì cả.
upload_2016-6-14_21-54-7.png


Quyền ưu tiên
Khi DMA được sử dụng cho nhiều Channel thì STM32 sẽ quản lý việc transfer data cho channel nào trước, channel nào sau dựa vào việc phân quyền ưu tiên khi cấu hình sử dụng DMA. Có 2 cách phân quyền ưu tiên:
1. Phân quyền bằng software (chính là việc cấu hình DMA), có 4 quyền ưu tiên như sau:
· DMA_Priority_VeryHigh
· DMA_Priority_High
· DMA_Priority_Medium
· DMA_Priority_Low

2. Phân quyền bằng hardware: nếu 2 request DMA có cùng một quyền ưu tiên từ software, STM32 sẽ tự động quy định channel có trị số thấp có quyền ưu tiên hơn channel có trị số cao (DMA_Channel_2 có quyền ưu tiên cao hơn DMA_Channel_4)

Tới đây mình xin dừng bài viết về DMA. Hy vọng các bạn tìm thấy điều gì đó hữu ích.
Xin chào !!!

 

Đính kèm

Quảng cáo Google