Como usar o SPM para carregar aplicativos da EEPROM – (Parte 34/46)

Em qualquer microcontrolador, o Boot-Loader é o primeiro código executado antes do código do aplicativo. A principal função do Boot-Loader é carregar o código da aplicação na memória flash do microcontrolador e executá-lo. No microcontrolador AVR o Modo de autoprogramação (SPM) ajuda o Boot-Loader a carregar um aplicativo específico de onde o binário do aplicativo está armazenado.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 específico, a operação de um código Boot-Loader usando o SPM é demonstrada reescrevendo a memória flash com o código binário que já foi atualizado na EEPROM integrada do ATMEGA16. 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.

A seção BLS é normalmente usada para armazenar o código do carregador de inicialização do microcontrolador. O código Boot-Loader pode ser usado para inicializar os periféricos no microcontrolador, inicializar os dispositivos conectados ao microcontrolador, selecionar o aplicativo para carregar e executar a partir de um meio de armazenamento, carregar o aplicativo selecionado para a seção de aplicativos, pular para a seção de aplicativos e execute o aplicativo. O código em execução na seção BLS pode ser executado Modo de autoprogramação (SPM) que são bloqueadas para o código em execução na seção Aplicativo. Usando instruções SPM, o código do BLS pode reescrever o código na seção do aplicativo ou o código no próprio BLS.

Configurando o SPM para carregar o aplicativo da EEPROM no protótipo AVR

Fig. 2: Diagrama de blocos da função 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_page_erase (endereço)

Apague a página flash referida pelo endereço

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_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

Figura 3: APIs importantes para a função SPM do AVR

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.

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

{C· Etapa: 2 Armazene os binários em um buffer temporário antes de gravar em uma página flash

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

As três etapas acima são explicadas com detalhes em um artigo anterior projeto no AVR SPM. Neste projeto específico, os dados necessários para preencher o buffer de página temporário, conforme discutido na etapa: 2, são retirados da EEPROM integrada do microcontrolador AVR, onde um código simples já foi inserido. A EEPROM interna do microcontrolador AVR possui capacidade de 512 bytes. Ele pode ser facilmente lido e escrito com a ajuda de 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 acesso à memória EEPROM.

FUNÇÃO

DESCRIÇÃO

vazio eeprom_is_ready (vazio)

Retorna 1 se a EEPROM estiver pronta para uma nova operação de leitura/gravação, 0 se não estiver

void eeprom_read_block (void *dst, const void *src, size_t n )

Retorna um bloco de n bytes do endereço EEPROM src para SRAM dst

uint8_t eeprom_read_byte (const uint8_t *p)

Retorna um byte do endereço EEPROM referido pelo ponteiro p

uint32_t eeprom_read_dword (const uint32_t *p)

Leia um duplo de 32 bits do endereço EEPROM referido pelo ponteiro p

float eeprom_read_float (const float *p)

Retorna um valor flutuante da EEPROM referido pelo ponteiro p

uint16_t eeprom_read_word (const uint16_t *p)

Leia uma palavra de 16 bits do endereço EEPROM referenciado pelo ponteiro p

void eeprom_update_block (const void *src, void *dst, size_t n)

Atualize um bloco de n bytes para o endereço EEPROM dst de src

void eeprom_update_byte (uint8_t *p, valor uint8_t)

Atualize um valor de byte para o endereço EEPROM referido pelo ponteiro p

void eeprom_update_dword (uint32_t *p, valor uint32_t)

Atualize um valor de palavra dupla de 32 bits para o endereço EEPROM referido pelo ponteiro p

void eeprom_update_float (float *p, valor flutuante)

Atualize um valor flutuante para o endereço EEPROM referido pelo ponteiro p

void eeprom_update_word (uint16_t *p, valor uint16_t)

Atualize um valor de palavra para o endereço EEPROM referido pelo ponteiro p

void eeprom_write_block (const void *src, void *dst, size_t n)

Escreva um bloco de n bytes no endereço EEPROM dst de src.

void eeprom_write_byte (uint8_t *p, valor uint8_t)

Escreva um valor de byte no endereço EEPROM referido pelo ponteiro p

void eeprom_write_dword (uint32_t *p, valor uint32_t)

Escreva um valor de palavra dupla de 32 bits no endereço EEPROM referido pelo ponteiro p

void eeprom_write_float (float *p, valor flutuante)

Escreva um valor flutuante na EEPROM referido pelo ponteiro p

void eeprom_write_word (uint16_t *p, valor uint16_t)

Escreva um valor de palavra na EEPROM referenciado pelo ponteiro p

Figura 4: APIs para acessar a memória EEPROM

Os dados para preencher o buffer temporário conforme discutido na etapa: 2 são lidos da memória EEPROM integrada do microcontrolador AVR usando a função de biblioteca;

uint8_t eeprom_read_byte (const uint8_t *p)

A função acima pode retornar o byte de dados que está armazenado no endereço EEPROM referido pelo argumento do ponteiro. O código é escrito de forma que o ponteiro aponte primeiro para 0º localização da EEPROM e, em seguida, aumenta o endereço à medida que lê cada byte para armazenamento no buffer temporário. Assim, as etapas com as quais o binário de um código é lido da memória EEPROM e flasheado o mesmo na memória flash são representados pictoricamente 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.

Diagrama de blocos de PageErase na função SPM

Fig. 5: Diagrama de blocos de PageErase na função SPM

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.Os dados de parâmetro na API boot_page_fill (endereço, dados) são na verdade lidos do primeiro local da memória EEPROM com a ajuda de uma API que está disponível no arquivo de cabeçalho .

uint8_t eeprom_read_byte (const uint8_t *p)

FUNÇÃO

DESCRIÇÃO

PARÂMETRO

uint8_t eeprom_read_byte (const uint8_t *p)

A função retorna um byte de dados que é armazenado no endereço EEPROM referido pelo ponteiro p

O ponteiro refere-se ao endereço EEPROM do qual o byte de dados precisa ser lido

Diagrama de blocos carregando buffer temporário para SPM do AVR

Fig. 6: Diagrama de blocos carregando buffer temporário para SPM do AVR

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)

