<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.ethernut.de/nutwiki/index.php?action=history&amp;feed=atom&amp;title=Einf%C3%BChrung_in_das_Nut%2FOS</id>
		<title>Einführung in das Nut/OS - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.ethernut.de/nutwiki/index.php?action=history&amp;feed=atom&amp;title=Einf%C3%BChrung_in_das_Nut%2FOS"/>
		<link rel="alternate" type="text/html" href="http://www.ethernut.de/nutwiki/index.php?title=Einf%C3%BChrung_in_das_Nut/OS&amp;action=history"/>
		<updated>2026-04-28T22:52:58Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://www.ethernut.de/nutwiki/index.php?title=Einf%C3%BChrung_in_das_Nut/OS&amp;diff=74&amp;oldid=prev</id>
		<title>Harald: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="http://www.ethernut.de/nutwiki/index.php?title=Einf%C3%BChrung_in_das_Nut/OS&amp;diff=74&amp;oldid=prev"/>
				<updated>2016-10-27T16:02:53Z</updated>
		
		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;tr style='vertical-align: top;' lang='en'&gt;
				&lt;td colspan='1' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan='1' style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 16:02, 27 October 2016&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan='2' style='text-align: center;' lang='en'&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Harald</name></author>	</entry>

	<entry>
		<id>http://www.ethernut.de/nutwiki/index.php?title=Einf%C3%BChrung_in_das_Nut/OS&amp;diff=73&amp;oldid=prev</id>
		<title>Bg: typos corrected</title>
		<link rel="alternate" type="text/html" href="http://www.ethernut.de/nutwiki/index.php?title=Einf%C3%BChrung_in_das_Nut/OS&amp;diff=73&amp;oldid=prev"/>
				<updated>2008-09-22T21:15:51Z</updated>
		
		<summary type="html">&lt;p&gt;typos corrected&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== System Initialisierung ==&lt;br /&gt;
Gundsätzlich beginnen C-Programme mit ''main()''. Hieran ändert sich auch nichts durch die Verwendung von Nut/OS. Durch das Einbinden der notwendigen Bibliotheken wird vor dem Ausführen der Funktion ''main()'' der Mikrocontroller initialisiert. Die Initialisierung findet mit der Routine ''nutinit'' statt. Dabei wird unter anderem das Speichermanagement und ein Threadsystem initialisiert. Anschließend wird ein Thread mit einem Idle-Thread gestartet der auch die Timer initialisiert. Zuletzt wird die Kontrolle des Programmablaufs der Funktion ''main()'' übergeben.&lt;br /&gt;
&lt;br /&gt;
Ein Beipielprogramm könnte so aussehen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;compiler.h&amp;gt;&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
     for (;;)&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Bis auf die Zeile mit ''&amp;quot;#include &amp;lt;compiler.h&amp;gt;&amp;quot;'' enthält das Programm keine Besonderheiten. Diese Zeile dient dazu ein Problem mit dem AVR-GCC zu beheben. Bei Verwendung des AVR-GCC ohne diese Zeile wird beim Aufruf der ''main()''-Funktion der Stackpointer erneut gesetzt. Um dieses Problem zu beheben wird bei Verwendung des AVR-GCC die ''main()''-Funktion in ''NutAppMain()'' umbenannt. Falls eine andere Header-Datei verwendet wird, braucht ''compiler.h'' nicht ausdrücklich eingebunden werden, da dieses in den anderen Headerdateien automatisch geschieht.&lt;br /&gt;
