Homepage Wiki Forum Buy

GNUBLIN embedded GNU/Linux

Open source learning and training plattorm for embedded GNU / Linux
A projects from Hochschule Augsburg and embedded projects GmbH

Project homepage: http://www.gnublin.org
Wiki: http://wiki.gnublin.org
Aktuelle Zeit: Mo 25. Sep 2017, 17:00

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Di 12. Feb 2013, 10:28 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Scheint nicht so: "Die Dateierweiterung h ist nicht erlaubt" und dasselbe für c.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Mi 13. Feb 2013, 00:35 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Hier "zum Anfixen" schon mal die Header-Datei inline, die C Source ist etwas länger, das muss warten, bis Benedikt C als Anhang erlaubt hat.
Code:
/* lpc3131_gpio.h
**
** user space memory mapped GPIO for LPC3131
**
** author: Markus Kuhn, AKA Schwabix in the GNUBLIN Forum
** revisions:
** 2013-02-03: first implementation
** 2013-02-12: first public release, free to share!
*/

#ifndef LPC3131_GPIO_H
#define LPC3131_GPIO_H

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus


#include <sys/types.h>


/* error return codes
** and a simple macro for error checks, will exit(e) on error if e!=0
*/
typedef enum { gpio_ok
             , gpio_no_init
             , gpio_no_bit_init
             , gpio_no_dev_mem
             , gpio_mmap_fail
             , gpio_sysfs_fail
             , gpio_invalid_bit
             } gpio_err;
#define GPIO_CHECK(f,e) { gpio_err err; \
                          if ((err=(f)) != gpio_ok) { \
                            printf("ERROR: %s returned error %d '%s'.\n", #f, err, gpio_err_str(err)); \
                            if (e) exit(e); \
                        } }

/* access mode for ports.
** CAUTION: mixing in-out with gpio_fast may currently cause problems, under evaluation
*/
typedef enum { gpio_sysfs        // access via sysfs
             , gpio_fastin       // read via mmap, write via sysfs
             , gpio_fastout      // write via mmap, read via sysfs
             , gpio_fast         // access mem mapped registers
             , gpio_sysfs_cached // sysfs with one open file per used bit
             } gpio_access;


/* the bit names, NXP named them out of order!
**
** gpi4      is input only, write 1 will crash system!
** gpio5..10 are multiplexed, they are part of
**           EBI_MCI register range and thus not here!
*/
typedef enum { gpio1,  gpio0,  gpio2,  gpio3
             , gpi4, /*gap!*/  gpio11, gpio12, gpio13
             , gpio14, gpio15, gpio16, gpio17
             , gpio18, gpio19, gpio20
             } gpio_bit;
#define GPIO_MAX_BIT  gpio20


/* functions on GNUBLIN std/ext/elektor, rest is n/a
** GNUBLIN dip has no functions assigned, and all gpio available
*/
#define GPIO_LED        gpio3
#define GPIO_USR1       gpio11
#define GPIO_USR2       gpio14
#define GPIO_USR3       gpio15
#define GPIO_BUTTON     gpio15  // shared with GPIO_USR3
#define GPIO_RELAIS     gpio18


gpio_err     gpio_init(gpio_access acc);
void         gpio_exit();

const char * gpio_err_str(gpio_err err);

gpio_err     gpio_setOutput(gpio_bit bit);
gpio_err     gpio_setInput(gpio_bit bit);

gpio_err     gpio_setHigh(gpio_bit bit);
gpio_err     gpio_setLow(gpio_bit bit);

gpio_err     gpio_read(gpio_bit bit, char * pResult);
char         gpio_readc(gpio_bit bit); // handy, but no error check!


#ifdef __cplusplus
}
#endif // __cplusplus

#endif // LPC3131_GPIO_H


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Do 14. Feb 2013, 06:20 
Offline
Administrator

Registriert: Sa 7. Apr 2012, 09:18
Beiträge: 251
hm da gibts nichts. Kannst du ein Archiv .zip oder .tar.gz heraufladen?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Do 14. Feb 2013, 10:56 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Dateianhang:
lpc3131_gpio.tar.gz [3.25 KiB]
222-mal heruntergeladen
Bingo! Ein tarball geht.

