Roteiro 2 EA870 2S2009

De DCA-Wiki

Contents

Roteiro 2 - Assembly, disassembly, memórias e portas

  • Programação em assembly
  • Portas IO

Agradecimento

O desenvolvimento deste roteiro teve a grata contribuição de Pedro Augusto (okaitt@gmail.com) e Guilherme A. Zalewski (buzzag@gmail.com).

Introdução

O objetivo deste roteiro é iniciar e habilitar o aluno na linguagem assembly do microcontrolador (MCF52221 - MCF52). Neste roteiro são abordados os seguintes aspectos:

  • aprender a linguagem de máquina utilizada (Disassembly/Debugger) Hint: See Freescale Commands /4e 5/;
  • monitorar e modificar a memória através do console do CodeWarrior;
  • modificar e visualisar os registradores de dados e endereços;
  • introdução à configuração e manejo das portas. Este procedimento deve permitir um claro entendimento do funcionamento da placa como um todo.

A aprendizagem destes conceitos deve habilitar o aluno a criar programas com as funções básicas da linguagem assembly.

Roteiro de Estudos

Responder às questões abaixo para estudo. Os textos de referência para este estudo estão listados na Seção de Referências.

  • 1. O que é Disassembly? Debugger? No que estes dois conceitos diferem? Exemplifique. /6,7/ e Generating Debugger Output /
  • 2. Uma mesma instrução, usada com diferentes tipos de endereçamento, pode ter tamanhos diferentes? Explique como e exemplifique, com ao menos 3 exemplos
  • 3a. Qual a diferença entre comandos do tipo branch e o comando JSR? Ambos usam o registrador de programa PC?
  • 3b. As instruções Bcc, JMP e JSR tem funções idênticas, são diferentes apenas no símbolo mnemônicos. Certo/Errado? Caso não concorde com tal afirmação, justifique e explique a função de cada instrução.
  • 4. Em instruções de comparação e de branch condicional - Bcc, qual o registrador usado com tal objetivo?
Recomenda-se para as questões, a seguir, que se estude o Capítulo 4 e 5 da Ref. /20/ 
  • 5. O que é o endereço base ISPBAR? E a FLASHBAR? E a RAMBAR? O que significaria acessar uma posição ISPBAR + 0x0100027?

(Detalhe: o valor 0x0100027 se chama Offset). /6/

  • 6a. Conceitue a diferença entre Porta e Interface.
  • 6b. Quantas portas o MCF52221 possui? Quais são elas? /1/ Cap. 12 e /6/
  • 7. Qual é o registrador que define a direção das portas I/O comuns? Dê o endereço de 2 registradores de direção de qualquer duas portas. /1/ Cap. 12 e /6/
  • 8. Para que serve os registradores PnPAR? /6/
  • 9. Explique a diferença entre PORTnP e PORTn. /1/ Cap. 12 e /6/
  • 10. Onde estão conectados os push-buttons SwA e SwB da placa auxiliar? E os LEDs da placa principal? Dê os endereços do DDRn, PnPAR, PORTnP e PORTn dos leds e dos push-buttons. /1/ Cap. 12 e /6/

Roteiro da Aula

Nesta experiência iremos criar e executar o programa MAIN.C que está codificado em assembly language do ColdFire MCF52221. Para facilitar seu estudo, neste roteiro, veja /6/. Neste roteiro executa-se os seguintes passos:

  1. Edição do arquivo fonte
  2. Montagem
  3. Carregamento do arquivo objeto
  4. Execução do programa na memória RAM

Edição do código fonte

Instruções para começar um novo projeto no CodeWarrior:

  • Inicialmente, deve-se criar o nome do projeto no CodeWarrior. Para isto:
    • primeiro clique no menu “File”;
    • depois em “New Project”;
    • selecione a placa em uso “M52221DEMO”
    • e ao lado, à direita, dê um nome ao arquivo (este é o nome do projeto).
    • Selecione, também, uma pasta no diretório para salvar o nome do projeto criado (Pede-se o favor de criar sua pasta, no SubDiretório: EA870Alunos);
    • Clique, então, em CONCLUIR.

O nome de um novo projeto já está criado.

Em seguida, para editar o código fonte, deve-se ir até a janela da esquerda, selecionar “Source”, com duplo clique e, então, “main.c”. O código do projeto (programa fonte) se abre na tela.

