Anwendungen / 10 MHz Uhr

Aug 27, 2019 14 Replies
Jump to replies (14)
10MHz kommen aus Rubidium Blechschachtel die als Surplus bei ebay.com zu finden ist. Simples Demoprojekt den Takt für Uhr zu verwenden:

formatting link
Krumme Frequenzteiler und 8 Bit BCD-Zahlen sind auch für manche anderen Projekte sinnvolle Programmiertechniken.



MfG JRD


Interessantes Projekt, im Gegensatz zum Obercholeriker beschreibst du deinen Aufbau transparent (MCU, IRQ-Frequenz, Clockrate der MCU) und machst Messungen, statt nur Behauptungen aufzustellen ("2 MHz IRQ-Frequenz!!!").

In deinem Code selbst sind zwei große Teile inline-Assembler. Hast du die erst in Forth geschrieben und dann optimiert oder aus Erfahrung raus direkt in ASM implementiert? Und wenn ja, hast du im ersten Fall gemessen was der Unterschied in der Laufzeit war? Der ISR sieht ja jetzt wirklich nicht so aufwändig aus; bei ~20 kHz ISR-Frequenz und 2.45 MHz CPU-Clock sind das 125 Clock Cycles. Habe ich nicht gemessen, aber ich vemute dass das in C direkt in Hochsprache abbildbar ist, ohne ASM.

Viele Grüße, Johannes

Es ist, wie unschwer erkennbar, Ralph Aichingers "Atomuhr".

Artikel über Demoprojekt wird viele simple Aspekte auch ansprechen, da er ja für Anfänger lesbar sein soll.

Es ist kein inline-Assembler. Den hätte das FORTH auch, aber der wird praktisch nie verwendet:

: Befehl-xyz ... FORTH ... [CODE ... Assembler ... CODE] ... FORTH ... ;

Ein Assembler-Befehl

:CODE Befehl-xyz ... Assembler ... CODE;

ist nach aussen hin äquivalent zu einem FORTH-Befehl

: Befehl-xyz ... FORTH ... ;

gleichen Namens. Wenn man low level IO programmiert und Portabilität kein Thema ist, verwende ich meist Assembler. Ein Interrupt ist in dem FORTH aber immer Assembler. Sonst hätte man den FORTH-Nucleus interruptfähig implementieren müssen. Lohnt sich aus meiner Erfahrung nicht.

Wenn man komplizierte Algorithmen zum Laufen bringen muß, codiert man erst in FORTH, weil leichter debuggbar. Oft ist eine langsame, portable Version auch langfristig nützlich. Wenn die HLL-Version läuft und man mit ihr Testdaten erzeugen kann, macht man sich an die Portierung auf Assembler. Im Archiv der FORTH e.V. (

formatting link
) sind Artikel zu Implementierungen von Verschlüsselungsverfahren:

DES

formatting link
formatting link
formatting link
Da wurde portiert und es ist auch Timing für FORTH und Assembler angegeben. FORTH ist bei sowas im Bereich 5 ... 10 (typ ) ... 20 langsamer. In der Anwendung hier war nichts an den Assmbler-Routinen kompliziert, wurden direkt in Assembler codiert und liefen auch sofort.

Bezweifle ich nicht. C soll ja möglichst schnellen Assembler-Code erzeugen. FORTH erzeugt relativ langsamen unoptimierten Code. Deshalb ist in meinem FORTH immer auch ein Assembler vorhanden für die 20% Software die schnell laufen müssen.

MfG JRD

Hallo Rafael,

Was ist dann am Kernel nicht interrupt fähig?

Ich hatte nie irgendwelche Probleme, egal was für ein FORTH, sowohl PC (F- PC) als auch diverseste (LMI) Metacompiler für Dutzende uC Familien sowie AMforth für 8051.

Den Multitasker vom F-PC (unter WinXP) habe ich so ertüchtigt, dass er sogar ABORT fest war. Das ginge lt. Tom Zimmer und anderen Gurus nicht, habs aber trotzdem gemacht. War garnichtmal sooo aufwändig, muss man nur RT und IR sattelfest sein. Schrub ich aber schon in adnerem Beitrag (AWAIT...), samt einer TSR (Finetime.com mit TCOM), die den Windoof IR auf