Also, das ist nun eine Sammlung von GPIO Funktionen für C / C++.

Beim Initialisieren des Moduls mit gpio_init muss man wählen, wie auf die Ports zugegriffen werden soll: über sysfs oder memory mapped oder eine Mischform aus beiden.
Ein Beispielprogramm zur Nutzung befindet sich in Form eines Unit-Tests am Ende der C Source. Defniert man beim Kompilieren MAIN, wird es als Konsolenprogramm erzeugt, z.B. so:
Code:
gcc -DMAIN lp3131_gpio.c -o gpio_test

Für eigene Projekte sollte man das Modul am besten per Makefile einbinden, z.B. so:
Code:
CC = arm-linux-gnueabi-gcc

all:      myStuff

clean:
   rm -f *.o *~ myStuff lpc3131_gpio.o

lpc3131_gpio.o:   lpc3131_gpio.c \
               lpc3131_gpio.h

myStuff:         mySource1.c mySource2.c \
               lpc3131_gpio.o

Wer noch das letzte Quäntchen Geschwindigkeit rauspressen will, kann in der C Source, Zeile 23 das MINIMIZED_ERROR_CHECKS aktivieren. Für meine Messungen brachte das allerdings nichts.

Bei Fragen ... ich bin in letzter Zeit öfter hier ;)


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: So 7. Apr 2013, 08:44 
Offline

Registriert: Sa 23. Mär 2013, 08:22
Beiträge: 10
Hallo Schwabix,

Diene Sammlung von GPIO Funktionen finde ich genial.
Wenn ich Dein Beispiel auf meinem Gnublin Board nach Deinen Vorgaben (gcc -DMAIN lp3131_gpio.c -o gpio_test) kompiliere
funktioniert alles wunderbar, auch mit Ein -und Ausgaben gemischt ohne unregelmäßige Ausgaben.
Aber wenn ich Dein Beispiel auf meinem Hauptrechner mit der Toolchain eldk-eglibc-i686-arm-toolchain-qte-5.2.1 wie folgt kompiliere
"arm-linux-gnueabi-gcc -o lpc3131_gpoi lpc3131_gpio.c" (hab ich bis jetzt immer so gemacht und geht)
erhalte ich eine Fehlermeldung:
"/opt/eldk-5.2.1/armv5te/sysroots/armv5te-linux-gnueabi/usr/lib/crt1.o: in funktion `start`:
init.c:(.text+0x34): undefined reference to `main'
collect2: ld returned 1 exit status"
Bis jetzt hab ich alle Programme auf meinem Hauptrechner compiliert. (geht schneller und ich hab auf dem Gnublin PCB nicht so viel von mir fabrizierten Datenmüll)
Da ich relativer Neuling in Linux und C bin, kenn ich mich mit Makefiles leider überhaupt nicht aus.

Kannst Du oder eventuell auch jemand anders mir da weiterhelfen?

Gruß
Jens


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: So 7. Apr 2013, 17:10 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Hallo Jens,

Da ich ein geduldiger Mensch bin, kompiliere ich bisher immer auf dem Gnublin. Man könnte es auch mit Faulheit, die Cross-Toolchain auf meinem Raspberry zu installieren, denn da hängt mein Gnublin während der Entwicklung dran.

Die Fehlermeldung würde ich so intepretieren (wenn jemand eine bessere Erklärung hat, bin ich nicht böse ;) ):

So wie Du gcc aufrufst, will er aus diesem einen Modul ein ausführbares Executable erzeugen, in lpc3131_gpio.c gibt es jedoch keine Funktion 'main' (es sei denn, Du aktivierst den Modultest mit -DMAIN), die für C-Programme Pflicht ist.
Wenn Du weiterhin aus der Shell direkt den Kompiler aufrufen willst, musst Du noch zusätzlich eine Sourcedatei mit Deinem main angeben, also z.B. so
Code:
arm-linux-gnueabi-gcc -o lpc3131_gpoi myMain.c lpc3131_gpio.c


Oder Du gehst den vorgeschlagenen Weg mit einem Makefile; wenn das Projekt zu wachsen droht, ist das auf jeden Fall der bessere Weg. Dadurch kannst Du verschiedene Funktionsbereiche Deiner Anwendung in getrennten C-Sourcen unterbringen. Für jedes Modul schreibst Du dann eine Abhängigkeitsregel in den Makefile, so wie in meinem Post mit 'myStuff' vorgeschlagen. Streng genommen gehört jeder includierte Header .h in die Abhänigkeitsliste, die Standardheader lässt man aber idR weg.
Damit kann das Tool make nach Deinen Änderungen jeweils entscheiden, welche Teile neu übersetzt werden müssen um alle Bestandteile Deines Executables wieder auf den neusten Stand zu bringen. Das wird anhand des Dateidatums entschieden; ein Gnublin ohne Uhr macht da gelegentlich Ärger.
Übersetzt wird dann ganz einfach mit
Code:
make
oder
Code:
make all

Über verschiedene sgn. Targets (im Beispiel all) kann man auch mehrere verwandte Ziele in einem Makefile unterbringen.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: So 7. Apr 2013, 22:17 
Offline

Registriert: Sa 23. Mär 2013, 08:22
Beiträge: 10
Hallo Schwabix,

vielen Dank für Deine schnelle ausführliche Erklärung.
Ich habs nochmal mit
Code:
arm-linux-gnueabi-gcc -DMAIN lpc3131_gpo.c -o lpc3131_gpio

probiert und es funktioniert.

Bis jetzt brauchte, und kannte ich noch nicht den Parameter -DMAIN beim Compiler-Aufruf,
ich hab gedacht er wäre nur für`s Gnublin Board nötig.