&lt;br /&gt;
== Thread Management ==&lt;br /&gt;
Häufig sollen mehre Aufgaben scheinbar gleichzeitig von der Hardware ausgeführt werden. Beispielsweise gehört dazu die regelmäßige abfrage von Sensoren während im Hintergrund Anfragen über das Netzwerk beantwortet werden sollen. klassischerweise werden solche Probleme mittels Interruptroutinen gelöst. Eleganter ist es, dieses mit Threads zu lösen. Threads sind bei Nut/OS um so wichtiger, da nur eine Applikation gleichzeitig laufen kann. Einen Thread kann man sich als eine Art Unterapplikation vorstellen, die unabhängig von dem anderen Thread läuft.&lt;br /&gt;
Bei Nut/OS sind Threads als kooperatives Multithreading implementiert. Anders als beim preemptiven Multithreading wird die jeweilige Rechenzeit dem jeweiligen Thread nicht fest zugeteilt. Vielmehr kann ein Thread Rechenzeit solange beanspruchen, bis er Rechenzeit an einen anderen Thread abgibt. Gibt der Thread die Rechenzeit nicht ab, können die anderen Threads nicht laufen. Dies kann eine Fehlerquelle darstellen. Vorteil dieses Threadmdodells ist, dass wenig Rechenzeit für das Multithreading verloren geht.&lt;br /&gt;
Da alle Threads im selben Adressbereich liegen und dieselbe Hardware benutzen, ist der Overhead für den Taskwechsel sehr kurz. Gleichzeitig muss bei dem Teilen der Resourcen darauf geachtet werden, dass die Threads nicht gegenseitig sich durch Überschreiben von Speicherbereichen oder Zugriff auf Resourcen stören. Dieses stellt aber auch einen Vorteil da, da Threads sich Resourcen auch teilen können.&lt;br /&gt;
Welcher Thread bei einem Taskwechsel als nächstes läuft, hängt davon ab welche Priorität er hat. Jeder Task hat eine Nummer zwischen 254 und 0. Je kleiner der Wert ist, desto höher ist die Priorität.&lt;br /&gt;
Ein Thread wird sofern er die Kontrolle nicht abgibt nur von Interrupts unterbrochen.&lt;br /&gt;
Die Funktion ''main()'' ist immer ein eigener Thread, der zusammen mit dem Idle-Thread läuft. Der Idle-Thread ist von der Applikation aus nicht sichtbar.&lt;br /&gt;
&lt;br /&gt;
Ein neuer Thread wird mit der Funktion ''NutThreadCreate'' erzeugt. Ein Thread ist nichts anderes als eine C-Funktion. Um plattformspezifische Deteils zu verbergen, wird zur Deklaration das THREAD-Makro verwendet.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 THREAD(Thread1, arg)&lt;br /&gt;
 {&lt;br /&gt;
     for (;;) {&lt;br /&gt;
         NutSleep(125)&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
     NutThreadCreate(&amp;quot;t1&amp;quot;, Thread1, 0, 512);&lt;br /&gt;
     for (;;) {&lt;br /&gt;
         NutSleep(125)&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm besteht aus zwei Endlosschleifen. Zunächst wird in der ''main()''-Funkion der Thread erzeugt. Anschließend läuft das Programm in eine Endlosschleife. Normalerweise könnte andere Code-Teile nicht mehr ausgeführt werden, das das Programm in der Endlosschleife &amp;quot;hängt&amp;quot;. Da die Endlosschleife die Kontrolle an andere Threads mit ''NutSleep'' abgibt, kommt auch der Thread zur Ausführung, der seinerseits eine Endlosschleife ist. Wichtig ist auch hier, dass der Thread die Kontrolle mit ''NutSleep'' wieder abgibt, da sonst der Main-Thread nicht weiter ausgeführt würde. Jeder Thread muss also die Prozesskontrolle abgeben.&lt;br /&gt;
&lt;br /&gt;
== Timer Management ==&lt;br /&gt;
== Heap Management ==&lt;br /&gt;
== Event Management ==&lt;br /&gt;
== Stream I/O ==&lt;br /&gt;
Typischerweise verwenden Programme die Standard-I/O-Bibliothek (z.B. printf) zwecks ausgabe. Da es bei Mikrocontrollern kein Standard-Ausgabesystem gibt, bedarf es einer Anpassung. Nut/OS bietet dazu Device-Treiber und eine eigene Bibliothek nutcrt, die die Standard-Funktionen der Laufzeitbibliothek des Compilers überschreibt:&lt;br /&gt;
&lt;br /&gt;
* void clearerr (FILE *stream) - Setzt den Fehlerstatus eines Streams zurück.&lt;br /&gt;
* int  fclose (FILE *stream) - Schließt einen Stream.&lt;br /&gt;
* void fcloseall (void) - Schließt alle offene Streams.&lt;br /&gt;
* int  feof (FILE *stream) - Prüft, ob ein Stream das Dateiende erreicht hat.&lt;br /&gt;
* int  ferror (FILE *stream) - Prüft einen Fehler in einem Dateistream.&lt;br /&gt;
* int  fflush (FILE *stream) - Flush eines Streams.&lt;br /&gt;
* int  fgetc (FILE *stream) - Liest ein Zeichen von einem Stream.&lt;br /&gt;
* char *  fgets (char *buffer, int count, FILE *stream) - Liest eine Zeile von einem Stream.&lt;br /&gt;
* FILE *  fopen (CONST char *name, CONST char *mode) - Öffnen eines Streams.&lt;br /&gt;
* int  fprintf (FILE *stream, CONST char *fmt,...) - Gibt Daten formatiert in einem Stream aus.&lt;br /&gt;
* int  fpurge (FILE *stream) - Löscht einen Stream, z.B. die in einem Eingabepuffer gespeicherten werden gelöscht.&lt;br /&gt;
* int  fputc (int c, FILE *stream) - Schreibt ein Zeichen auf einen Stream.&lt;br /&gt;
* int  fputs (CONST char *string, FILE *stream) - Schreibe einen String in einen Stream.&lt;br /&gt;
* size_t  fread (void *buffer, size_t size, size_t count, FILE *stream) - Lese Daten von einem Stream.&lt;br /&gt;
* FILE *  freopen (CONST char *name, CONST char *mode, FILE *stream) - Einen Stream erneut öffnen.&lt;br /&gt;
* int  fscanf (FILE *stream, CONST char *fmt,...) - Liest formatierte Daten von einem Stream.&lt;br /&gt;
* int  fseek (FILE *stream, long offset, int origin) - Verschiebt die Lese-/Schreibposition eines Streams.&lt;br /&gt;
* long  ftell (FILE *stream) - Gibt die Lese-/Schreibposition eines Streams zurück.&lt;br /&gt;
* size_t  fwrite (CONST void *data, size_t size, size_t count, FILE *stream) - Schreibt Daten in einen Stream.&lt;br /&gt;
* int  getc (FILE *stream) - Liest ein Zeichen von einem Stream.&lt;br /&gt;
* int  getchar (void) - Zeichenweise Lesen von der Standardeingabe.&lt;br /&gt;
* char *  gets (char *buffer) - Zeilenweises Lesen von der Standardeingabe. &lt;br /&gt;
* int  printf (CONST char *fmt,...) - Formatierte Ausgabe auf dem Standardausgabestream.&lt;br /&gt;
* int  putc (int c, FILE *stream) - Schreibe ein Zeichen auf den Stream.&lt;br /&gt;
* int  putchar (int c) - Schreibe ein Zeichen auf die Standardausgabe.&lt;br /&gt;
* int  puts (CONST char *string) - Gibt einen Stream auf stdout aus.&lt;br /&gt;
* int  scanf (CONST char *fmt,...) - Lese formatierte Daten vom Standardeingabestream. &lt;br /&gt;
* int  sprintf (char *buffer, CONST char *fmt,...) - Schreibt formatiert Daten in einen Stream. &lt;br /&gt;
* int  sscanf (CONST char *string, CONST char *fmt,...) - Least formatierte Daten von einem string. &lt;br /&gt;
* int  ungetc (int c, FILE *stream) - Schiebt gelesenes Zeichen in Stream zurück. &lt;br /&gt;
* int  vfprintf (FILE *stream, CONST char *fmt, va_list ap) - Schreibt Argumentenliste in vorgegebenen Format in Stream.&lt;br /&gt;
* int  vfscanf (FILE *stream, CONST char *fmt, va_list ap) - Liest formatierte Daten von einem Stream. &lt;br /&gt;
* int  vsprintf (char *buffer, CONST char *fmt, va_list ap) - Schreibt eine Liste von Argumenten formatiert in einen String.&lt;br /&gt;
* int  vsscanf (CONST char *string, CONST char *fmt, va_list ap) - Liest formatiete Daten von einen string.&lt;br /&gt;
&lt;br /&gt;
Darüber hinaus gibt es eine Reihe weiterer  low-level I/O-Funktionen:&lt;br /&gt;
* FILE *  _fdopen (int fd, CONST char *mode) - Open a stream associated with a file, device or socket descriptor.&lt;br /&gt;
* int  _fileno (FILE *stream) - Get the file descriptor associated with a stream.&lt;br /&gt;
* void  _flushall (void) - Flushes all streams&lt;br /&gt;
* int  _fmode (CONST char *mode)&lt;br /&gt;
* int  _getf (int _getb(int, void *, size_t), int fd, CONST char *fmt, va_list ap) - Read formatted data using a given input function.  &lt;br /&gt;
* int  _putf (int _putb(int, CONST void *, size_t), int fd, CONST char *fmt, va_list ap) - Write formatted data using a given output function.&lt;br /&gt;
&lt;br /&gt;
Um bei Harvard Architekturen, z.B. Atmel AVR, RAM Speicher einzusparen, gibt es für bestimmte Funktionen eine Variante, bei der der konstante String direkt aus dem Flash Speicher gelesene wird:&lt;br /&gt;
* int  fprintf_P (FILE *stream, PGM_P fmt,...) - Print formatted data to a stream.&lt;br /&gt;
* int  fputs_P (PGM_P string, FILE *stream) - Write a string from progam memory to a stream. &lt;br /&gt;
* int  fscanf_P (FILE *stream, PGM_P fmt,...) - Read formatted data from a stream.&lt;br /&gt;
* size_t  fwrite_P (PGM_P data, size_t size, size_t count, FILE *stream) - Write data from program space to a stream.&lt;br /&gt;
* int  printf_P (PGM_P fmt,...) - Print formatted output to the standard output stream. &lt;br /&gt;
* int  puts_P (PGM_P string) - Write a string from program memory to stdout. &lt;br /&gt;
* int  scanf_P (PGM_P fmt,...) - Read formatted data from the standard input stream. &lt;br /&gt;
* int  sprintf_P (char *buffer, PGM_P fmt,...) - Write formatted data to a string. &lt;br /&gt;
* int  sscanf_P (CONST char *string, CONST char *fmt,...) - Read formatted data from a string. &lt;br /&gt;
* int  vfprintf_P (FILE *stream, PGM_P fmt, va_list ap) - Write argument list to a stream using a given format. &lt;br /&gt;
* int  vfscanf_P (FILE *stream, PGM_P fmt, va_list ap) - Read formatted data from a stream. &lt;br /&gt;
* int  vsprintf_P (char *buffer, PGM_P fmt, va_list ap) - Write argument list to a string using a given format. &lt;br /&gt;
* int  vsscanf_P (CONST char *string, PGM_P fmt, va_list ap) - Read formatted data from a string.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aufgrund der Vielzahl der angepassten I/O-Funktionen ist es einfach, ein PC-Programm zu portieren. Wichtig dabei ist jedoch, dass vor der Nutzung eines Standarddevices wie z.B. stdin, stdout oder stderr, dieses Device per Devicetreiber zugewiesen wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dev/board.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    /* Device für Ausgabe vorbereiten */&lt;br /&gt;
    u_long baud = 115200;&lt;br /&gt;
    NutRegisterDevice(&amp;amp;DEV_UART, 0, 0);&lt;br /&gt;
    freopen(DEV_UART_NAME, &amp;quot;w&amp;quot;, stdout);&lt;br /&gt;
    _ioctl(_fileno(stdout), UART_SETSPEED, &amp;amp;baud);   &lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for(;;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Fehlerquelle bei der Verwendung der Nut/OS Ausgabefunktionen kann sein, dass man tatsächlich die Ausgaberoutinen  der Standard-Bibliothek versehentlich verwendet hat. Ein Blick in die Mapping-Datei verschafft dann Klarheit.&lt;br /&gt;
&lt;br /&gt;
== Dateisystem ==&lt;br /&gt;
== Device Treiber ==&lt;br /&gt;
== Netzwerk-API ==&lt;/div&gt;</summary>
		<author><name>Bg</name></author>	</entry>

	</feed>