PIC C-Compilervergleich

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Da im Forum öfter diskutiert und behauptet wurde, habe ich mir vorgenommen ein paar gängige C-Compiler für die PICs zu vergleichen. Der Auslöser für mich war, als ich endlich wissen wollte, was nun stimmt: Ist der Microchip C-Compiler in der Free-Version nun unbrauchbar oder ist die Optimierungsbegrenzung vernachlässigbar. Und da ich schon dabei war, habe ich gleich andere Compiler mit ins Boot genommen. Meine Vorgabe war ein selbsterstelltes Programm, dass nur so zum Optimieren einläd. Ich wollte aber nur Syntax-Anpassungen machen wollen, sodass ich ggf. auch gucken kann, welches Programm welche PICs nicht unterstützt. Aus diesem Grund habe ich mich auch bemüht relativ neue PICs zu nehmen.

Compiler

PIC12/16/18

xc8-cc

Version: 2.00 (Juni 2018)
Unterstützt: PIC10/12/16/18
Erfordert: Windows Vista oder neuer; Linux X86, MacOS (ungetestet)
Im Gegensatz zu XC8 1.x (s.u.) ist die Gesamtfunktionalität schon deutlich näher an avr-gcc, was das Umsteigen erleichtert! Kommandozeilensyntax, ELF-Output (statt COFF) und C99-Kompatibilität sind ordentlich. XC8-1.x-Quelltexte bei Interruptroutinen und Inline-Assembler müssen / sollten umgeschrieben werden. Leider kein C++. Lizenzierungsgebaren unverändert. Nerv-Output ("Kaufen Sie die PRO-Version") ist endlich weg. Standardmäßiger C-Compiler von Microchip, enthält mittlerweile avr-gcc.
Download-Größe: 230 MByte
Installationsgröße: 1,8 GByte (vor allem durch dusselig strukturierte, nämlich platte .H-Dateien)

XC8

Version: 1.30, MPLAB X 2.05
Unterstützt: PIC10/12/16/18
Preis (Standard/Pro): 495$ / 995$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 60-Tage PRO Version
Sonstiges: Ich habe mich für die XC-Reihe entschieden, da die C18,C30 und C32 von diesen abgelöst werden sollen. Standardmäßiger C-Compiler von Microchip.

Hi-Tech C for PIC10/12/16

Version: 9.83, MPLAB X 1.51
Unterstützt: PIC10/12/16
Preis (Standard/Pro): 495$ / 1195$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 45-Tage PRO Version

Hi-Tech C for PIC18

Version: 9.80, MPLAB X 1.51
Unterstützt: PIC10/12/16/18
Preis (Pro): 1195$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 45-Tage PRO Version

SDCC

Version: 3.2.0
Unterstützt: PIC16/18
Sonstiges: Dieses Programm ist Freeware. In der Konsolenausgabe wird wie beim cc5x-Compiler eine Beschreibung der Parameter ausgegeben, sehr unübersichtlich.
Am Target PIC16 ist keine warnungsfreie Compilierung möglich. Maschinenkode größer als beim Microchip-Compiler XC8 freie Version (ohne Optimierung), daher nahezu nutzlos. Scheint noch Bugs zu haben, beispielhafter Quelltext für XC8 führte zu nicht lauffähigem Maschinenkode.

PIC-C PCWHD

Version: 4.136d
Unterstützt: PIC10/12/16/18/24/dsPIC
Preis (Pro): 600$
Beschränkung der Freiversion: Wie Vollversion, jedoch nur 15% der Beispielcodes und nur 45 Tage nutzbar, danach garnicht (nichtmal ohne Optimierungsoptionen).
Sonstiges: Ich finde, dass der Wizard beim Erstellen eines Projektes sehr komplex, jedoch auch übersichtlich ist. Dort können Konfigurationsbits gesetzt werden, aber auch Timer, Module, IOs usw konfiguriert werden. Leider ist dieses Menü nach dem "Fertig"-Klicken nicht mehr aufrufbar. Der Compiler hat eine eigene IDE.

CC5X

