SIP telefonoa STM32F7-Discovery-n

Kaixo guztioi

Duela denbora bat guk писали SIP telefono bat abiarazteko nola lortu genuen STM32F4-Discovery-n 1 MB ROM eta 192 KB RAM dituena) oinarrituta. Embox. Hemen esan beharra dago bertsio hori minimoa zela eta bi telefono zuzenean zerbitzaririk gabe konektatzen zituela eta ahots transmisioa norabide bakarrean. Hori dela eta, zerbitzariaren bidez dei batekin telefono osatuagoa abian jartzea erabaki genuen, ahots bidezko transmisioa bi noranzkoetan, baina, aldi berean, ahalik eta memoria-tamaina txikienean mantentzea.


Telefonorako, aplikazio bat aukeratzea erabaki zen simple_pjsua PJSIP liburutegiaren parte gisa. Zerbitzarian erregistratu, deiak jaso eta erantzun ditzakeen gutxieneko aplikazioa da. Jarraian, berehala emango dut STM32F7-Discovery-n exekutatu nola exekutatzeko deskribapena.

Nola korrika egin

  1. Embox konfiguratzen
    make confload-platform/pjsip/stm32f7cube
  2. Ezarri beharrezko SIP kontua conf/mods.config fitxategian.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    non zerbitzaria SIP zerbitzari bat da (adibidez, sip.linphone.org), erabiltzailea ΠΈ pasahitza - Kontuaren erabiltzaile-izena eta pasahitza.

  3. Embox taldean muntatzea egiteko. Daukagun plakako firmwareari buruz wikia eta Artikulu.
  4. Exekutatu "simple_pjsua_imported" komandoa Embox kontsolan
    
    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. Azkenik, bozgorailuak edo entzungailuak audio irteeran sartzea geratzen da, eta pantailaren ondoan dauden bi MEMS mikrofono txikitan hitz egitea. Linuxetik deitzen dugu simple_pjsua, pjsua aplikazioaren bidez. Beno, edo beste edozein linphone mota erabil dezakezu.

Hau guztia gurean azaltzen da wikia.

Nola heldu ginen

Beraz, hasieran hardware plataforma bat aukeratzeari buruzko galdera sortu zen. STM32F4-Discovery memoriatik sartuko ez zela argi zegoenez, STM32F7-Discovery aukeratu zen. 1 MBko flash drive bat eta 256 KB RAM ditu (+ 64 memoria azkar berezi, guk ere erabiliko duguna). Zerbitzariaren bidez deietarako ere ez asko, baina sartzen saiatzea erabaki genuen.

Beraiek baldintzatuta, zeregina hainbat fasetan banatu zen:

  • PJSIP exekutatzen QEMU-n. Erosoa zen arazketarako, gainera dagoeneko bazeukagu ​​bertan AC97 kodekerako euskarria.
  • Ahotsa grabatzea eta erreproduzitzea QEMUn eta STM32n.
  • Aplikazio bat portatzea simple_pjsua PJSIP-tik. SIP zerbitzarian erregistratu eta deiak egiteko aukera ematen du.
  • Inplementatu zure zerbitzaria Asterisk-en oinarrituta eta probatu bertan, gero probatu kanpokoekin, hala nola sip.linphone.org

Embox-en soinuak Portaudio bidez funtzionatzen du, PISIP-en ere erabiltzen dena. Lehen arazoak QEMU-n agertu ziren - WAV-ek 44100 Hz-en ondo jokatu zuen, baina 8000-n zerbait gaizki joan zen. Maiztasuna ezartzea zen kontua - berez 44100 zen ekipoan, eta hori ez zen programatikoki aldatu.

Hemen, beharbada, merezi du apur bat azaltzea nola jotzen den soinua orokorrean. Soinu-txartela aurrez zehaztutako maiztasun batean erreproduzitu edo grabatu nahi duzun memoriaren erakusle batean ezar daiteke. Buffera amaitu ondoren, eten bat sortzen da eta exekuzioa hurrengo bufferarekin jarraitzen du. Kontua da buffer hauek aldez aurretik bete behar direla aurrekoa jotzen ari den bitartean. Arazo honi aurre egingo diogu gehiago STM32F7-n.

