SIP telefoan op STM32F7-Discovery

Hi everyone

In skoftke lyn hawwe wy skreaun oer hoe't wy it slagge om in SIP-tillefoan te lansearjen op STM32F4-Discovery mei 1 MB ROM en 192 KB RAM) basearre op Embox. Hjir moat sein wurde dat dy ferzje wie minimaal en ferbûn twa telefoans direkt sûnder in tsjinner en mei stim oerdracht mar yn ien rjochting. Dêrom hawwe wy besletten om in mear folsleine telefoan mei in oprop fia in tsjinner, stim oerdracht yn beide rjochtings, mar tagelyk passe yn de lytste mooglik ûnthâld grutte.


Der waard besletten om in applikaasje foar de telefoan te kiezen simple_pjsua as ûnderdiel fan de PJSIP bibleteek. Dit is in minimale applikaasje dy't kin registrearje op de tsjinner, ûntfange en beantwurdzje oproppen. Hjirûnder sil ik fuortendaliks in beskriuwing jaan fan hoe't jo dit útfiere kinne op 'e STM32F7-Discovery.

Hoe te starten

  1. It konfigurearjen fan Embox
    make confload-platform/pjsip/stm32f7cube
  2. Yn it bestân conf/mods.config sette wy it fereaske SIP-akkount yn.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    wêr tsjinner is in SIP-tsjinner (bygelyks sip.linphone.org), brûkersnamme и wachtwurd - brûkersnamme en wachtwurd foar it akkount.

  3. Wy stelle Embox gear mei in team meitsje. Wy hawwe ynformaasje oer board firmware by wiki en yn artikel.
  4. Laad it kommando "simple_pjsua_imported" yn 'e Embox-konsole
    
    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. Uteinlik is alles wat oerbliuwt om sprekkers of koptelefoanen yn te foegjen yn 'e audioútfier, en prate yn twa lytse MEMS-mikrofoans neist it display. Wy skilje fan Linux mei de applikaasje simple_pjsua, pjsua. No, of jo kinne elke oare soart linphone brûke.

Dit alles wurdt beskreaun op ús wiki.

Hoe binne wy ​​hjir kommen

Dat, yn earste ynstânsje ûntstie de fraach oer it kiezen fan in hardwareplatfoarm. Sûnt it dúdlik wie dat de STM32F4-Discovery net geskikt wêze soe foar ûnthâld, waard de STM32F7-Discovery keazen. Se hat in 1 MB flash drive en 256 KB RAM (+ 64 spesjale fluch ûnthâld, dat wy ek sille brûke). It is ek net in soad foar petearen fia de tsjinner, mar wy besletten om te besykjen om yn te kommen.

Konvinsjoneel waard de taak ferdield yn ferskate stadia:

  • Running PJSIP op QEMU. It wie handich foar debuggen, en wy hiene dêr al stipe foar de AC97-koade.
  • Stim opname en ôfspieljen op QEMU en STM32.
  • Porting de applikaasje simple_pjsua út de PJSIP. It lit jo registrearje op in SIP-tsjinner en oproppen meitsje.
  • Ynsette jo eigen server basearre op Asterisk en test derop, en besykje dan eksterne, lykas sip.linphone.org

Lûd yn Embox wurket fia Portaudio, dat ek brûkt wurdt yn PISIP. De earste problemen ferskynden op QEMU - WAV's waarden goed spile op 44100 Hz, mar by 8000 gie der dúdlik wat mis. It die bliken dat it probleem wie yn it ynstellen fan de frekwinsje - standert yn 'e apparatuer wie it 44100, en wy hawwe dit net feroare yn software.

Hjir is it wierskynlik in bytsje út te lizzen oer hoe't lûd yn 't algemien spile wurdt. De lûdskaart kin wat oanwizer ynstelle op in stik ûnthâld wêrfan it moat wurde spile of opnommen op in foarbeskaaide frekwinsje. Neidat de buffer rint út, in ûnderbrekking wurdt oanmakke en útfiering giet troch fan de folgjende buffer. It punt is dat dizze buffers moatte wurde ynfolle foarôf wylst de foarige wurdt spile. Wy sille dit probleem fierder tsjinkomme op 'e STM32F7.

Dêrnei hierden wy in tsjinner en hawwe Asterisk derop ynset. Sûnt der wie in soad debuggen te dwaan, en ik woe net prate folle yn 'e mikrofoan, it wie nedich om te dwaan automatyske Wiedergabe en opname. Om dit te dwaan, hawwe wy simple_pjsua patched sadat wy bestannen koene ynfoegje ynstee fan audioapparaten. Yn PJSIP wurdt dit frij simpel dien, om't se it konsept hawwe fan in poarte, dy't in apparaat as in bestân kin wêze. En dizze havens kinne fleksibel wurde ferbûn mei oare havens. Jo kinne de koade besjen yn ús pjsip repositories. Dêrtroch wie it skema as folget. Ik haw twa akkounts makke op 'e Asterisk-tsjinner - foar Linux en foar Embox. Dêrnei wurdt it kommando útfierd op Embox simple_pjsua_ymportearre, Embox registrearret op 'e tsjinner, wêrnei't wy Embox fan Linux neame. Op it momint fan ferbining kontrolearje wy op 'e Asterisk-tsjinner dat de heule ferbining is oprjochte, en nei in skoft moatte wy lûd hearre fan Linux yn Embox, en yn Linux bewarje wy it bestân dat wurdt spile fan Embox.

Sadree't dit wurke oan QEMU, binne wy ​​​​ferhuze nei it portearjen nei de STM32F7-Discovery. It earste probleem wie dat wy net yn 1 MB fan ROM passe koene sûnder de "-Os" kompilatoroptimalisaasje foar ôfbyldingsgrutte ynskeakele. Dêrom hawwe wy "-Os" opnommen. Folgjende, de patch útskeakele stipe foar C ++, dus it is allinnich nedich foar pjsua, en wy brûke simple_pjsua.

