Nemrég mi писали arról, hogyan sikerült elindítani egy SIP telefont STM32F4-Discovery-n 1 MB ROM-mal és 192 KB RAM-mal) Embox. Itt kell elmondani, hogy az a verzió minimális volt, és két telefont kötött közvetlenül szerver nélkül, és csak egy irányban hangátvitellel. Ezért úgy döntöttünk, hogy egy komplettebb telefont indítunk a szerveren keresztüli hívással, mindkét irányban hangátvitellel, ugyanakkor a lehető legkisebb memóriaméreten belül.
A telefonhoz úgy döntöttek, hogy egy alkalmazást választanak egyszerű_pjsua a PJSIP könyvtár részeként. Ez egy minimális alkalmazás, amely képes regisztrálni a szerveren, fogadni és fogadni hívásokat. Az alábbiakban azonnal leírom, hogyan kell futtatni az STM32F7-Discovery-n.
Hogyan kell futni
Az Embox konfigurálása
make confload-platform/pjsip/stm32f7cube
Állítsa be a szükséges SIP-fiókot a conf/mods.config fájlban.
include platform.pjsip.cmd.simple_pjsua_imported(
sip_domain="server",
sip_user="username",
sip_passwd="password")
ahol szerver egy SIP szerver (például sip.linphone.org), felhasználónév и jelszó - fiók felhasználóneve és jelszava.
Az Embox összeállítása csapatként csinál. Az általunk használt tábla firmware-ről вики és cikk.
Futtassa a „simple_pjsua_imported” parancsot az Embox konzolon
00:00:12.870 pjsua_acc.c ....SIP outbound status for acc 0 is not active
00:00:12.884 pjsua_acc.c ....sip:[email protected]: 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
Végül marad, hogy hangszórókat vagy fejhallgatót helyezzen be az audiokimenetbe, és beszéljen a kijelző melletti két kis MEMS-mikrofonba. Linuxról a simple_pjsua, pjsua alkalmazáson keresztül hívunk. Nos, vagy használhat bármilyen más típusú telefont.
Tehát kezdetben felmerült a kérdés a hardverplatform kiválasztásával kapcsolatban. Mivel egyértelmű volt, hogy az STM32F4-Discovery nem fér el a memóriából, az STM32F7-Discovery-t választottuk. 1 MB-os flash meghajtója és 256 KB RAM-ja van (+ 64 speciális gyorsmemória, amit szintén használni fogunk). Szintén nem sok a szerveren keresztüli hívás, de úgy döntöttünk, hogy megpróbálunk beilleszkedni.
Feltételesen saját maguk számára a feladatot több szakaszra osztották:
PJSIP futtatása QEMU-n. Kényelmes volt a hibakeresés, ráadásul ott már támogattuk az AC97 kodeket.
Hangrögzítés és lejátszás QEMU-n és STM32-n.
Alkalmazás portolása egyszerű_pjsua a PJSIP-től. Lehetővé teszi a SIP szerveren való regisztrációt és hívások kezdeményezését.
Telepítse saját Asterisk-alapú szerverét, és tesztelje azt, majd próbáljon ki külső szervereket, például sip.linphone.org
A hang az Emboxban a Portaudion keresztül működik, amelyet a PISIP is használ. Az első problémák a QEMU-n jelentek meg – a WAV jól játszott 44100 Hz-en, de 8000-nél valami egyértelműen elromlott. Kiderült, hogy a frekvencia beállításáról van szó - alapból 44100 volt a berendezésben, és ez programszerűen nem változott.
Itt talán érdemes egy kicsit elmagyarázni, hogyan szólal meg általában a hang. A hangkártya beállítható valamilyen mutatóra, amely egy memóriadarabra mutat, ahonnan előre meghatározott frekvencián szeretne játszani vagy rögzíteni. A puffer vége után megszakítás jön létre, és a végrehajtás a következő pufferrel folytatódik. A helyzet az, hogy ezeket a puffereket előre fel kell tölteni az előző lejátszása közben. Ezzel a problémával a továbbiakban szembesülünk az STM32F7-en.
Ezután béreltünk egy szervert, és telepítettük rajta az Asterisket. Mivel sokat kellett debugolni, de nem nagyon akartam beleszólni a mikrofonba, szükség volt az automatikus lejátszásra és felvételre. Ehhez javítottuk a simple_pjsua fájlt, hogy az audioeszközök helyett fájlokat csúsztathasson. A PJSIP-ben ez egészen egyszerűen megtörténik, mivel rendelkeznek a port fogalmával, amely lehet eszköz vagy fájl. És ezek a portok rugalmasan csatlakoztathatók más portokhoz. A kódot a pjsip-ünkben láthatja adattárak. Ennek eredményeként a séma a következő volt. Az Asterisk szerveren elindítottam két fiókot – Linuxhoz és Emboxhoz. Ezután a parancs végrehajtásra kerül az Emboxon simple_pjsua_imported, Embox regisztrál a szerveren, ami után meghívjuk az Emboxot Linuxról. A csatlakozás pillanatában ellenőrizzük az Asterisk szerveren, hogy létrejött-e a kapcsolat, majd egy idő után az Emboxban hallani kell a Linux hangját, Linuxban pedig elmentjük az Emboxból lejátszott fájlt.
Miután működött a QEMU-n, áttértünk az STM32F7-Discovery-re történő portolásra. Az első probléma az, hogy nem fértek bele 1 MB ROM-ba, ha a kép méretéhez nincs engedélyezve a fordítóoptimalizálás „-Os”. Ezért vettük fel a "-Os"-t. Továbbá a javítás letiltotta a C ++ támogatását, így csak a pjsua-hoz van szükség, mi pedig a simple_pjsua-t használjuk.
Az elhelyezés után egyszerű_pjsua, úgy döntött, hogy most van lehetőség elindítani. De először a hang rögzítésével és lejátszásával kellett foglalkozni. A kérdés az, hogy hova kell írni? Külső memóriát választottunk - SDRAM (128 MB). Ezt magad is kipróbálhatod:
Sztereó WAV-ot hoz létre 16000 Hz-es frekvenciával és 10 másodperc időtartammal:
record -r 16000 -c 2 -d 10000 -m C0000000
Vesztettünk:
play -m C0000000
Itt két probléma van. Az első kodekkel - WM8994 van használva, és van benne olyan, hogy egy slot, és ebből van 4. Tehát alapértelmezés szerint, ha ez nincs beállítva, akkor hang lejátszásakor a lejátszás mind a négy slotban történik . Ezért 16000 Hz-es frekvencián 8000 Hz-et kaptunk, de 8000 Hz-en a lejátszás egyszerűen nem működött. Amikor csak a 0-s és 2-es helyet választották ki, akkor úgy működött, ahogy kell. További probléma volt az STM32Cube-ban található audio interfész, amelyben a hangkimenet SAI-n (Serial Audio Interface) keresztül működik szinkronban az audio bemenettel (a részleteket nem értettem, de kiderült, hogy közös az óra, és mikor Az audiokimenet inicializálva van, a hang valahogy hozzá van kapcsolva a bejárathoz). Ez azt jelenti, hogy nem lehet őket külön futtatni, ezért a következőket tettük - az audio bemenet és hangkimenet mindig működik (beleértve a megszakításokat is). De ha nem játszik le semmit a rendszerben, egyszerűen csak egy üres puffert csúsztatunk az audiokimenetbe, és amikor a lejátszás elindul, őszintén elkezdjük feltölteni.
Továbbá azt tapasztaltuk, hogy a hangfelvétel közben nagyon halk volt a hang. Ez annak a ténynek köszönhető, hogy az STM32F7-Discovery MEMS mikrofonjai valahogy nem működnek jól 16000 Hz alatti frekvenciákon. Ezért 16000 Hz-et állítunk be, még akkor is, ha 8000 Hz jön. Ehhez azonban szükség volt az egyik frekvencia szoftveres átalakítására a másikra.
Ezután meg kellett növelnem a kupac méretét, amely a RAM-ban található. Számításaink szerint a pjsip körülbelül 190 KB-ot igényelt, nekünk pedig már csak körülbelül 100 KB maradt. Itt külső memóriát kellett használnom - SDRAM-ot (kb. 128 KB).
Mindezen szerkesztések után láttam az első csomagokat a Linux és az Embox között, és hallottam a hangot! De a hang szörnyű volt, egyáltalán nem olyan, mint a QEMU-n, nem lehetett kivenni semmit. Aztán azon gondolkodtunk, hogy mi lehet a baj. A hibakeresés azt mutatta, hogy az Emboxnak egyszerűen nincs ideje feltölteni / kiüríteni az audio puffereket. Amíg a pjsip egy keretet dolgozott fel, 2 megszakításnak volt ideje a pufferfeldolgozás befejezésekor, ami túl sok. Az első gondolat a gyorsítás érdekében a fordítóoptimalizálás volt, de ez már benne volt a PJSIP-ben. A második egy hardveres lebegőpontos, erről beszéltünk cikk. A gyakorlat azonban azt mutatja, hogy az FPU nem növelte jelentősen a sebességet. A következő lépés a szálak rangsorolása volt. Az Embox különböző ütemezési stratégiákkal rendelkezik, és beépítettem egyet, amely támogatja a prioritásokat, és a hangfolyamokat a legmagasabb prioritásra állítja. Ez sem segített.
A következő ötlet az volt, hogy külső memóriával dolgozunk, és jó lenne oda mozgatni a rendkívül gyakran elérhető struktúrákat. Előzetes elemzést készítettem, hogy mikor és mi alapján egyszerű_pjsua lefoglalja a memóriát. Kiderült, hogy a 190 Kb-ból az első 90 Kb a PJSIP belső igényeire van lefoglalva, és nem túl gyakran fér hozzá. Továbbá, egy bejövő hívás során a pjsua_call_answer függvény meghívásra kerül, amelyben ezután pufferek vannak lefoglalva a bejövő és kimenő keretekkel való munkavégzéshez. Még mindig 100 Kb körül volt. És akkor a következőket tettük. A hívás pillanatáig az adatokat külső memóriába helyezzük. A hívást követően azonnal cseréljük a kupacot egy másikkal - a RAM-ban. Így az összes „forró” adat gyorsabb és kiszámíthatóbb memóriába került.
Ennek eredményeként mindez együtt lehetővé tette az indulást egyszerű_pjsua és hívja a szerverén keresztül. Aztán más szervereken, például a sip.linphone.org oldalon keresztül.
Álláspontja
Ennek eredményeként sikerült elindítani egyszerű_pjsua hangátvitellel mindkét irányban a szerveren keresztül. A plusz 128 KB SDRAM problémája megoldható egy kicsit erősebb Cortex-M7 használatával (például STM32F769NI 512 KB RAM-mal), ugyanakkor még mindig nem adtuk fel a reményt, hogy bekerüljünk a 256-ba. KB 🙂 Örülünk, ha valakit érdekel, vagy még jobb, próbálja ki. Minden forrás, mint általában, a mi oldalunkon található adattárak.