Forum: PC-Programmierung alsa mit openwrt


von Audio (Gast)


Lesenswert?

Hallo,
ich habe mit openwrt keine Erfahrung, mit Kernel-Konfiguration etwas, 
aber nur zu Kernel-2.4 Zeiten.

Ich habe es mal installiert und für den Raspberry PI eine toolchain 
generiert mit den Standard-Einstellung bei "make menuconfig".

Dann wollte ich mal ein paar Waves ausgeben.

die Devices sind in /proc/asound/cards vorhanden (intern/usb-extern)

die libraries auch, z.B.
snd-mixer-oss.ko
snd-pcm-dmaengine.ko
snd-pcm-oss.ko
snd-pcm.ko
snd-rawmidi.ko
snd-seq-device.ko
snd-seq-midi-event.ko
snd-seq-midi.ko
snd-seq.ko
snd-timer.ko
snd-usb-audio.ko
snd-usbmidi-lib.ko
snd.ko

Aber es fehlen die header-Dateien zum cross-compilieren eines test 
c-programms.
in der toolchain gibt es die sound/*.h header dateien,
da sind strukturen z.B.  snd_pcm_access_t definiert, aber es fehlen die 
Deklaration von Funtionen zum Starten eines pcm-streams

Wahrscheinlich muss man in der openwrt-Konfiguration etwas auswählen 
(z.B. alsa-lib-dev), dass er die Headers entsprechend erstellt ???

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Audio schrieb:
> die libraries auch, z.B.

Audio schrieb:
> Aber es fehlen die header-Dateien zum cross-compilieren eines test
> c-programms.

Das (*.ko) sind doch Kernel-Module. Damit hast du in normalen 
C-Programmen nichts mit zu tun. Du brauchst den Userspace-Teil...

von Audio (Gast)


Lesenswert?

> Du brauchst den Userspace-Teil...

das ist klar.
Aber ich denke, wenn der build-prozess die Kernel-Module rauswirft, dann 
müssten die Userspace-Develop Dateien auch dabei sein, wenn man das 
entsprechende in der menuconfig anklickt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Soweit ich weiß gibt es im Kernel überhaupt keine Header oder Libraries 
für den Userspace. Die sind beide in separaten Paketen.

libasound2 und libasound2-dev sehen so aus als würden sie Libraries bzw. 
Header für ALSA enthalten. Vielleicht wäre es aber sinnvoller direkt 
gstreamer o.ä. zu verwenden, dann bist du unabhängig von ALSA und es 
gibt noch eine Menge Dateiformate und Codecs dazu...

von Audio (Gast)


Lesenswert?

Niklas G. schrieb:
> Soweit ich weiß gibt es im Kernel überhaupt keine Header oder Libraries
> für den Userspace. Die sind beide in separaten Paketen.


Header natürlich nicht.
Libraries denke ich schon.
Man kann bei menuconfig des build-prozesses anklicken, ob man jeweilige 
Module/Treiber als Module ('m') oder fest im Kernel ('*') haben möchte.
Theoretisch könnte man alles benötigte fest im Kernel haben 
(monolithischer Kernel)

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Audio schrieb:
> Libraries denke ich schon.
> Man kann bei menuconfig des build-prozesses anklicken, ob man jeweilige
> Module/Treiber als Module ('m') oder fest im Kernel ('*') haben möchte.

Da kommen aber keine Userspace-Libraries (*.a, *.so, *.la, *.o) heraus, 
sondern Kernel-Module (*.ko) welche man im Userspace überhaupt nicht 
nutzen kann ('m' = 'Module').

: Bearbeitet durch User
von Audio (Gast)


Lesenswert?

Da fehlen mir doch etwas die basics ...

Aber wo krieg ich die alsa-lib-dev headers und sourcen her ?
Wenn ich im kompletten openwrt-Baum ("git clone 
https://www.github.com/openwrt/openwrt"; mit allen feeds) suche (grep), 
dann finde ich die typischen Alsa-Dateien wie aplay.c gar nicht.

Soll man diese Sourcen dann extern besorgen?

von Audio (Gast)


Lesenswert?

Es scheint ein bisschen anders zu funktionieren als bei normalen Alsa.

Ich habe testweise ein Midi-Keyboard an den RPi mit openwrt 
angeschlossen.
dann erscheint die Datei '/dev/snd/midiC1D0'

wenn ich 'cat /dev/snd/midiC1D0' eingebe und Tasten betätige, erscheinen 
die Midi-Daten.

Aber ich interessiere mich eigentlich für Sound (PCM) Ein- und Ausgabe

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Audio schrieb:
> Aber wo krieg ich die alsa-lib-dev headers und sourcen her ?

Im Zweifelsfall bei ALSA direkt:
ftp://ftp.alsa-project.org/pub/lib/

Für Debian gibt es das als libasound2-Paket, vielleicht ja auch für 
openwrt?

von Clemens L. (c_l)


Lesenswert?

Audio schrieb:
> Aber wo krieg ich die alsa-lib-dev headers und sourcen her ?

Bei OpenWrt sind die Teil von alsa-lib: 
https://openwrt.org/packages/pkgdata/alsa-lib

Laut https://openwrt.org/docs/guide-user/additional-software/opkg 
probier mal dieses:
1
opkg install alsa-lib

aplay ist Teil von alsa-utils.

: Bearbeitet durch User
von Audio (Gast)


Lesenswert?

Das funktioniert bei mir nicht.
Internet ist da und openwrt.org ist definitiv errechbar.
Aber "opkg install alsa-lib" geht nicht.
1
root@OpenWrt:~# ping openwrt.org
2
PING openwrt.org (139.59.209.225): 56 data bytes
3
64 bytes from 139.59.209.225: seq=0 ttl=57 time=43.737 ms
4
64 bytes from 139.59.209.225: seq=1 ttl=57 time=47.435 ms
5
^C
6
--- openwrt.org ping statistics ---
7
2 packets transmitted, 2 packets received, 0% packet loss
8
round-trip min/avg/max = 43.737/45.586/47.435 ms
9
root@OpenWrt:~# 
10
root@OpenWrt:~# 
11
root@OpenWrt:~# 
12
root@OpenWrt:~# 
13
root@OpenWrt:~# 
14
root@OpenWrt:~# 
15
root@OpenWrt:~# opkg install alsa-lib
16
Unknown package 'alsa-lib'.
17
Collected errors:
18
 * opkg_install_cmd: Cannot install package alsa-lib.
19
root@OpenWrt:~#

von Audio (Gast)


Lesenswert?

Obiges Problem gelöst:

erst
1
root@OpenWrt:~# opkg update
aufrufen,
dann läuft
1
root@OpenWrt:~# opkg install alsa-lib

von Audio (Gast)


Lesenswert?

Es bleibt schwierig.
(Wenn ich mit opkg alsa-lib und alsa-utils installiere, habe ich eine 
lib-Datei (asound.so.2) und aplay funktioniert.)

Aber ich kann kein eigenes Programm installieren, wegen nicht 
aufgelöster Symbole.
1
root@OpenWrt:~# gcc -lasound alsa_test.c 
2
/tmp/ccfAJjdN.o: In function `main':
3
alsa_test.c:(.text+0x20): undefined reference to `snd_pcm_open'
4
alsa_test.c:(.text+0x38): undefined reference to `snd_strerror'
5
collect2: error: ld returned 1 exit status

Die Standard- libasound zeigt mir keine Symbole an:
1
root@OpenWrt:~# nm -D  /usr/lib/libasound.so.2
2
nm: /usr/lib/libasound.so.2: no symbols
3
root@OpenWrt:~#

Aber mit 'less' sehe ich dann doch die Symbole:
1
root@OpenWrt:~# less  /usr/lib/libasound.so.2
2
...
3
^@snd_pcm_open^@snd_pcm_open_lconf^@snd_pcm_open_fallback^

von Blubb (Gast)


Lesenswert?

Villeicht solltest Du mal bei den OpenWrt Leuten mal direkt nachfragen..

von Audio (Gast)


Lesenswert?

Ich denke das ist mehr ein Fall für Compiler, gcc, und 
libc/Alternativen.

Openwrt hat alles optimiert und binaries so klein wie möglich gemacht.

Ich vermute, dass die Symboltabelle irgendwo in einer anderen Datei 
vorhanden ist, die man nur für Build-Zwecke braucht, aber nicht zur 
execution-Time.

Ich habe versuchsweise die Sourcen direkt von den Alsa-sourcen 
(alsa-lib-1.1.6.tar.bz2) cross-kompiliert (gleiche Version wie openwrt 
verwendet).
Da bekomme ich ein binary, das 3x mal so groß ist, als das vom 
Openwrt-Buildroot.
Die Symbol-Auflösung funktioniert, aber die Ausführung nicht.

von Herr_schrullig (Gast)


Lesenswert?

Nein du must im Makefile (für das openwrt package)
1
DEPENDS:=+alsa-lib
(oder so ähnlich kann sein das es der ganze odner name des packages ist)
Dann das ganze mit dem SDK compilern.

Die developing files header etc werden in den buildroot des SDKs kopiert 
sofern dies im Abschnitt:
1
define Build/InstallDev
2
  ...
3
endef
angegeben ist

Es gibt dazu eine wikieintrag wie man eigene Packete baut und man kann 
sich ganz gut an bestehenden paketen orientieren.

von Audio (Gast)


Lesenswert?

Es funktionieren schon viel einfachere Sachen nicht, und ich verstehe es 
nicht.
Nämlich das Kompilieren von einfachen Demo-Progrämchem mit Bibliotheken, 
z.B ncurses, scheitert.

Und zwar gibt es im Bin-Verzeichnis ein script, was die benötgiten 
GCC-Flags exportiert
1
root@OpenWrt:~# source /usr/bin/gcc_env.sh 
2
root@OpenWrt:~# echo $CFLAGS ";" $LDFLAGS
3
-Os -pipe -mcpu=cortex-a53 -fno-caller-saves ; -Wl,-rpath=/usr/lib -Wl,--dynamic-linker=/usr/lib/ -L/usr/lib

Mit diesen Einstellungen kompiliere ich (auf dem Target, Raspberry mit 
openwrt) eine ncurses-demodatei:
1
root@OpenWrt:~# gcc $CFLAGS $LDFLAGS   -lncurses   hello.c
2
hello.c:(.text.startup+0xc): undefined reference to `initscr'
3
hello.c:(.text.startup+0x18): undefined reference to `printw'
4
hello.c:(.text.startup+0x1c): undefined reference to `stdscr'
5
...


(ncurses und ncurses-dev sind natürlich installiert)
Diese nicht aufgelösten Symbole sind mit Sicherheit in der 
/usr/lib/libncurses.so drin, aber sie werden nicht erkannt.
Irgenwie scheint mir noch eine Einstellung für den Gcc, zu fehlen.

[pre]
lrwxrwxrwx    1 root     root            30 Nov  9 14:00 /usr/bin/gcc -> 
aarch64-openwrt-linux-musl-gcc
[pre]

von Herr_schrullig (Gast)


Lesenswert?

OK ich sehe du compilerst auf der Zielmaschine (Raspberry Pi)
Das ist sehr unüblich (ich wusste nicht mal das dies geht).
Und es scheiter weil es keine Developing Packete gibt sondern die Header 
datein etc werden in Buildroot des SDKs bzw in der Source directory 
gespeichert.

Du must das ganze auf dem localem PC mit dem SDK compilieren

von Herr_schrullig (Gast)


Lesenswert?


von Audio (Gast)


Lesenswert?

Ja, aber kürzer oder später will ich direkt auf dem Target, das ja sehr 
viel Ressourcen hat (1 GB RAM) hat, so wie ein kleiner PC, kompilieren 
und linken.

Mit "opkg install" kann man ja die Entwicklungsumgebung installieren und 
das hat super funktioniert.
Programme ohne spezielle Bibliotheken sind kompilierbar und lauffähig.
Grundsätzlich geht es ja.

Aber was ist an meinem Befehl falsch, dass er fehl schlägt???

root@OpenWrt:~# gcc $CFLAGS $LDFLAGS   -lncurses   hello.c
hello.c:(.text.startup+0xc): undefined reference to `initscr'
hello.c:(.text.startup+0x18): undefined reference to `printw'
hello.c:(.text.startup+0x1c): undefined reference to `stdscr'
...

von Herr_schrullig (Gast)


Lesenswert?

probier mal: gcc $CFLAGS $LDFLAGS hello.c -lncurses

von Audio (Gast)


Lesenswert?

Das geht auch nicht, hatte ich schon vorher probiert.
Gerade läuft der make für das SDK.
Ich erhoffe mir von der PC-Seite detailliertere Fehler-Angaben.

@Herr_schrullig

Du scheinst dich mit openwrt auszukennen.

von Herr_schrullig (Gast)


Lesenswert?

Beim genauen hinsehen würde ich sagen das nicht mal die *.c Datei 
übersetzt wird und eigendlich fehlen auch die include anweisungen im gcc
(sowas wie -I/usr/include)
Also der pfad zu den ncurses header dateien allerdings sind die den in 
den c dateien mit #include <blah.h> angegeben ?


[quote]
Du scheinst dich mit openwrt auszukennen.
[/quote]
ist irgendwie mein Hobby geworden

von Herr_schrullig (Gast)


Lesenswert?

Und dann könnte es natürlich auch sein das die ncurses Version in 
Openwrt die ensprechenden funktionen tatsächlich nicht kennt das würde 
ich mal in der entsprechenden ncurses source mal prüfen.

von Audio (Gast)


Lesenswert?

"Beim genauen hinsehen würde ich sagen das nicht mal die *.c Datei 
übersetzt wird und eigendlich fehlen auch die include anweisungen im gcc
(sowas wie -I/usr/include)"

Nee, mit gcc -c hello.c láuft es und es kommt ein hello.o heraus.
Bei includes in Standard  Verzeicnissen braucht man kein -I.

von Herr_schrullig (Gast)


Lesenswert?

vieleicht noch -fno-plt zu den CFLAGS hinzufügen.
(ich habe keine ahnung was das bedeutet, aber das kann man bei 
Additional compiler options lesen wenn man make menuconfig aufruft)

Ansonsten habe ic auch keine idee mehr

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
> -Wl,-rpath=/usr/lib -Wl,--dynamic-linker=/usr/lib/ -L/usr/lib

Wozu soll das denn gut sein?

Herr_schrullig schrieb:
> probier mal: gcc $CFLAGS $LDFLAGS hello.c -lncurses

Genau das!

von Audio (Gast)


Lesenswert?

>> -Wl,-rpath=/usr/lib -Wl,--dynamic-linker=/usr/lib/ -L/usr/lib
>
> Wozu soll das denn gut sein?


Das war in der /usr/bin/gcc_env.sh enthalten.
Ich vermutete, dass das die richtige Einstellung sein soll, um mit der 
Entwicklungsumgebung auf dem Target native Programme zu erstellen.
Die $CFLAGS Einstellungen scheinen ja ganz vernünftig und notwendig.


>> probier mal: gcc $CFLAGS $LDFLAGS hello.c -lncurses
> Genau das!

Funktioniert genauso wenig.

Wenn ich auf dem PC kompiliere erhalte ich eine Warning, dass er das 
richtige libgcc.so nicht findet.
Vermutlich hat das was mit musl/glibc Verwechslung was zu tun.

von Audio (Gast)


Lesenswert?

Eine Methode zum Finden der richtigen Compiler-Switches wäre, mit dem 
Build-Root das Image/rootfs zu erstellen, dabei mit "make V=s | tee 
/path/save_my_output"

Dann sieht man nämlich, wie mit welchen Einstellungen die Build-Umgebung 
das erledigt, und diese dann kopieren.

Das ist natürlich ein längliches Unterfangen



auf dem openwrt-Forum hat mir jemand geschrieben:
>You will need to install a full build system on the target. A compiler alone 
>typically doesn't include all the needed headers, link libraries, and tools 
>required to generate executables.

>Getting something that requires curses to run may require files and/or ?
>utilities that define the "screen"
>...

Die include-Dateien waren alle da nach einem "opkg ncurses-dev".
Möglicherweise brauche ich eine andere libncurses.so, weil die 
bestehende nur für Runtime-Zwecke erstellt ist, und man keine Sourcen 
damit linken kann.

von Rolf M. (rmagnus)


Lesenswert?

Audio schrieb:
>>> -Wl,-rpath=/usr/lib -Wl,--dynamic-linker=/usr/lib/ -L/usr/lib
>>
>> Wozu soll das denn gut sein?
>
> Das war in der /usr/bin/gcc_env.sh enthalten.
> Ich vermutete, dass das die richtige Einstellung sein soll, um mit der
> Entwicklungsumgebung auf dem Target native Programme zu erstellen.
> Die $CFLAGS Einstellungen scheinen ja ganz vernünftig und notwendig.

Die LDFLAGS sollten aber so eigentlich nicht nötig sein. Da müsste der 
Compiler die richtigen Einstellungen eigentlich mitbringen.

>>> probier mal: gcc $CFLAGS $LDFLAGS hello.c -lncurses
>> Genau das!
>
> Funktioniert genauso wenig.

Hmm, das ist eigenartig. Bei weiteren Versuchen solltest du es aber so 
schreiben, denn das ist notwendig.

von Audio (Gast)


Lesenswert?

Auf dem PC kompiliert das Testprogramm problemlos.
Ich habe nur diese paar Befehle ausgeführt, das "make" dauerte aber 
lange, fast 3 Stunden.
Aber warum geht das auf dem Target nicht? Die Tools, libs sind ja die 
gleichen?!
1
git clone https://github.com/openwrt/openwrt.git
2
cd openwrt
3
./scripts/feeds update -a
4
./scripts/feeds install -a
5
make menuconfig
6
make -j8
7
8
PATH=$PATH:/S/openwrt/staging_dir/toolchain-arm_arm1176jzf-s+vfp_gcc-7.3.0_musl_eabi/bin/
9
export STAGING_DIR=/S/openwrt/staging_dir/
10
11
export INC=$STAGING_DIR/target-arm_arm1176jzf-s+vfp_musl_eabi/usr/include/
12
export LIBMUSL=$STAGING_DIR/target-arm_arm1176jzf-s+vfp_musl_eabi/usr/lib/
13
14
arm-openwrt-linux-gcc -I $INC hello.c -L $LIBMUSL  -lncurses


hello.c:
1
#include <ncurses.h>
2
3
int main()
4
{       
5
        initscr();                      /* Start curses mode              */