Nei it pleatsen simple_pjsua, besletten dat der no in kâns wie om it te lansearjen. Mar earst moasten wy útfine hoe't wy stimmen opnimme en ôfspielje. Fraach: wêr te skriuwen? Wy keas foar eksterne ûnthâld - SDRAM (128 MB). Jo kinne dit sels besykje:

Sil in stereo WAV meitsje mei in frekwinsje fan 16000 Hz en in doer fan 10 sekonden:


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

Wy ferlieze:


play -m C0000000

Hjir wiene twa problemen. De earste is mei de codec - WM8994 wurdt brûkt, en it hat sa'n ding as in slot, en d'r binne 4 fan dizze slots Dus, standert, as dit net is konfigureare, dan komt by it spyljen fan audio yn alles foar fjouwer slots . Dêrom, op in frekwinsje fan 16000 Hz wy krigen 8000 Hz, mar foar 8000 Hz ôfspieljen gewoan net wurke. As wy selektearre allinnich slots 0 en 2, it wurke as ferwachte. In oar probleem wie de audio-ynterface yn 'e STM32Cube, wêryn't de audio-útfier wurket fia SAI (Serial Audio Interface) synchroon mei de audio-ynput (ik begriep de details net, mar it docht bliken dat se in mienskiplike klok diele en by inisjalisearjen de audio útfier, audio is ien of oare manier bûn oan it yngong). Dat is, it is ûnmooglik om se apart út te fieren, dus wy hawwe it folgjende dien - de audio-ynput en audio-útfier wurkje altyd (ynklusyf interrupts wurde generearre). Mar as neat yn it systeem spilet, slipje wy gewoan in lege buffer yn 'e audioútfier, en as it ôfspieljen begjint, begjinne wy ​​it earlik te foljen.

Doe kamen wy it feit tsjin dat it lûd by it opnimmen fan de stim tige stil wie. Dit komt troch it feit dat de MEMS-mikrofoans op 'e STM32F7-Discovery op ien of oare manier net goed wurkje op frekwinsjes ûnder 16000 Hz. Dêrom sette wy it op 16000 Hz, sels as 8000 Hz komt. Om dit te dwaan, wie it lykwols nedich om softwarekonverzje fan ien frekwinsje ta te foegjen oan in oare.

Folgjende, wy moasten fergrutsje de grutte fan 'e heap, dat leit yn RAM. Neffens ús berekkeningen fereaske pjsip sa'n 190 KB, en wy hienen mar sawat 100 KB oer. Hjir moasten wy in bytsje ekstern ûnthâld brûke - SDRAM (sawat 128 KB).

Nei al dizze bewurkingen seach ik de earste pakketten tusken Linux en Embox, en hearde it lûd! Mar it lûd wie ferskriklik, hielendal net lykas op QEMU, neat koe wurde heard. Doe fregen wy ús ôf wat der oan de hân wêze koe. Debuggen liet sjen dat Embox gewoan gjin tiid hat om audiobuffers yn te foljen / te ûntladen. Wylst pjsip ien frame ferwurket, binne 2 ûnderbrekkings oer it foltôgjen fan bufferferwurking bard, wat te folle is. Myn earste gedachte foar speedup wie gearstalling optimalisaasje, mar dat wie al opnommen yn PJSIP. De twadde is hardware driuwend punt, wy prate deroer yn artikel. Mar sa't de praktyk hat bliken dien, joech FPU gjin signifikante ferheging fan snelheid. De folgjende stap wie om threadprioriteiten yn te stellen. Embox hat ferskate schedulingstrategyen, en ik haw dejinge ynskeakele dy't prioriteiten stipet en de audiostreamen de heechste prioriteit joech. Dit holp ek net.

It folgjende idee wie dat wy wurkje mei ekstern ûnthâld en it soe goed wêze om struktueren dêr te ferpleatsen dy't ekstreem faak tagonklik binne. Ik die in foarriedige analyze fan wannear en ûnder wat simple_pjsua allocates ûnthâld. It die bliken dat fan 190 KB de earste 90 KB wurde tawiisd foar de ynterne behoeften fan PJSIP en wurde net faak tagong. Dêrnei wurdt by in ynkommende oprop de funksje pjsua_call_answer oanroppen, wêryn dan buffers wurde tawiisd foar it wurkjen mei ynkommende en útgeande frames. It wie noch sa'n 100 KB. En doe diene wy ​​it folgjende. Oant de oprop wurdt makke, de gegevens wurde opslein yn eksterne ûnthâld. Sadree't de oprop rinkelt, ferfange wy fuortendaliks de heap mei in oar yn RAM. Sa waarden alle "hot" gegevens oerbrocht nei flugger en mear foarsisber ûnthâld.

As gefolch koe dit alles tegearre ús lansearje simple_pjsua en skilje fia jo tsjinner. En dan fia oare servers lykas sip.linphone.org.

befinings

Uteinlik wie it mooglik om te lansearjen simple_pjsua mei stim oerdracht yn beide rjochtingen fia de tsjinner. It probleem mei in ekstra 128 KB fan SDRAM kin oplost wurde troch it brûken fan in wat machtiger Cortex-M7 (bygelyks STM32F769NI mei 512 KB fan RAM), mar wy hawwe noch net opjûn de hope fan fitting yn 256 KB :) Wy sille wês bliid as immen ynteressearre is, of better noch, besykje it. Alle boarnen, lykas gewoanlik, binne yn ús repositories.

Boarne: www.habr.com

Add a comment