1msec (100ns?) beschleunigte und dann nur alle 55ms den Orijinol Windoof Uhrentimer IR startete. Die TSR war eine Mischung von : und CODE Words

Ansonsten verwaltete Finetime 16 Timer und 16 Ticker mit 1ms, 10ms, 100ms,

1sec... über die Windoof Inter Process Communication Area (IPC?)

Die Finetime TSR wurde beim WinBoot mit angeworfen, löschte die IPC und störte nicht weiter.

Irgendwann wurde dann die Application in F-PC gestartet, die dann die IPC nach Wunsch füllte (und die TSR darauf reagierte) und ab ging die Luzie. F-PC lief dann (voll von meiner Zusatz Hardware über eine IO-Extension Karte versorgt) in einem beliebigen Windoof Fenster. Auch mit weiteren IR, zB. Drehgeber Impulse, Wegaufnehmer, Positionsschalter, ADC und was weiss ich nicht alles. Einige IR waren in : andere (schnelle) in CODE.

Das mit der TSR hab ich dann unter W7 nicht mehr weiter probiert, da war irgendwas massiv geändert und man(ich) konnte keine TSR mehr unterschieben. Auch der Zugriff auf die HW wurde mächtig verkompliziert.

Eigentlich schade, aber ich brauch es nicht mehr.

Irgendwo in der FG 4.Dimension im vorigen Jahrtausend hab ich das mal veröffentlicht, aber wenig Echo, weil ich ja was gemacht habe, was lt. Gurus nicht ging :)

Die Finetime TSR samt F-PC hab ich bei einigen Prüfmaschinen erfolgreich angewendet. Die F-PC Application war dann mit Kunden/Aufgaben spezifischen Worten im Kundeneigenen Sprachkontext geschrieben, so dass er sich schnellstens in die Ablaufsteuerung einlesen konnte und Modifikationen auch ohne mich hinbekam. Ua. Lenkgetriebe Justierstand bei Mercedes Düsseldorf, Blechsignieranlage bei Thyssen-Krupp, über 20 Prüfstände für Stellungsregler bei ICE-Eckardt waren die umfangreichsten.

So genug gebrunzt :) JB glaubt und begreift das eh nicht :p

BTW selbst mein Micker-FORTH für den 8051 war voll IR-fähig. Auch in der

4.Dimension veröffentlicht. Im Prinzip ein mickerlicher Kern, der für 16/ 32 bit Grundrechenarten zuständig war, also */ DU/MOD,... samt einem ParameterStack in einer Reg-Bank und den üblichen Stack Worten SWAP DUP DROP ... So konnte ich einfach 32bit Mathematik in den 8051 durchführen ohne alles in Assembler schreiben zu müssen. War im Prinzip eine MACRO Erweiterungen für den ASM.

Keine Ahnung, auf welchen Platten das noch rumliegt.

Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang

Yep :-)

Ja, hilft aber eben auch bestimmte Teilaspekte genau zu verstehen, wenn sie gut dokumentiert sind.

Ah, du implementierst also die komplette Funktion in ASM und zwar so, dass sie der jeweiligen Forth-Calling Convention entspricht.

Echt, wieso das? Persönliche Präferenz?

Ich versuche Assembler immer so weit möglich zu vermeiden, auch bei I/O Zeugs. Solange es nur ASM alleine ist, ist das schon okay, z.B. meinen Startup-Code implementiere ich in reinem ASM, siehe

formatting link
-- aber sobald man C und ASM vermischt muss man echt *höllisch* aufpassen, dass man alles richtig Deklariert hat, insbesondere Clobber-Register und Seiteneffekte. Sonst hat man teilweise den Effekt, dass der Code zwar funktioniert, bei einer neuen Compilerversion dann aber zu undefiniertem Verhalten oder seltsamen Abstürzen führt.

