mikrocontroller.net

Forum: Compiler & IDEs Timelib und PROGMEM-Frage


Autor: Detlev T. (detlevt)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo AVR-Freunde,

bekanntermaßen fehlt so etwas wie "time.h" in GCC-AVR. Ich habe mir 
jetzt ein paar Funktionen geschrieben, die das für mich etwas beheben 
sollen. Die altbekannte Tastenentprell-Funktion von Peter Danneger(?) 
habe ich aufgebohrt, so dass ich einen 32-Bit-Sekundenzähler bekomme 
ohne weitere Resourcen (Timer) zu verschwenden. Es ist Teil einer 
größeren Library für das Minimod18 von Elektor, ist daher auf den 
ATMEGA328p@16MHz ausgelegt.

So etwas könnte aber auch für andere nützlich sein, deshalb poste ich 
das hier. Der Code steht unter der GPL, ihr könnt also nach Belieben 
anpassen und ändern.

Ich konnte keine Routinen für die Umrechnung Datum<->Sekunden finden, 
die mich überzeugt hätten. Dehalb habe ich sie mir selbst geschrieben 
(Sch***-Schaltjahre ;) ). Ein paar Beta-Tester wären da praktisch, die 
vielleicht kontruktive Verbesserungsvorschläge machen. Ich habe die 
Routinen so weit getestet, dass Hin- und Rückwandlung wieder dasselbe 
Ergebnis bringen (das ist ja schon einmal nicht schlecht) und dass es 
den 29.2 tatsächlich nur in Schaltjahren gibt.

Ich habe da aber auch noch eine technische Frage. Das Ganze soll als 
einbindbare Library (.a) genutzt werden können, wo sich der Linker nur 
das rauspickt, was wirklich gebraucht wird. Die Funktionen localtime() 
und mktime(), die nicht immer beide gebraucht werden, könnten auf 
dasselbe Array days_of_month[] im Flash zugreifen, wenn ich wüsste, wie 
man das korrekt im Header-File deklariert und dafür sorgt, dass dies 
auch automatisch eingebunden wird, wenn mindestens eine der beiden 
Funktionen genutzt wird.

Mit der jetzigen Lösung wird das Array für jedes Modul getrennt 
angelegt. Das "verschwendet" 12 Flash-Bytes, womit ich noch leben 
könnte. Aber ich würde natürlich für die Zukunft gern wissen, ob es 
besser geht. Vorschläge?

Gruß, DetlevT

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Detlev T. schrieb:
> Mit der jetzigen Lösung wird das Array für jedes Modul getrennt
> angelegt. Das "verschwendet" 12 Flash-Bytes, womit ich noch leben
> könnte. Aber ich würde natürlich für die Zukunft gern wissen, ob es
> besser geht. Vorschläge?

Packe in time.h nur eine Deklaration des Arrays und lagere die 
Definition in eine separate C-Datei aus (und dann natürlich ohne das 
static).

Außerdem geht eigentlich niemandem außerhalb der Lib dieses Array etwas 
an, es wäre also besser für diese internen Sachen eine zusätzliche 
Header-Datei anzulegen. Also time.h nur für das externe Interface und 
time_intern.h (oder wie auch immer du das nennen willst) für die Library 
internen Sachen.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

kannst du einmal genau aufschreiben, wie diese Deklaration aussehen 
muss?. Meine Versuche mit verschiedenen Kombinationen von attributen 
wollte dem Compiler alle nicht schmecken.

"Geht keinen was an" lasse ich in diesem speziellen Fall nicht gelten. 
Vielleicht will jemand irgendwann eine Eingaberoutine für das Datum 
schreiben und kann dann mit diesen ohnehin im Speicher schlummernden 
Informationen Fehleingaben wie den 31. April abfangen. In meinen 
Routinen habe ich bewusst auf Plausibilitätsprüfungen verzichtet.

Gruß, DetlevT

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deklaration in Header:
extern uint8_t days_of_month[12]; 

Definition in separater C-Datei:
uint8_t days_of_month[12] PROGMEM = {31,29,31,30,31,30,31,31,30,31,30,31}; 

PS: Wichtig ist hier auch das "separater". Wenn du es einfach in eine 
der bereits existierenden C-Dateien packst, funktioniert es zwar auch, 
verschwendet aber ggf. wieder Platz.

Detlev T. schrieb:
> "Geht keinen was an" lasse ich in diesem speziellen Fall nicht gelten.
> Vielleicht will jemand irgendwann eine Eingaberoutine ...

Dann solltest du im Header dokumentieren, dass das Array im Flash liegt. 
Das kannst du durch das PROGMEM-Attribut machen (was bei der Deklaration 
keinen funktionellen Unterschied macht), oder einfach durch einen 
Kommentar.

Autor: Detlev T. (detlevt)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

ja Danke, so gehts. (Wo zum Geier hatte ich jetzt noch gelesen, dass 
PROGMEM immer static sein muss?)

Im Anhang die korrigierte Version.

Falls es jemand interessiert: localtime() braucht etwa 600 Bytes, 
mktime() etwa 400.

Gruß, DetlevT

Autor: Detlev T. (detlevt)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Erratum: Ich hatte das Makefile noch nicht angepasst. Hier jetzt die 
korrigierte korrigierte Version. ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.