Forum: PC-Programmierung Peak PCAN USB in Qt nutzen


von Mike (Gast)


Lesenswert?

Hallo Forum,

folgendes Problem: Ich möchte über eine Applikation, die mit Qt erstellt 
wird, Daten auf dem CAN Bus senden und empfangen. Als Hardware wird der 
PCAN USB von Peak verwendet.
Die Entwicklung findet auf einem Linux Rechner statt. Der erste Schritt 
war den Treiber zum Laufen bekommen. Das hat auch funktioniert, ich kann 
über die Konsole Daten senden und empfangen. Der nächste Schritt ist die 
Anbindung der PEAK API in Qt. Dazu habe ich die .pro erweitert:
1
LIBS += "/home/Desktop/peak-linux-driver-7.14/lib/libpcan.so"

Nach einem "Run qmake" wurde auch kein Fehler gemeldet.
In der Applikaiton habe ich den Header PCANBasic.h inkludiert, eine 
Nachricht vom Typ TPCANMsg angelegt und initialisiert. Compilieren 
konnte ich es bis hier hin ohne Fehler. Dann wurde die Init-Funktion 
CAN_Initialize() eingefügt und nach dem Compilieren kommt der Fehler " 
undefines reference to CAN_Initialize ".
Anscheinend stimmt etwas mit der Anbindung des Treibers etwas nicht. 
Kann mir da einer helfen oder werden noch weiter Infosbenötigt?

Danke im Voraus.

Gruß Mike

von Stephan (Gast)


Lesenswert?

Hey,

bin mir nicht sicher aber teste mal dies:
1
LIBS += -L"/home/Desktop/peak-linux-driver-7.14/lib/libpcan"

sorry ist lange her.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hi Mike,

Mike schrieb:
> Dann wurde die Init-Funktion
> CAN_Initialize() eingefügt und nach dem Compilieren kommt der Fehler "
> undefines reference to CAN_Initialize ".

Das ist eine Fehlermeldung des LINKERS! Guck Dir mal den Aufruf den 
Linkers an, ob Deine build-Umgebung die Library da wirklich mit 
angehängt hat. Wenn dem so ist, dann steckt die gesuchte Funktion nicht 
in der angegebenen Library.

Anderes Problem könnte sein, dass Du eine C Library von C++ aus 
verwendest und der header der C-Library das so nicht vorsieht (Stichwort 
Namemangling). Versuche mal, den header in einem `extern "C"`-Block zu 
`includen`. Zumindest für die OS/X Version ist das aber nicht nötig.

mfg Torsten

von Mike (Gast)


Lesenswert?

Bringt leider die gleiche Fehlermeldung

von 4toTakoe (Gast)


Lesenswert?

Hi, Hab leider keine Lösung für dein Problem, jedoch eine Frage dazu:

Ich benutz den Peak CAN USB Adapter auch - und auch mit Qt. Aber unter 
Windows. Hatte für das Teil bisher keine Treiber für Linux / OSx 
gefunden. Wo hast du die Libs her?

Hintergund: Möchte von Windows weg...

Danke schonmal.

von Mike (Gast)


Lesenswert?

Torsten R. schrieb:
> Das ist eine Fehlermeldung des LINKERS!
1
-L/home/eldk/Desktop/peak-linux-driver-7.14/lib/libpcan

Das gibt der Linker u.a. aus.

Der Extern Block ist im Header vom PCAN integriert, von daher muss ich 
das ja nicht mehr in meiner Applikation machen.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Mike schrieb:
> Bringt leider die gleiche Fehlermeldung

Zeig doch mal die komplette Kommandozeile des Linkers!

von Mike (Gast)


Lesenswert?

4toTakoe schrieb:
> Ich benutz den Peak CAN USB Adapter auch - und auch mit Qt. Aber unter
> Windows. Hatte für das Teil bisher keine Treiber für Linux / OSx
> gefunden. Wo hast du die Libs her?

http://www.peak-system.com/fileadmin/media/linux/index.htm#download

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

4toTakoe schrieb:
> Hatte für das Teil bisher keine Treiber für Linux / OSx
> gefunden. Wo hast du die Libs her?

hier findest Du eine OS/X-Version: http://www.mac-can.com

von Thorsten (Gast)


Lesenswert?

Ich verwende die PCAN unter Windows mit Qt.
Im Project-File binde ich die folgendermaßen ein:
1
win32: LIBS +=  -L$$PWD/can/libs/ -lPCANBasic

Mit -L übergibst du das Verzeichnis, in dem gesucht werden soll und mit 
-l den Namen der Bibliothek, gegen die gelinkt werden soll.

von Mike (Gast)


Lesenswert?

