Como usar SPM para programação de Flash para Flash – (Parte 33/46)

O Modo de autoprogramação (SPM) é um recurso que permite a um microcontrolador programar sua própria memória flash. Usando o SPM, um microcontrolador pode programar-se com um código SPM. O SPM é comumente usado com os códigos Boot-Loader do microcontrolador que ajudam a programar o microcontrolador serialmente. No microcontrolador AVR o SPM está disponível apenas para o código rodando no BLS da memória flash. Com a ajuda do SPM, um código no BLS pode reescrever a memória flash do aplicativo inteiramente ou parte dela. Pode até reescrever seu próprio código na seção BLS.

O SPM é um fator chave do código do Boot-Loader, pois a principal função do Boot-Loader é carregar um código de aplicativo na seção flash do aplicativo. O Boot-Loader pode receber o código binário de outros chips de memória, cartões SD ou através da porta serial do microcontrolador no caso de programação serial. É então com a ajuda do SPM que o microcontrolador escreve o código binário na seção flash da aplicação. Neste projeto é demonstrado o funcionamento do SPM reescrevendo o código de uma região da memória flash para outra região e então tenta executar o mesmo código daquela região. O hardware utilizado neste projeto inclui ATMEGA16 como microcontrolador, USBASP como programador e os softwares utilizados são AVR STUDIO 4 como IDE e AVR-BURNO-MAT como software gravador.

Modo de autoprogramação (SPM) é um recurso do microcontrolador AVR que permite ao microcontrolador programar sua própria memória flash. Somente o código em execução no BLS pode fazer uso deste recurso SPM. O microcontrolador pode ser feito para iniciar a execução a partir do BLS a partir daí o código pode acessar a área flash da aplicação. O BLS pode ler ou gravar o conteúdo de todo o flash, incluindo o próprio BLS.

Diagrama de blocos de SPM com BLS em AVR

Fig. 2: Diagrama de blocos do SPM com BLS no AVR

A tarefa de escrever o código BLS com SPM foi simplificada pelas APIs disponíveis no arquivo de cabeçalho . A seguir estão as APIs importantes disponíveis no arquivo de cabeçalho que auxiliam no SPM.

FUNÇÃO

DESCRIÇÃO

PARÂMETRO

boot_is_spm_interrupt

Verifique se a interrupção SPM está habilitada.

boot_lock_bits_set (lock_bits)

Defina os bits de bloqueio do Boot-Loader

Uma máscara de quais bits de bloqueio do carregador de inicialização definir

boot_lock_bits_set_safe (lock_bits)

Aguarda a conclusão das operações EEPROM e SPM antes de definir os bits de bloqueio

Uma máscara de quais bits de bloqueio do carregador de inicialização definir

boot_lock_fuse_bits_get (endereço)

Leia os bits de bloqueio ou fusível no endereço fornecido. Retorna 0 ou 1 conforme o bit do fusível estiver programado ou não

O endereço a ser lido

boot_page_erase (endereço)

Apague a página flash referida pelo endereço

Um endereço de byte em flash

boot_page_erase_safe (endereço)

espera que as operações EEPROM e SPM sejam concluídas antes de apagar a página

Um endereço de byte em flash

boot_page_fill (endereço, dados)

Preencha o buffer de página temporário do Boot-Loader para endereço flash com palavra de dados

O endereço é um endereço de byte. Os dados são uma palavra

boot_page_fill_safe (endereço, dados)

espera que as operações EEPROM e SPM sejam concluídas antes de preencher a página

O endereço é um endereço de byte. Os dados são uma palavra

boot_page_write (endereço)

Grave o buffer de página temporário do Boot-Loader na página flash que contém o endereço

Endereço de byte em flash

boot_page_write_safe (endereço)

espera que as operações EEPROM e SPM sejam concluídas antes de escrever a página

Endereço de byte em flash

boot_rww_busy

Verifique se a seção RWW está ocupada

boot_rww_enable

Habilite a seção de memória Read-While-Write.

boot_rww_enable_safe

aguarda a conclusão das operações EEPROM e SPM antes de ativar a memória RWW

boot_signature_byte_get (endereço)

Retorna o byte da linha de assinatura no endereço fornecido

O endereço do parâmetro pode ser de 0 a 0x1F

boot_spm_busy

Verifique se a instrução SPM está ocupada

boot_spm_busy_wait

Aguarde enquanto a instrução SPM está ocupada

boot_spm_interrupt_disable

Desative a interrupção do SPM

boot_spm_interrupt_enable

Habilite a interrupção do SPM

Figura 3: APIs importantes no arquivo de cabeçalho do AVR para SPM

Usando as APIs acima, pode-se escrever um código para SPM em um microcontrolador AVR, desde que o código siga certas etapas na ordem. Neste projeto, o código que foi programado desde o início da memória flash é reprogramado em outra região da memória flash como tal. A tarefa de programar uma região da memória flash com o binário obtido da outra região pode ser realizada nas três etapas principais a seguir.

Passo: 1 Apague a página flash que está prestes a escrever

O primeiro passo é apagar a página flash que está prestes a ser escrita com os novos valores. A API que auxilia na execução desta etapa é;

Boot_page_erase (endereço)

Esta API pode apagar uma página inteira na flash que o parâmetro aborda. No código o endereço da página apagada é 256. A imagem a seguir mostra o status do buffer de página temporário e da memória flash na etapa 1. O buffer de página temporário é um buffer no qual uma página inteira pode ser armazenada antes de ser flashou em uma página na memória flash.

A figura representa o status do buffer de página temporário e da memória flash no SPM do AVR

Fig. 4: A figura representa o status do buffer de página temporário e da memória flash no SPM do AVR

