PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino IDE (Linux), DUE C++ Linken geht nicht



alexander_ro
05.06.2015, 19:40
Hi, Mädels ... Jungs ... :-)

Das die Arduino IDE 1.6.3 einen C++11 Code compiliert habe ich schon gefunden. Dazu habe ich in der Datei .arduino15/packages/arduino/hardware/sam/1.6.4/platform.txt eine Zeile so umgeschrieben: compiler.cpp.extra_flags=--std=c++11. Ich finde aber irgendwie nicht wie man der Arduino IDE bei bringt den C++ Code auch so zu linken. Ich bekomme für einen std::basic_string die Fehlermeldung undefinded reference.

So sieht die Zeile aus die die Meldung verursacht: std::string strMsg = "";

Die Arduino IDE ist ein bisschen seltsam weil man nicht mal eine Fehlermeldung kopiern kann ... :-(

Grüße
Alexander

Mxt
06.06.2015, 08:49
Hallo,

ja, man kann zwar den Compiler dazu bringen C++11 zu verwenden, aber die C++ Standardbibliothek bringt die Arduino IDE nicht vollständig mit.
Deswegen bleibe ich lieber bei mbed, das ist zwar nur C++03, aber wenigstens mit Bibliotheken.

Ich wollte bei Gelegenheit mal testen, ob man z.B. mit dem hier
http://platformio.org/#!/
C++11 Code auf den Due bringen kann. Das verwendet für mbed und Due den gleichen Compiler. Damit sollte eigentlich mehr Infrastruktur vorhanden sein.
Allerdings, wie hier schon als Frage gestellt, ist das Tool keineswegs perfekt. Unter Linux kriege ich die ARM-Targets nicht damit zum laufen.
Im Moment fehlt mir sowieso die Zeit dafür ...

alexander_ro
06.06.2015, 13:27
Ich weiss nun nicht genau wie gut die ARM Prozessoren untereinander kompatibel sind. Aber könnte man sich die C++ Standardbibliothek nicht einfach bei eim ARM Zweig einer Linux Distribution kopieren und verwenden?

Mxt
06.06.2015, 14:02
Wahrscheinlich gibt es da Probleme mit den Binärdaten der Bibliotheken. Die C++ Compiler auf (oder für) die Cortex-A Prozessoren sind ja meistens für das armhf- (Hardfloat) oder armel-Format. Die Cortex-M Entwicklungsumgebungen verwenden ja normalerweise den gcc-arm-none-eabi.

Es würde schon gehen, wenn man das komplette Compilerpaket installiert. Unter Windows kriegt das oben verlinkte Python Script das ja hin. Es lädt Compiler (für AVR und ARM-none), Bibliotheken (Arduino oder mbed) und diverse Tools (wie Avrdude, bossac usw.) herunter und installiert sie. Man kann Arduino Sketche und mbed-Programme auf der Kommandozeile erstellen und auf die Controller übertragen.

Ich hätte ja erwartet, dass ein Python-Script unter Linux besser läuft. Auch wird da ja mit Rasperry Pi und Beaglebone geworben. Unter Debian werden Programme für den Due ja auch übersetzt. Nur dann kommt der Linker nicht weiter. Unter Arch Linux auf dem Raspi 2 gibt es noch mehr Probleme, weil Python 3 da ja der Standard ist. Man kriegt es zwar mit Python 2 installiert, aber bei der Aufführung kommen dann doch wieder Syntaxfehler. Bin halt nicht so der Python Experte. Aber im Prinzip steht alles in dem Skript, was Du wissen musst.

alexander_ro
07.06.2015, 16:59
Also armhf und armel sagt mir was. Ich habe zwar nach längerer suche gefunden was es heißt: EABI (embedded application binary interface) aber richtig vorstellen was es ist kann ich mir noch nicht. Ist da sowas gemeint wie unter Linux das ELF Format?

Mxt
07.06.2015, 19:57
Im Prinzip ja, aber es geht noch eine Ebene tiefer. Dass es in C++ keine standardisierte ABI gibt, ist die Ursache dafür, dass man auf diversen Systemen keinen Binärcode von verschiedenen C++ Compilern mischen darf. Unterschiedliche Compiler können Klassen unterschiedlich binär darstellen.

Siehe auch Wikipedia

Eine ABI gilt manchmal nur für eine Programmiersprache bzw. einen Compilertyp, da die Regeln, wie beispielsweise aus einer Funktionsdefinition ein symbolischer Name werden soll, sprachabhängig sind.
http://de.wikipedia.org/wiki/Bin%C3%A4rschnittstelle

Um zum Thema zurückzukommen:

Ein Weg zu C++11 auf dem Due wäre eventuell Atmel Studio. Da kann ich aber nicht sagen, wie weit man dass mit Arduino Code kombinieren kann.

In der Arduino IDE (ich hab das damals mit 1.5.x getestet) bleiben einem Dinge wie constexpr, range based for, lambda funktionen, auto und alles mit templates, das keine Standardbibliothek benötigt.

Mxt
13.06.2015, 09:41
So ein kleines Update: Mit platformio funktioniert das besser als mit der Arduino-IDE.

Kurzanleitung:

- platformio nach Anleitung installieren.

- Kommandozeile öffnen und einmalig dies ausführen, damit die Tools für den Due installiert werden:
platformio platforms install atmelsam

- Ein Verzeichnis für das Projekt anlegen, hier als Beispiel DueCpp

- Auf der Kommandozeile in das Verzeichnis wechseln und dort eingeben
platformio init -b due
Die erste Frage mit no, die zweite mit yes beantworten.

Jetzt gibt es im Verzeichnis eine platformio.ini Datei, darin findet sich dieser Eintrag


[env:due]
platform = atmelsam
framework = arduino
board = due

der wird ergänzt zu


[env:due]
platform = atmelsam
framework = arduino
board = due
build_flags = -std=c++11


Jetzt in das src Unterverzeichnis wechsel. Dort eine DueCpp.ino Datei für den Sketch anlegen.
Hier zum Test mit diesem Inhalt, quasi ein mit C++11 gepimptes Blink


#include <string>

int counter = 0;

constexpr uint8_t led = 13;

void setup() {
Serial.begin(9600);

pinMode(led, OUTPUT);
digitalWrite(led, LOW);
}

auto switch_on = [](){ digitalWrite(led, HIGH); };
auto switch_off = [](){ digitalWrite(led, LOW); };

void loop() {
std::string s("Test");
Serial.println(s.c_str());

switch_on();
delay(1000);
switch_off();
delay(1000);
}


Jetzt wieder ins Projektverzeichnis wechsel und checken mit
platformio run

Wenn man keine Fehler hat, kann man es jetzt auf den Due schicken
platformio run -t upload
Normalerweise findet er den passenden COM-Port selber.

That's it.

alexander_ro
14.06.2015, 20:29
Das muss ich auch mal probieren was Du da beschrieben hast sieht gut aus.

Ich habe mal angefangen mir unter Gentoo mit dem Paket Crossdev so einen Compiler plus Zubehör ;-) passend für den ARM Cortex-M3 zusammen zu bauen. Das hat auch funktioniert aber die Arduino Menschen machen zwar OpenSource aber so was von umständlich das es nicht leicht ist die Bibliothek ohne die IDE zu benutzen. Mir ist das dann auf die Nerven gegangen und ich hab mal beschlossen nur das Platinchen von Arduino (den DUE) zu benutzen und die Software von denen ganz weg zu lassen. Aber das will noch nicht funktionieren mir fehlt da noch ein bisschen Hardware wissen zu Cortex-M3. Wenn Du da eine gute Quelle kennst bin ich ganz Ohr ... und in der zwischen Zeit probiere ich mal Deinen Vorschlag der sieht auf alle Fälle nach weniger Arbeit aus und deshalb schon interessant.


