Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial Internet of Things >> Ingebed

Ingebouwde firmwaretips:hoe arrays in C te initialiseren met signaalgolfvormen en andere bestandsgegevens

Dit artikel laat zien hoe je arrays in een C-programma initialiseert met waarden uit tekstbestanden.

Dit artikel laat zien hoe u arrays in een C-programma initialiseert met waarden uit tekstbestanden. De gegevens worden niet opgeslagen in de bronbestanden. De bestanden worden gelezen wanneer het programma wordt gecompileerd. Eendimensionale en multidimensionale arrays worden beschouwd. Voorbeelden laten ook zien hoe u kunt bepalen hoe u arrays in RAM of niet-vluchtig geheugen kunt plaatsen en kunt selecteren welke gegevensbestanden voor initialisatie moeten worden gebruikt.

De compiler die voor de voorbeelden wordt gebruikt, is GCC voor ARM met een 32-bits microcontroller als doel. Alle voorbeelden gebruiken standaard C en werkten met deze compiler.

Basisprincipes voor het initialiseren van een array

Een array kan worden geïnitialiseerd met waarden wanneer deze wordt "gedeclareerd". Een typische verklaring wordt hier getoond. De waarden binnen de accolades worden "initializers" genoemd.


Als de grootte van de array niet tussen haakjes is opgegeven, is de grootte het aantal initializers. Als er minder initializers zijn dan de grootte van de array, worden de extra elementen op 0 gezet. Het is een fout om meer initializers te hebben dan de grootte van de array.

Witte ruimte

Initializers moeten worden gescheiden door komma's. Het toevoegen van "witruimte" is OK. In dit geval is de witruimte "spaties" of spaties. De reeks witruimtetekens omvat blanco (of spatie), tab, nieuwe regel, regelterugloop, verticale tab en formulierinvoer. Nieuwe regel en regelterugloop worden gebruikt om het einde van een regel in C-broncode aan te geven. Ik ken formulierfeed maar verticaal tabblad?

Over het algemeen maakt het C niet uit of een statement witruimte bevat of op een andere regel wordt voortgezet. De verklaring hier is gelijk aan die hierboven. Het is gebruikelijk om vele, vele regels initializers te zien voor grote arrays. Misschien zelfs pagina's. Op een gegeven moment zouden we kunnen zeggen:"Is er een betere manier?"


Een array initialiseren vanuit een bestand

C-broncode wordt vóór compilatie door een preprocessor geleid. Een veelgebruikte functie van C-preprocessors is "bestandsopname". Hier is een citaat uit het beroemde boek "The C Programming Language" van Kernighan en Ritchie.

"Bestandsopname maakt het gemakkelijk om verzamelingen van #defines . te verwerken en verklaringen (onder andere ).”

Ik heb de cursieve tekst toegevoegd voor "onder andere". Hoewel we gewoonlijk ".c"- en ".h"-bestanden opnemen, geeft de preprocessor niets om de naamextensie van een bestand. Elk tekstbestand is in orde. De volgende syntaxis werkt dus om een ​​array te initialiseren.


Het bestand mag geen speciale tekens bevatten die soms verborgen zijn voor het opmaken van een document. Hou het simpel. Geen rich-text-indeling. Geen kolomkoppen. Alleen cijfers, komma's en witruimte. Hier is een bestand gemaakt met Windows Kladblok.


Hier is de array in het geheugen weergegeven met een debugger. In dit geval bevindt de array zich in RAM, zoals aangegeven door de hoge adressen in de kolom Locatie.


Een array opslaan in niet-vluchtig geheugen en een gegevensbestand selecteren

