Forum: Mikrocontroller und Digitale Elektronik Feld aus Festwerten im Programmspeicher


von Daniel S. (supernova01)


Lesenswert?

Nabend,

wie war noch die Formulierung wenn ich ein Feld aus Festwerten nicht im 
RAM beim Atmega haben möchte sondern im Programmspeicher?

uint8_t Feld[10];

Finde das gerade so ad hoc nicht.

Danke

: Bearbeitet durch User
von Georg M. (g_m)


Lesenswert?


von Daniel S. (supernova01)


Lesenswert?

PROGMEM - genau, so wars. Danke.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Daniel S. schrieb:
> Finde das gerade so ad hoc nicht.

C, oder C++?

Wenn C, dann: __flash
uint8_t __flash Feld[10];

Ist bequemer, als der Alte, bzw. der C++ Weg über PROGMEM.

von Daniel S. (supernova01)


Lesenswert?

c

bin aber gerade aufm arduino am rödeln...

von Harald K. (kirnbichler)


Lesenswert?

Daniel S. schrieb:
> bin aber gerade aufm arduino am rödeln

Arduino ist C++, nicht C.

von Daniel S. (supernova01)


Lesenswert?

jo,  Ich programmiere in c aufm arduino.

von Harald K. (kirnbichler)


Lesenswert?

Daniel S. schrieb:
> jo,  Ich programmiere in c aufm arduino.

Sicher? Nutzt Du die Arduino-IDE und das ganze zugehörige Zeug? Dann 
glaubst Du nur, in C zu programmieren.

von Daniel S. (supernova01)


Lesenswert?

Ja, ich glaube es nur. Die Frage sollte wohl auch eher lauten welcher 
compiler da werkelt...oder?

Arduino F. schrieb:
> Wenn C, dann: __flash

Das

uint8_t __flash test[2]={1,2};

geht in der IDE jedenfalls nicht. Ist ja aber auch die Arduino IDE.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel S. schrieb:
> Die Frage sollte wohl auch eher lauten welcher compiler da
> werkelt...oder?

Nein.

Der Compiler wird in diesen Fällen eh immer GCC sein.

In C hat Johann aber __flash implementiert; damit kannst du Daten im 
Flash ohne weitere Umstände direkt benutzen.  Der Compiler puzzelt für 
dich beim Zugriff aus, ob er das via LPM machen muss oder einen der 
anderen LP*-Befehle, ohne dass du den Zugriff in besondere Makro-Aufrufe 
kapseln musst.

Bei C++ gab es zumindest lange Zeit eine Tendenz, die zugrunde liegenden 
Prinzipien (type qualifier) nicht haben zu wollen, weshalb das dort 
trotz gleichen Compilers nicht implementiert ist.  Ich bin mir nicht 
ganz sicher, ob das inzwischen sogar möglich wäre.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Daniel S. schrieb:
> Ist ja aber auch die Arduino IDE.

Die setzt auf C++ auf, auch wenn es manchmal nicht danach aussieht.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Harald K. schrieb:
> Sicher? Nutzt Du die Arduino-IDE und das ganze zugehörige Zeug? Dann
> glaubst Du nur, in C zu programmieren.
*.ino Dateien werden zu *.cpp umgebaut.
Aber *.c bleiben *.c und werden auch als C kompiliert.

Daniel S. schrieb:
> geht in der IDE jedenfalls nicht.
Doch geht, wenn man will.
Spätestens nach einem Compiler update.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> Aber *.c bleiben *.c und werden auch als C kompiliert.

Nö.  g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus 
aufgerufen wird.  Guckst du

g++ -v main.c ... | grep cc1

Damit main.c als C übersetzt wird braucht's explizit

g++ -x c main.c ...

Jörg W. schrieb:
> Bei C++ gab es zumindest lange Zeit eine Tendenz, die zugrunde liegenden
> Prinzipien (type qualifier) nicht haben zu wollen, weshalb das dort
> trotz gleichen Compilers nicht implementiert ist.  Ich bin mir nicht
> ganz sicher, ob das inzwischen sogar möglich wäre.