Och ... bei mir Jammert wieder das Python Vieh rum.
(Gentoo hat da im Moment die Version 3.3.5)

File "get-platformio.py", line 118
except Exception, e:
^
SyntaxError: invalid syntax



Wenn man das Komma mit einem "as" ersetzt ist der Fehler Weg. Dafür bekomme ich dann die Fehlermeldung:
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-ho9_3h-build

Leider haben die diversen Vorschläge zu beheben auf anderen Seiten nicht geholfen.

Mxt
15.06.2015, 07:11
Hallo,

also Python ist auch nicht so mein Ding und mit Gentoo hatte ich noch nie zu tun.

Bei mir sind die ARM-Boards sowas wie intelligente IO-Interfaces am PC. Daher habe ich mir platformio angesehen, weil ich gerne aus meinen eigenen PC-Programmen Code generieren möchte, um die Controller umzuprogrammieren. Das ganze aber derzeit vorwiegend unter Visual Studio.

Deswegen verwende ich eher Boards mit etwas high level C++ Programmierung, im Moment hauptsächlich mbed. Die bringen ja im Dezember ihr eigenes Python Tool zur offline Programmierung, dann brauche ich Platformio nur noch für Arduino.

Hier mein derzeitiger Stand mit platformio auf verschiedenen Platformen:

