SIP-puhelin STM32F7-Discoveryssa

Hei kaikki

Vähän aikaa sitten me писали siitä, kuinka onnistuimme käynnistämään SIP-puhelimen STM32F4-Discoveryssä, jossa on 1 Mt ROM ja 192 KB RAM) perustuen Embox. Tässä on sanottava, että tuo versio oli minimaalinen ja liitti kaksi puhelinta suoraan ilman palvelinta ja puheensiirrolla vain yhteen suuntaan. Siksi päätimme tuoda markkinoille täydellisemmän puhelimen puhelulla palvelimen kautta, puheensiirrolla molempiin suuntiin, mutta samalla pitäen mahdollisimman pienen muistikoon sisällä.


Puhelimelle päätettiin valita sovellus simple_pjsua osana PJSIP-kirjastoa. Tämä on minimaalinen sovellus, joka voi rekisteröityä palvelimelle, vastaanottaa ja vastata puheluihin. Alla annan heti kuvauksen siitä, kuinka sitä käytetään STM32F7-Discoveryssä.

Kuinka juosta

  1. Emboxin määrittäminen
    make confload-platform/pjsip/stm32f7cube
  2. Aseta tarvittava SIP-tili conf/mods.config-tiedostossa.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    missä palvelin on SIP-palvelin (esimerkiksi sip.linphone.org), käyttäjätunnus и salasana - tilin käyttäjätunnus ja salasana.

  3. Emboxin kokoaminen joukkueena tehdä. Tietoja levyn laiteohjelmistosta, joka meillä on wiki ja статье.
  4. Suorita "simple_pjsua_imported" -komento Embox-konsolissa
    
    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. Lopuksi on vielä lisättävä kaiuttimet tai kuulokkeet äänilähtöön ja puhuttava kahteen pieneen MEMS-mikrofoniin näytön vieressä. Soitamme Linuxista sovelluksen simple_pjsua, pjsua kautta. No, tai voit käyttää mitä tahansa muuta linkkiä.

Kaikki tämä on kuvattu sivuillamme wiki.

Kuinka pääsimme sinne

Joten aluksi heräsi kysymys laitteistoalustan valinnasta. Koska oli selvää, että STM32F4-Discovery ei mahdu muistista, valittiin STM32F7-Discovery. Hänellä on 1 Mt:n flash-asema ja 256 KB RAM-muistia (+ 64 erityistä nopeaa muistia, jota myös käytämme). Ei myöskään paljon puheluita palvelimen kautta, mutta päätimme yrittää mahtua.

Ehdollisesti itselleen tehtävä jaettiin useisiin vaiheisiin:

  • PJSIP käynnissä QEMU:ssa. Se oli kätevä virheenkorjaukseen, ja meillä oli jo tuki AC97-koodekille siellä.
  • Äänen tallennus ja toisto QEMU:ssa ja STM32:ssa.
  • Sovelluksen siirtäminen simple_pjsua PJSIP:ltä. Sen avulla voit rekisteröityä SIP-palvelimelle ja soittaa puheluita.
  • Ota oma Asterisk-pohjainen palvelin käyttöön ja testaa sitä ja kokeile sitten ulkoisia, kuten sip.linphone.org

Emboxin ääni toimii Portaudion kautta, jota käytetään myös PISIP:ssä. Ensimmäiset ongelmat ilmenivät QEMU:ssa - WAV soitti hyvin 44100 Hz:llä, mutta 8000:lla jokin meni selvästi pieleen. Kävi ilmi, että kyse oli taajuuden asettamisesta - oletuksena se oli laitteessa 44100, eikä tämä muuttunut ohjelmallisesti.

