SIP-foon op STM32F7-Discovery

Hallo almal.

'N Rukkie gelede het ons писали oor hoe ons daarin geslaag het om 'n SIP-foon op STM32F4-Discovery met 1 MB ROM en 192 KB RAM te begin) gebaseer op Embos. Hier moet gesê word dat daardie weergawe minimaal was en twee fone direk gekoppel het sonder 'n bediener en met stemversending in slegs een rigting. Daarom het ons besluit om 'n meer volledige foon te begin met 'n oproep deur die bediener, stemversending in beide rigtings, maar terselfdertyd binne die kleinste moontlike geheuegrootte te hou.


Vir die foon is besluit om 'n toepassing te kies eenvoudig_pjsua as deel van die PJSIP-biblioteek. Dit is 'n minimale toepassing wat op die bediener kan registreer, oproepe kan ontvang en beantwoord. Hieronder sal ek dadelik 'n beskrywing gee van hoe om dit op STM32F7-Discovery te laat loop.

Hoe om te hardloop

  1. Stel Embbox op
    make confload-platform/pjsip/stm32f7cube
  2. Stel die vereiste SIP-rekening in die conf/mods.config-lêer.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    waar bediener is 'n SIP-bediener (byvoorbeeld sip.linphone.org), Gebruikersnaam и Wagwoord - rekening gebruikersnaam en wagwoord.

  3. Die samestelling van Embox as 'n span maak. Oor die bordfirmware wat ons aan het вики en Artikel.
  4. Voer die "simple_pjsua_imported" opdrag in die Embox-konsole uit
    
    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. Laastens bly dit om luidsprekers of oorfone in die oudio-uitvoer in te voeg en in twee klein MEMS-mikrofone langs die skerm te praat. Ons bel vanaf Linux deur die toepassing simple_pjsua, pjsua. Wel, of jy kan enige ander tipe linphone gebruik.

Dit alles word op ons beskryf вики.

Hoe het ons daar gekom

Dus, aanvanklik het die vraag ontstaan ​​​​oor die keuse van 'n hardeware-platform. Aangesien dit duidelik was dat STM32F4-Discovery nie uit die geheue sou pas nie, is STM32F7-Discovery gekies. Sy het 'n 1 MB flash drive en 256 KB RAM (+ 64 spesiale vinnige geheue, wat ons ook sal gebruik). Ook nie baie vir oproepe deur die bediener nie, maar ons het besluit om te probeer inpas.

Voorwaardelik vir hulself is die taak in verskeie fases verdeel:

  • Loop PJSIP op QEMU. Dit was gerieflik vir ontfouting, en ons het reeds ondersteuning vir die AC97-kodek daar gehad.
  • Stemopname en afspeel op QEMU en op STM32.
  • Portering van 'n toepassing eenvoudig_pjsua van PJSIP. Dit laat jou toe om op die SIP-bediener te registreer en oproepe te maak.
  • Ontplooi jou eie Asterisk-gebaseerde bediener en toets daarop, probeer dan eksterne bedieners soos sip.linphone.org

Klank in Embox werk deur Portaudio, wat ook in PISIP gebruik word. Die eerste probleme het op QEMU verskyn - WAV het goed gespeel by 44100 Hz, maar teen 8000 het iets duidelik verkeerd geloop. Dit het geblyk dat dit 'n kwessie was van die stel van die frekwensie - by verstek was dit 44100 in die toerusting, en dit het nie programmaties verander nie.

Hier is dit miskien die moeite werd om 'n bietjie te verduidelik hoe die klank in die algemeen gespeel word. Die klankkaart kan ingestel word op een of ander wyser na 'n stuk geheue waarvandaan jy wil speel of opneem op 'n voorafbepaalde frekwensie. Nadat die buffer geëindig het, word 'n onderbreking gegenereer en uitvoering gaan voort met die volgende buffer. Die feit is dat hierdie buffers vooraf gevul moet word terwyl die vorige een gespeel word. Ons sal hierdie probleem verder in die gesig staar op STM32F7.

Vervolgens het ons 'n bediener gehuur en Asterisk daarop ontplooi. Aangesien dit nodig was om baie te ontfout, maar ek nie baie in die mikrofoon wou praat nie, was dit nodig om outomatiese afspeel en opname te maak. Om dit te doen, het ons simple_pjsua gepleister sodat jy lêers kan skuif in plaas van oudio-toestelle. In PJSIP word dit eenvoudig gedoen, aangesien hulle die konsep van 'n poort het, wat óf 'n toestel óf 'n lêer kan wees. En hierdie poorte kan buigsaam aan ander poorte gekoppel word. U kan die kode in ons pjsip sien bewaarplekke. Gevolglik was die skema soos volg. Op die Asterisk-bediener het ek twee rekeninge begin - vir Linux en vir Embox. Vervolgens word die opdrag op Embbox uitgevoer simple_pjsua_imported, Embox registreer op die bediener, waarna ons Embox van Linux af bel. Op die oomblik van verbinding kyk ons ​​op die Asterisk-bediener dat die verbinding tot stand gebring is, en na 'n rukkie behoort ons klank van Linux in Embox te hoor, en in Linux stoor ons die lêer wat vanaf Embox gespeel word.

Nadat dit op QEMU gewerk het, het ons na STM32F7-Discovery oorgedra. Die eerste probleem is dat hulle nie in 1 MB ROM gepas het sonder die geaktiveerde samesteller-optimalisering "-Os" vir die grootte van die prent nie. Daarom het ons "-Os" ingesluit. Verder het die pleister ondersteuning vir C ++ gedeaktiveer, so dit is slegs nodig vir pjsua, en ons gebruik simple_pjsua.