Möglich wäre es, GCC ist ja nur Software.  Die Frage ist nur, ob 1) das 
jemand wirklich implementieren will und 2) ob die Maintainer das haben 
wollen.  clang kann's ja auch: Das dortige address_space Attribut agiert 
nämlich wie ein Qualifier.

Wobei soweit ich weiß clang nur 16-Bit Address-Spaces hat, also weder 
__memx noch __flashx.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Johann L. schrieb:
> Nö.

Einspruch!


xy.ino:
1
// total leer

main.c:
1
#include <arduino.h>
2
3
const uint8_t __flash test[2]={1,2};
4
5
int main()
6
{
7
  return test[0] + test[1];
8
}

Beide Dateien in einem Ordner, übersetzt ohne Fehler!

Der Aufruf:
1
"E:\\Programme\\arduino\\portable\\avr-gcc\\avr-gcc-15.2.0_mingw32_binutils2.45_avrLibc2.2.1\\bin\\avr-g++" -c -g -Os -w -std=gnu++23 -fno-exceptions -fpermissive -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -fmodules -Wall -Wextra -Wno-volatile -isystem "E:\\Programme\\arduino\\portable\\avr-libstdcpp2\\include" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "E:\\temp\\Arduino\\sketch\\main.c" -o nul

Interessant!

Natürlich sehe ich das -std=gnu++23 und auch das -x c++


Lasse ich das const in der main.c weg meldet es:
1
main.c:3:18: error: variable 'test' must be const in order to be put into read-only section by means of '__flash'
2
    3 |  uint8_t __flash test[2]={1,2};
3
      |                  ^~~~
Was auf jeden fall so richtig ist.

Ändere ich die Endung auf main.cpp kommt folgende Meldung:
1
main.cpp:3:23: error: expected initializer before 'test'
2
    3 | const uint8_t __flash test[2]={1,2};
3
      |                       ^~~~

Und jetzt du!
Wie kommt es, dass in der *.c kein Fehler geworfen wird, wenn sich da 
ein __flash befindet. Und natürlich auch funktioniert, denn das habe ich 
vorher schon ein paar mal verwendet.
Ich weiß es nicht.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> #include <arduino.h>

Und wie ist da __flash definiert / implementiert?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> Der Aufruf:

Da wird doch garnichts übersetzt, d.h. da sind keine TUs angegeben?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Keine Ahnung was Arduino da macht.

Wenn du
1
avr-g++ simple.c -v 2>&1 | grep cc1
Ist die Ausgabe:
1
$prefix/bin/../libexec/gcc/$target/$version/cc1plus -quiet -v -iprefix $prefix/../lib/gcc/$target/$version/ simple.c ...
Oder kommt bei dir cc1 statt cc1plus?

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Johann L. schrieb:
> Und wie ist da __flash definiert / implementiert?

Gar nicht!
Wird da nur für das uint8_t gebraucht.
(könnte man auch anders erreichen)

Johann L. schrieb:
> Wenn du avr-g++ simple.c -v 2>&1 | grep cc1
Kein linux, kein grep

Johann L. schrieb:
> Keine Ahnung was Arduino da macht.
Dürfte mit  Arduino nix zu tun haben.
Der Compiler ist nachträglich eingebunden.
Arduino dümpelt noch bei GCC 7.3 oder so, und C++11
Ich nutze Gcc 15.2 mit C++23 mit der IDE

Die gezeigte Zeile ist die einzige, in der main.c vorkommt.

Johann L. schrieb:
> TUs
Aha...
Was ist das?
Kenne mindestens 10 TU Dinger, glaube aber, du meinst was anderes.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Arduino F. schrieb:
>> TUs
>
> Aha...
> Was ist das?

Wenn du etwas mehr zitiert hättest, wäre dir wohl aufgefallen, dass es 
in diesem Zusammen nur "translation unit" heißen kann.

von Rainer W. (rawi)


Lesenswert?

Was hat diese Compiler- und IDE Diskussion mit Mikrocontrollern zu tun?

Bitte verschieben!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rainer W. schrieb:
> Was hat diese Compiler- und IDE Diskussion mit Mikrocontrollern zu tun?

