Moin,
in meiner Schaltung habe ich einige LED, die über Multiplexing
angesteuert werden. Jetzt würde ich natürlich gerne im Quelltext
übersichtlich die Zuordnung LED<->(Pins,Speicherplatz) haben.
Der für mich schönste Ansatz wäre sowas wie
1
#define ZEILE 0
2
#define SPALTE 1
3
4
constuint8_tLED_Start[3]={0,0,0};
5
constuint8_tLED_Stop[3]={1,0,1};
6
constuint8_tLED_Bereit[3]={2,0,2};
7
constuint8_tLED_Aus[3]={0,1,4};
8
// ...
9
10
voidLED_schalten(uint8_tZeile,uint8_tSpalte);
11
12
intmain(void)
13
{
14
LED_schalten(LED_Start[ZEILE],LED_Start[SPALTE]);
15
}
Die Arrays werden aber dabei natürlich im RAM abgelegt und da möchte ich
sie ungerne haben, weil es ein paar mehr LED sind und RAM knapp ist.
Die andere Möglichkeit wäre, alles mit #define zu machen
1
#define LED_Start_Zeile 0
2
#define LED_Start_Spalte 0
3
#define LED_Start_Position 0
4
#define LED_Stop_Zeile 1
5
#define LED_Stop_Spalte 0
6
#define LED_Stop_Position 1
7
#define LED_Bereit_Zeile 2
8
// ...
Das hat sehr viel Redundanz und ist dadurch unübersichtlicher.
Die Konstanten werden auch wirklich nur konstant, also zur Compilezeit
vorhersagbar benutzt, auch die Arrayindizes. Es wird also nicht sowas
wie
for(int i=0;i<3;i++) x=LED_Start[i];
oder sowas geben.
Gibt es eine saubere Möglichkeit, die const-Konstanten im Code zu
speichern oder über #define mit Arrays zu arbeiten?
Dussel schrieb:> Die Arrays werden aber dabei natürlich im RAM abgelegt und da möchte ich> sie ungerne haben, weil es ein paar mehr LED sind und RAM knapp ist.
Welcher µC? Für die AVRs gibt es dafür PROGMEM bzw. beim avr-gcc neueren
Datums __flash.
Frank M. schrieb:> Dussel schrieb:>> Die Arrays werden aber dabei natürlich im RAM abgelegt und da möchte ich>> sie ungerne haben, weil es ein paar mehr LED sind und RAM knapp ist.>> Welcher µC? Für die AVRs gibt es dafür PROGMEM bzw. beim avr-gcc neueren> Datums __flash.
Es ist ein AVR (ein ATmega8).
Stimmt, die Anweisungen gibt es und ich kenne sie auch. Dafür muss ich
dann aber die speziellen Zugriffsfunktionen für Flash oder EEPROM
verwenden. Das wollte ich eigentlich nicht.
Mir geht es einfach nur darum, dass wie bei #define alle Vorkommen im
Code durch die entsprechenden Konstanten ersetzt werden.
Dussel schrieb:> Stimmt, die Anweisungen gibt es und ich kenne sie auch. Dafür muss ich> dann aber die speziellen Zugriffsfunktionen für Flash oder EEPROM> verwenden. Das wollte ich eigentlich nicht.
Geht auf Harvard-Architekturen nicht anders.
Dussel schrieb:> Mir geht es einfach nur darum, dass wie bei #define alle Vorkommen im> Code durch die entsprechenden Konstanten ersetzt werden.
Sowas kann C nicht, was du suchst bietet C++ mit constexpr.
asdfasd schrieb:> Mach die Arrays mal "static const" ...
Ändert nichts daran, dass sie dennoch im RAM landen.
Dussel schrieb:> Gibt es eine saubere Möglichkeit, die const-Konstanten im Code zu> speichern oder über #define mit Arrays zu arbeiten?
Bei deinem Atmega 8 mit PROGMEM arbeiten
1
#include<avr/pgmspace.h> // fuer PROGMEM und entsprechenden Funktionen zum Zugriff auf die Variablen im Flash
>> Mach die Arrays mal "static const" ...>> Ändert nichts daran, dass sie dennoch im RAM landen.
Doch! Der Optimizer verwirft sie. Ohne const darf er nicht.
An Deiner Stelle würde ich versuchen das Programm mit avr-g++ zu
compilieren und schauen obs einen Unterschied macht. Wurde ja schon
gesagt, dass hier die kleinen Unterschiede zwischen C und dem C Teil von
C++ liegen.
Static habe ich jetzt mal ausprobiert und das scheint das Problem zu
lösen. Ich habe auch mal ausprobiert, ob es einen Unterschied gibt, wenn
ich die Konstante benutze oder nicht. Da hat sich nichts geändert. Die
Ersparnis liegt also nicht darin, dass er die Konstanten wegoptimiert.
Die anderen Hinweise werde ich ausprobieren, wenn es doch noch Problem
gibt.
Vielen Dank.
Dussel schrieb:> Static habe ich jetzt mal ausprobiert und das scheint das Problem zu> lösen. Ich habe auch mal ausprobiert, ob es einen Unterschied gibt, wenn> ich die Konstante benutze oder nicht. Da hat sich nichts geändert. Die> Ersparnis liegt also nicht darin, dass er die Konstanten wegoptimiert.>> Die anderen Hinweise werde ich ausprobieren, wenn es doch noch Problem> gibt.>> Vielen Dank.
Bezogen auf den Code im ersten Post:
Darin wird ein konstanter Wert, zugegeben komplex notiert, an eine
Funktion übergeben. Da die ganzen const Arrays aber nicht static
deklariert sind, sind sie von anderen "Compilation-Units", sprich
anderen c-Files des gleichen Projekts aus sichtbar. Ob das so ist, weis
der Compiler nicht, also kann er sie nicht wegwerfen. Mit static kennt
er jede Verwendung, kann nur in diesem c-File sein, und weiß, daß damit
nur kompliziert 8 Bit "errechnet" werden. Das kann er auch zur
Compile-Time und damit sind die Arrays nicht mehr notwendig. Ob sie dann
const sind, ist egal, denn jegliche Verwendung ist bekannt.
Carl D. schrieb:> Mit static kennt> er jede Verwendung, kann nur in diesem c-File sein, und weiß, daß damit> nur kompliziert 8 Bit "errechnet" werden. Das kann er auch zur> Compile-Time und damit sind die Arrays nicht mehr notwendig. Ob sie dann> const sind, ist egal, denn jegliche Verwendung ist bekannt.
Das war ja der Plan. Ich hatte nur Bedenken, dass der niedrigere
Speicherverbrauch dadurch zustande kommt, dass der Compiler merkt, dass
die meisten Konstanten nie verwendet werden (das Projekt steht ja noch
ganz am Anfange) und sie deshalb komplett wegoptimiert.
Gewundert hat mich zuerst, dass auch der Programmspeicherverbrauch
zurückgeht. Aber es werden durch die Codierung ja auch alle
Speicherladebefehle gespart.