Telefoni SIP në STM32F7-Discovery

Pershendetje te gjitheve

Pak kohë më parë ne писали se si arritëm të lëshonim një telefon SIP në STM32F4-Discovery me 1 MB ROM dhe 192 KB RAM) bazuar në Embox. Këtu duhet thënë se ai version ishte minimal dhe lidhte dy telefona direkt pa server dhe me transmetim zëri vetëm në një drejtim. Prandaj, vendosëm të lançojmë një telefon më të plotë me një telefonatë përmes serverit, transmetim zëri në të dy drejtimet, por në të njëjtën kohë të mbajmë brenda madhësisë më të vogël të mundshme të memories.


Për telefonin, u vendos të zgjidhej një aplikacion thjeshtë_pjsua si pjesë e bibliotekës PJSIP. Ky është një aplikacion minimal që mund të regjistrohet në server, të marrë dhe t'u përgjigjet thirrjeve. Më poshtë do të jap menjëherë një përshkrim se si ta ekzekutoni atë në STM32F7-Discovery.

Si të vraponi

  1. Konfigurimi i Embox
    make confload-platform/pjsip/stm32f7cube
  2. Vendosni llogarinë e kërkuar SIP në skedarin conf/mods.config.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    ku server është një server SIP (për shembull, sip.linphone.org), Emri i përdoruesit и Fjalëkalimi - emri i përdoruesit dhe fjalëkalimi i llogarisë.

  3. Montimi i Embox si një ekip bërë. Rreth firmuerit të bordit që kemi wiki dhe artikull.
  4. Ekzekutoni komandën "simple_pjsua_imported" në tastierën Embox
    
    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
    

  5. Më në fund, mbetet të futni altoparlantët ose kufjet në daljen audio dhe të flisni në dy mikrofona të vegjël MEMS pranë ekranit. Ne thërrasim nga Linux përmes aplikacionit simple_pjsua, pjsua. Epo, ose mund të përdorni çdo lloj telefoni tjetër.

E gjithë kjo përshkruhet në faqen tonë wiki.

Si arritëm atje

Pra, fillimisht lindi pyetja në lidhje me zgjedhjen e një platforme harduerike. Meqenëse ishte e qartë se STM32F4-Discovery nuk do të përshtatej nga kujtesa, u zgjodh STM32F7-Discovery. Ajo ka një flash drive 1 MB dhe 256 KB RAM (+ 64 memorie speciale të shpejtë, të cilën do ta përdorim gjithashtu). Gjithashtu jo shumë për thirrjet përmes serverit, por vendosëm të përpiqemi të përshtatemi.

Me kusht për veten e tyre, detyra u nda në disa faza:

  • Ekzekutimi i PJSIP në QEMU. Ishte i përshtatshëm për korrigjimin e gabimeve, plus ne kishim tashmë mbështetje për kodekun AC97 atje.
  • Regjistrimi dhe riprodhimi i zërit në QEMU dhe në STM32.
  • Transferimi i një aplikacioni thjeshtë_pjsua nga PJSIP. Kjo ju lejon të regjistroheni në serverin SIP dhe të bëni thirrje.
  • Vendosni serverin tuaj të bazuar në Asterisk dhe provoni në të, më pas provoni ato të jashtme si sip.linphone.org

Tingulli në Embox funksionon përmes Portaudio, i cili përdoret gjithashtu në PISIP. Problemet e para u shfaqën në QEMU - WAV luajti mirë në 44100 Hz, por në 8000 diçka nuk shkoi qartë. Doli që bëhej fjalë për vendosjen e frekuencës - si parazgjedhje ishte 44100 në pajisje, dhe kjo nuk ndryshoi në mënyrë programore.

Këtu, ndoshta, ia vlen të shpjegohet pak se si luhet tingulli në përgjithësi. Karta e zërit mund të vendoset në një tregues të një pjese të memories nga e cila dëshironi të luani ose regjistroni me një frekuencë të paracaktuar. Pasi mbaron buferi, krijohet një ndërprerje dhe ekzekutimi vazhdon me buferin tjetër. Fakti është se këto bufera duhet të plotësohen paraprakisht ndërsa luhet i mëparshmi. Ne do të përballemi me këtë problem më tej në STM32F7.

