Eigenes Modul hinzufügen: Unterschied zwischen den Versionen
(→Funktion beim Boot und Periodisch aufrufen lassen) |
K (→Funktion beim Boot und Periodisch aufrufen lassen) |
||
Zeile 78: | Zeile 78: | ||
* '''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 wie bei mainloop. Beispiel timer(50, function). | ||
+ | * '''header''' - nicht dokumentiert | ||
== Debug Ausgaben == | == Debug Ausgaben == |
Version vom 19. April 2009, 16:40 Uhr
Hier findest du die wichtigsten Informationen, um dein eigenes Modul entwickeln zu können. Beachte bitte auch den projektweit gültigen Coding Style.
Inhaltsverzeichnis
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:
/* * * 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 2 * 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.
- Die Email Adresse kann verschleiert werden, etwa max.mustermann ät email DÖT de.
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. 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):
- Die Datei soll immer mit eingelinkt werden.
SRC += Pfad/deinedatei.c
- Die Datei soll in Abhängigkeit von einer Konfigurationsoption aus Menuconfig mit eingebunden werden.
${DEINGENIALESMODUL_SUPPORT}_SRC += Pfad/deinedatei.c
- 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
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):
TOPDIR ?= ../.. include $(TOPDIR)/.config $(DC3840_SUPPORT)_SRC += hardware/camera/dc3840.c ############################################################################## # generic fluff include $(TOPDIR)/scripts/rules.mk
Abhängig von der Ordnertiefe des von dir angelegten Ordners musst du selbstverständlich die Zahl der ../ betreffend TOPDIR anpassen.
Funktion beim Boot und Periodisch aufrufen lassen
- Du hast ein neues Modul entwickelt, dieses Enthält eine Initialisierungsfunktion, die beim Start der Ethersex-Firmware aufgerufen werden muss.
- 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 wie bei mainloop. Beispiel timer(50, function).
- header - nicht dokumentiert
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.
Folgende Debug Funktionen 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