Stefans Frage hat mich an etwas erinnert, was ich nie zu fragen wagte. In C gibt es ja globale Variablen, z.B. in Interrupt-Routinen. Mit einem RTOS braucht man etwas ähnliches, um Daten zwischen zwei Tasks auszutauschen. Solche Variablen sind ja "über-global" -- wie nennt man die? Galaktische oder interplanetare Variablen? Ja, ein RTOS bietet Mechanismen mit denen die Frage nicht aufkommt. Aber wenn man auf einem uC den kleinen Dienstweg gehen will? Auch wenn man offizielles shared memory benutzt: da drin sind auch Variablen versteckt, die mehr als global sind.
:
Bauform B. schrieb: > Solche Variablen sind ja "über-global" -- wie nennt man die? Die sind global (Sichtbarkeit) und statisch (Lebensdauer). Wenn du innerhalb einer Übersetzungseinheit (also C-Quelle plus alle #includes) eine Variable auf dem äußeren Level ohne weitere Schlüsselworte anlegst, wird sie genau das: global. Legst du sie an der gleichen Stelle mit "static" an, bleibt die Lebensdauer statisch, aber die Sichtbarkeit wird auf die Übersetzungseinheit beschränkt. Code aus anderen Übersetzungseinheiten kann auf sie nicht zugreifen.
Jörg W. schrieb: > Die sind global (Sichtbarkeit) und statisch (Lebensdauer). > > Wenn du innerhalb einer Übersetzungseinheit (also C-Quelle plus alle > #includes) eine Variable auf dem äußeren Level ohne weitere > Schlüsselworte anlegst, wird sie genau das: global. Legst du sie an der > gleichen Stelle mit "static" an, bleibt die Lebensdauer statisch, aber > die Sichtbarkeit wird auf die Übersetzungseinheit beschränkt. Code aus > anderen Übersetzungseinheiten kann auf sie nicht zugreifen. Genauso habe ich es mal gelernt 👍
Bauform B. schrieb: > . Mit einem RTOS braucht man etwas ähnliches, um Daten zwischen zwei > Tasks auszutauschen. Solche Variablen sind ja "über-global" -- wie nennt > man die? Galaktische oder interplanetare Variablen? Sie sind "volatile". Und dazu unter Umständen auch nicht atomar, brauchen als einen synchronisationsmechanismus. Bei manchen Prozessoren sind alle integer-Typen atomar, bei anderen können 16 Bit schon Müll ergeben. Dazu braucht es kein RTOS, Interrupts bewirken das gleiche.
Jörg W. schrieb: > Wenn du innerhalb einer Übersetzungseinheit (also C-Quelle plus alle > #includes) eine Variable auf dem äußeren Level ohne weitere > Schlüsselworte anlegst, wird sie genau das: global. Einverstanden. Und alle Übersetzungseinheiten, die damit gelinkt werden, sehen sie auch. Aber auch nur die. Für alles, was getrennt gelinkt wird (anderer Prozess, Task, Programm...), wird sie erst sichtbar, wenn man ein attribute wie ((section ("shared_memory"))) dazu schreibt. Ich meine, das ist unterschiedlich genug zum normalen global, das verdient einen eigenen Namen. Ich rede nur von kleinen uC, gerade groß genug für etwas RTOS-ähnliches. Cyblord -. schrieb: > Was rauchst du eigentlich? Lack von überlasteten Widerständen. Aber dank SMD nicht mehr so viel wie früher. Außerdem: heute dampft man ja, vor allem Flussmittel.
A. S. schrieb: > Bauform B. schrieb: >> . Mit einem RTOS braucht man etwas ähnliches, um Daten zwischen zwei >> Tasks auszutauschen. Solche Variablen sind ja "über-global" -- wie nennt >> man die? Galaktische oder interplanetare Variablen? > > Sie sind "volatile". > > Und dazu unter Umständen auch nicht atomar, brauchen als einen > synchronisationsmechanismus. Auch einverstanden. > Dazu braucht es kein RTOS, Interrupts bewirken das gleiche. Ja, was volatile und atomar betrifft. Wenn man aber mehrere "Programme" getrennt linkt, die aber zusammen arbeiten müssen (z.B. Steuerung und Benutzerschnittstelle), braucht man einen zusätzlichen Mechanismus.
Bauform B. schrieb: > Für alles, was getrennt gelinkt wird (anderer Prozess, Task, > Programm...), wird sie erst sichtbar, wenn man ein attribute wie > ((section ("shared_memory"))) dazu schreibt. Nö. Woher sollten die irgendwelche Namen völlig separat gelinkter Programme erfahren? Wenn es irgendwo einen shared memory zwischen verschiedenen Programmen gibt, kann es nur auf Absprachen beruhen, wie dieser aufgebaut ist. Solche Absprachen kann man natürlich automatisch aus den Symboltabellen generieren, aber das ist dann nichts mehr, was irgendwo allgemein definiert wäre. Die Sprache C kennt erstmal nichts, was ein "shared memory" sein soll. Ein bisschen anders ist es noch, wenn zur Laufzeit dynamische Bibliotheken nachgeladen werden (dlsym und Konsorten): diese haben eine Symboltabelle, über die man wieder zu den Namen Werte bekommen kann. Diese verhalten sich ab dem Moment aber wieder wie alle anderen globalen Variablen; die so geladene Bibliothek wird ja (temporärer) Bestandteil des Programms.
Jörg W. schrieb: > Woher sollten die irgendwelche Namen völlig separat gelinkter > Programme erfahren? Die Programme benutzen zwei includes gemeinsam: eins mit typedef struct und eins in ihrem Linkerscript für die absolute Adresse (letztlich die Adresse der struct).
> Mit einem RTOS braucht man etwas ähnliches, um Daten zwischen zwei > Tasks auszutauschen. Solche Variablen sind ja "über-global" -- wie > nennt man die? Galaktische oder interplanetare Variablen? Im Kontext von Multithreading gibt es thread-local Variablen[1]. Vom Scope meist global (können aber z.B. auch static locals sein), aber jeder Thread hat eine private Kopie (bei Linux z.b. errno). Die normalen Variablen sind thread-global - für alle Threads gemeinsam (dein "über-global"). Im Kontext von mehreren Prozessen mit getrennten Adressräumen bieten die Betriebssysteme unterschiedliche Methoden der Inter-Process-Communication (IPC) - bei Unix u.a. shared memory via sysv-shm oder mmap(MAP_SHARED). Auf der Sprachebene von C/C++ findet man da üblicherweise nichts. [1] https://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html
Bauform B. schrieb: > Die Programme benutzen zwei includes gemeinsam: eins mit typedef struct > und eins in ihrem Linkerscript für die absolute Adresse (letztlich die > Adresse der struct). Es gibt Mechanismen, um Variablen an feste Orte zu legen. Manuell (wie z.b. Registern), dynamisch (das eine Programm sucht im anderen, zur Link- oder Laufzeit), per Interface (Pointer-austausch), per Linkeranweisung, etc. etc. Am Ende spielt das aber keine Rolle. Es bleiben vom Prinzip her globale Variablen. Oder auf was möchtest Du hinaus. Bzw. wie sprichst Du die an, was ist für Dich der Unterschied?
A. S. schrieb: > Oder auf was möchtest Du hinaus. Im Grunde geht es mir um die unterschiedliche Sichtbarkeit. 1. nur für eine Funktion 2. für alle Funktionen in einer Quell-Datei 3. überall im ganzen Programm 4. für alle Programme auf dem gleichen uC 5. für alle Programme auf allen CPUs im ganzen Rack (naja...) 1. bis 3. kennt jeder, das ist normales C in einem einzelnen Programm. Mit Multitasking kommt die 4 dazu. Die ist identisch mit 3, solange man alles zusammen linkt. Ich fand es angenehmer, die "Programme" auch getrennt zu linken. Damit brauche ich einen neuen Mechanismus, weil normale globale Variablen nicht mehr funktionieren. Und ich dachte, dafür muss es doch einen Namen geben, so als Fortsetzung von 1=lokal über 3=global müsste 4 interplanetar heißen oder so. > Bzw. wie sprichst Du die an, was ist für Dich der Unterschied? Zur Zeit sind alle gemeinsamen Daten in einer struct in einer extra section verpackt. Die wird per Linkerscript auf eine feste Adresse gelegt. Per "extern" kann das jeder ziemlich normal benutzen. Gerade fällt mir ein: Stattdessen könnte sich eine Funktion auch einen Pointer vom "Betriebssystem" holen. Dann sind die gemeinsamen Daten nur für diese Funktion sichtbar. Das sieht garnicht mehr global aus, damit entfällt der Punkt 4 komplett und ich brauche keinen neuen Begriff -- sehr vorteilhaft! Das wäre zwar langsamer als die jetzige rein statische Lösung, aber immer noch besser als ausgewachsene IPC.
Bauform B. schrieb: > Im Grunde geht es mir um die unterschiedliche Sichtbarkeit. > 1. nur für eine Funktion > 2. für alle Funktionen in einer Quell-Datei Gibt's in C nicht. Das Konstrukt heißt dort "Übersetzungseinheit" (translation unit), und das umfasst halt auch alle inkludierten Dateien. > 3. überall im ganzen Programm Bis hierhin definiert der C-Standard sowas. > 4. für alle Programme auf dem gleichen uC Da verlässt du den C-Standard. Aber auch APIs, die sowas wie shared memory kennen (mmap() in Posix oder das SystemV shmem interface) haben da keinerlei Vorkehrungen außer dem puren Teilen eines gemeinsamen Speicherbereichs. Was in diesem Speicher steht ist, schrieb ich oben, gegenseitige Absprache. Man tut natürlich im allgemeinen gut daran, wenn sich alle beteiligten Seiten in dieser Absprache untereinander einig sind. :-)) > 5. für alle Programme auf allen CPUs im ganzen Rack (naja...) In der Regel gar nicht. Soweit ich weiß, benutzen diese völlig separate Speicher, die nicht verbunden sind. Hatte ich aber noch nicht in der Hand.
Bauform B. schrieb: > Im Grunde geht es mir um die unterschiedliche Sichtbarkeit. > 1. nur für eine Funktion da fehlt noch 0, innerer Block Scrope > 2. für alle Funktionen in einer Quell-Datei > 3. überall im ganzen Programm > 4. für alle Programme auf dem gleichen uC Z.B. Register, Memory-Mapped IO, … also ganz normal global. > 5. für alle Programme auf allen CPUs im ganzen Rack (naja...) Da Verlässt Du C und kommst zu sowas, was bei uns in der Firma "Parameter" heisst. Mit physicher Kommunikation zwischen den CPUs. Also weit weg von "Variablen" im herkömmlichen Sinn. > 1. bis 3. kennt jeder, das ist normales C in einem einzelnen Programm. > Mit Multitasking kommt die 4 dazu. OK. Ich assoziiere Multitasking auf µC mit EINEM gelinkten Programm, wie z.B. bei FreeRTOS, µITRON, sowas halt und 1 bis 100 Tasks. Was Du meinst ist für mich eher ein OS wie DOS oder OSx. > Gerade fällt mir ein: Stattdessen könnte sich eine Funktion auch einen > Pointer vom "Betriebssystem" holen. Dann sind die gemeinsamen Daten nur > für diese Funktion sichtbar. Das sieht garnicht mehr global aus, damit > entfällt der Punkt 4 komplett und ich brauche keinen neuen Begriff -- O.T.: Ich habe noch nie verstanden, warum "versteckte" Variablen, auf die ich jederzeit beliebig viele Pointer bekommen kann, nicht global sein sollen.
Beitrag #6490806 wurde von einem Moderator gelöscht.
Beitrag #6490808 wurde von einem Moderator gelöscht.
Beitrag #6490811 wurde von einem Moderator gelöscht.
Bauform B. schrieb: > Einverstanden. Und alle Übersetzungseinheiten, die damit gelinkt werden, > sehen sie auch. Aber auch nur die. Für alles, was getrennt gelinkt wird > (anderer Prozess, Task, Programm...), wird sie erst sichtbar, wenn man > ein attribute wie ((section ("shared_memory"))) dazu schreibt. > > Ich meine, das ist unterschiedlich genug zum normalen global, das > verdient einen eigenen Namen. Ich rede nur von kleinen uC, gerade groß > genug für etwas RTOS-ähnliches. Dort hat man dann aber auch keine separaten Prozesse mit eigenen Adressräumen. >> 5. für alle Programme auf allen CPUs im ganzen Rack (naja...) > Da Verlässt Du C und kommst zu sowas, was bei uns in der Firma > "Parameter" heisst. Mit physicher Kommunikation zwischen den CPUs. Also > weit weg von "Variablen" im herkömmlichen Sinn. Es gibt auch noch reflective shared memory. Da greifen die Programme auch über Rechnergrenzen auf einen Shared-Memory zu, der von der Hardware im Hintergrund über einen schnellen Link synchron gehalten wird. Das funktioniert dann sogar, wenn unterschiedliche Betriebssysteme auf den Rechnern laufen. >> 1. bis 3. kennt jeder, das ist normales C in einem einzelnen Programm. >> Mit Multitasking kommt die 4 dazu. > OK. Ich assoziiere Multitasking auf µC mit EINEM gelinkten Programm, wie > z.B. bei FreeRTOS, µITRON, sowas halt und 1 bis 100 Tasks. Was Du meinst > ist für mich eher ein OS wie DOS oder OSx. Klassisches DOS hat kein Multitasking. > O.T.: Ich habe noch nie verstanden, warum "versteckte" Variablen, auf > die ich jederzeit beliebig viele Pointer bekommen kann, nicht global > sein sollen. Weil sich "global" nicht auf den Zugriff auf die Daten, sondern auf die Sichtbarkeit des Namens bezieht.
Rolf M. schrieb: >> OK. Ich assoziiere Multitasking auf µC mit EINEM gelinkten Programm, wie >> z.B. bei FreeRTOS, µITRON, sowas halt und 1 bis 100 Tasks. Was Du meinst >> ist für mich eher ein OS wie DOS oder OSx. > > Klassisches DOS hat kein Multitasking. Richtig. Dem TO ging es aber darum, getrennt gelinkte Programme auf einem µC laufen zu lassen. Das ist etwas, was mit einem RTOS eher ungewöhnlich ist, bei DOS die Regel. >> O.T.: Ich habe noch nie verstanden, warum "versteckte" Variablen, auf >> die ich jederzeit beliebig viele Pointer bekommen kann, nicht global >> sein sollen. > > Weil sich "global" nicht auf den Zugriff auf die Daten, sondern auf die > Sichtbarkeit des Namens bezieht. Naja, dass ist eine der sinnvollen Definitionen. Und das Zumüllen mit Namen ist ein Issue. Die allermeisten Empfehlungen, globale Variablen zu vermeiden, beziehen sich jedoch auf die Möglichkeit, von überall unkontrolliert drauf zugreifen zu können. Das ist bei dem Weg weiterhin der Fall. Und statt des namens der Variable braucht es den Namen des Pointers oder der Pointer-Get-Funktion. Oder man hat fest vereinbarte Adressen, was m.E. noch schlechter ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.