Më pas, morëm me qira një server dhe vendosëm Asterisk në të. Meqenëse ishte e nevojshme të korrigjohej shumë, por nuk doja të flisja shumë në mikrofon, ishte e nevojshme të bëja riprodhimin dhe regjistrimin automatik. Për ta bërë këtë, ne rregulluam simple_pjsua në mënyrë që të mund të rrëshqitni skedarët në vend të pajisjeve audio. Në PJSIP, kjo bëhet mjaft thjesht, pasi ato kanë konceptin e një porti, i cili mund të jetë ose një pajisje ose një skedar. Dhe këto porte mund të lidhen në mënyrë fleksibël me porte të tjera. Ju mund ta shihni kodin në pjsip tonë depove. Si rezultat, skema ishte si më poshtë. Në serverin Asterisk, fillova dy llogari - për Linux dhe për Embox. Më pas, komanda ekzekutohet në Embox thjeshtë_pjsua_importuar, Embox regjistrohet në server, pas së cilës ne thërrasim Embox nga Linux. Në momentin e lidhjes kontrollojmë në serverin Asterisk që lidhja është krijuar dhe pas një kohe duhet të dëgjojmë zë nga Linux në Embox dhe në Linux ruajmë skedarin që luhet nga Embox.

Pasi funksionoi në QEMU, ne kaluam në transferimin në STM32F7-Discovery. Problemi i parë është se ato nuk futeshin në 1 MB ROM pa optimizimin e aktivizuar të përpiluesit "-Os" për madhësinë e imazhit. Kjo është arsyeja pse ne kemi përfshirë "-Os". Më tej, patch-i çaktivizoi mbështetjen për C ++, kështu që nevojitet vetëm për pjsua, dhe ne përdorim simple_pjsua.

Pasi vendoset thjeshtë_pjsua, vendosi që tani ka një shans për ta nisur atë. Por së pari ishte e nevojshme të merreshim me regjistrimin dhe riprodhimin e zërit. Pyetja është ku të shkruani? Ne zgjodhëm memorie të jashtme - SDRAM (128 MB). Ju mund ta provoni këtë vetë:

Krijon një WAV stereo me një frekuencë prej 16000 Hz dhe një kohëzgjatje prej 10 sekondash:


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

Ne humbem:


play -m C0000000

Këtu ka dy probleme. E para me kodekun - WM8994 përdoret, dhe ka një gjë të tillë si slot, dhe ka 4 nga këto lojëra elektronike. Pra, si parazgjedhje, nëse kjo nuk është e konfiguruar, atëherë kur luani audio, riprodhimi ndodh në të katër slotat . Prandaj, në një frekuencë prej 16000 Hz, ne morëm 8000 Hz, por për 8000 Hz, rishikimi thjesht nuk funksionoi. Kur u zgjodhën vetëm lojëra elektronike 0 dhe 2, funksionoi ashtu siç duhej. Një problem tjetër ishte ndërfaqja audio në STM32Cube, në të cilën dalja audio funksionon nëpërmjet SAI (Serial Audio Interface) në mënyrë sinkrone me hyrjen audio (nuk i kuptova detajet, por rezulton se ata ndajnë një orë të përbashkët dhe kur Dalja audio është inicializuar, audio është disi e lidhur me hyrjen e saj). Kjo do të thotë, ju nuk mund t'i ekzekutoni ato veç e veç, kështu që ne bëmë sa vijon - hyrja audio dhe dalja audio funksionojnë gjithmonë (duke përfshirë gjenerohen ndërprerje). Por kur asgjë nuk luhet në sistem, atëherë ne thjesht rrëshqasim një tampon bosh në daljen e audios dhe kur riprodhimi fillon, ne sinqerisht fillojmë ta mbushim atë.