Tässä on ehkä syytä selittää hieman, kuinka ääni yleensä toistetaan. Äänikortti voidaan asettaa osoittamaan jotakin muistipaikkaa, josta haluat toistaa tai äänittää ennalta määrätyllä taajuudella. Puskurin päätyttyä syntyy keskeytys ja suoritus jatkuu seuraavalla puskurilla. Tosiasia on, että nämä puskurit on täytettävä etukäteen, kun edellistä toistetaan. Tulemme kohtaamaan tämän ongelman edelleen STM32F7:ssä.

Seuraavaksi vuokrasimme palvelimen ja otimme siihen Asteriskin. Koska virheenkorjausta piti tehdä paljon, mutta en halunnut puhua paljon mikrofoniin, piti tehdä automaattinen toisto ja tallennus. Tätä varten korjasimme simple_pjsuan, jotta voit liu'uttaa tiedostoja äänilaitteiden sijaan. PJSIP:ssä tämä tehdään yksinkertaisesti, koska niillä on portin käsite, joka voi olla joko laite tai tiedosto. Ja nämä portit voidaan yhdistää joustavasti muihin portteihin. Näet koodin pjsip-tiedostostamme arkistot. Tämän seurauksena kaava oli seuraava. Avasin Asterisk-palvelimella kaksi tiliä - Linuxille ja Emboxille. Seuraavaksi komento suoritetaan Emboxissa simple_pjsua_imported, Embox on rekisteröity palvelimelle, minkä jälkeen soitamme Emboxiin Linuxista. Yhteyden muodostushetkellä tarkistamme Asterisk-palvelimelta, että yhteys on muodostettu, ja hetken kuluttua meidän pitäisi kuulla ääntä Linuxista Emboxissa ja Linuxissa tallennamme Emboxista toistetun tiedoston.

Kun se toimi QEMU:ssa, siirryimme siirtämään STM32F7-Discoveryyn. Ensimmäinen ongelma on, että ne eivät mahtuneet 1 Mt:n ROM-muistiin ilman kuvan koon kääntäjän optimointia "-Os". Siksi lisäsimme "-Os". Lisäksi korjaustiedosto poisti tuen C ++:lle, joten sitä tarvitaan vain pjsualle, ja käytämme simple_pjsuaa.

Sijoittamisen jälkeen simple_pjsua, päätti, että nyt on mahdollisuus käynnistää se. Mutta ensin oli tarpeen käsitellä äänen tallennus ja toisto. Kysymys kuuluukin mihin kirjoittaa? Valitsimme ulkoisen muistin - SDRAM (128 MB). Voit kokeilla tätä itse:

Luo stereo-WAV:n taajuudella 16000 Hz ja keston 10 sekuntia:


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

Häviämme:


play -m C0000000

Tässä on kaksi ongelmaa. Ensimmäinen koodekilla - WM8994 on käytössä, ja siinä on sellainen asia kuin korttipaikka, ja näitä paikkoja on 4. Joten oletusarvoisesti, jos tätä ei ole määritetty, niin ääntä toistettaessa toisto tapahtuu kaikissa neljässä paikassa . Siksi taajuudella 16000 Hz saimme 8000 Hz, mutta 8000 Hz:llä toisto ei yksinkertaisesti toiminut. Kun valittiin vain paikat 0 ja 2, se toimi niin kuin pitää. Toinen ongelma oli STM32Cuben ääniliitäntä, jossa äänilähtö toimii SAI:n (Serial Audio Interface) kautta synkronisesti äänitulon kanssa (en ymmärtänyt yksityiskohtia, mutta kävi ilmi, että niillä on yhteinen kello ja kun äänilähtö alustetaan, ääni on jotenkin liitetty sen sisääntuloon). Eli et voi ajaa niitä erikseen, joten teimme seuraavaa - äänitulo ja äänilähtö toimivat aina (mukaan lukien keskeytykset syntyy). Mutta kun järjestelmässä ei toisteta mitään, liu'utamme vain tyhjän puskurin äänilähtöön, ja kun toisto alkaa, alamme rehellisesti täyttää sitä.