In het bovenstaande voorbeeld is de array een globale variabele en niets geeft aan waar de array moet worden geplaatst. De compiler en linker gaan ervan uit dat de array door het programma kan worden gewijzigd en dat deze in het RAM wordt geplaatst. De initiële waarden bevinden zich in niet-vluchtig geheugen ("NVM", typisch Flash-geheugen), en de array in RAM wordt op basis van deze gegevens geïnitialiseerd door code die vóór het hoofdprogramma wordt uitgevoerd. Deze gegevens in NVM zijn niet toegankelijk voor het programma. Als de array niet wordt gewijzigd (het is een "constante"), wordt deze alleen in NVM geplaatst en rechtstreeks door het programma benaderd. Dit bespaart RAM die vaak schaars is. De compiler en linker vertellen dat een array niet zal worden gewijzigd en deze in NVM te lokaliseren, wordt meestal gedaan met de "const kwalificatie. Hier is een voorbeeld en een blik op het resultaat. De kolom Locatie toont het laag in de geheugenkaart, wat voor deze microcontroller Flash-geheugen is.


De #define en #if preprocessing-instructies kunnen worden gebruikt om opties te geven voor het lokaliseren van de array en het selecteren van welke gegevensbestanden worden gebruikt voor initialisatie. Hier is een voorbeeld dat de keuze geeft om een ​​array in RAM of NVM te lokaliseren.


De #if construct is een voorbeeld van “voorwaardelijke inclusie”. In dit geval bepaalt het of de “const ” kwalificatie wordt gebruikt bij het declareren van de array. Het werkt omdat de declaratie op meer dan één regel kan staan ​​of, anders gezegd, witruimte is OK.

Hier is een voorbeeld van het gebruik van voorwaardelijke opname om het bestand voor initialisatie te selecteren.


Testen met een grote array

Ik had een groot bestand met willekeurige gegevens die een ruisgolfvorm afbeeldden en gebruikte het om de initialisatie van een grote array in NVM te testen. Hier is een plot van de gegevens en de aangifte.



Hier is het begin van het bestand.


Het originele csv-bestand had geen komma achter de waarden. Deze konden eenvoudig worden toegevoegd met behulp van een editor die uitdrukkingen kon gebruiken in zoek-/vervangbewerkingen. In dit geval heb ik de uitdrukking voor een regelscheidingsteken "\R" gebruikt. De vondst was "\R" en de vervanging was ",\R". Eén Zoek/Vervang-bewerking heeft alle komma's voor 10.000 waarden toegevoegd.

Alles werkte geweldig en zeer snel gecompileerd! Hier is het begin van de array in het geheugen. De debugger heeft het scherm netjes opgedeeld in groepen van elk 100 elementen.


Multidimensionale arrays

Wat als de gegevens in twee of meer dimensies zijn georganiseerd? Laten we eens kijken naar een tweedimensionale array gedeclareerd als uint16_t test[2][3] . In C is het rechter subscript (3) een eendimensionale array met aaneengesloten elementen in het geheugen. Het linker subscript (2) betekent dat er twee van deze arrays met drie elementen zijn. Dit is de geheugenrangschikking van de zes elementen:

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

De volgorde in het geheugen is belangrijk omdat toegang tot opeenvolgende elementen in het geheugen door het verhogen van het rechter subscript sneller is dan het openen van elementen door het linker subscript te verhogen, wat "hops" door het geheugen vereist. Als de array twee vectoren van 1000 elementen bevat, moet de organisatie test[2][1000] zijn voor de snelste toegang.

Hier is een voorbeeld van het initialiseren van een tweedimensionale array. Merk op dat de initialen zijn gegroepeerd met extra accolades die de initialen voor de eendimensionale arrays van het juiste subscript groeperen.


Dit formaat creëert een probleem voor een gegevensbestand dat alleen cijfers, komma's en witruimte mag bevatten. Wat gebeurt er als de extra accolades worden weggelaten?