6
        printw("Hello World !!!");      /* Print Hello World              */
7
        refresh();                      /* Print it on to the real screen */
8
        getch();                        /* Wait for user input */
9
        endwin();                       /* End curses mode                */
10
11
        return 0;
12
}

von Audio (Gast)


Lesenswert?

Ich bin etwas weitergekommen.
Die Libraries auf PC und Target sind unterschiedlich.

PC:
1
[u@archlinux ~]$ ls -l staging_dir/target-arm_arm1176jzf-s+vfp_musl_eabi/usr/lib/libncursesw.so.6.1 
2
-rwxr-xr-x 1 u u 304884 Nov 13 20:36 staging_dir/target-arm_arm1176jzf-s+vfp_musl_eabi/usr/lib/libncursesw.so.6.1

Target (original Lib umbenannt in orig)
1
root@OpenWrt:~# ls -l /usr/lib/libncursesw.orig.so.6.1 
2
-rwxr-xr-x    1 root     root        246269 Jul 22 16:38 /usr/lib/libncursesw.orig.so.6.1
3
root@OpenWrt:~#

Wenn ich die Lib vom PC zum Target kopiere, dann lässt sich "hello.c" 
übersetzen und fehlerfrei ausführen
1
root@OpenWrt:~# ./a.out 
2
root@OpenWrt:~#