Version: 3.4H
Unterstützt: PIC12/16
Preis (Standard): 250€
Beschränkung der Freiversion: 32768 instructions, nur 16bit signed/unsigned int und 24bit float.
Sonstiges: Bei diesem Compiler konnte ich leider nur die Freiversion testen und diese konnte wie der SDCC nichts mit double anfangen. Auch ist keine Lib wie math.h dabei. In der Freiversion nur 3 Datentypen zu haben und die dann auch noch 2-3Byte groß sind, finde ich eher nicht so üppig. Wenn jemand die Vollversion von cc5x und/oder cc8e hat, der kann sich gerne bei mir melden (Hier) und ich schicke ihm mein Quellcode. Er kann natürlich auch gerne den Code weiter unten kopieren.

CC8E

Version: 1.3E
Unterstützt: PIC18
Preis (Standard): 250€
Beschränkung der Freiversion: 131072 instructions, nur 16bit signed/unsigned int und 24bit float.
Sonstiges: Siehe CC5X

MikroC for PIC

Version: 5.6.1
Unterstützt: PIC12/16/18
Preis (Pro): 199$
Beschränkung der Freiversion: max. Flash-Speicher 2048 Byte
Sonstiges: Diesen Compiler kenne ich wohl am besten, da ich ihn auch bisher ausschließlich benutzt habe. 2kB als Code-Grenze ist gerade bei PIC18er nicht gerade viel, jedoch reicht es für viele Projekte aus. Dazu sind die MikroC Compiler in der Voll-Version die günstigsten. Der Compiler kommt mit einem m.M. nach guten Konfigurator und auch mit diversen Standard-Libs und PIC-Bezogenen Bibliotheken. Der Compiler hat eine eigene IDE.

WIZ-C, SourceBoost

Diese beiden Compiler hab ich auch getestet, jedoch hatte SourceBoost z.B. keine Math-Lib und mit WIZ-C bin ich irgendwie nicht zurecht gekommen


PIC24/dsPIC

XC16

Version: 1.21, MPLAB X 2.05
Unterstützt: PIC24/dsPIC
Preis (Pro): 995$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 60-Tage PRO Version

Hi-Tech C for PIC24 & dsPIC

Version: 9.62, MPLAB X 1.51
Unterstützt: PIC24/dsPIC
Preis (Standard): 895$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 45-Tage Standard Version

PIC-C PCWHD

Siehe "PIC-C PCWHD" unter "PIC12/16/18".

MikroC for dsPIC/PIC24

Version: 5.7.0
Unterstützt: PIC24/dsPIC
Preis (Pro): 199$
Beschränkung der Freiversion: max. Flash-Speicher 6144 Byte

PIC32

XC32

Version: XC32 1.31, MPLAB X 2.05
Unterstützt: PIC32
Preis (Pro): 995$
Beschränkung der Freiversion: Begrenzte Code-Optimierung (maximal -O1), 60-Tage PRO Version. Keine Code Größen Beschränkung und keine Einschränkung für die Verwendung der Freiversion in kommerziellen Produkten

Hi-Tech C for PIC32

Version: 9.62, MPLAB X 1.51
Unterstützt: PIC32
Preis (Pro): 1495$
Beschränkung der Freiversion: Begrenzte Code-Optimierung, 45-Tage Standard Version

MikroC for PIC32

Version: 2.5.1
Unterstützt: PIC32
Preis (Pro): 249$
Beschränkung der Freiversion: max. Flash-Speicher 8192 Byte

Programmbeschreibung

char arr[5] = {1, 2, 3, 4, 5};
char gleiches_arr[5] = {1, 2, 3, 4, 5};
const char teilsgenutztes_arr[5] = {10, 20, 30, 40, 50};
const char ungenutztes_arr[5] = {3,2,5,3,1};

void sinnlose_funktion(char i){
	i++;
	return;
}

int unaufgerufene_funktion(double a){
	int erg;
	erg = a / 10;
	return erg;
}

char f1(){
	char var_in_f1;
	var_in_f1 = PORTA * 3;
	PORTA = 0;
	if(var_in_f1 > 18) return 18;
	else return 0;
}

char f2(){
	char var_in_f2;
	var_in_f2 = PORTB * 5;
	PORTB = 0;
	if(var_in_f2 > 30) return 30;
	else return 0;
}