De compiler vult de array door van links naar rechts door de initializers te gaan met eerst het rechter subscript. De compiler die ik gebruik geeft een waarschuwing:"ontbrekende accolades rond initializer ”. Er is geen probleem als het aantal initializers exact gelijk is aan het aantal elementen in de array. Als het echter niet gelijk is, is het niet duidelijk hoe de array moet worden gevuld als er geen accolades zijn die als richtlijn dienen.

De array kan uit meerdere bestanden worden gevuld met meerdere #include verklaringen. Hier is een voorbeeld waarbij de initialisatie volledig tussen accolades staat. Ik laat de details uit de vorige voorbeelden weg.


Arrays initialiseren in vakbonden

Een unie is een variabele die objecten van verschillende typen kan bevatten die hetzelfde geheugen delen en de compiler houdt de objecten bij alsof het verschillende dingen zijn. Deze opstelling kan handig zijn voor een embedded applicatie met een tekort aan geheugen. Hier is een voorbeeld met vector[6] met één dimensie en matrix[2][3] met twee dimensies. Het zijn twee arrays die dezelfde locaties in het geheugen innemen.


De regel voor het initialiseren van een unie is het eerste in de unie (vector[6] ) is gevuld met de initialen. Als de volgorde van de arrays is omgekeerd, geeft de compiler een waarschuwing omdat de initializers niet volledig tussen accolades staan. Let op de accolades rond de #include zijn verdubbeld. Ik denk dat de buitenste set alle initialen voor de unie bevat en de binnenste set is voor een array-type.

Hier is het bestand. Ik heb twee rijen, maar dat maakt niet uit. Gewoon meer witruimte.


Hier is de array in het geheugen. Let op de startlocatie van vector[ ] en matrix[ ][ ] zijn hetzelfde.


Zijn er andere manieren om multidimensionale arrays te initialiseren vanuit een enkel bestand met alleen cijfers, komma's en witruimte? Vertel het ons door een opmerking toe te voegen.

Bonustip:snaren

Hoe zit het met snaren? Hier is een voorbeeld van het initialiseren van een string.


Een #include tussen aanhalingstekens werkt niet. Mijn redacteur, die op de hoogte is van de C-syntaxis, geeft me veel vraagtekens en kronkelige onderstrepingen. Tekens voor de nieuwe regels en de #include zelf zijn initializers! De arme redacteur is in de war. Deze puinhoop wordt gecompileerd, maar de tekenreeks is gevuld met de tekens die we hier zien en niet uit het bestand.


De oplossing is om de aanhalingstekens in het bestand te plaatsen.


Gebruik dan een verklaring zoals deze.


Let op, de aanhalingstekens rond de bestandsnaam maken deel uit van de #include syntaxis en hebben geen controle over initializers. Hier is het resultaat in RAM.

Het is belangrijk op te merken dat de voorbeelden allemaal in theorie moeten werken met een willekeurige compiler. Sommige voorbeelden zijn echter ongebruikelijk en kunnen problemen veroorzaken bij sommige compilers. Laat het ons weten in de comments als je een probleem vindt.


Ingebed

  1. Cloud en hoe het de IT-wereld verandert
  2. ST stuurt AI naar edge en node embedded apparaten met STM32 neural-netwerk developer toolbox
  3. DATA MODUL:grote open frame monitoren met hoge helderheid en easyTouch-functie
  4. Microchip:24-bit en 16-bit ADC's met datasnelheden tot 153,6 kSPS
  5. Contrinex:cloud-ready slimme sensoren en veiligheidslichtgordijnen met Bluetooth-interface
  6. Arrays in C++ | Verklaren | Initialiseren | Aanwijzer naar matrixvoorbeelden
  7. C++ Dynamische toewijzing van arrays met voorbeeld
  8. Java BufferedReader:hoe een bestand in Java te lezen met voorbeeld
  9. Hoe IOT echt te maken met Tech Data en IBM Part 2
  10. Hoe maak je IoT echt met Tech Data en IBM Part 1
  11. Nexus Integra-verschillen met andere IoT- en Big Data-platforms