Teach lesson
Nios V na DE1-SoC (2/5): E/S mapeada em memória com C
Edite E/S mapeada em memória em C no Nios V, leia chaves, controle LEDs e explique como os endereços ligam o código ao hardware.
New to LabsLand? Create your teacher account
Learning Outcomes
Usar ponteiros volatile em C para acessar E/S mapeada em memória.
Ler as chaves lógicas do Nios V no LabsLand pelo caminho GPIO JP1.
Usar máscaras e deslocamentos para mapear bits de entrada nos bits de saída dos LEDs.
Validar o comportamento do hardware pela câmera ao vivo da placa.
Student activity preview
Activity Content
Preview only. In a class session, students can fill in responses and submit their work to the teacher.
O mapa de E/S
8 min
O processador Nios V enxerga os periféricos de hardware como endereços de memória. Neste laboratório, o programa inicial usa:
- LEDR em 0xFF200000: registrador de saída dos LEDs vermelhos.
- dados JP1 em 0xFF200060: caminho de entrada das chaves lógicas do LabsLand.
- direção JP1 em 0xFF200064: registrador de direção do GPIO.
- JTAG UART em 0xFF201000: saída do terminal por printf.
A CPU lê e escreve esses endereços como memória comum, mas o tecido da FPGA encaminha cada acesso a um periférico, e não à RAM. Isso é E/S mapeada em memória.
Os controles do navegador têm os rótulos NSW0..NSW9. Neste fluxo remoto, eles não são a porta física SW0..SW9 em 0xFF200040. Os controles NSW lógicos entram pelos bits do GPIO JP1; o programa inicial desloca esses bits para baixo antes de escrever no registrador de LEDs.
Limite da referência: o manual FPGAcademy DE1-SoC Computer with Nios V é a referência correta para o computador Nios V fixo e seu mapa de periféricos. Esta lição usa deliberadamente o caminho JP1 validado pelo LabsLand para os controles NSW do navegador, em vez de usar diretamente o registrador das chaves físicas da FPGAcademy.
Os controles NSW do navegador são lidos nos bits 5 a 14 dos dados JP1. O programa desloca o valor cinco posições à direita para que NSW0 se torne o bit 0 e escreve o valor de dez bits em LEDR0..LEDR9.
Posições principais:
- NSW0 é lida como o bit 5 do JP1 e se torna LEDR0.
- NSW1 é lida como o bit 6 do JP1 e se torna LEDR1.
- NSW2 é lida como o bit 7 do JP1 e se torna LEDR2.
- O padrão continua até NSW9, lida como o bit 14 e transformada em LEDR9.
Neste perfil, escrever 0 no registrador de direção JP1 configura como entradas as linhas usadas por NSW0..NSW9. Por isso o programa executa *JP1_DIR = 0; antes de ler os dados JP1.
Por que o programa escreve em 0xFF200064 antes de ler as chaves em 0xFF200060?
Compile o programa C inicial
14 min
Abra
Nios V C IDE for DE1-SoC.Examine
main.c.Clique em
Build ELF(Compilar ELF).Envie para a FPGA com
Upload to FPGA.Confirme que o terminal imprime
Hello from Nios V.Alterne
NSW0,NSW3eNSW9; observe as saídasLEDRcorrespondentes.
Registre três testes rápidos. Em cada linha, preveja primeiro a saída LEDR, alterne o controle NSW na placa e anote o resultado observado.
Registre três testes. Para cada linha, preveja a saída LEDR antes de testar e depois anote a saída realmente observada na placa.
| Entrada testada | LEDR esperada antes do teste | LEDR observada na placa | Coincidiu com a previsão? |
|---|---|---|---|
Leia o caminho do código
15 min
Mantenha aberta a aba do laboratório C. Você pode responder usando o código abaixo, que é o mesmo main.c que acabou de compilar e testar.
Concentre-se no laço:
*JP1_DIR = 0;
while (1) {
*LEDS = (*JP1 >> 5) & 0x3FF;
}
O deslocamento move para as posições 0 a 9 os bits do JP1 usados por NSW0..NSW9. A máscara mantém apenas esses dez bits antes da escrita no registrador de LEDs.
Por exemplo, quando apenas NSW0 está ligada, o bit 5 do JP1 é 1. Depois de >> 5, ele se torna o bit 0 e acende LEDR0. Os qualificadores volatile são necessários porque o valor apontado por JP1 pode mudar devido ao hardware, não a uma atribuição em C. Sem volatile, uma otimização poderia reutilizar um valor antigo ou remover um acesso repetido que pareceria redundante na memória comum.
Se NSW0 chega ao bit 5 dos dados JP1, por que o código desloca o valor cinco posições à direita?
Qual seria o risco de escrever o valor bruto do JP1 diretamente no registrador de LEDs sem & 0x3FF?
Por que esses ponteiros devem ser volatile? Explique em termos de otimização do compilador e registradores de hardware.
Modifique o mapeamento
13 min
Use novamente a aba do C IDE. Se a primeira sessão ainda estiver aberta, reutilize-a; se tiver expirado, compile o ELF modificado e envie-o outra vez. Altere o programa para que os LEDs mostrem um padrão transformado das chaves, clique em Build ELF, envie-o e teste na placa.
Escolha uma transformação:
- Inverta os dez bits das chaves antes de escrever nos LEDs.
- Mostre apenas os cinco controles NSW inferiores em LEDR0..LEDR4.
- Desloque o padrão NSW uma posição de LED para a esquerda e explique o que acontece com NSW9.
Envie o laço C modificado e um parágrafo explicando a transformação.
O resultado observável deve corresponder à explicação. Por exemplo, se você inverter o padrão, NSW0 desligada deve acender LEDR0, e NSW0 ligada deve apagá-lo.
Descreva um padrão de chaves testado, o resultado esperado nos LEDs e o que a placa mostrou.
Síntese
5 min
Resuma o caminho completo dos dados, desde o clique em NSW4 no navegador até a mudança de LEDR4 na placa.