SIP-telefono sur STM32F7-Discovery

Saluton

Antaŭ iom da tempo ni skribis pri kiel ni sukcesis lanĉi SIP-telefonon sur STM32F4-Discovery kun 1 MB ROM kaj 192 KB RAM) bazita sur Embox. Ĉi tie oni devas diri, ke tiu versio estis minimuma kaj konektis du telefonojn rekte sen servilo kaj kun voĉa transsendo en nur unu direkto. Sekve, ni decidis lanĉi pli kompletan telefonon kun alvoko tra la servilo, voĉa transdono ambaŭdirekte, sed samtempe konservi ene de la plej malgranda ebla memora grandeco.


Por la telefono, oni decidis elekti aplikaĵon simpla_pjsua kiel parto de la PJSIP-biblioteko. Ĉi tio estas minimuma aplikaĵo, kiu povas registriĝi en la servilo, ricevi kaj respondi vokojn. Malsupre mi tuj donos priskribon pri kiel ruli ĝin sur STM32F7-Discovery.

Kiel kuri

  1. Agordante Embox
    make confload-platform/pjsip/stm32f7cube
  2. Agordu la bezonatan SIP-konton en la dosiero conf/mods.config.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    kie servilo estas SIP-servilo (ekzemple, sip.linphone.org), uzantonomo и pasvorto - konto uzantnomo kaj pasvorto.

  3. Kunvenante Embox kiel teamo fari. Pri la tabulo-firmvaro, kiun ni havas vikio kaj en artikolo.
  4. Rulu la komandon "simple_pjsua_imported" en la Embox-konzolo
    
    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. Fine, restas enigi laŭtparolilojn aŭ aŭdilojn en la aŭdan eliron, kaj paroli en du malgrandajn MEMS-mikrofonojn apud la ekrano. Ni vokas de Linukso per la aplikaĵo simple_pjsua, pjsua. Nu, aŭ vi povas uzi ajnan alian tipon de linphone.

Ĉio ĉi estas priskribita sur nia vikio.

Kiel ni alvenis tien

Do, komence ekestis la demando pri elekto de aparataro platformo. Ĉar estis klare, ke STM32F4-Discovery ne konvenus de memoro, STM32F7-Discovery estis elektita. Ŝi havas 1 MB-memorilon kaj 256 KB da RAM (+ 64 speciala rapida memoro, kiun ni ankaŭ uzos). Ankaŭ ne multe por vokoj per la servilo, sed ni decidis provi kongrui.

Kondiĉe por si mem, la tasko estis dividita en plurajn stadiojn:

  • Kurante PJSIP sur QEMU. Estis oportune por sencimigi, krome ni jam havis subtenon por la kodeko AC97 tie.
  • Voĉregistrado kaj reprodukto sur QEMU kaj sur STM32.
  • Porti aplikaĵon simpla_pjsua de PJSIP. Ĝi permesas vin registri en la SIP-servilo kaj fari vokojn.
  • Deploji vian propran Asterisk-bazitan servilon kaj provu sur ĝi, tiam provu eksterajn tiajn kiel sip.linphone.org

Sono en Embox funkcias per Portaudio, kiu ankaŭ estas uzata en PISIP. La unuaj problemoj aperis ĉe QEMU - WAV bone ludis ĉe 44100 Hz, sed ĉe 8000 io klare misfunkciis. Montriĝis, ke temas pri agordo de la frekvenco - defaŭlte ĝi estis 44100 en la ekipaĵo, kaj ĉi tio ne ŝanĝiĝis programe.

Ĉi tie, eble, indas iom klarigi kiel la sono ĝenerale ludas. La sonkarto povas esti agordita al iu montrilo al memorpeco de kiu vi volas ludi aŭ registri je antaŭdeterminita frekvenco. Post kiam la bufro finiĝas, interrompo estas generita kaj ekzekuto daŭras kun la sekva bufro. La fakto estas, ke ĉi tiuj bufroj devas esti plenigitaj anticipe dum la antaŭa estas ludata. Ni alfrontos ĉi tiun problemon plu sur STM32F7.

Poste, ni luis servilon kaj deplojis Asterisk sur ĝi. Ĉar necesis multe sencimi, sed mi ne multe volis paroli en la mikrofonon, necesis fari aŭtomatan reproduktadon kaj registradon. Por fari tion, ni flikis simple_pjsua por ke vi povu gliti dosierojn anstataŭ sonaparatoj. En PJSIP, tio estas farita tute simple, ĉar ili havas la koncepton de haveno, kiu povas esti aŭ aparato aŭ dosiero. Kaj ĉi tiuj havenoj povas esti flekseble konektitaj al aliaj havenoj. Vi povas vidi la kodon en nia pjsip deponejoj. Kiel rezulto, la skemo estis kiel sekvas. Sur la Asterisk-servilo, mi komencis du kontojn - por Linukso kaj por Embox. Poste, la komando estas ekzekutita ĉe Embox simpla_pjsua_importita, Embox estas registrita sur la servilo, post kio ni vokas Embox de Linukso. En la momento de la konekto, ni kontrolas sur la Asterisk-servilo, ke la konekto estas establita, kaj post iom da tempo ni devus aŭdi sonon de Linukso en Embox, kaj en Linukso ni konservas la dosieron, kiu estas ludata de Embox.

Post kiam ĝi funkciis pri QEMU, ni pluiris al portado al STM32F7-Discovery. La unua problemo estas, ke ili ne konvenis en 1 MB da ROM sen la ebligita kompilila optimumigo "-Os" por la grandeco de la bildo. Tial ni inkluzivis "-Os". Plue, la flikaĵo malfunkciigis subtenon por C ++, do ĝi estas bezonata nur por pjsua, kaj ni uzas simple_pjsua.