Etapa: 2 Armazene os valores em um buffer temporário antes de gravar em uma página flash

Esta é a segunda etapa na qual se deve armazenar o binário necessário em um buffer temporário, antes de gravar em qualquer página da memória flash. A API que pode ser usada para esse fim é;

boot_page_fill (endereço, dados)

Esta API fpreenche o buffer de página temporário do Boot-Loader byte por byte antes de atualizar os dados no buffer de página temporário em uma página como tal. Os dados do parâmetro representam cada byte no buffer e o endereço do parâmetro representa o endereço da página + deslocamento do local do buffer onde o byte de dados precisa ser armazenado.

A figura a seguir representa a operação na qual o buffer de página temporário é preenchido byte por byte usando a API boot_page_fill (endereço, dados).

Operação de transferência de dados para buffer de página temporário usando a API boot_page_fill do AVR

Fig. 5: Operação de transferência de dados para buffer de página temporário usando a API boot_page_fill do AVR

Os dados de parâmetro na API boot_page_fill (endereço, dados) são na verdade lidos do primeiro local da própria memória flash com a ajuda de outra API que está disponível no arquivo de cabeçalho .

pgm_read_byte (endereço)

FUNÇÃO

DESCRIÇÃO

PARÂMETRO

pgm_read_byte (endereço)

Esta função retorna o byte que lê da memória flash referida pelo parâmetro 'address'

Refere-se à localização da memória flash da qual o byte precisa ser lido

Etapa: 3 Programe o buffer temporário preenchido na página flash já apagada

Esta é a etapa final na qual o buffer temporário preenchido é atualizado usando uma API na página já apagada da memória flash. A API que auxilia nesta etapa é;

boot_page_write (endereço)

Dados de buffer temporário transferidos na memória flash do AVR usando API

Fig. 6: Dados de buffer temporário transferidos na memória Flash do AVR usando API

O código neste projeto que foi escrito para o BLS pode copiar 300 bytes da memória flash para o buffer temporário começando no endereço 0x0000. Esses bytes são então transferidos para a página da memória flash começando no endereço 0x0100. Depois de fazer isso, o código do BLS saltará para o endereço 0x0100 para que o binário reescrito possa ser executado a seguir. Com este código do carregador de boot, qualquer programa que inserirmos no endereço começando em 0x0000 será reescrito em ox 0x0100 e executado. Um simples aplicativo de teste de LED piscando pode ser gravado na memória flash a partir de 0x0000 para testar o funcionamento. Atualize primeiro o código do BLS e depois o código da aplicação do LED usando as etapas explicadas no projeto anterior em LED piscando do BLS do AVR. Quando o led pisca, significa que o código foi reescrito de uma seção da memória flash para outra e está sendo executado a partir daí.

LED piscando usando SPM do circuito AVR configurado na placa de ensaio

Fig. 7: LED piscando usando SPM do circuito AVR configurado na placa de ensaio

Código-fonte do projeto

###


#define F_CPU 8000000
#incluir
#incluir #incluir #incluir #incluir #incluir #incluir int principal (void) { uint16_ti; uint8_tA(300); uint8_t registro; página uint32_t = 256; caractere não assinado *buf = A; //------------------------------------------------ ------------------------------- DDRD = 0x80; PORTD = 0x7F; //continuou. carregador de inicialização ok. _atraso_ms (2000); PORTD = 0x80; //desliga o led agora. Esperamos que o aplicativo acenda o LED novamente _atraso_ms (2000); //------------------------------------------------ -------------------------------- // armazenando os bytes da i-ésima localização da memória flash para a i-ésima variável do array A // para (eu = 0; eu <300; eu++) A(i)=pgm_read_byte(i); // armazenando os bytes da i-ésima localização da memória flash para a i-ésima variável do array A // //================================ SPM ============== ============================// sreg = SREG; // armazena o status atual da interrupção em sreg cli ; //limpa interrupções eeprom_busy_wait ; // espere até que a eeprom esteja livre. boot_page_erase (página); //apaga a página do flash na qual estamos prestes a escrever boot_spm_busy_wait ; //Espere até que a memória seja apagada. //---- preenche os bytes da página no buffer de página temperory antes de passar para o flash ----// para (eu = 0; eu

{ //converte os bytes para palavra little-endian// uint16_t w = *buf++; w += (*buf++) << 8; //converte os bytes para palavra little-endian// boot_page_fill (página + i, w); //preenche o buffer da página temperada byte por byte } //---- preenche os bytes da página no buffer de página temperory antes de passar para o flash ----// //------------------------------------------------ --------------------// boot_page_write (página); // Armazena buffer na página flash. //------------------------------------------------ --------------------// boot_spm_busy_wait ; //Espere até que a memória seja escrita. boot_rww_enable ; //Reativa a seção RWW novamente SREG = sreg; //Reativa as interrupções //================================ SPM ============== ============================// asm("jmp 0x0100"); // salta para a aplicação programada em 0x0100 }

###

Código-fonte do projeto

###


#define F_CPU 8000000
#incluir #incluir int principal (void) { DDRD = 0x80; enquanto(1) { PORTD &= 0x7F; _atraso_ms (2000); PORTD = 0x80; _atraso_ms (2000); } }

###

Diagramas de circuito

Diagrama de circuito de como usar o SPM para programação de Flash para Flash

Componentes do Projeto

  • ATmega16
  • LCD
  • LIDERADO
  • Resistor

Vídeo do projeto

Perguntas relacionadas a este artigo?
👉Pergunte e discuta nos fóruns Electro-Tech-Online.com e EDAboard.com.

Nos diga o que você acha!! Cancelar resposta

Conteúdo Relacionado

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.