Më tej, kemi hasur në faktin se tingulli gjatë regjistrimit të zërit ishte shumë i qetë. Kjo për faktin se mikrofonat MEMS në STM32F7-Discovery disi nuk funksionojnë mirë në frekuencat nën 16000 Hz. Prandaj, vendosim 16000 Hz, edhe nëse vjen 8000 Hz. Për ta bërë këtë, megjithatë, ishte e nevojshme të shtohej një konvertim i softuerit të një frekuence në tjetrën.

Tjetra, më duhej të rrisja madhësinë e grumbullit, i cili ndodhet në RAM. Sipas llogaritjeve tona, pjsip kërkonte rreth 190 KB, dhe ne kemi vetëm rreth 100 KB. Këtu më duhej të përdorja një memorie të jashtme - SDRAM (rreth 128 KB).

Pas gjithë këtyre modifikimeve, pashë paketat e para midis Linux dhe Embox dhe dëgjova zërin! Por tingulli ishte i tmerrshëm, aspak i njëjtë si në QEMU, ishte e pamundur të dalloje asgjë. Pastaj menduam se çfarë mund të ishte çështja. Korrigjimi tregoi se Embox thjesht nuk ka kohë për të mbushur / shkarkuar buferat audio. Ndërsa pjsip po përpunonte një kornizë, 2 ndërprerje kishin kohë që të ndodhnin rreth përfundimit të përpunimit të buferit, që është shumë. Mendimi i parë për shpejtësinë ishte optimizimi i përpiluesit, por ai tashmë ishte përfshirë në PJSIP. E dyta është një pikë lëvizëse harduerike, ne folëm për të artikull. Por siç ka treguar praktika, FPU nuk dha një rritje të konsiderueshme të shpejtësisë. Hapi tjetër ishte caktimi i prioriteteve të fijeve. Embox ka strategji të ndryshme planifikimi, dhe unë kam përfshirë një që mbështet prioritetet dhe vendos transmetimet audio në përparësinë më të lartë. As kjo nuk ndihmoi.

Ideja tjetër ishte që ne po punojmë me memorie të jashtme dhe do të ishte mirë të zhvendosnim strukturat atje që aksesohen jashtëzakonisht shpesh. Bëra një analizë paraprake se kur dhe nën çfarë thjeshtë_pjsua alokon memorie. Doli se nga 190 Kb, 90 Kb e para ndahen për nevoja të brendshme të PJSIP dhe nuk aksesohen shumë shpesh. Më tej, gjatë një thirrjeje hyrëse, thirret funksioni pjsua_call_answer, në të cilin më pas ndahen buferët për të punuar me kornizat hyrëse dhe dalëse. Ishte ende rreth 100 Kb. Dhe më pas bëmë sa vijon. Deri në momentin e thirrjes i vendosim të dhënat në memorien e jashtme. Menjëherë pas thirrjes, ne e zëvendësojmë menjëherë grumbullin me një tjetër - në RAM. Kështu, të gjitha të dhënat "të nxehta" u transferuan në memorie më të shpejtë dhe më të parashikueshme.

Si rezultat, e gjithë kjo së bashku bëri të mundur nisjen thjeshtë_pjsua dhe telefononi përmes serverit tuaj. Dhe më pas përmes serverëve të tjerë si sip.linphone.org.

Gjetjet

Si rezultat, u bë e mundur të lëshohej thjeshtë_pjsua me transmetim zëri në të dy drejtimet përmes serverit. Problemi me 128 KB të shpenzuara shtesë SDRAM mund të zgjidhet duke përdorur një Cortex-M7 pak më të fuqishëm (për shembull, STM32F769NI me 512 KB RAM), por në të njëjtën kohë, ne ende nuk kemi hequr dorë nga shpresa për të hyrë në 256 KB 🙂 Do të jemi të lumtur nëse dikush është i interesuar, ose më mirë akoma, ta provojë. Të gjitha burimet, si zakonisht, janë te ne depove.

Burimi: www.habr.com

Shto një koment