Post esti metita simpla_pjsua, decidis ke nun estas ŝanco lanĉi ĝin. Sed unue necesis trakti la registradon kaj reproduktadon de la voĉo. La demando estas kie skribi? Ni elektis eksteran memoron - SDRAM (128 MB). Vi povas provi ĉi tion mem:

Kreas stereofon WAV kun frekvenco de 16000 Hz kaj daŭro de 10 sekundoj:


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

Ni perdas:


play -m C0000000

Estas du problemoj ĉi tie. La unua kun la kodeko - WM8994 estas uzata, kaj ĝi havas tian fendon, kaj estas 4 el ĉi tiuj fendoj. Do, defaŭlte, se ĉi tio ne estas agordita, tiam dum ludado de audio, reproduktado okazas en ĉiuj kvar fendoj. . Sekve, je ofteco de 16000 Hz, ni ricevis 8000 Hz, sed por 8000 Hz, la reprodukto simple ne funkciis. Kiam nur fendoj 0 kaj 2 estis elektitaj, ĝi funkciis kiel ĝi devus. Alia problemo estis la soninterfaco en la STM32Cube, en kiu la soneligo funkcias per SAI (Serial Audio Interface) sinkrone kun la sonenigo (mi ne komprenis la detalojn, sed rezultas, ke ili kunhavas komunan horloĝon kaj kiam la aŭda eligo estas pravigita, aŭdo estas iel alfiksita al ĝi enirejo). Tio estas, vi ne povas ruli ilin aparte, do ni faris la jenon - la aŭda enigo kaj aŭda eligo ĉiam funkcias (inkluzive de interrompoj estas generitaj). Sed kiam nenio estas ludata en la sistemo, tiam ni simple glitas malplenan bufron en la aŭdan eligon, kaj kiam reludado komenciĝas, ni honeste komencas plenigi ĝin.

Plue, ni renkontis la fakton, ke la sono dum voĉregistrado estis tre kvieta. Ĉi tio estas pro la fakto, ke MEMS-mikrofonoj sur la STM32F7-Discovery iel ne funkcias bone ĉe frekvencoj sub 16000 Hz. Tial ni fiksas 16000 Hz, eĉ se 8000 Hz venas. Por fari tion, tamen, necesis aldoni programaran konvertiĝon de unu frekvenco al alia.

Poste, mi devis pliigi la grandecon de la amaso, kiu situas en RAM. Laŭ niaj kalkuloj, pjsip postulis ĉirkaŭ 190 KB, kaj restas al ni nur ĉirkaŭ 100 KB. Ĉi tie mi devis uzi iom da ekstera memoro - SDRAM (ĉirkaŭ 128 KB).

Post ĉiuj ĉi redaktoj, mi vidis la unuajn pakaĵojn inter Linukso kaj Embox, kaj mi aŭdis la sonon! Sed la sono estis terura, tute ne sama kiel ĉe QEMU, estis neeble distingi ion ajn. Tiam ni pensis pri kio povus esti la afero. Sencirmigado montris, ke Embox simple ne havas tempon por plenigi/malŝarĝi sonbufrojn. Dum pjsip prilaboris unu kadron, 2 interrompoj havis tempon por okazi pri la finiĝo de bufra prilaborado, kio estas tro multe. La unua penso por rapideco estis kompililo optimumigo, sed ĝi jam estis inkluzivita en PJSIP. La dua estas aparatara glitpunkto, ni parolis pri ĝi en artikolo. Sed kiel praktiko montris, FPU ne donis signifan pliiĝon de rapideco. La sekva paŝo estis prioritatigi fadenojn. Embox havas malsamajn planajn strategiojn, kaj mi inkluzivis unu, kiu subtenas prioritatojn kaj starigas sonfluojn al la plej alta prioritato. Ankaŭ ĉi tio ne helpis.

La sekva ideo estis, ke ni laboras kun ekstera memoro kaj estus bone movi tien strukturojn, kiuj estas alireblaj ege ofte. Mi faris antaŭan analizon de kiam kaj sub kio simpla_pjsua asignas memoron. Montriĝis, ke el 190 Kb, la unuaj 90 Kb estas asignitaj por internaj bezonoj de PJSIP kaj ili ne estas alireblaj tre ofte. Plue, dum envenanta voko, la pjsua_call_answer funkcio estas vokita, en kiu bufroj tiam estas asignitaj por labori kun envenantaj kaj elirantaj kadroj. Ĝi estis ankoraŭ proksimume 100 Kb. Kaj tiam ni faris la jenon. Ĝis la momento de la voko, ni metas la datumojn en eksteran memoron. Tuj kiam la voko, ni tuj anstataŭigas la amason per alia - en RAM. Tiel, ĉiuj "varmaj" datumoj estis transdonitaj al pli rapida kaj pli antaŭvidebla memoro.

Rezulte, ĉio ĉi kune ebligis lanĉon simpla_pjsua kaj voku per via servilo. Kaj poste per aliaj serviloj kiel sip.linphone.org.

trovoj

Kiel rezulto, eblis lanĉi simpla_pjsua kun voĉtransdono ambaŭdirekte tra la servilo. La problemo kun aldone elspezitaj 128 KB da SDRAM povas esti solvita uzante iomete pli potencan Cortex-M7 (ekzemple, STM32F769NI kun 512 KB da RAM), sed samtempe ni ankoraŭ ne forlasis esperon eniri 256. KB 🙂 Ni ĝojos, se iu interesiĝas, Aŭ pli bone, provu ĝin. Ĉiuj fontoj, kiel kutime, estas en nia deponejoj.

fonto: www.habr.com

Aldoni komenton