Ondoren, zerbitzari bat alokatu genuen eta Asterisk ezarri genuen bertan. Asko arazketa beharrezkoa zenez, baina mikrofonoan asko hitz egin nahi ez nuenez, erreprodukzio eta grabazio automatikoa egin behar zen. Horretarako, simple_pjsua adabaki dugu, audio-gailuen ordez fitxategiak irristatu ahal izateko. PJSIP-en, hau nahiko sinplea egiten da, ataka kontzeptua baitute, gailu bat edo fitxategi bat izan daitekeen. Eta portu horiek malgutasunez konekta daitezke beste portu batzuetara. Kodea gure pjsip-en ikus dezakezu biltegiak. Ondorioz, eskema honakoa zen. Asterisk zerbitzarian, bi kontu hasi nituen: Linuxerako eta Embboxerako. Ondoren, komandoa Emboxen exekutatzen da simple_pjsua_imported, Embox zerbitzarian erregistratzen da, eta ondoren Linuxetik Embox deitzen dugu. Konexioaren momentuan, Asterisk zerbitzarian egiaztatzen dugu konexioa ezarrita dagoela, eta pixka bat igaro ondoren Linux-en soinua entzun beharko genuke Emboxen, eta Linux-en Emboxen erreproduzitzen den fitxategia gordetzen dugu.

QEMU-n funtzionatu ondoren, STM32F7-Discovery-ra eraman genuen. Lehenengo arazoa da ez zirela ROM 1 MB-n sartzen irudiaren tamainarako gaituta dagoen konpiladorearen optimizazio "-Os" gabe. Horregatik sartu dugu "-Os". Gainera, adabakiak C ++-rako euskarria desgaitu zuen, beraz, pjsua-rako bakarrik beharrezkoa da, eta simple_pjsua erabiltzen dugu.

Jarri ondoren simple_pjsua, orain martxan jartzeko aukera dagoela erabaki zuen. Baina lehendabizi ahotsaren grabaketa eta erreprodukzioa jorratu behar zen. Galdera da non idatzi? Kanpoko memoria aukeratu dugu - SDRAM (128 MB). Zuk zeuk proba dezakezu hau:

WAV estereo bat sortzen du 16000 Hz-ko maiztasuna eta 10 segundoko iraupena duena:


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

Galtzen dugu:


play -m C0000000

Hemen bi arazo daude. Kodekarekin lehena - WM8994 erabiltzen da, eta zirrikitu bat du, eta zirrikitu horietako 4 daude. Beraz, lehenespenez, hau konfiguratuta ez badago, audioa erreproduzitzean, erreprodukzioa lau zirrikituetan gertatzen da. . Hori dela eta, 16000 Hz-ko maiztasunarekin, 8000 Hz jaso genuen, baina 8000 Hz-rako erreprodukzioa ez zuen funtzionatu. 0 eta 2 zirrikituak bakarrik hautatu zirenean, behar bezala funtzionatu zuen. Beste arazo bat STM32Cube-ko audio-interfazea izan zen, zeinean audio-irteerak SAI (Serial Audio Interface) bidez funtzionatzen duen audio-sarrerarekin sinkronoki (ez nituen xehetasunak ulertu, baina erloju komun bat partekatzen dutela eta noiz audio irteera hasieratzen da, audioa nolabait erantsita dago sarreran). Hau da, ezin dituzu bereizita exekutatu, beraz, honako hau egin dugu: audio-sarrerak eta audio-irteerak beti funtzionatzen dute (etenaldiak sortzen dira barne). Baina sisteman ezer erreproduzitzen ez denean, buffer huts bat audio irteeran sartzen dugu, eta erreprodukzioa hasten denean, zintzotasunez betetzen hasten gara.

