SIP-Telefon auf STM32F7-Discovery

Hallo an alle.

Vor einiger Zeit haben wir darüber geschrieben, wie wir es geschafft haben, ein SIP-Telefon auf dem STM32F4-Discovery mit 1 MB ROM und 192 KB RAM (basierend auf Embox ) zu starten . Hier muss gesagt werden, dass diese Version minimal war und zwei Telefone direkt ohne Server und mit Sprachübertragung nur in eine Richtung verband. Aus diesem Grund haben wir uns entschlossen, ein vollständigeres Telefon mit einem Anruf über den Server zu starten, die Sprachübertragung in beide Richtungen, aber gleichzeitig die kleinstmögliche Speichergröße beizubehalten.


Für das Telefon wurde beschlossen, die Anwendung simple_pjsua als Teil der PJSIP-Bibliothek auszuwählen. Dies ist eine minimale Anwendung, die sich auf dem Server registrieren, Anrufe empfangen und beantworten kann. Im Folgenden werde ich sofort beschreiben, wie dies auf dem STM32F7-Discovery ausgeführt wird.

Wie man läuft


  1. Embox konfigurieren
    make confload-platform/pjsip/stm32f7cube 
  2. Legen Sie in der Datei conf / mods.config das gewünschte SIP-Konto fest.

     include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password") 

    Wenn Server der SIP-Server ist (z. B. sip.linphone.org), sind Benutzername und Kennwort der Benutzername und das Kennwort des Kontos.
  3. Erstellen Sie Embox mit dem Befehl make . Über die Firmware des Boards haben wir im Wiki und im Artikel .
  4. Führen Sie den Befehl "simple_pjsua_imported" in der Embox-Konsole aus

     00:00:12.870 pjsua_acc.c ....SIP outbound status for acc 0 is not active 00:00:12.884 pjsua_acc.c ....sip:alexk2222@sip.linphone.org: registration success, status=200 (Registration succes 00:00:12.911 pjsua_acc.c ....Keep-alive timer started for acc 0, destination:91.121.209.194:5060, interval:15s 

  5. Schließlich müssen noch Lautsprecher oder Kopfhörer in den Audioausgang eingesetzt und in zwei kleine MEMS-Mikrofone in der Nähe des Displays gesprochen werden. Wir rufen von Linux über die Anwendung simple_pjsua, pjsua auf. Nun, oder Sie können jede andere Art von Telefon.

All dies ist in unserem Wiki beschrieben .

Wie sind wir dazu gekommen?


Daher stellte sich zunächst die Frage nach der Wahl einer Hardwareplattform. Da klar war, dass der STM32F4-Discovery nicht in den Speicher passen würde, wurde der STM32F7-Discovery ausgewählt. Sie hat ein 1 MB Flash-Laufwerk und 256 KB RAM (+ 64 spezielle schnelle Speicher, die wir auch verwenden werden). Auch nicht viel für Anrufe über den Server, aber beschlossen, zu versuchen, einzusteigen.

Herkömmlicherweise war die Aufgabe in mehrere Phasen unterteilt:

  • Ausführen von PJSIP auf QEMU. Es war praktisch zum Debuggen, und wir hatten dort bereits AC97-Codec-Unterstützung.
  • Sprachaufnahme und -wiedergabe auf QEMU und STM32.
  • Portieren einer simple_pjsua- Anwendung aus PJSIP heraus. Sie können sich auf dem SIP-Server registrieren und Anrufe tätigen.
  • Stellen Sie Ihren eigenen Asterisk-basierten Server bereit und testen Sie ihn. Probieren Sie dann externe Server wie sip.linphone.org aus

Sound in Embox funktioniert über Portaudio, das auch in PISIP verwendet wird. Die ersten Probleme traten bei QEMU auf - WAV spielte bei 44100 Hz gut, aber bei 8000 ging offensichtlich etwas schief. Es stellte sich heraus, dass es darum ging, die Frequenz einzustellen - standardmäßig waren es 44100 in der Ausrüstung, und dies änderte sich bei uns nicht programmatisch.

Hier lohnt es sich wahrscheinlich, ein wenig zu erklären, wie Sound im Allgemeinen gespielt wird. Die Soundkarte kann einen Zeiger auf ein Speicherelement setzen, aus dem Sie mit einer vorgegebenen Frequenz abspielen oder aufnehmen möchten. Nach dem Ende des Puffers wird ein Interrupt generiert und die Ausführung ab dem nächsten Puffer fortgesetzt. Tatsache ist, dass diese Puffer im Voraus gefüllt werden müssen, bevor der vorherige abgespielt wird. Dieses Problem wird beim STM32F7 weiter auftreten.

Als Nächstes haben wir einen Server gemietet und Asterisk darauf bereitgestellt. Da es notwendig war, viel zu debuggen, aber nicht viel in das Mikrofon sprechen wollte, war es notwendig, die automatische Wiedergabe und Aufnahme durchzuführen. Zu diesem Zweck haben wir simple_pjsua gepatcht, sodass es möglich war, Dateien anstelle von Audiogeräten zu verschieben. In PJSIP geschieht dies ganz einfach, da sie das Konzept eines Ports haben, der entweder ein Gerät oder eine Datei sein kann. Und diese Ports können flexibel mit anderen Ports verbunden werden. Sie können den Code in unserem pjsip- Repository sehen . Infolgedessen war das Schema wie folgt. Ich habe zwei Konten auf dem Asterisk-Server erstellt - für Linux und für Embox. Als nächstes wird der Befehl simple_pjsua_imported auf Embox ausgeführt. Embox wird auf dem Server registriert. Danach rufen wir Embox unter Linux auf. Zum Zeitpunkt der Verbindung überprüfen wir auf dem Asterisk-Server, ob die gesamte Verbindung hergestellt ist, und nach einiger Zeit sollten sie in Embox Sound von Linux hören, und unter Linux speichern wir die von Embox abgespielte Datei.

Nachdem es auf QEMU funktioniert hatte, wechselten wir zur Portierung auf STM32F7-Discovery. Das erste Problem: Ohne die mitgelieferte Optimierung des Compilers "-Os" in Bezug auf die Bildgröße gelangten sie nicht in ein 1-MB-ROM. Daher enthalten "-Os". Außerdem hat der Patch die C ++ - Unterstützung deaktiviert, sodass er nur für pjsua benötigt wird, und wir verwenden simple_pjsua.

Nachdem wir simple_pjsua angepasst hatten , entschieden wir, dass es jetzt Chancen gibt, es zu starten. Aber zuerst musste man sich mit Sprachaufnahme und -wiedergabe befassen. Frage - wo schreiben? Wir haben einen externen Speicher gewählt - SDRAM (128 MB). Sie können es selbst versuchen:

Erstellt Stereo-WAV mit einer Frequenz von 16000 Hz und einer Dauer von 10 Sekunden:

 record -r 16000 -c 2 -d 10000 -m C0000000 

Wir verlieren:

 play -m C0000000 

Es gab zwei Probleme. Der erste mit einem Codec ist WM8994 und hat ein Konzept wie einen Steckplatz. Diese Steckplätze sind 4. Wenn dies nicht konfiguriert ist, erfolgt die Wiedergabe bei der Audiowiedergabe standardmäßig in allen vier Steckplätzen. Daher haben wir bei einer Frequenz von 16000 Hz 8000 Hz empfangen, aber bei 8000 Hz hat die Wiedergabe einfach nicht funktioniert. Wenn nur die Steckplätze 0 und 2 ausgewählt wurden, funktionierte es wie es sollte. Ein weiteres Problem war das Audio-Interface im STM32Cube, bei dem der Audioausgang über SAI (Serial Audio Interface) synchron mit dem Audioeingang arbeitet (die Details wurden nicht verstanden, aber es stellte sich heraus, dass sie eine gemeinsame Uhr haben und das Audio beim Initialisieren des Audioausgangs irgendwie daran angeschlossen ist Eingabe). Das heißt, sie können nicht separat gestartet werden, daher haben sie Folgendes getan: Der Audioeingang und der Audioausgang funktionieren immer (einschließlich Interrupts werden generiert). Wenn jedoch nichts im System verloren geht, schieben wir einfach einen leeren Puffer in den Audioausgang, und wenn die Wiedergabe beginnt, beginnen wir ehrlich, ihn zu füllen.

Außerdem stellten sie fest, dass der Ton bei der Sprachaufnahme sehr leise war. Dies liegt an der Tatsache, dass MEMS-Mikrofone am STM32F7-Discovery bei Frequenzen unter 16000 Hz irgendwie nicht gut funktionieren. Daher stellen wir 16000 Hz ein, auch wenn 8000 Hz kommen. Um dies zu tun, war die Wahrheit, eine Software-Konvertierung von einer Frequenz zu einer anderen hinzuzufügen.

Als nächstes musste ich den Heap vergrößern, der sich im RAM befindet. Nach unseren Schätzungen benötigte pjsip ungefähr 190 Kb, und wir hatten nur ungefähr 100 Kb. Hier musste ich ein bisschen externen Speicher verwenden - SDRAM (ca. 128 Kb).

Nach all diesen Änderungen sah ich die ersten Pakete zwischen Linux und Embox und hörte einen Ton! Aber der Sound war schrecklich, überhaupt nicht wie bei QEMU, nichts konnte erkannt werden. Dann haben wir darüber nachgedacht, was los sein könnte. Das Debuggen hat gezeigt, dass Embox einfach keine Zeit hat, Audiopuffer zu füllen / zu entladen. Während pjsip einen Frame verarbeitet, sind vor Abschluss der Pufferverarbeitung zwei Unterbrechungen aufgetreten, was zu viel ist. Der erste Gedanke zur Beschleunigung war die Optimierung des Compilers, der jedoch bereits in PJSIP enthalten war. Der zweite ist ein Hardware-Gleitkomma, über den wir im Artikel gesprochen haben . Wie die Praxis gezeigt hat, hat die FPU die Geschwindigkeit nicht signifikant erhöht. Der nächste Schritt bestand darin, die Threads zu priorisieren. Embox hat verschiedene Planungsstrategien, und ich habe eine hinzugefügt, die Prioritäten unterstützt und Audio-Streams auf die höchste Priorität setzt. Es hat auch nicht geholfen.

Das nächste war die Idee, dass wir mit externem Speicher arbeiten und es wäre schön, Strukturen dorthin zu verschieben, auf die extrem oft zugegriffen wird. Ich habe eine vorläufige Analyse durchgeführt, wann und unter was simple_pjsua Speicher zuweist . Es stellte sich heraus, dass von 190 KB die ersten 90 KB für die internen Anforderungen von PJSIP reserviert sind und nicht sehr oft darauf zugegriffen wird. Während eines eingehenden Aufrufs wird dann die Funktion pjsua_call_answer aufgerufen, in der dann Puffer für die Arbeit mit eingehenden und ausgehenden Frames zugewiesen werden. Es war ungefähr 100 kb. Und hier haben wir wie folgt gehandelt. Vor dem Anruf werden die Daten in einem externen Speicher abgelegt. Sobald der Aufruf - sofort den Heap durch einen anderen ersetzen - im RAM. Somit wurden alle "heißen" Daten in einen schnelleren und vorhersehbareren Speicher übertragen.

Infolgedessen konnte all dies zusammen simple_pjsua starten und über seinen Server einen Anruf tätigen. Und dann über andere Server wie sip.linphone.org.

Schlussfolgerungen


Infolgedessen stellte sich heraus, dass simple_pjsua mit Sprachübertragung in beide Richtungen über den Server ausgeführt wurde. Das Problem mit dem zusätzlich verbrauchten 128-Kb-SDRAM kann mit einem etwas leistungsstärkeren Cortex-M7 (z. B. STM32F769NI mit 512 Kb RAM) gelöst werden. Gleichzeitig haben wir jedoch keine Hoffnung, in 256 Kb zu passen :) Wir werden uns freuen, wenn jemand interessiert ist und noch besser - versuchen Sie es. Alle Quellen befinden sich wie gewohnt in unserem Repository .

Source: https://habr.com/ru/post/de431134/


All Articles