Apresentação
Iniciaremos uma série que abordará a configuração do Linker respectivo a um projeto no ambiente do IAR.
Partiremos de um projeto gerado pela ferramenta STM32CubeMX, visando a utilização da STM32F0Discovery kit para o próprio ambiente em questão. Vale ressaltar que a sistemática apresentada aqui transcende arquiteturas e/ou hardwares.
Serão demonstrados os meios (configuração realizada diretamente no arquivo ou usando recursos gráficos) e também o que pode ser configurado (endereços e tamanhos de memórias Flash – vetor de interrupção – e RAM – stack e heap).
Portanto, o conteúdo apresentado aqui será para aqueles que já possuem certa experiência em desenvolvimento em sistemas embarcados, logo não serão apresentados conceitos de Linker e compilação, muito menos a demonstração do funcionamento das ferramentas descritas. Para saber mais sobre o Linker, leia este artigo.
Requisitos
Para fácil entendimento e reprodução do conteúdo, serão necessários:
- Conhecimentos em linguagem C e diretivas de compilação;
- Familiaridade com STM32CubeMX e IAR;
- STM32F0 Discovery kit e um conversor Serial / USB;
- IAR versão 8.22 e STM32CubeMX versão 4.24.
Propósito
A necessidade em configurar o Linker vem de situações em que a aplicação que está sendo desenvolvida requer endereços e tamanhos de memórias específicas, por exemplo: aumento do tamanho do heap e/ou stack, escolha de endereço de uma variável do tipo struct na memória RAM, escolha de endereço de uma rotina a ser alocada na Flash, um projeto que contém um Bootloader e Aplicação, etc.
Projeto gerado no STM32CubeMX
Requisitos do projeto STM32CubeMX para o ambiente IAR são:
- STM32F0DISCOVERY (Board Selector), cujo Mounted Device é o STM32F051R8Tx;
- Habilitar USART1 (Mode Asynchronous). Vide figura 1.
Feito isto, gere os códigos fontes para o EWARM (ambiente IAR).
IAR
Acesse o diretório no qual o projeto gerado pelo STM32CubeMX foi salvo e em seguida abra o diretório “EWARM”. Feito isto, execute “Project”, cuja extensão é .eww, e que provavelmente terá um ícone do IAR.
Logo, o software será automaticamente executado e a árvore do projeto terá a aparência da figura 2. Nesta mesma figura observamos que o diretório Output contém um arquivo chamado stm32f051x8_flash.icf. Este é o arquivo do Linker, no qual faremos a configuração.
Abra o arquivo com a extensão .icf para edição, logo o ambiente terá a aparência a seguir (figura 3):
Na primeira linha do arquivo podemos ver a seguinte frase:
“Section handled by ICF editor, don’t touch!”
Que, em tradução livre, significa:
“Seção manipulada pelo editor ICF, não toque!”
Mas como sabemos o que estamos fazendo, daremos sequência no conteúdo 🙂 . Brincadeiras à parte, no IAR, as modificações realizadas manualmente no arquivo do Linker podem ser visualizadas no recurso gráfico do ambiente e vice-versa. Por isso que podemos executar a alteração do parâmetro escolhido sem preocupações, mas vale a pena fazer uma observação: isso apenas pode ser feito por aqueles que possuem experiência ou que leram este artigo, caso contrário, o não ou mal funcionamento pode ocorrer.
A seguir, faremos o detalhamento da figura 3:
Definição do endereço do vetor de interrupção
/*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08000000;
Definição dos endereços iniciais e finais das memórias Flash e RAM do STM32F051R8Tx
/*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0800FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x20001FFF;
Definição do tamanho das regiões de Stack e Heap
/*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x200;
Definição de 4G bytes de memória endereçável
define memory mem with size = 4G;
Definição das regiões das memórias Flash e RAM
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
Definição do alinhamento dos blocos de Stack e Heap
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
* size pode ser definido como: 1k, 2k, 4k. etc.
Determinar o tipo de acesso ao conteúdo alocado
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite, block CSTACK, block HEAP };
Os nomes das variáveis (todas) podem ser escolhidos da mesma forma que uma variável em um código em linguagem C, facilitando o entendimento do propósito daquela configuração.
Assim como em C, os números em hexadecimal à direita do caractere de igual “=” remetem a valores atribuídos à respectiva variável. Assim, pode-se alterar (seguindo os limites impostos pelo fabricante) sem que ultrapasse os limites das regiões memórias.
Conclusão
Entender o propósito e como alterar as configurações do Linker é de extrema importância para desenvolvimento, mesmo que haja diferenças no formato do arquivo para diferentes compiladores, plataformas ou IDEs, porém o entendimento absorvido pode ser aproveitado.
Além disso, possibilita e flexibiliza todo o mapa de memória do seu projeto, deixando-o organizado e atendendo as necessidade e requisitos de projetos.
No próximo artigo determinaremos regiões específicas de regiões de memórias Flash e RAM, aumentando a experiência e aproximando o leitor de condições reais de projetos, confirmando essas alterações no arquivo .map.
Saiba mais
IAR C/C++ Development Guide – página 80












