Hallo zusammen.
Vor einiger Zeit haben wir darĂŒber gesprochen, wie es uns gelungen ist, ein SIP-Telefon auf der STM32F4-Discovery mit 1 MB ROM und 192 KB RAM zu starten, basierend auf . Hier muss gesagt werden, dass diese Version minimal war und zwei Telefone direkt ohne Server verband und die SprachĂŒbertragung nur in eine Richtung erfolgte. Daher haben wir beschlossen, ein vollstĂ€ndigeres Telefon mit Anrufen ĂŒber einen Server und SprachĂŒbertragung in beide Richtungen zu starten, dabei jedoch den Speicherplatz so gering wie möglich zu halten.

FĂŒr das Telefon wurde entschieden, die Anwendung simple_pjsua aus der PJSIP-Bibliothek zu wĂ€hlen. Dies ist eine minimale Anwendung, die sich auf dem Server registrieren, Anrufe empfangen und beantworten kann. Im Folgenden werde ich gleich beschreiben, wie man das auf der STM32F7-Discovery startet.
So starten Sie
- Konfigurieren Sie Embox
make confload-platform/pjsip/stm32f7cube - Im Datei conf/mods.config geben wir das benötigte SIP-Konto an.
include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password")wo server â das ist der SIP-Server (zum Beispiel sip.linphone.org), username und passwort â der Benutzername und das Passwort des Kontos.
- Wir kompilieren Embox mit dem Befehl make. Ăber das Flashen des Boards haben wir Informationen auf unserem und in .
- Wir starten im Embox-Konsolenbefehl âsimple_pjsua_importedâ
00:00:12.870 pjsua_acc.c ....SIP-Outbound-Status fĂŒr acc 0 ist nicht aktiv 00:00:12.884 pjsua_acc.c ....sip:alexk2222@sip.linphone.org: Registrierung erfolgreich, status=200 (Registrierung erfolgreich) 00:00:12.911 pjsua_acc.c ....Keep-alive-Timer fĂŒr acc 0 gestartet, Ziel:91.121.209.194:5060, Intervall:15s - SchlieĂlich bleibt es nur noch, Lautsprecher oder Kopfhörer an den Audioausgang anzuschlieĂen und in zwei kleine MEMS-Mikrofone neben dem Display zu sprechen. Wir rufen von Linux ĂŒber die Anwendung simple_pjsua an, pjsua. oder jede andere wie linphone.
All dies ist auf unserem .
Wie wir dazu gekommen sind
UrsprĂŒnglich stellte sich die Frage nach der Wahl der Hardware-Plattform. Da klar war, dass die STM32F4-Discovery aufgrund des Speichers nicht geeignet war, wurde die STM32F7-Discovery gewĂ€hlt. Sie hat 1 MB Flash-Speicher und 256 KB RAM (+ 64 KB speziellen schnellen Speicher, den wir ebenfalls nutzen werden). Auch dies ist nicht viel fĂŒr Anrufe ĂŒber den Server, aber wir wollten es versuchen.
Wir haben uns die Aufgabe grob in mehrere Phasen unterteilt:
- Starten von PJSIP auf QEMU. Das war praktisch fĂŒr das Debugging, auĂerdem hatten wir dort bereits UnterstĂŒtzung fĂŒr den AC97-Codec.
- Aufnahme und Wiedergabe von Stimmen auf QEMU und auf STM32.
- Portierung der Anwendung simple_pjsua aus PJSIP. Diese ermöglicht die Registrierung auf einem SIP-Server und das TÀtigen von Anrufen.
- Erstellen Sie Ihren eigenen Server auf Basis von Asterisk und testen Sie darauf, danach versuchen Sie externe wie sip.linphone.org.
Der Sound in Embox funktioniert ĂŒber Portaudio, das auch in PISIP verwendet wird. Auf QEMU traten die ersten Probleme auf â WAV-Dateien wurden bei 44100 Hz gut abgespielt, aber bei 8000 Hz lief etwas offensichtlich nicht richtig. Es stellte sich heraus, dass es an der Frequenzeinstellung lag â standardmĂ€Ăig war sie in der Hardware auf 44100 eingestellt, was wir programmatisch nicht geĂ€ndert hatten.
Hier sollte vielleicht etwas erklĂ€rt werden, wie das Abspielen von Sound ĂŒberhaupt funktioniert. Der Soundkarte kann ein Zeiger auf einen Speicherbereich zugewiesen werden, aus dem bei einer zuvor festgelegten Frequenz abgespielt oder aufgezeichnet werden soll. Nachdem der Puffer aufgebraucht ist, wird eine Unterbrechung ausgelöst, und die AusfĂŒhrung geht mit dem nĂ€chsten Puffer weiter. Das Problem ist, dass diese Puffer im Voraus gefĂŒllt werden mĂŒssen, wĂ€hrend der vorherige abgespielt wird. Mit diesem Problem werden wir spĂ€ter noch auf dem STM32F7 konfrontiert werden.
Dann haben wir einen Server gemietet und Asterisk darauf installiert. Da viel debuggt werden musste und ich nicht gerne ins Mikrofon sprach, musste ein automatisches Abspielen und Aufzeichnen implementiert werden. DafĂŒr haben wir simple_pjsua gepatcht, damit wir Dateien anstelle von AudiogerĂ€ten verwenden können. In PJSIP ist das ziemlich einfach, da es dort das Konzept eines Ports gibt, der sowohl ein GerĂ€t als auch eine Datei sein kann. Diese Ports können flexibel mit anderen Ports verbunden werden. Den Code kann man in unserem pjsip anschauen. Das Ergebnis war folgendes Schema. Auf dem Asterisk-Server habe ich zwei Konten angelegt â eines fĂŒr Linux und eines fĂŒr Embox. Dann wird auf Embox der Befehl simple_pjsua_imported, Embox registriert sich am Server, danach rufen wir von Linux aus auf Embox an. Zum Zeitpunkt der Verbindung ĂŒberprĂŒfen wir am Asterisk-Server, dass die gesamte Verbindung hergestellt wurde, und nach einiger Zeit sollten wir in Embox den Sound von Linux hören, wĂ€hrend wir in Linux die Datei speichern, die aus Embox abgespielt wird.
Nachdem das auf QEMU funktioniert hatte, gingen wir zur Portierung auf das STM32F7-Discovery ĂŒber. Das erste Problem war â wir passten nicht in 1 MB ROM ohne aktivierte Compiler-Optimierung â-Osâ bezĂŒglich der BildgröĂe. Daher aktivierten wir â-Osâ. AuĂerdem deaktivierten wir mit einem Patch die UnterstĂŒtzung fĂŒr C++, da sie nur fĂŒr pjsua benötigt wird, und wir verwenden simple_pjsua.
Nachdem wir Platz schaffen konnten simple_pjsua, waren wir der Meinung, dass die Chancen, das jetzt zu starten, bestehen. Aber zuerst mussten wir uns mit der Aufnahme und Wiedergabe von Sprache befassen. Die Frage â wo aufzeichnen? Wir wĂ€hlten externen Speicher â SDRAM (128 MB). Sie können es selbst ausprobieren:
Erstellt Stereo-WAV mit einer Frequenz von 16000 Hz und einer Dauer von 10 Sekunden:
record -r 16000 -c 2 -d 10000 -m C0000000
Wiedergabe:
play -m C0000000
Hier gab es zwei Probleme. Das erste betraf den Codec â es wird WM8994 verwendet, und in diesem gibt es einen Begriff namens Slot, von denen es vier gibt. Wenn dies nicht eingestellt wird, spielt AUDIO standardmĂ€Ăig in allen vier Slots ab. Bei einer Frequenz von 16000 Hz erhielten wir also 8000 Hz, und bei 8000 Hz funktionierte die Wiedergabe einfach nicht. Als wir nur die Slots 0 und 2 auswĂ€hlten, funktionierte es wie gewĂŒnscht. Ein weiteres Problem war die Audio-Schnittstelle in STM32Cube, bei der der Audioausgang synchron mit dem Audioeingang ĂŒber SAI (Serial Audio Interface) funktioniert (ich habe mich nicht im Detail damit beschĂ€ftigt, aber es scheint, dass sie eine gemeinsame Uhr teilen, und bei der Initialisierung des Audioausgangs wird der Audioeingang irgendwie eingebunden). Das heiĂt, wir können sie nicht getrennt starten, also haben wir Folgendes gemacht â sowohl der Audioeingang als auch der Audioausgang arbeiten immer (einschlieĂlich der erzeugten Unterbrechungen). Wenn im System nichts wiedergegeben wird, geben wir einfach einen leeren Puffer an den Audioausgang weiter, und wenn die Wiedergabe gestartet wird, fangen wir an, ihn richtig zu fĂŒllen.
SpĂ€ter stieĂen wir auf das Problem, dass der Ton bei der Sprachaufnahme sehr leise war. Dies liegt daran, dass die MEMS-Mikrofone auf STM32F7-Discovery bei Frequenzen unter 16000 Hz schlecht arbeiten. Daher stellen wir 16000 Hz ein, selbst wenn 8000 Hz ankommen. DafĂŒr war es nötig, eine Softwareumwandlung von einer Frequenz zur anderen hinzuzufĂŒgen.
AuĂerdem mussten wir die GröĂe des Heaps, der im RAM liegt, erhöhen. Nach unseren Berechnungen benötigte pjsip etwa 190 KB, und uns blieben nur noch etwa 100 KB. Dabei mussten wir ein wenig externen Speicher â SDRAM (ca. 128 KB) â verwenden.
Nach all diesen Ănderungen sah ich die ersten Pakete zwischen Linux und Embox und hörte den Ton! Aber der Ton war schrecklich, ganz anders als in QEMU, nichts war zu erkennen. Dann ĂŒberlegten wir, wo das Problem liegen könnte. Das Debugging zeigte, dass Embox einfach nicht rechtzeitig die Audio-Puffer fĂŒllen/entladen konnte. WĂ€hrend pjsip einen Frame verarbeitet, traten bereits 2 Unterbrechungen ĂŒber die Beendigung der Pufferverarbeitung auf, was zu viel ist. Der erste Gedanke zur Beschleunigung war die Compiler-Optimierung, aber die war bereits in PJSIP aktiviert. Das zweite â Hardware-Gleitkomma, ĂŒber die wir gesprochen haben. . Aber wie sich gezeigt hat, hat die FPU keinen wesentlichen Geschwindigkeitszuwachs gebracht. Der nĂ€chste Schritt war das Setzen von PrioritĂ€ten fĂŒr die Streams. In Embox gibt es verschiedene Planungsstrategien, und ich habe die aktiviert, die PrioritĂ€ten unterstĂŒtzt, und den Audiostreams die höchste PrioritĂ€t zugewiesen. Das hat auch nicht geholfen.
Die nĂ€chste Idee war, dass wir mit externer Speicher arbeiten und es gut wĂ€re, die Strukturen dorthin zu verschieben, auf die sehr hĂ€ufig zugegriffen wird. Ich habe eine vorlĂ€ufige Analyse durchgefĂŒhrt, wann und wofĂŒr simple_pjsua Speicher reserviert wird. Es stellte sich heraus, dass von 190 Kb die ersten 90 Kb fĂŒr interne BedĂŒrfnisse von PJSIP reserviert werden und der Zugriff darauf nicht sehr hĂ€ufig erfolgt. DarĂŒber hinaus wird wĂ€hrend eines eingehenden Anrufs die Funktion pjsua_call_answer aufgerufen, bei der dann Puffer fĂŒr die Verarbeitung von eingehenden und ausgehenden Frames reserviert werden. Das waren noch etwa 100 Kb. Und hier sind wir wie folgt vorgegangen. Vor dem Anruf platzieren wir die Daten im externen Speicher. Sobald der Anruf kommt, tauschen wir sofort den Heap gegen einen anderen aus â im RAM. So wurden alle âheiĂenâ Daten in einen schnelleren und vorhersehbareren Speicher verschoben.
Letztendlich hat all das zusammen ermöglicht, simple_pjsua und ĂŒber unseren Server zu telefonieren. Und dann auch ĂŒber andere Server wie sip.linphone.org.
Das DBMS Tarantool ist ein attraktives, zukunftstrÀchtiges Produkt zur Erstellung von hochbelasteten Anwendungen.
Letztendlich gelang es, simple_pjsua mit der SprachĂŒbertragung in beide Richtungen ĂŒber den Server. Das Problem mit den zusĂ€tzlich benötigten 128 Kb SDRAM kann durch den Einsatz eines etwas leistungsstĂ€rkeren Cortex-M7 (zum Beispiel STM32F769NI mit 512 Kb RAM) gelöst werden, aber wir haben auch die Hoffnung nicht aufgegeben, es in 256 Kb zu schaffen đ Wir wĂŒrden uns freuen, wenn sich jemand dafĂŒr interessiert, noch besser â es ausprobiert. Alle Quellcodes sind wie gewohnt in unserem .
Quelle: habr.com