Montagem, arquivo objeto e debug

  • Após uma edição qualquer ou mesmo para rodar o programa exemplo, siga os passos:
    • Clique no menu “Project” e em seguida em “Compile” (CTRL + F7).
    • Clique no menu “Project“ e em seguida em “Make” (F7).
    • Clique no menu “Project” e em seguida em “Debug” (F5): – A janela de debug irá se abrir e o cursor estará parado no início do programa. Mudando-se a opção de visualização de *source* para *assembler*, você irá visualizar o programa no formato assembler e código binário na memória.

É possível abrir também o Command Window e deixar as duas janelas visíveis de modo que na janela de debug, execute-se passo-a-passo e na janela do command window visualize-se e inicializa-se registradores da CPU.

Execução do programa

Para se executar o programa passo-a-passo, pode-se usar a tecla F11 (step-into)


- Programa MDC/main.c

Nota: Existem tres formas de calcular o MDC: 1) por divisões sucessivas; 2)pela multiplicação dos fatores comuns e 3)por subtrações e comparações sucessivas: Veja em Máximo Divisor Comum. Neste programa estamos usando esta última forma.

#include "support_common.h"
#include <stdio.h>

int main(void)
{
	asm
	{
	//ALGORITMO DO MAXIMO DIVISOR COMUM (MDC)
	move	#0x0000001e, D3	//Armazena o operando em D3
	move	#0x2000010c, A4	//A4 aponta para o primeiro endereço de memória
	move	#0x2000018d, A6	//A6 aponta para outro endereço de memória
			
	//(A4) = x
	//D3   = y
	//(A6) = z = MDC
			
INI:	cmp.l	(A4), D3	//Compara o x e y
	beq	FIM		//Se x e y são iguais, encontrou MDC (Branch FIM)
	bgt 	OP2		//Se x<y, realiza operação 2
			
				//Se x>y, realiza operação 1
OP1:	sub	D3, (A4)	//x = x - y
	bra	INI		//Volta para INI
			
OP2:	sub	(A4), D3	//y = y - x
	bra 	INI		//Volta para INI
			
FIM:	move 	(A4), (A6)	//z = x = MDC
			
	}
}


IMPORTANTE: Considere o RA: abcdef, onde, cada letra corresponde ao respectivo digito do seu RA. (apenas neste programa)

  • A partir do que foi visto no roteiro anterior /6/, usando o Command Window, mude a posição de memória 0x2000010c para o valor 0x000001f usando o comando change. Então execute o programa passo-a-passo (Debug Mode - "F11"), observando os valores do registrador utilizado e da posição de memória modificada anteriormente.

- Programa PORTAS/main.c

#include "support_common.h" /* include peripheral declarations and more */
#include <stdio.h>

//Cria as definiçoes abaixo (algo como .EQU em assembly de outros processadores)
#define DDRNQ   0x40100020
#define PNQPAR  0x40100068
#define PORTNQP 0x40100038
#define DDRTC   0x40100027
#define PTCPAR  0x4010006F
#define PORTTC  0x4010000F

int main(void)
{
  asm
  {
	//Configuração para a porta NQ
		
	move.w	#0b1000000000001000, D0 // 0b indica um número em binário 
	move.w	D0, PNQPAR              //Os pinos PORTNQ1/7 são definidos em sua função alternativa 1
	move.b	#0x0, D6                //(porta comum I/O)
	move	D6, DDRNQ	            //A porta NQ é definida como entrada
		
	//SwA está na PORTNQ1(IRQ1) e SwB na PORTNQ7(IRQ7)

	//O codigo abaixo verifica o valor do conteúdo do registrador D0, quem tem o conteúdo de PORTNQP
	//e confere onde os bits mudam (confira com o manual!)

	//Verifica o SwB
INI:	move 	PORTNQP, D0	    //Recebe o valor que se encontra na porta NQ
	andi	#0x02000000, D0	    //Devemos testar os botoes pressionados atraves de uma mascara
	beq	SWB_ON	            //Caso o AND logico SEJA zero, pule para SWB_ON (está apertado)
				    //(lógica inversa nesta porta)
									
	//Continua o código e verifica o SwA		
        move 	PORTNQP, D0         //Recebe o valor que se encontra na porta NQ
 	andi	#0x80000000, D0	    
	beq	SWA_ON		    //Caso o AND logico SEJA zero, pule para SWA_ON (está apertado)

	bra 	INI                 //Nenhum está apertado, volte a pesquisar

SWA_ON: nop        
        bra     SWA_ON          	//Qualquer operação

SWB_ON: nop
        bra     SWB_ON 		    	//Qualquer operação

  }
}
  • Crie um novo projeto no CodeWarrior e utilize o código acima como código principal (main).
  • Utilizando o esquemático de nossa placa auxiliar, busque entender exatamente o que o código faz.

