2016-06-03 24 views
2

Ich versuche, einen SPI-Treiber für benutzerdefinierte Hardware zu implementieren. Ich habe mit einer Kopie des Spidev-Treibers begonnen, der fast alles unterstützt, was ich brauche.Benutzerdefinierter SPI-Treiber zur Implementierung von lseek

Wir verwenden ein Protokoll, das aus drei Teilen besteht: einem Befehlsbit (Lesen/Schreiben), einer Adresse und einer beliebigen Datenmenge.

Ich hatte angenommen, dass das Hinzufügen von LSEEK-Funktionen der beste Weg wäre, dies zu tun. Suchen Sie nach der gewünschten Adresse und lesen oder schreiben Sie eine beliebige Anzahl von Bytes. Ich habe ein benutzerdefiniertes .llseek in den file_operations des neuen Treibers erstellt, aber ich habe nie gesehen, dass diese Funktion überhaupt aufgerufen wird. Ich habe versucht, fseek(), lseek() und pread() zu verwenden, und keine dieser Funktionen scheint die neue Funktion my_lseek() aufzurufen. Jeder Anruf Berichte „errno 29 ESPIPE Illegal Suche“

Das Gerät in der board.c-Datei definiert ist:

static struct spi_board_info my_spi_board_info[] __initdata = { 
[0] = { 
    .modalias  = "myspi", 
    .bus_num  = 1, 
    .chip_select = 0, 
    .max_speed_hz = 3000000, 
    .mode   = SPI_MODE_0, 
    .controller_data = &spidev_mcspi_config, 
}, ... 

ich vermute, es etwas mit der Art und Weise sein könnte, dass die dev-Dateien erstellt bekommen, vor allem, weil das Beispiel, dass ich Referenzen filp-> f_pos

static int myspi_llseek(struct file *filp, loff_t off, int whence) 
{ 
    ... 
    newpos = filp->f_pos + off; 
    ... 
} 

So sind meine Fragen gefunden: gibt es eine Möglichkeit, diese Treiber zu haben (leicht modifizierte spidev) unterstützen die „suchen“ nennen? An welchem ​​Punkt wird errno 29 zurückgegeben? Muss ich von einem neuen Treiber starten und mich nicht auf die Installation von spi_board_info() und spi_register_board_info() verlassen können?

Nur ein Treiber im Verzeichnis/drivers/spi (spi-dw) verweist auf lseek und verwendet die Implementierung default_llseek. Es gibt ein paar "Hacks", die wir uns ausgedacht haben, um alles zum Laufen zu bringen, aber ich bin eher eine Person, die lernen will, es richtig zu machen.

Alle Vorschläge werden sehr geschätzt! (PS, die Kernel-Version ist 3.4.48 für ein OMAP Android-System)

+0

Ich vermute, dass irgendwo, müssen Sie die * anfängliche * Position auf "0" statt "-1", aber ich habe dieses Zeug nie getan. – o11c

+0

* "Nur ein Treiber im Verzeichnis/drivers/spi (spi-dw) verweist auf lseek ..." * - Das ist völlig irrelevant. Dieses Verzeichnis (außer spidev.c) ist für SPI-Master-Controller und nicht für SPI-Slave-Geräte. Die SPI-Protokolltreiber für SPI-Slave-Geräte sind in ihrem jeweiligen Subsystemverzeichnis gespeichert. IOW durch ihre * Funktionalität *, und nicht ihre (SPI) Schnittstelle. * "An welchem ​​Punkt wird das definiert, um errno 29 zurückzugeben?" * - Hast du versucht, nach ESPIPE zu suchen? Bist du vergesslich und hast immer noch den Anruf zu ** no_llseek() ** in deinem Code? – sawdust

+0

@ sawdust Ich habe sicherlich die Funktion "my_llseek()" in der file_operations-Struktur implementiert. – ColoradoIcculus

Antwort

4

Spi-Treiber-Dosis unterstützt keine llseek oder fseek-Funktionalität. Es hat diese vielen Rückruffunktionen.

struct spi_driver { 
    const struct spi_device_id *id_table; 
    int      (*probe)(struct spi_device *spi); 
    int      (*remove)(struct spi_device *spi); 
    void     (*shutdown)(struct spi_device *spi); 
    int      (*suspend)(struct spi_device *spi, pm_message_t mesg); 
    int      (*resume)(struct spi_device *spi); 
    struct device_driver driver; 

};

Jetzt Treiber/spi/spi-dw.c ist registrieren als Charter-Treiber (debugfs_create_file ("Register", S_IFREG | S_IRUGO, DWS-> debugfs, (void *) dws, & dw_spi_regs_ops);). Sie implementieren also, um eine Datei im debugfs-Dateisystem zu erstellen. Sie implementieren lseek Callback-Funktion.

static const struct file_operations dw_spi_regs_ops = { 
    .owner   = THIS_MODULE, 
    .open   = simple_open, 
    .read   = dw_spi_show_regs, 
    .llseek   = default_llseek, 

}; Die Struktur file_operations ist in linux/fs.h definiert und enthält Zeiger auf vom Treiber definierte Funktionen, die verschiedene Operationen auf dem Gerät ausführen. Jedes Feld der Struktur entspricht der Adresse einer Funktion von dem Fahrer definiert, um eine angeforderte Operation

lseek zu handhaben -: lseek ist ein Systemaufruf, der verwendet wird, um die Position des Lese zu ändern/Schreibzeiger eines Dateideskriptor.

SPI -: Die "Serial Peripheral Interface" (SPI) ist eine synchrone vieradrige serielle Verbindung zum Anschluss von Mikrocontrollern an Sensoren, Speicher und Peripheriegeräte. SPI kann keine lseek- und fseek-Funktion bereitstellen.

Es gibt zwei Arten von SPI-Treiber (https://www.kernel.org/doc/Documentation/spi/spi-summary)

Controller-Treiber ... Steuerungen können in System-On-Chip Prozessoren gebaut werden, und oft sowohl Master- und Slave-Rollen unterstützen. Diese Treiber berühren Hardwareregister und können DMA verwenden. Oder sie können PIO-Bitbanger sein, die nur GPIO-Pins benötigen.

Protokolltreiber ... diese übergeben Nachrichten über den Controller Treiber zur Kommunikation mit einem Slave oder Master-Gerät auf der anderen Seite einer SPI-Verbindung.

Wenn Sie Benutzer lesen, schreiben und llseek wollen, dann müssen Sie einen Charter-Treiber auf SPI registrieren. Dann werden Sie in der Lage sein, Ihre Aneignung zu erreichen.

+0

-1 für offensichtlich nicht die Linux-Dokumente auf SPI gelesen haben (zB [Dokumentation/spi/spi-Zusammenfassung] (https://www.kernel.org/doc/Documentation/spi/spi-summary). * "Spi-Treiber dose [sic] not support ... "* - Da es zwei Arten von SPI-Treibern gibt, ist Ihre Aussage mehrdeutig und daher irreführend. – sawdust

+0

Ja, es gibt zwei Arten von SPI-Treibern, aber beide unterstützen lseek, SPI Protocal-Treiber nicht hat file_operations implementiert Die Struktur file_operations ist in linux/fs.h definiert und enthält Zeiger auf vom Treiber definierte Funktionen, die verschiedene Operationen auf dem Gerät ausführen.Jedes Feld der Struktur entspricht der Adresse einer vom Treiber definierten Funktion Handle eine angeforderte Operation. –

+0

Ich dachte mit spidev.c als meine Basis, ich war mit einem generischen Charakter-Treiber auf SPI. Ich habe gerade ein wenig mehr graben heute Morgen und bemerkte die folgende Zeile: 'nonseekable_open (inode, filp);' Es scheint, dass wahrscheinlich der Schuldige in Schach ist! – ColoradoIcculus