g++ -Wl,-rpath,/home/QtCreator_5.2.1/5.2.1/gcc 
-Wl,-rpath,/home/QtCreator_5.2.1/5.2.1/gcc/lib -o TestProjekt main.o 
mainwindow.o analogcamera.o can_bus.o keyboard.o display.o mmi.o 
qrc_pictures.o moc_mainwindow.o moc_analogcamera.o moc_can_bus.o 
moc_display.o 
/home/Display/TestProjekt/bios/Libs/Diagnostic/Kit_Desktop/libdiagnostic 
textdata.a  -L/home/Desktop/peak-linux-driver-7.14/lib/libpcan 
-L/home/QtCreator_5.2.1/5.2.1/gcc/lib -lQt5Widgets -lQt5Gui -lQt5Core 
-lGL -lpthread

display.o: In function `Display::Display()':
/home/eldk/Display/build-Desktop_Qt_5_2_1_GCC_32bit-Debug/../TestProjekt 
/display.cpp:239:  undefined reference to `CAN_Initialize'
collect2: error: ld returned 1 exit status
make: *** [TestProjekt] Error 1
12:39:53: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project TestProjekt (kit: Desktop Qt 
5.2.1 GCC 32bit)
When executing step 'Make'

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Mike schrieb:
> g++ -Wl,-rpath,/home/QtCreator_5.2.1/5.2.1/gcc
> -Wl,-rpath,/home/QtCreator_5.2.1/5.2.1/gcc/lib -o TestProjekt main.o
> mainwindow.o analogcamera.o can_bus.o keyboard.o display.o mmi.o
> qrc_pictures.o moc_mainwindow.o moc_analogcamera.o moc_can_bus.o
> moc_display.o
> /home/Display/TestProjekt/bios/Libs/Diagnostic/Kit_Desktop/libdiagnostic 
textdata.a
> -L/home/Desktop/peak-linux-driver-7.14/lib/libpcan
> -L/home/QtCreator_5.2.1/5.2.1/gcc/lib -lQt5Widgets -lQt5Gui -lQt5Core
> -lGL -lpthread

Du gibst den Pfad an, in dem der Linker suchen soll, aber nicht die 
Library, gegen die er linken soll.

von 4toTakoe (Gast)


Lesenswert?

@Mike und Torsten: Besten Dank ;)

Allen ein schönes Wochenende

von Mike (Gast)


Lesenswert?

1
INCLUDEPATH += "/home/eldk/Desktop/peak-linux-driver-7.14/lib"
2
LIBS += "/home/eldk/Desktop/peak-linux-driver-7.14/lib/libpcan.so"

So habe ich es aktuell in der .pro. Habe es auch schon mit -L und -l 
probiert, wie es Thorsten vorgeschlagen hat

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Mike schrieb:
>
1
> INCLUDEPATH += "/home/eldk/Desktop/peak-linux-driver-7.14/lib"
2
> LIBS += "/home/eldk/Desktop/peak-linux-driver-7.14/lib/libpcan.so"
3
>


Und geht es jetzt? Wenn nicht, wie sieht die Linker-Kommando-Zeile jetzt 
aus? QMake aufgerufen?

von Mike (Gast)


Lesenswert?

Torsten R. schrieb:
> Und geht es jetzt?

Anscheinend war es die falsche Header Datei. Ich blick gerade selbst 
nicht mehr so durch mit den ganzen Header Dateien. Muss noch einmal in 
Ruhe alles überdenken und melde mich dann wieder.
Vielen Dank bis hier her.

von Mike (Gast)


Lesenswert?

Hallo,

ich wollte mich mal wieder melden.
Natürlich war die falsche Header Datei inkludiert. Mit der richtigen 
Datei, libpcan.h, kann ich nun Nachrichten senden und empfangen.
Allerdings bereitet die Funktion CAN_Write() probleme. Arbeitet einer 
mit dem Peak und der Linux API?

von Steffen R. (steffen_rose)


Lesenswert?

Wir nutzen das Peak unter Linux nur per socketCAN.

von Mike (Gast)


Lesenswert?

Steffen R. schrieb:
> Wir nutzen das Peak unter Linux nur per socketCAN.

Das war auch meine Idee. Wie schon erwähnt schreibe ich meine 
Applikation mit Qt unter Linux. Die Applikation läuft dann auf einem 
Terminal, auf dem ebenfalls ein Linux läuft. Die Kommunikation auf dem 
Terminal läuft ebenfalls über den socketCAN.
Nun habe ich im Qt den Peak Treiber eingebunden und die Funktion 
CAN_Open( HW_USB ) aufgerufen, anschließend wird die socketCAN 
Initfunktion aufgerufen. Ergebnis: das Empfangen von Nachrichten klappt 
ohne Probleme. Nur das Senden funktioniert nicht. Daher habe ich dann 
mal auf die API vom Peak zurückgegriffen und das funktioniert so 
einigermaßen. Mehr ein Workaround als eine Lösung....
Mich wundert nur, dass das Empfanggen über socketCAN funktioniert und 
das Senden nicht.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Mike schrieb:
> Mich wundert nur, dass das Empfanggen über socketCAN funktioniert und
> das Senden nicht.

