Hallo,

Ik vroeg me af hoe ik het beste volgend probleem aanpak.

Ik heb een programma dat op verschillende processoren moet kunnen lopen.
De processoren weet ik niet en er kunnen er nog steeds bijkomen.

Hoe kan ik met een minimale effort het programma op vele verschillende processoren gebruiken?

C wordt op vrijwel alle processoren ondersteunt. Dus schrijf je programma in C.

Maar zodra je iets aan IO moet gaan doen wordt je al snel afhankelijk van je processor en/of OS. Voor simpele dingen (platte tekst) kun je vaak (niet altijd) nog op de standaard C library vertrouwen, en daarna houd het op.
Je kunt proberen een glazen bol te kopen, maar die schijnen erg onbetrouwbaar te zijn.

Even als eerste vraag, wat is je ervaring met embedded systems ontwikkeling? Ik veronderstel dat dit in C gaat gebeuren.

Wat bedoel je met verschillend? Zijn het verschillende ARM processoren van dezelfde fabrikant? Verschillende fabrikanten? Of compleet verschillend dus, ARM, AVR en MIPS? Dit om een beetje een beeld te krijgen hoe ver je moet gaan.

Dit is belangrijk zodat je weet wat voor compiler infrastructuur er aanwezig zal zijn.

In C maak ik meestal een board.h aan die afhankelijk van de juiste build target de juiste board_type.h include, deze definieert vaak de processor, dat is een bord afhankelijk iets namelijk.

Hier heb ik het nog niet over gehad over hoe je de periferie gaat abstraheren. Dit kan nog even goed denkwerk vereisen zeker als de periferie wezelijk anders is per architectuur.

Ik probeer altijd abstracties zo op te zetten dat deze niets kosten qua ruimte en reken cycli, of desnoods minimaal. Je kan al heel ver komen met slim gebruik van inline en macros in C, maar dit is al wel gevorderd C gebruik.

Aangepast zal het programma altijd wel moeten worden bij embedded processors, kans dat het zo werkt is bijna nul...
(er zijn altijd interne verschillen qua opbouw en peripherals)

Tegenwoordig is er een flinke trend om HAL (Hardware Abstraction Layers) functies te gebruiken.

Deze HAL functies schrijf je specifiek voor iedere processor, en vervolgens spreekt je applicatiecode enkel HAL functies aan. Zodoende is de applicatiecode universeel.

Over de gehele ARM range is hier veel voor gebruikt, maar denk bijvoorbeeld aan de functie GPIO_Write(pin, state); waarbij pin een define kan zijn (platform specifiek of niet eens).

enter the HAL: Hardware Abstraction Layer..

Als je in C werkt, dan kun je voor (bijna) elke processor compileren. Echter: Indien er IO is, dan is dat altijd verschillend per processor. Dan kun je een HAL maken: Een abstrahering van bijvoobeeld de I/O 's naar een set van variabelen (bijvoorbeeld een array van digitale inputs). ZO hoef je bij porten naar een volgende setup alleen de HAL voor die setup te maken, en kun je het eigenlijke programma ongemoeid laten.

Zie ook: https://en.wikipedia.org/wiki/Hardware_abstraction

Dat is op papier heel mooi en aardig, maar valt in de praktijk toch bitter tegen; is ook een hoop werk.
(Windows is in beginsel ook als een multi-platform systeem begonnen, maar daar is weinig meer van over...)

Wij doen het al jaren.. en werkt prima. We doen veel PC gebaseerd (non-realtime) besturingswerk, via verschillende IO platforms. Switchen tussen platforms is nu simpel: Alleen de HAL herschrijven...

@Arco & @fripster

Inderdaad met een Hal maak je een abstractie van je periferie/IO. Een UART is over het algemeen hetzelfde, idem met een ADC en GPIO. Als je meer geavanceerdere features van een processor gaat gebruiken, kan je bijna niet omheen om de periferie op een lager niveau te gebruiken. Dit kan je lastig verbergen, DMA als voorbeeld, sommige processoren hebben een event handling systeem voor hun DMA, anderen hebben weer een soort van scatter gather DMA.

Voor de Cortex-M processoren geven veel fabrikanten een CMSIS library mee, desnoods met hun eigen sausje (NXP heeft LPCopen).

Een goed ontworpen HAL zou als het goed is, nul overhead moeten hebben.

Ik begin van (bijna) 0
Ik heb wel wat kennis van C en processoren maar dat zit redelijk diep :s

Wat ik nu vooral wil kunnen is UART ADC/DAC en GPIO

Welke software gebruiken jullie ? Waar kan ik een begin van de HAL libraries vinden?

Processoren kunnen compleet verschillen

daar is JAVA ooit voor bedacht.

Zelf vindt ik het een COMPLEET drama en eigenlijk ook een FLOP....Maar das persoonlijk.

de UART gaat wel lukken, de ADC en DAC en GPIO zal lastig worden, daar dat geen std. port is...

@falaigai:
Ik zou dan eerst gewoon beginnen met een programma en pas later denken over overdraagbaarheid tussen processoren. Je kan met dit het beste stapje voor stapje doen en met vragen hier komen.

