Como iniciar o núcleo 1,2,3 no Raspberry Pi 2

10

Eu escrevi um exemplo simples de núcleo múltiplo de metal.

Código, diagrama de circuitos está aqui - https://github.com/jeffreyantony/multipi/tree/master/Example_01

No meu exemplo, existem 3 LEDs conectados aos pinos GPIO do raspberry Pi. Existem totalmente 4 núcleos no Raspberry Pi 2. Cada núcleo é designado para piscar o LED correspondente.

Escrevi o endereço do código a ser executado por cada núcleo nos endereços abaixo 0x4000009C para o núcleo 1 0x400000AC para o núcleo 2 0x400000BC para o núcleo 3

Após a compilação do código, apenas o LED atribuído ao núcleo 1 está piscando (como neste exemplo, LED amarelo). Outros não são.

Isso significa que o código do Core 2 e 3 não está em execução (já que os outros LEDs não estão piscando). Também descobri que o código após o início de todos os núcleos também não está em execução, ou seja, core0_submain () - essa função deve piscar o LED ACT no Raspberry Pi

Alguém poderia me informar qual é o problema? É porque todos os quatro núcleos tentam gravar no mesmo registro GPIO e apenas o Core 1 está ganhando na gravação?

Eu tentei adicionar " attribute ((naked));" para core0_submain (), mas não houve uso.

Estou usando o conjunto de ferramentas de https://launchpad.net/gcc-arm-embedded

código mais uma vez - https://github.com/jeffreyantony/multipi/blob/master/Example_01/main.c

makefile - https://github.com/jeffreyantony/multipi/blob/master/Example_01/Makefile

Atualização 20 de outubro de 2015 : adicionei suporte ao JTAG. Mas não foi possível obter a interface de depuração
Atualização 25 de outubro de 2015 : o problema foi corrigido. Ver resposta.

Diagrama de circuito insira a descrição da imagem aqui

Robomon
fonte
Isso parece muito legal. Eu vou dar uma olhada. Quer dizer, pode haver algum software em raspbian que só usa um núcleo a menos que outros são necessários para economizar energia ou algo assim ...
Kachamenus

Respostas:

6

Atualização 25 de outubro de 2015:

Fórum Raspberry Pi deu a resposta para mim .

  1. Não há conceito de _start ao usar -nostdlib

  2. o código a ser executado primeiro deve ser o primeiro arquivo a ser passado ao vinculador.

  3. Se um controle melhor for necessário, o código precisará ser colocado em uma seção init e solicitar ao vinculador que copie esta seção para 0x8000

Obrigado a todos pelo apoio. Aprendi muito sobre o GNU C Compiler.

Atualização 24 de outubro de 2015:

Quando alterei a ordem dos arquivos fornecidos para compilação no Makefile, recebi a ordem correta (ou seja 0x8000, temos a _startfunção) com -O2otimização. Ainda assim, minha pergunta abaixo sobre o stackoverflow em relação ao _startsímbolo ainda não foi resolvida. Novo código é registrado.

Eu tive algum sucesso. O novo código é verificado no github .

O exemplo não está sendo executado completamente. Existem alguns problemas com a compilação. Vou explicar cada um:

  1. Na verdade, eu esperava que o _startsímbolo do meu start.S personalizado fosse usado. Mas não foi o caso. Por esse motivo, o ponteiro da pilha não foi configurado e o salto para o principal não aconteceu.

Eu já fiz uma pergunta sobre isso. Mas não progredi muito. Então, adicionei um assembly embutido para carregar o ponteiro da pilha na função principal.

  1. Mas ainda assim o código não foi executado. Quando verifiquei a lista de montagem, descobri que no endereço 0x8000(onde a execução começa) do Raspberry Pi é o código para o Core 1 - void core1_main(void). Minha suposição era de que 0x8000haveria a _start(que não é desde o arquivo start.S não é usada para compilação) ou, pelo menos, a função void main (void). Isso acontece devido à -O2otimização do GCC. No GCC, com níveis mais altos de otimização, as funções são reordenadas. Quando eu desliguei a otimização ( -O0), no endereço 0x8000, o principal estava presente.

Você pode ler sobre a reordenação de funções aqui

Resumo: o código atual é apenas uma correção. Problema principal a ser resolvido - Por que _start não é chamado desde o início.S? Se isso for corrigido, o endereço 0x8000 _startvirá. Com isso, não precisamos nos preocupar com a ordem das funções executadas pelo GCC durante uma otimização mais alta.

Há também um vídeo de demonstração do meu lado como prova. Embora as taxas de piscamento dos LEDs sejam diferentes e periódicas no código, uma vez que todos os núcleos tentam gravar nos mesmos registros GPIO, existem alguns conflitos que fazem com que os LEDs pisquem em intervalos aleatórios.

Robomon
fonte
Experimente e veja o código-fonte htop de como eles fazem isso para mostrar dados de vários núcleos na tela.
Piotr Kula
3
@ppumkin Isso é inútil. htopé uma ferramenta baseada em * nix. No Linux, apenas obtém suas informações do kernel via /proc. Isso é coisa de metal puro. Não há nenhum kernel para consulta.
goldilocks