Dass named address spaces (um diese geht es letztlich) vorrangig etwas 
für den Anwendungsfall "Mikrocontroller" sind.  Bei einem Compiler für 
einen PC braucht man das nicht.

: Bearbeitet durch Moderator
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> Johann L. schrieb:
>> Wenn du avr-g++ simple.c -v 2>&1 | grep cc1
> Kein linux, kein grep

Dann halt
1
avr-g++ simple.c -v

und du musst eben selber nach "cc1" suchen weil du nicht danach filtern 
kannst.

> Johann L. schrieb:
>> Keine Ahnung was Arduino da macht.
> Dürfte mit  Arduino nix zu tun haben.
> Der Compiler ist nachträglich eingebunden.
> Arduino dümpelt noch bei GCC 7.3 oder so, und C++11
> Ich nutze Gcc 15.2 mit C++23 mit der IDE

GCC verhält sich konsistent; das Verhalten ändert sich ja nicht in jeder 
Version.  GCC 5 macht das gleiche wie GCC 15:

"g++ main.c" übersetzt als C++.  Um das als C zu übersetzen brauch man 
"gcc main.c" oder "g++ -x c  main.c".

> Die gezeigte Zeile ist die einzige, in der main.c vorkommt.

Das Kommando compiliert nicht sondern präprozessiert lediglich, weil -E 
angegeben ist!

Du hast den COMPILERaufruf für main.c also noch nicht gefunden...

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Johann L. schrieb:
> Du hast den COMPILERaufruf für main.c also noch nicht gefunden...

Noch mal nachgesehen.
Du hast wahr. Ist mir gestern durch die Lappen gegangen.
1
"E:\\Programme\\arduino\\portable\\avr-gcc\\avr-gcc-15.2.0_mingw32_binutils2.45_avrLibc2.2.1\\bin\\avr-gcc" -c -g -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10819 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino" "-IE:\\Programme\\arduino\\portable\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard" "E:\\temp\\Arduino\\sketch\\main.c" -o "E:\\temp\\Arduino\\sketch\\main.c.o"

Johann L. schrieb:
> Nö.  g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus
> aufgerufen wird.
Damit hast auch du dich geirrt.

Jörg W. schrieb:
> Wenn du etwas mehr zitiert hättest, wäre dir wohl aufgefallen, dass es
> in diesem Zusammen nur "translation unit" heißen kann.
Ein seltsamer Vorwurf...
Anständig wäre: Die erste Verwendung einer Abkürzung mit einer Erklärung 
versehen.
Merke:
Lesen und verstehen, klappt manchmal.
Zitieren ist eine andere Baustelle.
Dass es deine TU ist, die da fehlt, ist mit nicht in den Sinn gekommen, 
da ja die main.c.o Datei klar vor meinen Augen liegt.
Also im Endeffekt doch eine TU vorhanden.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> Johann L. schrieb:
>> Nö.  g++ main.c ... übersetzt als C++ weil der C++ Compiler cc1plus
>> aufgerufen wird.
> Damit hast auch du dich geirrt.

Wieso? Hast du ein Gegenbeispiel?

> Noch mal nachgesehen.
> Du hast wahr. Ist mir gestern durch die Lappen gegangen.
> ...avr-gcc -c ... main.c -o ...main.c.o

Also wird gcc verwendet, nicht g++.

Und mithin nicht automatisch Arduino = C++.

: Bearbeitet durch User
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Johann L. schrieb:
> Und mithin nicht automatisch Arduino = C++.

Richtig!
Viel von dem Basis Kram steckt in *.c Dateien, und wird auch so 
übersetzt.
Weniges steckt in *.S Dateien, also Assembler.
Der Rest, wie *.ino, Print, Serial und quasi alle Libraries sind C++

Aus dem 3er Pool, an Sprachen, kann man sich jeweils das raus suchen, 
was einem am besten schmeckt.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Johann L. schrieb:
> Arduino F. schrieb:
>> Aber *.c bleiben *.c und werden auch als C kompiliert.
>
> Nö.

Johann L. schrieb:
> Wieso? Hast du ein Gegenbeispiel?
Das "Nö" ist an der Stelle falsch.
Ein Gegenbeispiel habe ich geliefert, wenn auch etwas holperig.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.