Lisäksi havaitsimme, että ääni äänityksen aikana oli erittäin hiljaista. Tämä johtuu siitä, että STM32F7-Discoveryn MEMS-mikrofonit eivät jotenkin toimi hyvin alle 16000 Hz:n taajuuksilla. Siksi asetamme 16000 Hz, vaikka 8000 Hz tulisikin. Tätä varten oli kuitenkin tarpeen lisätä ohjelmistomuunnos yhdestä taajuudesta toiselle.

Seuraavaksi minun piti kasvattaa RAM-muistissa sijaitsevan kasan kokoa. Laskelmiemme mukaan pjsip vaati noin 190 kt, ja meillä on enää noin 100 kt jäljellä. Tässä jouduin käyttämään ulkoista muistia - SDRAM-muistia (noin 128 KB).

Kaikkien näiden muokkausten jälkeen näin ensimmäiset paketit Linuxin ja Emboxin välillä ja kuulin äänen! Mutta ääni oli kauhea, ei ollenkaan sama kuin QEMU:ssa, oli mahdotonta saada mitään selvää. Sitten mietimme, mikä voisi olla hätänä. Virheenkorjaus osoitti, että Emboxilla ei yksinkertaisesti ole aikaa täyttää/purkaa äänipuskureita. Kun pjsip prosessoi yhtä kehystä, 2 keskeytystä ehti tapahtua puskurikäsittelyn valmistumisen jälkeen, mikä on liikaa. Ensimmäinen ajatus nopeudesta oli kääntäjän optimointi, mutta se oli jo mukana PJSIP:ssä. Toinen on laitteiston liukuluku, puhuimme siitä статье. Mutta kuten käytäntö on osoittanut, FPU ei lisännyt merkittävästi nopeutta. Seuraava askel oli ketjujen priorisointi. Emboxilla on erilaisia ​​ajoitusstrategioita, ja olen lisännyt yhden, joka tukee prioriteetteja ja asettaa äänivirrat korkeimpaan prioriteettiin. Tämäkään ei auttanut.

Seuraava ajatus oli, että työskentelemme ulkoisen muistin kanssa ja sinne olisi mukava siirtää rakenteita, joihin pääsee erittäin usein. Tein alustavan analyysin siitä, milloin ja minkä alla simple_pjsua varaa muistia. Kävi ilmi, että 190 kb:sta ensimmäiset 90 kb on varattu PJSIP:n sisäisiin tarpeisiin eikä niitä käytetä kovin usein. Lisäksi tulevan puhelun aikana kutsutaan pjsua_call_answer-funktiota, jossa sitten varataan puskureita saapuvien ja lähtevien kehysten kanssa työskentelemistä varten. Se oli edelleen noin 100 Kb. Ja sitten teimme seuraavaa. Soitamme tiedot ulkoiseen muistiin puhelun hetkeen saakka. Heti puhelun jälkeen korvaamme kasan välittömästi toisella - RAM-muistissa. Siten kaikki "kuuma" data siirrettiin nopeampaan ja ennustettavampaan muistiin.

Tämän seurauksena kaikki tämä yhdessä mahdollisti käynnistämisen simple_pjsua ja soita palvelimesi kautta. Ja sitten muiden palvelimien kautta, kuten sip.linphone.org.

Tulokset

Tämän seurauksena se oli mahdollista käynnistää simple_pjsua puheensiirrolla molempiin suuntiin palvelimen kautta. Ylimääräisen 128 KB SDRAM:n ongelma voidaan ratkaista käyttämällä hieman tehokkaampaa Cortex-M7:ää (esim. STM32F769NI, jossa on 512 KB RAM-muistia), mutta samalla emme ole vielä luopuneet toivosta päästä 256:een. KB 🙂 Olemme iloisia, jos joku on kiinnostunut, tai vielä parempaa, kokeile sitä. Kaikki lähteet, kuten tavallista, ovat meillä arkistot.

Lähde: will.com

Lisää kommentti