Und das ist echt leicht, da was zu übersehen. Also beispielsweise jetzt mal auf dem x86 gesprochen, wenn ich da ein IDIV mache sieht man nicht, dass das eine drei-Register-Operation ist (idiv %rbx macht %rax = (%rdx:%rax) / %rbx, %rdx = %rax = (%rdx:%rax) % %rbx). Einmal den Remainder vergessen und der Compiler glaubt, das was vorher drin war ist auch nachher noch drin...

Hm, interessant. Weil die Forth-Entwicklungsumgebung auf dem jeweiligen Target die Forth-Opcodes nicht atomar ausführt, oder? Weil sonst wäre der IRQ ja komplett transparent.

Yep, das haben die Hipsterprogrammierer auch wiederentdeckt und nennen es TDD (Test Driven Development). Extrem nützlich eine langsame (aber eben ziemlich sicher korrekte) Implementierung zu haben, mache ich in anderen Sprachen ebenso.

Sehr cool, auch toll geschriebene Artikel. Hat bestimmt viel Zeit gekostet. Beim DES Key Schedule gibt es gar keine Performance Penalty, interessantes Ergebnis -- wäre spannend zu schauen, warum. Den AES Key Schedule hast du deswegen vermutlich gleich nur in Forth implementiert?

Das sind Ergebnisse, die auch viel praktikabler wirken, also so Faktor

5-20. Ich frage mich, warum bei meinem Messungen auf x86_64 dann so ein krasser Unterschied besteht (Faktor 500). Ich vermute ein großer Punkt liegt an der sehr guten Erklärung von Gerhard Hoffmann zur Architektur (<qjcajd$rpl$ snipped-for-privacy@solani.org). Da µC quasi kein Chaching machen (jetzt mal die dicken CM3+ ausgenommen) fällt das alles nicht ins Gewicht.

Platzmäßig etwa 40% Overhead im Flash.

Aber habe ich das schon richtig verstanden, dass jeweils Forth-Unterroutinen keinerlei feste Calling Convention haben, d.h. sich das jeweils von Funktion zu Funktion unterscheiden kann? D.h. also auch nicht statisch geprüft werden kann, ob die Funktion jeweils den Stack in einem ordentlichen Zustand hinterlässt? Ist das in der Praxis kein Problem?

Danke für die Erklärungen!

Viele Grüße, Johannes

Der Stack selbst ist die Konvention, Variablenplätze sind bei Lowlevel-Sachen eher sehr spezielle Kontext-Abhängigkeiten, bei normalen Forth-Worten (die Du Unterroutinen nennst - in der Art der Fädelung ist aber eigentlich alles irgendwie unten, also sub...).

Man sollte dazusagen, dass bei ASM-Gebrauch (im Forth-Slang: Forth-Worte als Prinitives anstelle Secondaries) die Register-Architektur berücksichtigt werden muss, ein gewisses Sortiment von Registern geht für die Forth-Maschine selbst drauf, wg. 2 Stacks und fixem Instruction-Pointer plus Umladeregister, dann gern auch Top-Of-Stack im Register.

Nur bei ISRs können die Register als frei angenommen werden, wenn beim Ansprung die ganze Registerbank freigeschaufelt und später restauriert wird.

Nett ist nb. die Konstruktion von gemeinsamen Methoden für Sammelobjekte auch in Asm,

: def-wort CREATE dies und das ;CODE methode in asm endcode

statt des secondary-Aufbaus

: def-wort CREATE dies und das ;DOES methode in forth-worten ;

(mit diesem universellen Konstrukt braucht es auch keine Arrays, die sind mit einem Fingerschnippen billig zu haben, wie immer man sie braucht.)

Bei Aufruf des dann mit CREATE erstellten Wortes liegt für die Methode die Startaddesse des zum Zeitpunkt der Erstellung mit CREATE gültigen Speicherplatzes an Top of Stack (nennt sich sinnigerweise HERE ), kann im Definitionswort oder im Zuge der Definition ad hoc mit ALLOT reserviert werden, oder mit <wert> ',' (Komma), was immer das Objekt so braucht, damit wandert das HERE weiter.