void main(){
	char fuer_pointer = 5, i;
	char *ptr;
	char boolsch1 = 0, boolsch2 = 0;
	bit b1, b2, b3;
	int zahl1 = 0xFA00, zahl2;
	double kommazahl1, kommazahl2;
	
	ptr = &fuer_pointer;
	*ptr = f1() + f2();
	PORTB = *ptr;
	
	b1 = 0;
	b2 = 0;
	b3 = 0;
	
	if(PORTB > 30){
		boolsch1 = 1;
		b1 = 1;
	}
	if(PORTB == 0){
		boolsch2 = 1;
		b2 = 1;
	}
	if(boolsch1 && boolsch2){
		PORTB = 255;
		b3 = 1;
	}
	if(b1 && b2 && b3) PORTB = 0;
	
	zahl1 |= PORTB;
	zahl2 = zahl1 / 40000;
	
	kommazahl1 = PORTA / 255.0;
	kommazahl2 = PORTB / 255.0;
	
	fuer_pointer = kommazahl1 / kommazahl2;
	
	sinnlose_funktion(zahl2+kommazahl2);
	
	for(i=0; i<5; i++){
		PORTB = arr[i];
	}

	for(i=0; i<5; i++){
		PORTB = gleiches_arr[i];
	}

	PORTB = teilsgenutztes_arr[2];

	if(sqrt(PORTA) > 3) PORTB = 1;			//PIC12/16/18/24/32/dsPIC
	if(log(PORTA) < 2) PORTB = 5;			//PIC12/16/18/24/32/dsPIC
	if(pow(PORTA, PORTB) > 100) PORTB = 20;	//PIC18/24/32/dsPIC
}

Die Arrays arr und gleiches_arr sind identisch und da diese nicht verändert werden bräuchte man nur eins speichern. teilsgenutztes_arr hat 5 Elemente, jedoch wird davon nur eins benutzt wird. Somit würde es reichen, nur diese eine Zahl zu speichern oder gar die Zahl fest in den Code zu schreiben. ungenutztes_arr wird komplett nicht benutzt.

sinnlose_funktion ergibt keinen Sinn. Beim Aufruf wird eine Variable i erstellt und inkrementiert, doch danach wird die Funktion ohne Rückgabewert beendet. Somit könnte man sich Code und RAM sparen.

unaufgerufene_funktion wird nie aufgerufen und kann deshalb auch weggelassen werden.

f1 und f2 unterscheiden sich und werden auch benutzt. Jedoch ruft keine der beiden Funktion die jeweils andere auf. Somit kann var_in_f1 und var_in_f2 in das gleiche Register, da sie niemals gleichzeitig genutzt werden.

∗ptr zeigt immer und ausschließlich auf "fuer_pointer" und kann somit auch weggelassen werden.

b1, b2 und b3 sind vom Typ bit und sollten/könnten in ein Register. Allerdings nehmen boolsch1 und boolsch2 auch nur die Werte 0 oder 1 an, obwohl sie vom Typ char sind. Somit könnten diese 2 Variablen auch statt char bit sein und mit in das eine Register.

Was Folgt ist die Benutzung von Variablen, damit diese nicht wegoptimiert werden und ein bisschen "sinnloses" gerechne mit int und double.

Zum Schluss wird noch eine Wurzel und der Logarithmus von PORTA gebildet und bei PIC18/24/32/dsPIC auch noch PORTA hoch PORTB gerechnet.


Ergebnisse

