Introdução ao periférico DMA (Direct Memory Access)

Capa Embarcados

DMA significa Direct Memory Access, e foi implementado primeiramente no computador IBM 709 em 1958: a função do periférico era de mover os dados de uma região da memória para I/O e vice-versa, tendo acesso direto a elas sem a intervenção da CPU. Explicado o contexto, o nome DMA faz sentido, mas é um tanto infeliz: ao aprender o significado do nome GPIO (General Purpose Input Output) pode-se relacionar à vantagem de um pino ser configurável como entrada ou saída. Porém, a vantagem de se usar DMA não está exatamente no fato dele ter acesso direto à memória, como o nome pode sugerir.

Eu já não tinha acesso direto à memória? Tem a ver com a Memory Protection Unit?

Se o projetista compreender este periférico, pode otimizar os seus projetos evitando, assim, a necessidade de investir em componentes mais robustos e caros. Por esse motivo, neste artigo vou tentar explicar como funciona e quais são as vantagens desse periférico.

O processamento com e sem DMA

Vamos demonstrar na escala de tempo o processamento de um microcontrolador nos dois modos. Como exemplo, vamos imaginar o seguinte processamento:

  1. Task A vai montar um pacote de mensagem para ser enviado via UART;
  2. Task B vai enviar a mensagem via UART;
  3. Task C vai montar um pacote de dados diferente para ser enviado via SPI;
  4. Task D vai enviar o pacote via SPI;
  5. Ao terminar a Task D, a CPU vai realizar a Task A novamente, continuando o ciclo.

Tanto faz se é uma task de RTOS ou uma função comum. Neste primeiro caso de processamento, a CPU do microcontrolador fará todas as tarefas. Na escala do tempo ficaria como na Figura 1.

CPU responsável por executar todas as Tasks - sem DMA.
Figura 1 – CPU responsável por executar todas as Tasks.

O DMA é como se fosse um coprocessador, porém tem somente a função de transportar as mensagens. No nosso exemplo seria encarregado em realizar as tasks/funções B e D, deixando o processamento do sistema como na Figura 2.

Divisão de Tasks entre a CPU e o DMA.
Figura 2 – Divisão de Tasks entre a CPU e o DMA.

Como visto as áreas hachuradas na figura anterior, percebe-se que a CPU ganhou mais tempo de processamento. O tempo ocioso pode ser usado para colocar outras tasks/funções (Task E de cálculo matemático, por exemplo), ou até mesmo antecipar a Task A (a que está em cima da Task D), se for possível na lógica do sistema.

Quando uma transferência é concluída pelo DMA, este envia um sinal de interrupção para a CPU. Na figura anterior, ao final da Task B o DMA enviou um sinal para a CPU, que ordenou o DMA a realizar o Task D imediatamente, já que a Task C estava concluída. Claro que espera-se que exista um pequeno espaço de tempo entre a Task B e D, aonde há o tratamento da dita interrupção, como também a preparação dos ponteiros para o envio da mensagem.

Neste exemplo fizemos a transferência de dados somente da memória para o periférico, mas o DMA consegue realizar o caminho contrário, como também da memória para memória. Transferências de periférico a periférico são incomuns em microcontroladores.

Entendi que assim fica eficiente, mas o quanto?

Vamos supor que eu queira mandar “Hello World!” via UART (120 bits: 12 caracteres, cada um tem 8 bits mais start e stop bits no envio) na velocidade de 115200 bps, e o microcontrolador X roda na velocidade de 80 MHz. A conta fica da seguinte maneira:

dma conta

Isso significa que a CPU pode rodar 83 mil ciclos de clock realizando outras tarefas paralelamente ao envio da mensagem “Hello World!”. Aqui, deve-se tomar cuidado em dizer que seriam 83 mil instruções Assembly, pois dependendo da arquitetura algumas instruções levam dois ciclos de clock para serem executadas. Modificando o cálculo anterior, você pode estimar a otimização por tempo em milissegundos, e avaliar se alguma tarefa pode caber naquele tempo, ou não. Podem caber várias outras tarefas, como pode não ser o suficiente para um cálculo matemático complexo. O projetista deve avaliar cada caso, mas, via de regra, o DMA é usado em comunicações de baixa velocidade, como a UART, ou em transporte maciço de dados em sinais mais rápidos como a SPI.

O problema do DMA e a coerência de cache

A memória cache se localiza próxima ao CPU e é mais rápida que a RAM. O acesso aos dados da memória RAM podem exigir múltiplos ciclos de clock, e nesse cenário a memória cache tem a função de acelerar o processo de leitura e escrita, deixando os dados e instruções disponíveis numa região aonde seja necessário menos ciclos de clock.

O principal problema que pode acontecer ao se implementar o DMA no sistema é a falta de coerência dele com o cache. Veja o problema ilustrado na Figura 3. Num primeiro momento a memória cache acessa o endereço X da memória RAM, armazenando o valor “15”. O DMA armazena o valor “10” no endereço X num segundo momento, e operações subsequentes na CPU serão feitas com o valor desatualizado “15”. Por isso, há a necessidade de sinalização entre o cache e o DMA para uma possível invalidação e atualização do valor.

Ilustração simples do problema da coerência de cache.
Figura 3 – Ilustração simples do problema da coerência de cache.

A memória cache não é somente “coisa de browser”, os desenvolvedores devem se atentar pois microcontroladores ARM Cortex-M7 já utilizam sistema de cache. Este Application Note da ST recomenda que se for utilizar o DMA, que seja feita a alocação dos dados relativos a este numa região da memória que não seja “cacheável”.

Considerações finais

Este artigo tem o caráter introdutório e teórico sobre o DMA, sendo que a implementação em código pode mudar entre diferentes fabricantes de microcontroladores. Eu implementei no Tiva TM4C e você pode conferir neste link. Evandro Teixeira fez também um artigo explicando e aplicando o DMA na FRDM-KL25Z.

O desenvolvedor deverá ter paciência para ler o datasheet com calma e analisar com cuidado as bibliotecas fornecidas pelos fabricantes. A depuração da execução do DMA é um tanto complicado, portanto, um analisador lógico nessas horas é um grande aliado. Se estiver analisando um sinal SPI de alta frequência, não precisará de um analisador caro que capte altas frequências: abaixe a frequência do sinal em firmware, e se o sinal estiver conforme na baixa velocidade, muito provavelmente estará certo nas altas.

Saiba mais

Biblioteca de Software de DMA para FRDM-KL25Z

Soft-SPI: Biblioteca para memória SPI-Flash em microcontroladores PSoC-4

Utilizando os periféricos do microcontrolador ARM Cortex-M0+ ATSAMC21, da Microchip

Referências

Understanding DMA – Hackaday

DMA – A Little Help From My Friends – embedded.fm

DMA – The Ganssle Group

Direct memory access – Wikipedia

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

[wpseo_breadcrumb]
Comentários:
Notificações
Notificar
guest
2 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Wellington Mateus
Wellington
20/07/2018 12:07

Não compreendi o cálculo!

Talvez você goste:

Séries

Menu
Privacy Settings saved!
Configurações de Privacidade

Entenda quais dados e informações usamos para ter melhor entrega de conteúdo personalizado para você.

These cookies are necessary for the website to function and cannot be switched off in our systems.

Para usar este site, usamos os seguintes cookies tecnicamente exigidos

  • wordpress_test_cookie
  • wordpress_logged_in_
  • wordpress_sec

Decline all Services
Accept all Services