Windows 7 und 8: geht alles, schon seit Version 1.x

Raspi 2, Raspian: Die Version 2.1.1 von platformio kann mit sudo python get-platformio.py installiert werden, es geht auch alles.

Beaglebone Black, Debian 8 beta: Installation klappt wie beim Raspi. 8 Bit Arduino funktioniert. Bei allen 32-Bit Targets findet der gcc die libmpc nicht.

Raspi 2, Arch Linux: Zuerst scons manuell installieren sudo pacman -S scons, platformio versucht das selber und baut Mist. Dann installieren mit sudo python2 get-platformio.py geht. Dann der gleiche Zustand wie bei Debian 8.

Vielleicht hilft Dir das schon etwas weiter.

alexander_ro
15.06.2015, 07:35
Die zwei machts ... :-) ... python2

Ich habe noch einen Zuhause herumsteh PC mit einem alten Debian da konnte ich es installieren. Bei der Gentoo Installation von python muss man die zwei anhängen vermutlich damit das dann die alte Python Version benutzt. Das Gentoo läuft auf meinem Notebook bei Debian sind die Pakete immer zu alt und bei Gentoo sind die Pakete immer zu neu ... Moderne EDV halt ... (Ende der Vernunft).


Hier "/usr/bin/scons" muss man auch die Zeile ändern: #! /usr/bin/env python2
Dann läuft das Übersetzen und der Upload von Deinem Beispiel Programm oben.

Mehr habe ich jetzt nicht probiert muss ich nun mal testen.

alexander_ro
24.06.2015, 17:48
Danke für die Hilfe ... hier mein Testprogramm für ein Navilock Modul mit TTL 3,3 Volt Schnittstelle an dem Arduino DUE mit eins oder Null in der if Abfrage kann man umschalten zwischen alle NEMA Messages über USB zum PC leiten oder nur die VTG Msg und davon nur die Geschwindigkeit in Km/h. Wenn man alle NEMA Msg weiterleitet kann man auch die Ublox Software unter Windows benutzen.

Die splitString Funktion steht unter der GPL die habe ich aus einem OpenSource Projekt kopiert. Der Rest ist ja sonst nicht wirklich was besonderes.



#include <string>
#include <vector>

void setup()
{
Serial.begin (115200);
Serial1.begin (115200);
}

std::vector<std::string> splitString (const std::string& strString, char cTrenner = ',')
{
std::vector<std::string> vecValues;

unsigned int iAnf = 0;

for (;;)
{
unsigned int iPos = strString.find (cTrenner, iAnf);

if (iPos != std::string::npos)
{
vecValues.push_back (std::move (strString.substr (iAnf, iPos - iAnf)));
iAnf = iPos + 1;
}
else
{
if (iAnf < strString.size ())
vecValues.push_back (std::move (strString.substr (iAnf, iPos - iAnf)));
else
vecValues.push_back (std::string (""));
break;
}
}

return vecValues;
}

void loop()
{

if (1)
{
// Lese die Msg vom Navimodul
std::string strMsg = "";
for (;;)
{
if (Serial1.available () > 0)
{
int iZeichen = Serial1.read ();
if ((iZeichen != '\n') && (iZeichen != '\r'))
strMsg.append (1, iZeichen);
else
break;
}
}

// Msg zerlegen
std::vector<std::string> vecMsg = splitString (strMsg);

// NEMA Msg nach Wunsch verarbeiten.
if (vecMsg[0] == "$GNVTG")
{
// Zum testen die ganze Msg augeben.
// for (auto&& strWert : vecMsg)
// {
// Serial.write (strWert.c_str ());
// Serial.write (" ");
// }

// Geschwindigkeit über Grund in Km/h.
Serial.write ("Km/h: ");
Serial.write (vecMsg[7].c_str ());
Serial.write ('\n');
Serial.write ('\r');
}
}
else
{
// Daten unverändert weiterleiten
if (Serial1.available () > 0)
{
Serial.write ((char) Serial1.read ());
}
}

// Schreibe die Daten zum Navimodul
if (Serial.available () > 0)
{
Serial1.write ((char) Serial.read ());
}
}

Unregistriert
13.09.2015, 16:01
hallo,
funktioniert der Due jetzt mit Linux und Python?

alexander_ro
13.09.2015, 21:22
Phyton weiss ich nicht ... meine Frage war nach C++.