Trabalho com um STM32F2 (especificamente, o STM32F217IGH6 em uma placa de desenvolvimento) há cerca de dois meses. De longe, meu maior problema tinha a ver com a "configuração", que inclui makefile, script de vinculador e arquivo de inicialização.
Em particular, não consegui configurar corretamente minha tabela de vetores de interrupção e chamei os manipuladores de interrupção. A ST fornece exemplos personalizados para IDEs comerciais. Em vez disso, estou usando a recompilação gratuita do Yagarto da cadeia de ferramentas GCC (e do OpenOCD para carregar a imagem via JTAG).
Existem exemplos de projetos para minha diretoria (ou um primo próximo dela) que contenham a combinação apropriada de makefile, script de vinculador e arquivo de inicialização para IDEs não comerciais configurados para que os manipuladores de interrupção sejam chamados?
Respostas:
http://github.com/dwelch67
stm32f4 e stm32vld em particular, mas os outros também podem ser úteis para você. mbed e o diretório mzero em mbed (córtex-m0).
Eu gosto de manter uma abordagem simples e estúpida, scripts mínimos de vinculador, código mínimo de inicialização etc. O trabalho é feito pelo código e não por qualquer cadeia de ferramentas específica.
A maioria das formas de gcc e binutils (capazes de usar o polegar) funcionará um pouco com esses exemplos, pois eu uso o compilador para compilar não como um recurso para chamadas de biblioteca, não uso scripts de vinculador de ações etc. O gcc e binutils mais antigos não sabem sobre as partes mais recentes do thumb2, portanto, algumas alterações podem ser necessárias.
Eu construo meu próprio gcc, binutils e llvm / clang, além de usar o codesourcery, por exemplo (agora mentor dos gráficos, mas você ainda pode obter a versão free / lite).
Esp Ao começar a montar um projeto para um novo alvo, você precisa desmontar. Em particular, para garantir que os itens estejam onde você deseja, a tabela de vetores, por exemplo.
Veja stm32f4d / blinker02 por exemplo. Começa com vectors.s, a tabela de exceção / vetor, além de algumas rotinas de suporte asm:
Sem interrupções neste exemplo, mas as outras coisas que você precisa estão aqui.
O blinker02.c contém o corpo principal do código C com o ponto de entrada C que eu chamo de notmain () para evitar chamá-lo de principal (alguns compiladores adicionam lixo ao seu binário quando você tem um main ()).
você vai economizar um recorte e colar. o makefile conta a história sobre compilação e vinculação. Observe que vários dos meus exemplos compilam dois ou mais binários do mesmo código. compilador gcc, compilador clang do llvm, thumb only e thumb2, otimizações diferentes etc.
Comece criando arquivos de objeto a partir dos arquivos de origem.
o vinculador, ld, usa um script vinculador que eu chamo de memmap, que pode ser extremamente doloroso, às vezes por uma boa razão, às vezes não. Prefiro que menos seja mais abordagem para o tamanho único, tudo, menos a abordagem da pia da cozinha.
Eu não uso .data normalmente (bem quase nunca) e este exemplo não precisa .bss, então aqui está o script do vinculador, apenas o suficiente para colocar o programa (.text) onde ele precisa estar para esse processador do jeito que eu sou usando isso.
Eu tenho uma região de memória para definir isso, não há nada de especial no nome ram que você pode chamar de foo ou bar ou bob ou ted, não importa, apenas vincula os itens de memória às seções. As seções definem coisas como .text, .data, .bss, .rodata e para onde elas vão no mapa de memória.
quando você constrói isso, você vê que eu desmonte tudo (objdump -D) você vê isso
O ponto principal a ser observado é que o endereço à esquerda é o local onde desejávamos, o código vectors.s é o primeiro no binário (como é o primeiro na linha de comando ld, a menos que você faça algo no script do vinculador, os itens serão mostrados no binário na ordem em que estão na linha de comando ld). Para inicializar corretamente, você deve garantir que sua tabela de vetores esteja no lugar certo. O primeiro item é o endereço da minha pilha, tudo bem. O segundo item é o endereço para _start e deve ser um número ímpar. o uso de .thumb_func antes de um rótulo faz com que isso aconteça, assim você não precisa fazer outras coisas feias.
portanto, 0x08000051 e 0x08000057 são as entradas de vetor adequadas para _start e travar. iniciar chamadas não principais ()
Isso parece bom (eles não mostram o endereço numerado ímpar na desmontagem).
Tudo está bem.
Vá para o exemplo blinker05, este suporta interrupções. e precisa de um pouco de ram, então .bss é definido.
lembre-se ram e rom são nomes arbitrários, bob e ted, foo e bar funcionam bem.
Não mostrará os vetores inteiros porque o córtex-m3 possui um zilhão de entradas na tabela de vetores se você fizer um completo (varia de núcleo para núcleo e talvez dentro do mesmo núcleo, dependendo das opções escolhidas pelo fornecedor do chip) As partes relevantes estão aqui após a desmontagem:
é preciso algumas tentativas e erros para colocar o manipulador exatamente no lugar certo, verifique com o seu chip onde ele precisa estar, não necessariamente no mesmo local que este e, com tantas interrupções, você pode estar procurando uma interrupção diferente. os processadores córtex-m, diferentemente dos braços normais, fazem com que você não precise de códigos de trampolim para interrupções, eles preservam um certo número de registros e gerenciam a alternância de modos de processador através do conteúdo do registro de links. desde que o hardware e a abi do compilador estejam próximos o suficiente, tudo funcionará. Neste caso, eu fiz o manipulador em C, ao contrário de outras plataformas e no passado, você não precisa fazer nada de especial com o compilador / sintaxe, basta criar uma função (mas não faz coisas estúpidas na função / manipulador)
O makefile para blinker05 deve se parecer com o exemplo blinker02, principalmente recortar e colar para a maioria deles. transforme os arquivos de origem individuais em objetos e vincule-os. Eu construo para thumb, thumb2 usando gcc e clang. você pode alterar a linha all: no momento para incluir apenas os itens do gcc se não tiver / deseja clang (llvm) envolvido. Eu uso binutils para montar e vincular a saída clang btw.
Todos esses projetos usam ferramentas gratuitas, prontas para uso, de código aberto. sem IDE, apenas linha de comando. Sim, eu apenas mexo no Linux e não no Windows, mas essas ferramentas também estão disponíveis para os usuários do Windows, alteram coisas como rm -f algo para deletar algo no makefile, coisas assim ao criar no Windows. Isso ou execute o linux no vmware, no virtualbox ou no qemu. Não usar um IDE significa que você escolhe seu editor de texto também, não vou entrar nisso, tenho meus favoritos. Note que uma característica extremamente irritante do programa gnu make é que ele requer abas reais no makefile, eu odeio abas invisíveis com paixão. Então, um editor de texto para makefiles que sai de abas, outro para código fonte que cria espaços. Eu não sei sobre janelas,
Espero que isso ajude, não é o chip / placa exato, mas um córtex-m4 bem m4 não m3, perto o suficiente para esta discussão. veja o dir mbed ou stm32vld para um córtex-m3 real (não há diferenças suficientes do m4 para makefiles e código de inicialização, etc.), mas não é feito por st. Os núcleos do córtex-m3 devem ser os mesmos entre os fornecedores, o córtex-m3 e o córtex-m4 são ambos ARMv7m e estão mais próximos do que diferentes. O córtex-m0 é um ARMv6m, dificilmente tem instruções para o polegar2 o suficiente para se preocupar, os compiladores não o alcançaram; portanto, use apenas o polegar (finja que você está construindo para um ARMv4T (apenas polegar), se necessário). Meu simulador de polegar é apenas polegar, sem polegar2, pode ser útil para você também, acho que o fiz executar interrupções de alguma forma ou moda.
fonte
Você pode dar uma olhada neste site, onde ele tenta explicar o básico do vinculador e low_level_init no código.
Observe que a página está focada na descrição do problema, portanto o vetor nvic é mínimo.
Então você tem exemplos mais completos na "biblioteca de periféricos padrão STM32F2xx", basta olhar nas seções gcc (já que o Yagarto é baseado no gcc). E há um código de exemplo que o ajudará com uma configuração correta da nvic (tabela de vetores de interrupção).
Portanto, mesmo que essa não seja uma resposta completa, espero que seja útil.
fonte