Wenn ich auf dem Target die Symbole der Lib ausgebe, finde ich bei der 
original-Lib keine, auf der Lib vom PC aber schon:
1
root@OpenWrt:~# nm /usr/lib/libncursesw.orig.so.6.1 
2
nm: /usr/lib/libncursesw.orig.so.6.1: no symbols
3
root@OpenWrt:~# 
4
root@OpenWrt:~# 
5
root@OpenWrt:~# nm /usr/lib/libncursesw.so.6.1 | head -n 12
6
0003aa9c r 
7
0004d824 B BC
8
0004d234 B COLORS
9
000129d4 T COLOR_PAIR
10
0004d238 B COLOR_PAIRS
11
0004d71c B COLS
12
0001db34 t CatchIfDefault
13
0001fe70 t ClrBottom
14
0001fc6c t ClrToEOL
15
0001f194 t ClrToEOS
16
0004d004 D ESCDELAY
17
00020128 t EmitRange
18
root@OpenWrt:~#


Das ist jetzt eine brauchbare (Hack-) Lösung.

von Rolf M. (rmagnus)


Lesenswert?

Ist die lib vielleicht gestript, um Platz zu sparen?

von Herr_Schrullig (Gast)


Lesenswert?

1
Ist die lib vielleicht gestript, um Platz zu sparen?
Ja bei Openwrt wird alles gestript und die libncursesw vom PC ist 
anscheinend nicht gestrippt da grösser.
1
das "make" dauerte aber 
2
lange, fast 3 Stunden.
Es muss ja auch erst Ncurses und deren Abhängigkeiten compiliert werden, 
beim zweiten mal geht es schneller (natürlich bei dem selben SDK).

von Audio (Gast)


Lesenswert?

> das "make" dauerte aber
> lange, fast 3 Stunden.

da wurde alles neu erstellt: toolchain, target-images, ... insgesamt 
13GiB

Wenn man nur das SDK runterlädt, dann geht das schneller, weil das SDK 
für die jeweilige Architektur nur eine Untermenge des build-system ist.

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.