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.
fonte
Respostas:
Atualização 25 de outubro de 2015:
Fórum Raspberry Pi deu a resposta para mim .
Não há conceito de _start ao usar -nostdlib
o código a ser executado primeiro deve ser o primeiro arquivo a ser passado ao vinculador.
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_start
função) com-O2
otimização. Ainda assim, minha pergunta abaixo sobre o stackoverflow em relação ao_start
sí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:
_start
sí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.
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 que0x8000
haveria 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 à-O2
otimizaçã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ço0x8000
, 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 _start
virá. 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.
fonte
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.