PIC12/16/18
PIC12F1840
7kB ROM
256B RAM
PIC16F1827
7kB ROM
384B RAM
PIC18F46K22
64kB ROM
3896B RAM
XC8 Free
(Optimization: all)
Used RAM: 118 Byte (46%)
Used ROM: 2502 Words (61%)
Built in 110ms
Used RAM: 118 Byte (31%)
Used ROM: 2502 Words (61%)
Built in 94ms
Used RAM: 143 Byte (4%)
Used ROM: 6626 Byte (10%)
Built in 109ms
XC8 Standard
(Optimization: all)
Used RAM: 118 Byte (46%)
Used ROM: 2021 Words (49%)
Built in 110ms
Used RAM: 118 Byte (31%)
Used ROM: 2021 Words (49%)
Built in 94ms
Used RAM: 143 Byte (4%)
Used ROM: 5264 Byte (8%)
Built in 93ms
XC8 PRO
(Optimization: all)
Used RAM: 108 Byte (42%)
Used ROM: 1632 Words (40%)
Built in 109ms
Used RAM: 108 Byte (28%)
Used ROM: 1632 Words (40%)
Built in 93ms
Used RAM: 135 Byte (3%)
Used ROM: 4706 Byte (7%)
Built in 109ms
Hi-Tech C for PIC10/12/16 Lite Used RAM: 115 Byte (45%)
Used ROM: 2498 Words (61%)
Built in 110ms
Used RAM: 115 Byte (30%)
Used ROM: 2498 Words (61%)
Built in 110ms
x
Hi-Tech C for PIC10/12/16 Standard Used RAM: 115 Byte (45%)
Used ROM: 2017 Words (49%)
Built in 110ms
Used RAM: 115 Byte (30%)
Used ROM: 2017 Words (49%)
Built in 110ms
x
Hi-Tech C for PIC10/12/16 Pro Used RAM: 105 Byte (44%)
Used ROM: 1572 Words (38%)
Built in 110ms
Used RAM: 105 Byte (27%)
Used ROM: 1572 Words (38%)
Built in 110ms
x
Hi-Tech C for PIC18 Lite x x Used RAM: 143 Byte (4%)
Used ROM: 6518 Byte (10%)
Built in 110ms
Hi-Tech C for PIC18 Pro x x Used RAM: 135 Byte (3%)
Used ROM: 4688 Byte (7%)
Built in 110ms
SDCC x Keine double-Unterstützung Keine double-Unterstützung
PIC-C PCWHD Demo/Pro Used RAM: 92 Byte (36%)
Used ROM: 1920 Words (47%)
Built in 1s
Used RAM: 87 Byte (23%)
Used ROM: 1920 Words (47%)
Built in 1s
Used RAM: 103 Byte (3%)
Used ROM: 6622 Byte (10%)
Built in 1s
CC5X Free Keine double-&Globals-Unterstützung Keine double-&Globals-Unterstützung x
CC5X Standard n.V. n.V. x
CC8E Free x x Keine double-&Globals-Unterstützung
CC8E Standard x x n.V.
MikroC for PIC Free Used RAM: 61 Byte (25%)
Used ROM: 1879 Words (46%)
Built in 203ms
Used RAM: 61 Byte (17%)
Used ROM: 1879 Words (46%)
Built in 281ms
Datei zu Groß
MikroC for PIC Pro Used RAM: 61 Byte (25%)
Used ROM: 1879 Words (46%)
Built in 188ms
Used RAM: 61 Byte (17%)
Used ROM: 1879 Words (46%)
Built in 275ms
Used RAM: 64 Byte (2%)
Used ROM: 6955 Byte (11%)
Built in 703ms