CMSIS is een voorbeeld van een HAL library voor de cortex M processoren. Maar vaak genoeg zal je dit zelf moeten maken.

Voorbeeldje van een HAL voor een UART is dat je altijd een initialisatie functie hebt, waar je baud rate, bits, party enzo instelt. Iets om characters uit te lezen, characters schrijven en de UART status uit kan lezen.

Je definieert een paar functies voor de functionaliteit van hierboven. Deze implementeer je voor een van je platforms. Ik zou dan ook eens beginnen met een hele simpele UART implementatie, niet met interrupts en dergelijke. Hiermee leer je een beetje de begin abstracties te maken.

Ik heb vroeger veel AVR gebruikt maar nu ben ik helemaal overgestapt op de LPC ARM microcontrollers van NXP. Ik heb een hele set van de development boards liggen omdat ik vroeger voor NXP heb gewerkt. De ontwikkel omgeving is daar LPCxpresso maar je ziet dat veel processoren onderhuids de GCC compiler gebruiken. AVR, ARM en geloof de MIPS processoren van microchip gebruiken die allemaal onderhuids.

@High met Henk:

ADC valt nog wel mee? Je initialiseert, zet een multiplexer voor een bepaalde poort pin die je in je board.h hebt gedefineerd, start de conversie en en leest het resultaat uit. Heel simpel, niets nog met interrupts.

Later zou je het complexer kunnen maken met bufferen, periodiek vuren, circulaire buffers om meetwaarden te bufferen, etc. Simpel beginnen bij zoiets en stapje voor stapje werken. Big bang in een keer alles maken, werkt vaak niet zo goed. Je maakt het dan veel te complex met veel overbodige functionaliteit of heel ondoorzichtig en traag.

Welke software gebruiken jullie ?

De compiler die bij de betreffende processor hoort. Er zijn er die meerdere ondersteunen, maar meestal heeft iedere familie zijn eigen (c of andere) compiler/assembler.
Da's ook nog een punt: C is niet altijd C. De syntax kan verschillen (zeker qua preprocessor), dus dat moet dan aangepast worden.

Simpele begin van een HAL file vindt je bijvoorbeeld al bij de PIC's; iedere pic heeft een eigen .inc file die zijn interne structuur beschrijft.
Voor portabiliteit moeten processoren natuurlijk wel redelijk compatible zijn; je kunt niet verwachten dat ze iets doen wat ze niet kunnen...

Een HAL speciaal voor beginners bestaat ook: Arduino.

(oke, arduino is meer dan alleen een HAL. Maar Arduino's 'digitalWrite' en 'Serial.print' werken op ieder ondersteund platform hetzelfde)

#squant: hoe initialiseer je een ADC als je de hardware niet kent?
Kijk een UART kun je in java als en seriele (COM) port benaderen en afvangen.
Ethernet en USB ook.

MAar ik zou niet weten of JAVA zomaar IO of ADC's ondersteund.. denk het niet..

High met Henk:
Natuurlijk zal je zelf de Hal driver moeten maken. Het gaat er meer om dat veel ADC periferie veelal hetzelfde werkt. Vaak zijn dingen zoals DMA triggering, event matrixen en andere "non standaard" dingen wel erg lastig te vertalen naar puur een HAL.

Ook niet echt een idee, maar Java op een embedded device vind ik ongeschikt eigenlijk.

@Blurp:
Dat is inderdaad een goeie, arduino werkt op AVR, MSP430 en ARM.

@HmH: Ondersteund Java UARTS? Volgens mij niet, er zijn alleen libraries/classes die de UART functies van een onderliggend OS gebruiken.

Een "standaard" interface voor DAC/ADC's bestaat ook: sound-drivers. Alleen die is veel te zwaar voor de meeste embedded systemen.

En dat is gelijk een makke van een HAL: Wat voor de ene toepassing te weinig features heeft, heeft er teveel voor de andere.

...arduino werkt op AVR, MSP430 en ARM

MikroE compilers werken op PIC, AVR, 8051, ARM, FT90x...

Op 28 september 2015 21:31:19 schreef Squant:
[...]

Ook niet echt een idee, maar Java op een embedded device vind ik ongeschikt eigenlijk.

Persoonlijk ik ook. Maar JAVA draait op een virtual machine (JAVA VM) en die is voor elke hardware anders.

Java is juist bedoeld om VOLLEDIG platform onafhankelijk in de embedded wereld te gebruiken. Dat is de oorspronkelijke doelstelling van JAVA. Dus je hebt ergens een stuk HW. Daarop draai je de JAVA VM. en dan is het programma overal hetzelfde..

met dat in gedachte is JAVA ooit geschreven!
lees even de eerste 3 alinea's:
https://nl.wikipedia.org/wiki/Java_%28programmeertaal%29

@ blurp:
Ja dus, en niet via het OS. Onze kopieermachine heeft niet eens een OS, Maar wel een VM draaien. Je moet dat wel doen via een lib of een class in java of je moet zelf tegen die VM gaan praten...

Die hele VM is ook hetgene wat java kwetsbaar en zwaar maakt. Je draait feitelijk op een bestaand OS nog een interface... Of op je normale uC nog een extra interface. afhankelijk welk HW platform je hebt... trager wordt het altijd

En dat is 1 van de redenen dat het niet mij kopje thee is (grappig in dit verband het logo van java is een kopje koffie, Java is zoals hierboven te lezen is ook vernoemd naar koffie)

De tweede reden is dat ik helemaal gek werd van alle classen, libraries en objecten die er standaard al zijn.. Ik zie door de bomen het bos niet meer.

Mijn bijnaam in de elektronica is niet voor niets BITN**KER.

Maar ik heb toen ik leerde programmeren altijd geleerd: JAVA is de enige platform onafhankelijke programmeertaal.
C werkt wel maar moet je nog door de compiler halen... en die maakt het HW specifiek (elke HW kent een eigen C compiler)
Java kent dat niet. er is maar 1 compiler. Staat trouwens ook in de link (JAVA vs C++)

De andere taal die standaard bytecode gebruikte en in theorie portabel was, is al een hele tijd niet meer nieuw in het wild gesignaleerd. Ik heb het natuurlijk over Microsoft Basic ;)