Es gibt also noch viel zu lernen.

Vielen Dank nochmal und
Gruß
Jens


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Mo 8. Apr 2013, 07:48 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Jens,

Jedem Kompileraufruf kann man sgn. Defines auf der Befehlszeile mitgeben. Die werden dann behandelt als stünde am Anfang jeder damit übersetzten Source eine Zeile '#define MAIN'. Das 'MAIN' ist dabei nur ein Beispiel, statt dessen kann da alles stehen, was hinter #define stehen darf, nur wird das Symbol von eventuellem Makro mit Gleichheitszeichen getrennt und man muss mit Leerzeichen acht geben.
Beispiel: 'gcc -MLoopCount=1000 mybenchmark.c -o benchmark1000'

So lassen sich aus einer Source verschiedene Varianten übersetzen.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Do 11. Apr 2013, 08:52 
Offline

Registriert: Do 8. Nov 2012, 09:47
Beiträge: 93
Wohnort: Aachen
Fehlerteufel, die Zeile muss natürlich
Zitat:
gcc -DLoopCount=1000 mybenchmark.c -o benchmark1000

lauten.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: GPIO in C
BeitragVerfasst: Do 18. Apr 2013, 15:16 
Offline

Registriert: Sa 6. Apr 2013, 11:12
Beiträge: 22
Hallo Schwabix,

hast du diesen Kommentar von weiter oben mal nachvollziehen können ?
Zitat:
// GPIO3 kippt bei mir zufällig
while (getPort(mymem, GPIO11)) {
setPortHigh(mymem, GPIO3);
}
// GPIO3 bleibt nahezu stabil... aber nur wenn das printf drin ist
while (value) {
setPortHigh(mymem, GPIO3);
value = getPort(mymem, GPIO11);
printf("pin:%i\n",value);
}


Das Problem hatte ich gestern nämlich auch so weit nachvollziehen können. Ich hab doch hier irgendwo auch ein Posting zum Thema "Signalflanken werden nicht erkannt". Soweit ich das debuggen konnte, liegt das am Mapped Memory. Sobald ich darauf verzichte oder ebenfalls ein printf einbauen funktioniert alles.

Mfg,
Jens


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 25 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
cron
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de