Beschreibe doch einfach mal das Problem und gib uns einen Link zur 
Dokumentation, vielleicht kann Dir dann schon einer helfen.

von Mike (Gast)


Lesenswert?

Das Problem ist, dass sich die Applikation manchmal bereits nach 5 
Sekunden oder ein anderes mal erst nach 30 Sekunden aufhängt. Ich schaue 
mir immer die Rückgabewerte der Write Funktion an aber da ist nix 
auffällig.
Über
1
cat /proc/pcan
 sehe ich dann auch, dass das Interface einen Fehler anzeigt, nur nicht 
die Art des Fehlers. Ich habe auch ein Programm, welches die Daten auf 
dem CAN zeigt und dort sehe ich ab und an einen Stuff Error.

von Mike (Gast)


Lesenswert?

Ich habe mir die halbe Nacht um die Ohren geschlagen, aber das Senden 
über den socketCAN funktioniert noch immer nicht. Der Treiber muss doch 
mit netdev support kompiliert werden.
1
*------------- PEAK-System CAN interfaces (www.peak-system.com) -------------
2
*------------- Release_20141219_n (7.14.0) Sep  4 2015 09:47:36 --------------
3
*------------- [mod] [isa] [pci] [dng] [par] [usb] [pcc] [net] --------------
4
*--------------------- 1 interfaces @ major 250 found -----------------------
5
*n -type- -ndev- --base-- irq --btr- --read-- --write- --irqs-- -errors- status
6
32    usb   can0 ffffffff 255 0x011c 00005d26 00000000 00002e40 00000001 0x0000

Oder liegt hier schon der Fehler?

Wie gesagt auf dem Terminal funktionieren die CAN Funktionen ohne 
Problem. NUr wenn ich die Funktionen auf meinem Linux Rechner nutze 
kommt bei der write Funktione als Rückgabewert -1. Das Erzeugen des 
Sockets und das Binding erfolgt auch ohen Fehler.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Ich kann Dir dabei leider nicht helfen. Aber, hast Du schon mal daran 
gedacht, den Support von Peak zu kontaktieren?

von Mike (Gast)


Lesenswert?

Torsten R. schrieb:
> Aber, hast Du schon mal daran
> gedacht, den Support von Peak zu kontaktieren?

Ja, aber ich wollte mal abwarten, ob hier jemand eine Idee hat.

von Steffen R. (steffen_rose)


Lesenswert?

Mike schrieb:
> Nun habe ich im Qt den Peak Treiber eingebunden und die Funktion
> CAN_Open( HW_USB ) aufgerufen, anschließend wird die socketCAN
> Initfunktion aufgerufen.

Ich kenne nur:
Entweder die (alte) Peak-Lib aus vor-socketcan Zeit oder das Ansprechen 
von SocketCAN über die socketAPI ohne Peak Lib.

Ich glaube, du mischelst und bekommst daher Probleme. Die Peak 
Unterstützung von socketCAN dürfte im Kernel sein. Insofern hast du 
eigentlich garnichst mehr mit Peak zu tun.
(aus der Erinnerung heraus. Ist schon eine Weile her.)

von Mike (Gast)


Lesenswert?

Steffen R. schrieb:
> Ich glaube, du mischelst und bekommst daher Probleme. Die Peak
> Unterstützung von socketCAN dürfte im Kernel sein. Insofern hast du
> eigentlich garnichst mehr mit Peak zu tun.
> (aus der Erinnerung heraus. Ist schon eine Weile her.

Ja teilweise, die Empfangsroutine verwendet den socketCAN, ich muss nur 
ein CAN_Open() vom Peak machen, damit der Dongle überhaupt etwas tut.

von Steffen R. (steffen_rose)


Lesenswert?

Mike schrieb:
> ich muss nur
> ein CAN_Open() vom Peak machen, damit der Dongle überhaupt etwas tut.

Sicher?

Ich hab noch sowas in meinen Notizen:

modprobe pcan
cat /proc/pcan
ip link set up can0

Bitrate
Peak früher:
echo "i 0x001C e" > /dev/pcan32
(500k)

sockeCAN aktuell:
ip link set can0 type can bitrate 250000

Bitrate setzen natürlich vor dem 'set up'.

Im Programm gabs dann nur socketCAN Funktionen.

Mehr kann ich leider nicht dazu beitragen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.