En ik herken het bitneukergedeelte misschien wel; in assembler ben ik het overzicht veel minder snel kwijt dan in Java...

Overigens wordt op de wikipagina iets teveel eer gegeven aan Android; op Nokia S40 en Symbian was Java ook relatief populair, al was voor de zwaardere apps het voor Symbian gecompileerde werk wel in het voordeel.

Ja viel mij ook al op.. Her en der is nogal schromelijk overdreven met dat JAVA niet aan zou slaan in het verleden... De enige kracht van JAVA is feitelijk het platform onafhankelijke EN als je er van houdt dat er heel veel voorgebakken is. (niet mijn kopje thee dus, maar kan wel een heel sterk voordeel zijn)

Op 29 september 2015 03:55:13 schreef High met Henk:
Maar ik heb toen ik leerde programmeren altijd geleerd: JAVA is de enige platform onafhankelijke programmeertaal.

Dat ben ik niet met je eens. Vrijwel iedere fatsoenlijke (hogere) taal is platform-onafhankelijk. Toen C ontwikkeld werd bestonden er geeneens embedded processoren, laat staan AVR, ARM, PIC...

Het is eigenlijk alleen de IO en de hoeveelheid rekenkracht die verschillen tussen processoren. Beiden staan los van de taal bij zowel C, als Java, als Lisp.

C werkt wel maar moet je nog door de compiler halen... en die maakt het HW specifiek (elke HW kent een eigen C compiler)
Java kent dat niet. er is maar 1 compiler.

Die VM is HW specifiek. Of je nu door de hond of door de kat gebeten word...

Wel degelijk een HEEL groot verschil of je een VM draait of dat je eerst je code opnieuw moet compileren...

En dat is precies wat ik aan wilde geven. bij compileren voor andere hardware moet je registers en adressen ook ineens anders noemen. de VM lost dit ALLEMAAL voor je op. en dat zonder te ook maar iets opnieuw te compileren.

nogmaals: JAVA is niet mijn taal en ik heb er een pest hekel aan, maar het lost wel AL je problemen op

en idd de std routines in C werken allemaal hetzelfde. maar libraries, classes enzo zijn meestal niet 1 op 1 te gebruiken cross platform. omdat de registers en adressen totaal anders zijn en soms zelfs de totale wijze van benaderen van hardware.

@HmH: Voor je portabiliteit maakt het niet uit dat je opnieuw moet compileren.

De Java VM lost niets voor je op. Een aantal libraries (classes) "lost" iets op (tekst op terminal, UART, disk I/O), maar diezelfde dingen worden ook door de standaard C library opgelost.

De adressen en registers e.d. hebben niets met de taal te maken. Een self-hosted Java omgeving (dus een Java VM+libraries die zelf ook in Java geschreven is, netzoals een C-compiler en C-library ook in C geschreven (kunnen) worden) zal dezelfde adressen en registers nodig hebben

Pas als je naar een PC-platform gaat (windows, linux) heeft gebruik van Java portabiliteitsvoordelen, omdat beide OS'en een redelijke Java implementatie hebben. Maar daarmee kun je alleen de standaard PC-io, en dus nog geen ledje besturen.

Dat was PRECIES mijn betoog wat je nu zegt: De seriele poort (UART) gaat wel lukken. De USB en ethernet ook wel

er zijn ook uC? met HW ethernet en USB als je daar een VM op draait werkt dat ook probleemloos daar hoef je ECHT geen heel OS voor te hebben.

Met C of om het even welke andere taal die apart gecompileerd moet worden door een HW specifieke compiler zou ik daar toch echt wel andere zaken (registers of adressen daarvan) voor moeten instellen. de ene ethernet interface (heb ik het niet eens over de PHY)

Maar de GPIO en ADC zijn waarschijnlijk niet gedefinieerd, zoals ik al eerder betoogde.

Echter ik heb ervaring met de TINI van dallas en dat was software op de PC schrijven, naar de uC poorten en de uart en ethernet werkten meteen.