Danke, sehr schönes Beispiel. Ich werd mir das anschauen und es durcharbeiten wenn ich "meinen" ersten Arduino-Prototypen soweit fertig habe.

lg Ralph

[...]

Schlimm, so ein Leben als verkanntes Genie. Die Bürde, die du trägst, weil du deiner Zeit 100 Jahre voraus bist. Niemand versteht deine Brillianz. Selbst die sogenannten Gurus sind reinste Amateure im Vergleich mit dir, aber niemand merkt es, weil du allen einfach so massiv überlegen bist mit deinem messerschafen Verstand.

Es mag dich immerhin trösten, dass du in 100-200 Jahren als ein Voltaire unserer Zeit im Gedächtnis bleiben wird. Ein Galileo Galilei der Programmiersprachen. Jemand, der mit Leonardo da Vinci quasi verpflichtend und voller Ehrfurcht in einem Satz genannt werden wird.

Ja, sicher auf irgendwelchen Platten, die gerade eben nicht zur Hand sind. Und wenn sie zur Hand wären, hätten sie bestimmt ein technischen Problem, sodass man den Inhalt nicht mehr lesen kann. Aber wenn man den Inhalt lesen könnte, dann wäre das bestimmt alles ultrahochgeheim und unter den strengsten NDAs, die man sich so vorstellen kann. Und wenn die ganzen NDAs abgelaufen wären, dann würde bestimmt irgendein technisches Problem in deinem Newsreader verhindern, dass du Fakten lieferst.

Schlimm, dass dir so unnötige Stolpersteine in den Weg gelegt werden. Denn dass das alles genau so stimmt, darauf gibst du uns sicherlich dein Ehrenwort. Ich wiederhole, dein Ehrenwort.

Viele Grüße, Johannes

Bei IO hängt man an der Hardware des Controllers, Portabilität ist da nicht viel möglich. Funktionen a la Portpin setzen und Portpin löschen sind so trivial dass Debugging auch selten ein Thema ist. Und letztlich: dieses System ist ja so ausgelegt daß man HLL und Assembler leicht mischen kann. Die meisten Implementierungen von Programmiersprachen ( gilt für FORTH genauso wie C ) behandeln Assembler stiefmütterlich und deshalb verwenden Programmierer heute nur noch selten Assembler. Sie verlieren damit aber die Möglichkeit in usec genaues Timing sicherzustellen. Und haben den Drang weg von simplen 8 Bit Prozessoren auf denen ihre HLL nicht optimal läuft.

C sollte da wenig Problem haben, weil es Assembler erzeugt. FORTH greift aber auf Befehle im Nucleus zurück, die wiederum verwenden etwa 8 ... 12 Byte RAM. Das alles auf Stack sichern war mir zu mühsam. Und wie ja gesagt: ich habe ja die Wahl ob ich einen Befehl in FORTH oder Assembler codiere. Bei Interrupt ist Assembler naheliegend.

Der wird ja nur im Startup einmal aufgerufen, den zu optimieren bringt nicht viel.

Die Übergabe erfolgt über den Stack. Das einzige was fix ist, ist die minimale Wortbreite, in diesem FORTH 16 Bit. Der Stack wird durch ein Index-Register, bei Motorola typisch X adressiert:

0,X High Byte Top of Stack 1 ,X Low Byte Top of Stack 2 ,X High Byte Second 3 ,X Low Byte Second

Das wäre der Nucleus-Befehl für 16 Bit Addition:

:CODE + \ ( N1 N2 --- N3 ) \ N1 + N2 = N3 3 ,X LDA, 1 ,X ADD, 3 ,X STA, 0,X LDA, 2 ,X ADC, 2 ,X STA, INX, INX, RTS, CODE;

D.h. der 1. und der 2. Wert wurden addiert und in den

  1. Werten gespeichert. Dann wurde der Zeiger hochgesetzt so daß der zweite Wert der Top of Stack wird. Benutzung sieht auf der Kommandozeile so aus:

---- ---- ---- | 3

---- ---- 0003 | 5

---- 0003 0005 | +

---- ---- 0008 |