Diagrama de blocos de gravação de página na memória flash

Fig. 7: Diagrama de blocos de gravação de página na memória flash

O código neste projeto que foi escrito para o BLS pode copiar 300 bytes da memória EEPROM para o buffer temporário começando no endereço 0x00. Esses bytes são então transferidos para a página da memória flash começando no endereço 0x0000. Depois de fazer isso, o código do BLS saltará para o endereço 0x0000 para que o binário reescrito possa ser executado a seguir. Com este código do carregador de inicialização, qualquer programa atualizado na EEPROM será reescrito na seção Flash do aplicativo do AVR e será executado. Um simples aplicativo de teste de LED piscando pode ser gravado na memória EEPROM começando a testar o funcionamento.bAtualize primeiro o código do BLS e depois o código do aplicativo LED para a memória EEPROM usando as etapas explicadas no projeto anterior em LED piscando do BLS do AVR. Quando o led pisca, significa que o código foi carregado de uma seção da memória EEPROM para a memória flash e está em execução. Com isso, o código no BLS pode carregar qualquer aplicativo que esteja programado na EEPROM na reinicialização e, portanto, atua como um Boot-Load

LED piscando usando a função SPM do circuito AVR na placa de ensaio

Fig. 8: LED piscando usando a função SPM do circuito AVR na placa de ensaio

Código-fonte do projeto

###


#define F_CPU 8000000
#incluir
#incluir #incluir #incluir #incluir #incluir #incluir #incluir int principal (void) { uint16_ti; uint8_tA(300); uint8_t registro; página uint32_t = 0; caractere não assinado *buf = A; uint16_t w; volátil int j = 2; DDRD = 0x80; para (eu = 0; eu <3; eu++) { PORTD &= 0x7F; _atraso_ms(500); PORTD = 0x80; _atraso_ms(500); } para (eu = 0; eu <300; eu++) A (i) = eeprom_read_byte ((const uint8_t *) i); enquanto(1) { //============================================== ==============================// se(j) { //Desativa interrupções. sreg = SREG; cli ; eeprom_busy_wait ; boot_page_erase (página); boot_spm_busy_wait ; //Espere até que a memória seja apagada. para (eu = 0; eu

{ //Configura a palavra little-endian. w = *buf++; w += (*buf++) << 8; boot_page_fill (página + i, w); } 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 ; SREG = sreg; } outro { asm("jmp 0x0000"); } j--; página = página + 128; //============================================== ==============================// } }

###

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 carregar o aplicativo da EEPROM

Vídeo do projeto

Perguntas relacionadas a este artigo?
👉Pergunte e discuta nos fóruns EDAboard.com e Electro-Tech-Online.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.