Eigenes Modul hinzufügen: Unterschied zwischen den Versionen

Aus Ethersex_Wiki
Wechseln zu: Navigation, Suche
(Funktion beim Boot und Periodisch aufrufen lassen)
K (timer Erläuterung ergänzt)
 
(10 dazwischenliegende Versionen von 8 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Hier findest du die wichtigsten Informationen, um dein eigenes Modul entwickeln zu können. Beachte bitte auch den projektweit gültigen [[Coding_style|Coding Style]].
+
Hier findest du die wichtigsten Informationen, um dein eigenes Modul entwickeln zu können. Beachte bitte auch den projektweit gültigen [[Coding_style|coding style]] und weitere Infos wie unter [[Pins in Ethersex definieren]].
  
 
== Lizenz ==
 
== Lizenz ==
Damit dein Modul mit ethersex veröffentlicht werden kann, musst du deinen Code unter die selbe Lizenz stellen (GPLv2+ bzw. GPLv3). Füge dafür folgenen Lizenzkopf in jede deiner Quellcode Dateien (*.h,*.c) ein:
+
Damit dein Modul mit ethersex veröffentlicht werden kann, musst du deinen Code unter eine GPLv3-kompatible Lizenz stellen. Füge dazu am besten folgenen Lizenzkopf in jede deiner Quellcode Dateien (*.h,*.c) ein:
  
 
  /*
 
  /*
Zeile 10: Zeile 10:
 
  * This program is free software; you can redistribute it and/or
 
  * This program is free software; you can redistribute it and/or
 
  * modify it under the terms of the GNU General Public License
 
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
+
  * as published by the Free Software Foundation; either version 3
 
  * of the License, or (at your option) any later version.
 
  * of the License, or (at your option) any later version.
 
  *
 
  *
Zeile 27: Zeile 27:
  
 
* Vergiss nicht, DEIN_NAME durch deinen Namen zu ersetzen.
 
* Vergiss nicht, DEIN_NAME durch deinen Namen zu ersetzen.
* Die Email Adresse kann verschleiert werden, etwa max.mustermann ät email DÖT de.
 
  
 
== Richtiges Verzeichnis ==
 
== Richtiges Verzeichnis ==
Du kannst dein Modul in eines der Verzeichnisse Hardware, Services oder Protocols einsortieren. Wenn dein Modul mehrere dieser Kategorien erfüllt, muss das Modul eventuell in kleinere Untermodule aufgeteilt werden. Genaue Beschreibungen findest du im jeweiligen Verzeichnis in der Datei "content.txt". Wenn du dir nicht sicher bist, wo dein Modul genau einsortiert werden sollte, frag' in der Mailingliste nach.
+
Du kannst dein Modul in eines der Verzeichnisse „hardware“, „services“ oder „protocols“ einsortieren. Wenn dein Modul mehrere dieser Kategorien erfüllt, muss das Modul eventuell in kleinere Untermodule aufgeteilt werden. Genaue Beschreibungen findest du im jeweiligen Verzeichnis in der Datei "content.txt". Wenn du dir nicht sicher bist, wo dein Modul genau einsortiert werden sollte, frag in der Mailingliste nach.
  
 
Die 3 Kategorien grob umrissen:
 
Die 3 Kategorien grob umrissen:
Zeile 38: Zeile 37:
  
 
== Dateien in Make-Prozess aufnehmen ==
 
== Dateien in Make-Prozess aufnehmen ==
Du hast in einem beliebigen Unterverzeichnis eine Datei hinzugefügt und möchtest natürlich, dass das Make-System diese jetzt auch mit berücksichtigt. Hierzu gibt's grob eingeteilt drei Hauptvarianten.  Abhängig vom Ziel musst du eine der folgenden Alternativen aufnehmen (du kannst dich dabei auch an den bereits vorhandenen Einträgen orientieren):
+
Du hast in einem beliebigen Unterverzeichnis eine Datei hinzugefügt und möchtest natürlich, dass das Make-System diese jetzt auch mit berücksichtigt. Dazu musst du ein Makefile erstellen, welches beispielsweise wie folgt aussehen kann:
  
# Die Datei soll immer mit eingelinkt werden.<pre>SRC += Pfad/deinedatei.c</pre>
 
# Die Datei soll in Abhängigkeit von einer Konfigurationsoption aus Menuconfig mit eingebunden werden.<pre>${DEINGENIALESMODUL_SUPPORT}_SRC += Pfad/deinedatei.c</pre>
 
# Die Datei soll in Abhängigkeit von einer Konfigurationsoption mit eingebunden werden, wenn der ECMD-Parser aktiviert ist.<pre>${DEINGENIALESMODUL_SUPPORT}_ECMD_SRC += Pfad/deinedatei.c</pre>
 
 
Wenn du ein neues Verzeichnis angelegt hast, sollte die von dir zu erstellende Makefile in etwa so aussehen (hier die ''hardware/camera/Makefile'' als Beispiel):
 
 
<pre>
 
<pre>
 
TOPDIR ?= ../..
 
TOPDIR ?= ../..
Zeile 55: Zeile 49:
 
include $(TOPDIR)/scripts/rules.mk
 
include $(TOPDIR)/scripts/rules.mk
 
</pre>
 
</pre>
 +
 +
Anstelle der Variable, die auf _SRC endet, kannst du eine der folgenden Alternativen wählen:
 +
 +
# Die Datei soll immer mit eingelinkt werden.<pre>SRC += Pfad/deinedatei.c</pre>
 +
# Die Datei soll in Abhängigkeit von einer Konfigurationsoption aus Menuconfig mit eingebunden werden.<pre>${DEINGENIALESMODUL_SUPPORT}_SRC += Pfad/deinedatei.c</pre>
 +
# Die Datei soll in Abhängigkeit von einer Konfigurationsoption mit eingebunden werden, wenn der ECMD-Parser aktiviert ist.<pre>${DEINGENIALESMODUL_SUPPORT}_ECMD_SRC += Pfad/deinedatei.c</pre>
  
 
Abhängig von der Ordnertiefe des von dir angelegten Ordners musst du selbstverständlich die Zahl der ''../'' betreffend ''TOPDIR'' anpassen.
 
Abhängig von der Ordnertiefe des von dir angelegten Ordners musst du selbstverständlich die Zahl der ''../'' betreffend ''TOPDIR'' anpassen.
 +
 +
Weiterhin musst du dein Makefile dem eigentlichen Makefile in $(TOPDIR) bekannt machen, indem du es folgendermaßen hinzufügst:
 +
SUBDIRS += hardware/camera
 +
 +
== Menuconfig ==
 +
 +
Um dein Modul zur grafischen Konfiguration hinzuzufügen (make menuconfig), brauchst du im Ordner deines Moduls eine Datei namens config.in, beispielsweise mit folgendem Inhalt:
 +
dep_bool_menu 'Genius module' DEINGENIALESMODUL_SUPPORT $TCP_SUPPORT
 +
Dieser Eintrag bedeutet, dass du dein Modul nur dann aktivieren kannst, wenn TCP_SUPPORT aktiviert ist. Weiters wird hier noch ein Untermenü angelegt. Um dein Modul ohne Abhängigkeiten und ohne zusätzlichem Menü aktivieren zu können solltest du folgende Methode wählen:
 +
bool 'Genius module' DEINGENIALESMODUL_SUPPORT
 +
 +
Dieses musst du, analog zum Makefile, in $(TOPDIR)/config.in hinzufügen:
 +
source hardware/camera/config.in
  
 
== Funktion beim Boot und Periodisch aufrufen lassen ==
 
== Funktion beim Boot und Periodisch aufrufen lassen ==
Zeile 77: Zeile 90:
 
* '''net_init''' - zum Initialisieren von Netzwerkanwendungen.  Die Funktionen werden nach den ''init''-Funktionen ausgeführt.
 
* '''net_init''' - zum Initialisieren von Netzwerkanwendungen.  Die Funktionen werden nach den ''init''-Funktionen ausgeführt.
 
* '''startup''' - diese Funktionen werden vor Aufruf der Mainloop gestartet.  Der Sendmail-Service sendet hier beispielsweise die Startnachricht.
 
* '''startup''' - diese Funktionen werden vor Aufruf der Mainloop gestartet.  Der Sendmail-Service sendet hier beispielsweise die Startnachricht.
* '''timer''' - Periodisch wie bei mainloop. Beispiel timer(50, function).
+
* '''timer''' - Periodisch (alle 20ms) wie bei mainloop. Beispiel: timer(50, function()) ruft function() alle 50*20ms auf, also 1x pro Sekunde.
 +
* '''header''' - nicht dokumentiert
 +
 
 +
Bei den aufzurufenden Funktionen muss bei init(<fkt>) die Funktion ohne Klammern und bei timer(<int>, <fkt>()) mit Klammern geschrieben werden.
  
== Debug Ausgaben ==
+
== Debug-Ausgaben ==
Für eingebettete Systeme zu programmieren kann manchmal ziemlich nervenaufreibend sein. In der Regel hat man nicht die nötige Hardware (JTAG) um step-by-step debugging durchführen zu können. Der ethersex Core bietet dir einige Debug Ausgabe Funktionen an, um zumindest über syslog oder die serielle Schnittstelle den Programmablauf mitverfolgen zu können.
+
Für eingebettete Systeme zu programmieren kann manchmal ziemlich nervenaufreibend sein. In der Regel hat man nicht die nötige Hardware (JTAG) um step-by-step Debugging durchführen zu können. Der ethersex Core bietet dir einige Debug-Ausgabefunktionen an um zumindest über syslog oder die serielle Schnittstelle den Programmablauf mitverfolgen zu können.
  
Folgende Debug Funktionen kannst du nutzen, nachdem du core/debug.h inkludiert hast:
+
Folgende Debugfunktionen kannst du nutzen, nachdem du core/debug.h inkludiert hast:
 
* void debug_printf(s, args...); // Syntax wie bei printf aus der standard C library
 
* void debug_printf(s, args...); // Syntax wie bei printf aus der standard C library
 
* char* debug_binary(uint8_t); // Gibt eine 8 Byte lange Zeichenfolge von 0/1 zurück, die den integer repräsentiert
 
* char* debug_binary(uint8_t); // Gibt eine 8 Byte lange Zeichenfolge von 0/1 zurück, die den integer repräsentiert
 +
 +
Folgende Debug Funktionen kannst du nutzen, nachdem du protocols/syslog/syslog.h inkludiert hast:
 +
* void syslog_sendf(s, args...); // Syntax wie bei printf aus der standard C library
 +
 +
[[Category:Ethersex]]
 +
[[Category:StepByStep]]

Aktuelle Version vom 14. Februar 2011, 23:27 Uhr

Hier findest du die wichtigsten Informationen, um dein eigenes Modul entwickeln zu können. Beachte bitte auch den projektweit gültigen coding style und weitere Infos wie unter Pins in Ethersex definieren.

Lizenz

Damit dein Modul mit ethersex veröffentlicht werden kann, musst du deinen Code unter eine GPLv3-kompatible Lizenz stellen. Füge dazu am besten folgenen Lizenzkopf in jede deiner Quellcode Dateien (*.h,*.c) ein:

/*
*
* Copyright (c) 2009 by DEIN_NAME <DAVOR@DANACH.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* For more information on the GPL, please go to:
* http://www.gnu.org/copyleft/gpl.html
*/
  • Vergiss nicht, DEIN_NAME durch deinen Namen zu ersetzen.

Richtiges Verzeichnis

Du kannst dein Modul in eines der Verzeichnisse „hardware“, „services“ oder „protocols“ einsortieren. Wenn dein Modul mehrere dieser Kategorien erfüllt, muss das Modul eventuell in kleinere Untermodule aufgeteilt werden. Genaue Beschreibungen findest du im jeweiligen Verzeichnis in der Datei "content.txt". Wenn du dir nicht sicher bist, wo dein Modul genau einsortiert werden sollte, frag in der Mailingliste nach.

Die 3 Kategorien grob umrissen:

  • Hardware: Module, die es ermöglichen externe Hardware anzusteuern.
  • Services: Module, die Anwendungen/Daemons/Services realisieren.
  • Protocols: Module, die Protokolle implementieren.

Dateien in Make-Prozess aufnehmen

Du hast in einem beliebigen Unterverzeichnis eine Datei hinzugefügt und möchtest natürlich, dass das Make-System diese jetzt auch mit berücksichtigt. Dazu musst du ein Makefile erstellen, welches beispielsweise wie folgt aussehen kann:

TOPDIR ?= ../..
include $(TOPDIR)/.config

$(DC3840_SUPPORT)_SRC += hardware/camera/dc3840.c

##############################################################################
# generic fluff
include $(TOPDIR)/scripts/rules.mk

Anstelle der Variable, die auf _SRC endet, kannst du eine der folgenden Alternativen wählen:

  1. Die Datei soll immer mit eingelinkt werden.
    SRC += Pfad/deinedatei.c
  2. Die Datei soll in Abhängigkeit von einer Konfigurationsoption aus Menuconfig mit eingebunden werden.
    ${DEINGENIALESMODUL_SUPPORT}_SRC += Pfad/deinedatei.c
  3. Die Datei soll in Abhängigkeit von einer Konfigurationsoption mit eingebunden werden, wenn der ECMD-Parser aktiviert ist.
    ${DEINGENIALESMODUL_SUPPORT}_ECMD_SRC += Pfad/deinedatei.c

Abhängig von der Ordnertiefe des von dir angelegten Ordners musst du selbstverständlich die Zahl der ../ betreffend TOPDIR anpassen.

Weiterhin musst du dein Makefile dem eigentlichen Makefile in $(TOPDIR) bekannt machen, indem du es folgendermaßen hinzufügst:

SUBDIRS += hardware/camera

Menuconfig

Um dein Modul zur grafischen Konfiguration hinzuzufügen (make menuconfig), brauchst du im Ordner deines Moduls eine Datei namens config.in, beispielsweise mit folgendem Inhalt:

dep_bool_menu 'Genius module' DEINGENIALESMODUL_SUPPORT $TCP_SUPPORT

Dieser Eintrag bedeutet, dass du dein Modul nur dann aktivieren kannst, wenn TCP_SUPPORT aktiviert ist. Weiters wird hier noch ein Untermenü angelegt. Um dein Modul ohne Abhängigkeiten und ohne zusätzlichem Menü aktivieren zu können solltest du folgende Methode wählen:

bool 'Genius module' DEINGENIALESMODUL_SUPPORT

Dieses musst du, analog zum Makefile, in $(TOPDIR)/config.in hinzufügen:

source hardware/camera/config.in

Funktion beim Boot und Periodisch aufrufen lassen

  1. Du hast ein neues Modul entwickelt, dieses Enthält eine Initialisierungsfunktion, die beim Start der Ethersex-Firmware aufgerufen werden muss.
  2. Dein Modul enthält eine Funktion, die nach Möglichkeit ständig wieder aufgerufen wird (bzw. möglichst oft, soviel Rechenzeit wie die anderen Applikationen die ebenfalls ihre Dienste verrichten sollen, übrig lassen)

Hierzu gibt es die Ethersex Meta-Bereiche, die du evtl. bereits am Ende der einen oder anderen C-Datei entdeckt hast. Diese haben grundsätzlich den folgenden Aufbau:

/*
  -- Ethersex META --
  mainloop(stella_process)
  init(stella_init)
*/

Diese Zeilen, am Dateiende eingefügt, sorgen dafür, dass die Funktion stella_init einmal beim Start der von dir modifizierten Ethersex-Firmware aufgerufen wird und die Funktion stella_process' möglichst oft. Du kannst in den Meta-Bereich auch mehrere init-Direktiven aufnehmen, etc.

Weitere Direktiven sind:

  • initearly - funktioniert wie init. Die Funktionen werden nur vor init aufgerufen. Dies ist bei Abhängigkeiten praktisch, in der Regel solltest du jedoch init verwenden.
  • net_init - zum Initialisieren von Netzwerkanwendungen. Die Funktionen werden nach den init-Funktionen ausgeführt.
  • startup - diese Funktionen werden vor Aufruf der Mainloop gestartet. Der Sendmail-Service sendet hier beispielsweise die Startnachricht.
  • timer - Periodisch (alle 20ms) wie bei mainloop. Beispiel: timer(50, function()) ruft function() alle 50*20ms auf, also 1x pro Sekunde.
  • header - nicht dokumentiert

Bei den aufzurufenden Funktionen muss bei init(<fkt>) die Funktion ohne Klammern und bei timer(<int>, <fkt>()) mit Klammern geschrieben werden.

Debug-Ausgaben

Für eingebettete Systeme zu programmieren kann manchmal ziemlich nervenaufreibend sein. In der Regel hat man nicht die nötige Hardware (JTAG) um step-by-step Debugging durchführen zu können. Der ethersex Core bietet dir einige Debug-Ausgabefunktionen an um zumindest über syslog oder die serielle Schnittstelle den Programmablauf mitverfolgen zu können.

Folgende Debugfunktionen kannst du nutzen, nachdem du core/debug.h inkludiert hast:

  • void debug_printf(s, args...); // Syntax wie bei printf aus der standard C library
  • char* debug_binary(uint8_t); // Gibt eine 8 Byte lange Zeichenfolge von 0/1 zurück, die den integer repräsentiert

Folgende Debug Funktionen kannst du nutzen, nachdem du protocols/syslog/syslog.h inkludiert hast:

  • void syslog_sendf(s, args...); // Syntax wie bei printf aus der standard C library