32 Bit werden aus zwei 16 Bit Werten simuliert. Der obere Stackwert ist das obere 16 Bit Datenwort. Bei mir sind auch Portpins per Konvention zwei 16 Bit Zahlen:

PB 0 B1! \ Bit 0 an Port PB auf 1 setze PB 0 B0! \ Bit 0 an Port PB auf 0 setzen PB 0 B@ \ --- flag ) Bit 0 an Port PB lesen

Die 16 Bit müssen keine Zahl sein, sie können auch eine Adresse sein. Da ja 65kByte MemoryMap. Die 16 Bit können auch ein Byte sein, dann ist die obere Hälfte eben 00. Es gibt keinerlei typechecking durch den Compiler. Sonst wäre interaktives Arbeiten auf der Kommandozeile kaum noch angenehem.

Zu Laufzeit wird Stack nicht geprüft. Beim Entwickeln testet man auf der Kommanozeile. Bei mir werden immer die drei obersten Wert angzeigt:

RESET

---- ---- ---- | 1

---- ---- 0001 | drop

---- ---- ---- | drop

0000 0000 0000 |

Ein Wert zu viel ist leicht zu sehen. Ein Wert zu wenig sieht wie übervoller Stack aus. Dann ist Druck auf Resetknopf fällig und 3sec später ist das System wieder da. FORTH geht davon aus, daß ein System das maximal simpel und transparent ist, auch funktionssicher programmierbar ist. Sorgfältig testen muß der Programmierer aber auch in FORTH.

Dieses FORTH hat auch ein Handbuch. Das behandelt alle gängigen Details. Im Abschnitt FORTH ist auf S.10 z.B. die Laufzeit der NucleusBefehle gelistet. Und im Anhang ist erklärt wie so ein FORTH intern funktioniert:

formatting link
MfG JRD

Mein FORTH ist JSR,-threaded, ich habe kein NEXT. Ich hatte NEXT auf dem AIM65 anno 1980. Konkurrierte dort mit interpretiertem Microsoft BASIC. Aber Implementierungstechniken der 70er Jahre waren auf 8 Bit CPUs Ende der 90er Jahren nicht mehr praktikabel. Der trade off Speicherverbrauch vs. Geschwindigkeit lag völlig falsch. Der erste C-Compiler mit dem ich arbeitete war Lattice anno 1989. Der war so schlecht daß antikes FORTH konkurrenzfähig war. Aber C-Compiler wurden besser, bei Forth ist überwiegend die Zeit stehengeblieben.

Die VD sucht immer noch Artikel. Hat aber wohl auch Mindestanforderungen was den Inhalt und seine Darstellung angeht.

MfG JRD

Johannes Bauer schrieb:

Wo liegt eigentlich dein Problem? Sauer, nur weil dir einer ziemlich weit über ist? Peinlich sowas... Kriech doch einfach wieder zurück unter deinen Stein!

MfG Rupert

Guter Vorschlag :)

Saludos (an alle Vernünftigen, Rest sh. sig) Wolfgang

Am 31.08.2019 um 00:50 schrieb Rupert Haselbeck:

Na, du bist ja ein richtig doll übergeschnappter.

Am 31.08.2019 um 02:14 schrieb Wolfgang Allinger:

Klar, dass du Prahlhans das lustig findest.

Wieso ist das ein Problem, wenn man Brillianz neidlos anerkennt?

"Über", wie in "überlegen"? Oder eher "über" wie in "überdrüssig"?

Sauer, nee. Ich amüsiere mich nur über die proklamierte Kompetenz von Wolferl, gepaart mit kompletter sprachlicher Inkohärenz und der demonstrierten Unfähigkeit, einfachste Programme auszuführen.

Wie man in den Wald hineinruft, weißt du, Rupert, wie man hineinruft. Dann sollte man aber auch nicht rumflennen, wenn es genauso herausschallt.

Habe momentan keine Ambitionen bei dir einzuziehen, aber falls ich so tief sinke komme ich gerne auf dein Angebot zurück.

Alles Liebe, Dein Johannes

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required