Relatório

Entregar as questões abaixo na forma de relatório

Considere o programa MDC/main.c:

IMPORTANTE: Considere o RA: abcdef, onde, cada letra corresponde ao respectivo digito do seu RA. (apenas neste programa)

  • 1. Explique a necessidade da instrução ”bra INI” no programa. Uma vez entendido e sua utilização sugere uma alternativa a este laço, com idêntica programação.
  • 2. Codifique as instruções do programa no formato hexadecimal /2/ /6/. Comente cada instrução.
  • 3. Indique o tamanho e ilustre graficamente os campos, em bytes, da instrução “sub (A4), D3”. Explique e justifique graficamente o que acontece se o endereçamento do segundo operando na instrução fosse modificado para imediato, esse tamanho mudaria? Se sim, indique e justifique o novo valor. Represente as palavras - "words" - graficamente.
  • 4. Explique como é feito o salto relativo nos comandos do tipo branch utilizados no programa (beq, bgt e bra). Mostre o formato gráfico das "words" em cada explicação.

PS: O comando "move #0x[ENDERECO], A0" não é listado no manual, pois este é automaticamente transformado para "movea #0x[ENDERECO], A0" (ambos possuem o mesmo código hexadecimal).

Considere o programa PORTAS/main.c:

  • 1. Edite o código “PORTAS/main.c” para que inicialmente os leds estejam apagados.
    • DICA: Para utilizar os LEDs, a porta onde eles estão conectados deve ser configurado como "SAÍDA" (Eles estão conectados à Porta TC /6/). Ilustre graficamente cada registro configurado e, para cada bit no respectivo registro, explique porquê "0" ou "1" foi setado. Veja isto na Ref /3/, Cap 12.
    • DICA: Lembre-se que cada bit corresponde a um led. O bit setado como "1" acende o led e o inverso apaga o mesmo.
  • 2. Após, edite o código “PORTAS/main.c” para que ao ser detectado o SwA pressionado, acenda os seguintes leds: 0 e 2.
  • 3. Após, edite o código “PORTAS/main.c” para que ao ser detectado o SwB pressionado, acenda os seguintes leds: 1 e 3.
  • 4. Após, edite o código “PORTAS/main.c” para que ao ser detectado o SwA e o SwB pressionados juntos, acenda todos os leds.
  • 5. Após as modificações feitas e corretamente testadas, faça com que ocorra as rotinas acima, porém, apenas enquanto o(s) push-button(s) estiver(em) apertado(s). (Por exemplo, ao apertar o SwA os leds 0 e 2 são acesos durante o tempo em que o botão permanecer pressionado. Ao ser solto, o programa volta ao estado inicial - tudo apagado)
  • 6. Faça um fluxograma para o programa modificado.


  • Observação: Pede-se, por gentileza aos alunos que, quando for editar programas e criar projetos, sempre, mas sempre mesmo gere-o em alguma subpasta, porém que seja dentro da pasta: EA870 Alunos no desktop. Veja dicas para isto em /6/.

Referências

  • /100/ Beatriz M. Daltrini, Mario Jino, Léo P. Magalhães; Introdução a Sistemas de Computação Digital; Makron Books do Brasil Editora Ltda; ISBN 85-346-0986-1
  • /2/ ColdFire Family Programmer´s Reference Manual; Doc nº:CFPRM.
  • /3/ MCF52221 ColdFire Integrated Microcontroller Reference Manual. Doc n°:MCF52223RM
  • /4/ CodeWarrior Development Studio IDE 5.6 Windows Automation Guide

http://www.freescale.com/files/soft_dev_tools/doc/user_guide/IDE_5.6_Automation_Guide.pdf?fsrch=1

Ferramentas pessoais