Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial Internet of Things >> Integrado

Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Aprenda como inicializar arrays em C usando arquivos de texto externos.

Este guia explica como popular arrays em um programa C com dados armazenados em arquivos de texto separados. Os valores não são incorporados no código-fonte; em vez disso, são carregados em tempo de compilação. Cobrimos arrays unidimensionais e multidimensionais, mostramos como controlar se o array reside na RAM ou em memória não volátil, e ilustramos como escolher entre múltiplos arquivos de dados para inicialização.

Os exemplos visam um microcontrolador ARM de 32 bits e são compilados com GCC. Todos os trechos usam C padrão e funcionam com este compilador.

Fundamentos da Inicialização de um Array

Ao declarar um array em C, você pode fornecer uma lista de valores – conhecidos como inicializadores – entre chaves. Por exemplo:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Se você omitir o tamanho entre colchetes, o compilador o infere a partir do número de inicializadores. Se o array for declarado maior que a lista de inicializadores, os elementos restantes recebem zero por padrão. Fornecer mais inicializadores que o tamanho declarado gera erro de compilação.

Espaço em Branco

Inicializadores são separados por vírgulas, e você pode adicionar livremente espaços em branco – espaços, tabs, novas linhas, retorno de carro, tabs verticais ou alimentação de formulário – entre eles. Em C, instruções podem abranger múltiplas linhas; isso é especialmente útil para arrays grandes que podem preencher várias páginas de código-fonte.


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Inicializando um Array a partir de um Arquivo

O pré-processador C pode incluir arquivos de texto arbitrários usando a diretiva #include. Esse recurso não se limita a arquivos de cabeçalho ou fonte; qualquer arquivo de texto simples é aceitável. Um arquivo simples contendo números, vírgulas e espaços em branco pode ser usado para inicializar um array:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

O arquivo incluído deve ser texto simples – sem formatação rich-text, cabeçalhos ou outros artefatos. Um exemplo rápido criado com o Bloco de Notas do Windows parece com isto:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Quando compilado, o array aparece na memória como mostrado na captura do depurador. Neste caso, o array reside na RAM, indicado pelos endereços altos na coluna "Location".


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Armazenando um Array em Memória Não Volátil e Selecionando um Arquivo de Dados

No exemplo acima, o array é uma variável global sem posicionamento explícito. O compilador assume que pode ser modificado em tempo de execução, então coloca a variável na RAM. Os valores iniciais vivem em memória não volátil (tipicamente Flash) e uma rotina de inicialização os copia para a RAM. Se o array for verdadeiramente constante, declará-lo const diz ao compilador para mantê-lo apenas no Flash, economizando RAM preciosa. A captura a seguir mostra o efeito: a "Location" do array aponta para endereços baixos do Flash.


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Você pode usar diretivas #define e #if para alternar entre armazenamento em RAM e Flash, ou para escolher diferentes arquivos de dados para inicialização. Por exemplo, o código a seguir permite escolher o local de armazenamento em tempo de compilação:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

A construção #if é um exemplo clássico de inclusão condicional. Ela determina se o qualificador const é aplicado com base em uma flag de compilação.

Da mesma forma, você pode selecionar condicionalmente qual arquivo fornece os dados iniciais:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Testando com um Array Grande

Para validar a técnica, usei uma forma de onda de ruído de 10.000 amostras armazenada em um arquivo CSV. O gráfico abaixo mostra a forma de onda, enquanto a declaração demonstra como os dados são incorporados ao programa:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda
 

O arquivo CSV original não tinha vírgulas após cada valor. Usando uma substituição com expressão regular (buscar \R e substituir por ,\R) adicionou vírgulas a todas as 10.000 entradas em uma única operação.

O array resultante é visível no depurador, agrupado ordenadamente em linhas de 100 elementos.


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Arrays Multidimensionais

Ao trabalhar com dados bidimensionais ou tridimensionais, lembre-se que C armazena arrays em ordem de linha principal (row-major). Por exemplo, um array uint16_t test[2][3] é disposto na memória como:

[0,0] [0,1] [0,2] [1,0] [1,1] [1,2]

Acessar elementos consecutivos ao longo do subscrito mais à direita é mais rápido porque os dados são contíguos. Se você precisar de dois vetores de 1.000 amostras, declare test[2][1000] para maximizar a amigabilidade ao cache.

O inicializador para um array bidimensional normalmente é agrupado com chaves aninhadas:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

No entanto, você pode omitir as chaves externas; o compilador então preenche o array da esquerda para a direita. Ele emite um aviso: missing braces around initializer. Desde que o número total de valores corresponda ao tamanho do array, o código compila.


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Para espalhar os dados em vários arquivos, simplesmente inclua cada arquivo em sequência, envolvendo a lista inteira com um par de chaves:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Inicializando Arrays em Uniões

Uma union permite que diferentes tipos compartilhem a mesma memória. Por exemplo, uma união contendo um vetor unidimensional e uma matriz bidimensional ocupa o mesmo espaço de endereço:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Ao inicializar, o compilador preenche o primeiro membro primeiro. Se a ordem for invertida, você pode ver um aviso porque a lista de inicializadores não está totalmente entre chaves. Chaves duplas ao redor do #include garantem o agrupamento correto:

O arquivo de dados para a união parece com isto:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Na memória, tanto vector quanto matrix começam no mesmo local, como mostrado no depurador:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

Você conhece outro método para inicializar um array multidimensional a partir de um único arquivo numérico? Compartilhe suas ideias nos comentários.

Dica Extra: Strings

Inicializar uma string a partir de um arquivo externo requer que as aspas estejam dentro do próprio arquivo. Um #include direto dentro do literal da string quebra o compilador. Em vez disso, coloque as aspas no arquivo e inclua-o assim:


Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda

A string resultante reside na RAM, como ilustrado na captura.

 

Firmware Embarcado: Boas Práticas para Inicializar Arrays em C com Dados de Arquivos Externos e Formas de Onda


 

Estes exemplos são teóricos e devem funcionar com qualquer compilador C padrão. Se você encontrar peculiaridades específicas do compilador, avise-nos nos comentários.

 

Fonte fornecida.

Integrado

  1. A Revolução da Nuvem: Como a Computação em Nuvem Transforma TI, Segurança e Carreiras
  2. STMicroelectronics Lança STM32Cube.AI: Redes Neurais Embarcadas para Dispositivos Edge
  3. DATA MODUL Lança Monitores Open-Frame Ultra-Bright 21.5" e 31.5" com EasyTouch para Uso Outdoor e Indoor
  4. Microchip Introduz ADCs Delta-Sigma 24-bit e 16-bit com Data Rates 153.6 kSPS
  5. Contrinex 2020: Sensores Cloud-Ready e Light Curtains Bluetooth para Segurança
  6. Arrays em C++ Desmistificados: Declaração, Inicialização e Técnicas com Ponteiros
  7. Dominando Alocação Dinâmica de Arrays em C++: Guia Prático com Exemplos de Código
  8. Lendo Arquivos em Java com BufferedReader – Guia Prático com Exemplos
  9. Dando Vida à IoT com IBM e Tech Data – Parte 2
  10. Transformando IoT em Realidade: Insights da Tech Data e IBM – Parte 1