Nadat dit geplaas is eenvoudig_pjsua, het besluit dat daar nou 'n kans is om dit bekend te stel. Maar eers was dit nodig om die opname en terugspeel van die stem te hanteer. Die vraag is waar om te skryf? Ons het eksterne geheue gekies - SDRAM (128 MB). Jy kan dit self probeer:

Skep 'n stereo WAV met 'n frekwensie van 16000 Hz en 'n duur van 10 sekondes:


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

Ons verloor:


play -m C0000000

Hier is twee probleme. Die eerste met die codec - WM8994 word gebruik, en dit het iets soos 'n gleuf, en daar is 4 van hierdie gleuwe. Dus, as dit nie gekonfigureer is nie, vind afspeel in al vier gleuwe by verstek plaas wanneer klank speel. . Daarom het ons teen 'n frekwensie van 16000 Hz 8000 Hz ontvang, maar vir 8000 Hz het afspeel eenvoudig nie gewerk nie. Toe slegs gleuwe 0 en 2 gekies is, het dit gewerk soos dit moes. Nog 'n probleem was die oudio-koppelvlak in die STM32Cube, waarin die oudio-uitvoer via SAI (Serial Audio Interface) sinchronies met die oudio-invoer werk (ek het nie die besonderhede verstaan ​​nie, maar dit blyk dat hulle 'n gemeenskaplike horlosie deel en wanneer die oudio-uitvoer is geïnitialiseer, oudio is op een of ander manier aan die ingang geheg). Dit wil sê, jy kan hulle nie afsonderlik laat loop nie, so ons het die volgende gedoen - die oudio-invoer en oudio-uitvoer werk altyd (insluitend onderbrekings word gegenereer). Maar wanneer niks in die stelsel gespeel word nie, skuif ons eenvoudig 'n leë buffer in die oudio-uitvoer, en wanneer die afspeel begin, begin ons dit eerlik vul.

Verder het ons die feit teëgekom dat die klank tydens stemopname baie stil was. Dit is te wyte aan die feit dat MEMS-mikrofone op die STM32F7-Discovery op een of ander manier nie goed werk by frekwensies onder 16000 Hz nie. Daarom stel ons 16000 Hz, selfs al kom 8000 Hz. Om dit te doen, was dit egter nodig om 'n sagteware-omskakeling van een frekwensie by 'n ander by te voeg.

Vervolgens moes ek die grootte van die hoop vergroot, wat in RAM geleë is. Volgens ons berekeninge het pjsip ongeveer 190 KB benodig, en ons het net ongeveer 100 KB oor. Hier moes ek 'n bietjie eksterne geheue gebruik - SDRAM (ongeveer 128 KB).

Na al hierdie wysigings het ek die eerste pakkette tussen Linux en Embox gesien, en ek het die geluid gehoor! Maar die klank was verskriklik, glad nie dieselfde as op QEMU nie, dit was onmoontlik om iets uit te maak. Toe het ons gedink wat die saak kan wees. Ontfouting het getoon dat Embox eenvoudig nie tyd het om klankbuffers te vul / af te laai nie. Terwyl pjsip een raam verwerk het, het 2 onderbrekings tyd gehad om te voorkom oor die voltooiing van bufferverwerking, wat te veel is. Die eerste gedagte vir spoed was samestelleroptimalisering, maar dit was reeds in PJSIP ingesluit. Die tweede is 'n hardeware drywende punt, ons het daaroor gepraat Artikel. Maar soos die praktyk getoon het, het FPU nie 'n beduidende toename in spoed gegee nie. Die volgende stap was om drade te prioritiseer. Embox het verskillende skeduleringstrategieë, en ek het een ingesluit wat prioriteite ondersteun en klankstrome op die hoogste prioriteit stel. Dit het ook nie gehelp nie.

Die volgende idee was dat ons met eksterne geheue werk en dit sal lekker wees om strukture daarheen te skuif wat baie gereeld toeganklik is. Ek het 'n voorlopige ontleding gedoen van wanneer en onder wat eenvoudig_pjsua ken geheue toe. Dit het geblyk dat uit 190 Kb, die eerste 90 Kb vir interne behoeftes van PJSIP toegewys word en hulle word nie baie gereeld verkry nie. Verder, tydens 'n inkomende oproep, word die pjsua_call_answer-funksie opgeroep, waarin buffers dan toegeken word om met inkomende en uitgaande rame te werk. Dit was nog so 100 Kb. En toe het ons die volgende gedoen. Tot die oomblik van die oproep plaas ons die data in eksterne geheue. Sodra die oproep, ons onmiddellik vervang die hoop met 'n ander een - in RAM. Dus is alle "warm" data na vinniger en meer voorspelbare geheue oorgedra.

As gevolg hiervan het dit alles saam dit moontlik gemaak om te loods eenvoudig_pjsua en bel deur jou bediener. En dan deur ander bedieners soos sip.linphone.org.

Bevindinge

As gevolg hiervan was dit moontlik om te begin eenvoudig_pjsua met stemoordrag in beide rigtings deur die bediener. Die probleem met addisionele bestee 128 KB van SDRAM kan opgelos word deur die gebruik van 'n effens kragtiger Cortex-M7 (byvoorbeeld, STM32F769NI met 512 KB RAM), maar terselfdertyd het ons steeds nie moed opgegee om in 256 te kom nie. KB 🙂 Ons sal bly wees as iemand belangstel, Of beter nog, probeer dit. Alle bronne, soos gewoonlik, is in ons bewaarplekke.

Bron: will.com

Voeg 'n opmerking