PIC24/32/dsPIC
PIC24FJ16MC102
16kB ROM
1024B RAM
dsPIC33FJ16GS402
16kB ROM
2048B RAM
PIC32MX220F032B
32kB ROM
8192B RAM
XC16 Free
(Optimizing Level 1)
Used RAM: 12 Byte (1%)
Used ROM: 1404 Byte (26%)
Built in 109ms
Used RAM: 12 Byte (1%)
Used ROM: 1404 Byte (26%)
Built in 110ms
x
XC16 PRO
(Optimizing Level 3/s[Size])
Used RAM: 12 Byte (1%)
Used ROM (LV: 3) : 1437 Byte (26%)
Used ROM (LV: s) : 1408 Byte (25%)
Built in 110ms
Used RAM: 12 Byte (1%)
Used ROM (LV: 3) : 1437 Byte (26%)
Used ROM (LV: s) : 1408 Byte (25%)
Built in 112ms
x
XC32 Free
(Optimizing Level 1)
x x Used RAM: 20 Byte (1%)
Used ROM: 14532Byte (41%)
Built in 625ms
XC32 PRO
(Optimizing Level 3/s[Size])
x x Used RAM: 20 Byte (1%)
Used ROM (LV: 3) : 14568Byte (41%)
Used ROM (LV: s) : 14496 Byte (40%)
Built in 828ms
Hi-Tech C for PIC24 & dsPIC Standard PIC-Typ nicht Unterstützt Used RAM: 1072 Byte (52%)
Used ROM: 1289 Byte (23%)
Built in 825ms
x
Hi-Tech C for PIC32 Lite x x Nicht Unterstützt
Hi-Tech C for PIC32 Pro x x Nicht Unterstützt
PIC-C PCWHD Demo/Pro Used RAM: 438 Byte (43%)
Used ROM: 5438 Byte (48%)
Built in 2s
Used RAM: 438 Byte (21%)
Used ROM: 5438 Byte (48%)
Built in 1s
x
MikroC for dsPIC/PIC24 Free/Pro Used RX: 32 Byte (100%)
Used RAM: 10 Byte
Used ROM: 3599 Byte (32%)
Built in 562ms
Used RX: 32 Byte (100%)
Used RAM: 10 Byte
Used ROM: 3599 Byte (32%)
Built in 468ms
x
MikroC for PIC32 Free/Pro x x Used RX: 29 Byte (91%)
Used RAM: 10 Byte (1%)
Used ROM: 5851 Byte (18%)
Used BOOTROM: 300 Byte (10%)
Built in 1062ms


Ergebnisse ein paar Beispielcodes

Da mich, wie Eingangs geschrieben, der Unterschied der Pro und Free-Version der Microchip-Compiler interessiert hat, hab ich mir bei microchip.com ein paar Beispielcodes runtergeladen, um auch mal anderen, realistischen Code zu haben.

BeispielControllerXC8 FreeXC8 StandardXC8 ProHiTech C FreeHiTech C ProGrößen
ECAN Mode 0 with BaudPIC18F46K8018 / 102818 / 5705 / 44218 / 10085 / 422Bytes RAM / Flash
PIC18 USART Code ExamplePIC18F468550 / 54450 / 41047 / 376
BeispielControllerXC16 FreeXC16 Pro (O3)XC16 Pro (Os)Größen
CE312, CRCPIC24FJ128GA01064 / 40564 / 43064 / 392Byte RAM / Word Flash
CE351, Extended CRC 32PIC24FJ64GB00436 / 46736 / 46736 / 467
CE369, Complementary PWMPIC24FJ16MC1020 / 4000 / 4400 / 398
CE374, SPI Master and Framed Master ModePIC24FJ128GA0100 / 4830 / 5500 / 479

Man sieht auch hier, das der Unterschied beim XC8 ziemlich groß ist (Free:Pro -> 2:1), jedoch beim XC16 von der Dateigröße zwischen den beiden höchsten Optimierungsstufen liegt.

Schlusswort

Das was natürlich bei den ganzen Ergebnissen berücksichtigt werden muss, ist, dass dort nur der Verbrauch von ROM und RAM steht. Dies sagt nichts über die Ablaufgeschwindigkeit aus. Ein Compiler kann evtl einen minimal kleineren Code erzeugen aber doppelt so lange dauern wie ein anderer. Ich hab bloß keine Ahnung, wie ich die Laufzeit ermitteln könnte. Alle Assembles durchgucken und die Takte zusammenrechnen werde ich sicher nicht. Es gibt aber vielleicht ein Programm dafür!?

zumindest für Microchip: Die Stopwatch (Stoppuhr) Funktion in MPLAB:

Wenn jemand einen Code genauso getestet haben will, kann mir gerne den Code schicken und ich versuch mein bestes ihn auf so vielen Compilern wie möglich zum laufen zu bringen. Auf folgende Compiler hab ich Zugriff:

  • XC8/16/32 Free/Standard/Pro
  • Hi-Tech C for PIC10/12/16/18/32 Free/Pro
  • Hi-Tech C for PIC24 & dsPIC Free
  • SDCC
  • PIC-C PCWHD
  • CC5X Free
  • CC8E Free
  • MikroC for PIC, dsPIC/PIC24, PIC32 Pro

Jedoch kann sich jeder bis auf die Pro-Version der MikroC-Compiler alles selber laden und testen.