Gainera, ahotsa grabatzerakoan soinua oso lasaia zela ikusi genuen. STM32F7-Discovery-ko MEMS mikrofonoek nolabait ez dutelako ondo funtzionatzen 16000 Hz azpiko maiztasunetan. Horregatik, 16000 Hz ezarri dugu, nahiz eta 8000 Hz etorri. Horretarako, baina, beharrezkoa zen maiztasun baten software bihurketa bat gehitzea.

Ondoren, RAM-n dagoen heap-aren tamaina handitu behar izan nuen. Gure kalkuluen arabera, pjsip-ek 190 KB inguru behar zituen, eta 100 KB inguru besterik ez ditugu geratzen. Hemen kanpoko memoria batzuk erabili behar izan ditut - SDRAM (128 KB inguru).

Aldaketa guzti hauen ostean, Linux eta Emboxen arteko lehen paketeak ikusi nituen, eta soinua entzun nuen! Baina soinua izugarria zen, ez zen batere QEMUn bezala, ezinezkoa zen ezer ateratzea. Orduan pentsatu genuen zer izan zitekeen kontua. Arazketak erakutsi zuen Emboxek ez duela audio buffer-ak bete/deskargatzeko astirik. Pjsip fotograma bat prozesatzen ari zen bitartean, 2 etenaldi gertatu ziren buffer prozesatzeari buruz, gehiegizkoa da. Abiadurarako lehen pentsatua konpiladoreen optimizazioa izan zen, baina dagoeneko PJSIP-en sartuta zegoen. Bigarrena hardware koma mugikor bat da, horri buruz hitz egin dugu Artikulu. Baina praktikak erakutsi duenez, FPUk ez zuen abiadura handitu handirik eman. Hurrengo urratsa hariak lehenestea izan zen. Embox-ek programazio estrategia desberdinak ditu, eta lehentasunak onartzen dituena eta audio-korronteak lehentasun handiena ezartzen dituen bat sartu dut. Horrek ere ez zuen lagundu.

Hurrengo ideia zen kanpoko memoriarekin lan egiten ari garela eta polita litzatekeela oso maiz sartzen diren egiturak bertara eramatea. Aurretiazko analisia egin nuen noiz eta zer pean simple_pjsua memoria esleitzen du. 190 Kb-tik, lehenengo 90 Kb PJSIP-en barne beharretarako esleitzen direla eta ez dira askotan sartzen. Gainera, sarrerako dei batean, pjsua_call_answer funtzioa deitzen da, eta orduan buffer-ak esleitzen dira sarrerako eta irteerako markoekin lan egiteko. 100 Kb ingurukoa zen oraindik. Eta gero honako hau egin genuen. Deiaren unera arte, datuak kanpoko memorian jartzen ditugu. Deia egin bezain laster, berehala ordezkatzen dugu heap beste batekin - RAM batean. Horrela, datu "beroak" guztiak memoria azkarrago eta aurreikuspen handiago batera transferitzen ziren.

Ondorioz, guzti honek batera martxan jartzea ahalbidetu zuen simple_pjsua eta deitu zure zerbitzariaren bidez. Eta gero sip.linphone.org bezalako beste zerbitzari batzuen bitartez.

Findings

Ondorioz, martxan jartzea posible izan zen simple_pjsua zerbitzariaren bidez bi noranzkoetan ahots transmisioarekin. Gainera, 128 KB SDRAM gastatutako arazoa Cortex-M7 apur bat indartsuagoa erabiliz konpon daiteke (adibidez, STM32F769NI 512 KB RAMarekin), baina, aldi berean, oraindik ez dugu galdu 256an sartzeko itxaropena. KB πŸ™‚ Pozik egongo gara norbait interesatuta badago, Edo hobeto esanda, proba ezazu. Iturri guztiak, ohi bezala, gurean daude biltegiak.

Iturria: www.habr.com

Gehitu iruzkin berria