SIP telefonas STM32F7-Discovery

Sveiki visi.

Prieš kurį laiką mes писали apie tai, kaip mums pavyko paleisti SIP telefoną STM32F4-Discovery su 1 MB ROM ir 192 KB RAM), remiantis Embox. Čia reikia pasakyti, kad ta versija buvo minimali ir jungė du telefonus tiesiogiai be serverio ir su balso perdavimu tik viena kryptimi. Todėl nusprendėme paleisti pilnesnį telefoną su skambučiu per serverį, balso perdavimu į abi puses, tačiau tuo pačiu išlaikant kuo mažesnį atminties dydį.


Telefonui buvo nuspręsta pasirinkti programą paprastas_pjsua kaip PJSIP bibliotekos dalis. Tai minimali programa, galinti užsiregistruoti serveryje, priimti ir atsiliepti į skambučius. Žemiau iš karto pateiksiu aprašymą, kaip jį paleisti STM32F7-Discovery.

Kaip bėgti

  1. „Embox“ konfigūravimas
    make confload-platform/pjsip/stm32f7cube
  2. Nustatykite reikiamą SIP paskyrą conf/mods.config faile.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    kur serveris yra SIP serveris (pvz., sip.linphone.org), Nick и slaptažodis - paskyros vartotojo vardas ir slaptažodis.

  3. „Embox“ kaip komandos surinkimas padaryti. Apie plokštės programinę-aparatinę įrangą, kurią turime wiki ir straipsnis.
  4. „Embox“ konsolėje paleiskite komandą „simple_pjsua_imported“.
    
    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. Galiausiai belieka į garso išvestį įkišti garsiakalbius arba ausines ir kalbėti į du mažus MEMS mikrofonus, esančius šalia ekrano. Mes skambiname iš Linux per programą simple_pjsua, pjsua. Na, arba galite naudoti bet kokį kitą linphone tipą.

Visa tai aprašyta mūsų svetainėje wiki.

Kaip mes ten atsidūrėme

Taigi, iš pradžių kilo klausimas apie aparatinės įrangos platformos pasirinkimą. Kadangi buvo aišku, kad STM32F4-Discovery iš atminties netilps, buvo pasirinktas STM32F7-Discovery. Ji turi 1 MB „flash“ diską ir 256 KB RAM (+ 64 specialią greitąją atmintį, kurią naudosime ir mes). Taip pat nėra daug skambučių per serverį, bet nusprendėme pabandyti prisitaikyti.

Sąlygiškai jiems patiems užduotis buvo suskirstyta į kelis etapus:

  • Paleidžiamas PJSIP naudojant QEMU. Tai buvo patogu derinant, be to, ten jau turėjome AC97 kodeko palaikymą.
  • Balso įrašymas ir atkūrimas naudojant QEMU ir STM32.
  • Programos perkėlimas paprastas_pjsua iš PJSIP. Tai leidžia registruotis SIP serveryje ir skambinti.
  • Įdiekite savo Asterisk pagrįstą serverį ir išbandykite jį, tada išbandykite išorinius, pvz., sip.linphone.org

„Embox“ garsas veikia per „Portaudio“, kuris taip pat naudojamas PISIP. Pirmosios problemos atsirado su QEMU – WAV gerai grojo 44100 Hz dažniu, bet ties 8000 kažkas aiškiai suklydo. Paaiškėjo, kad tai buvo dažnio nustatymo reikalas – pagal nutylėjimą įrangoje buvo 44100, ir tai programiškai nepasikeitė.

Čia galbūt verta šiek tiek paaiškinti, kaip apskritai grojamas garsas. Garso plokštę galima nustatyti kaip žymeklį į atminties dalį, iš kurios norite groti ar įrašyti iš anksto nustatytu dažniu. Pasibaigus buferiui, sugeneruojamas pertraukimas ir vykdymas tęsiamas su kitu buferiu. Faktas yra tas, kad šiuos buferius reikia užpildyti iš anksto, kol bus žaidžiamas ankstesnis. Su šia problema susidursime toliau STM32F7.

Tada išsinuomojome serverį ir jame įdiegėme Asteriską. Kadangi reikėjo daug derinti, bet nelabai norėjau kalbėti į mikrofoną, reikėjo padaryti automatinį atkūrimą ir įrašymą. Norėdami tai padaryti, pataisėme simple_pjsua, kad galėtumėte paslysti failus, o ne garso įrenginius. PJSIP tai daroma gana paprastai, nes jie turi prievado, kuris gali būti įrenginys arba failas, koncepciją. Ir šie prievadai gali būti lanksčiai prijungti prie kitų prievadų. Kodą galite pamatyti mūsų pjsip saugyklos. Dėl to schema buvo tokia. Asterisk serveryje sukūriau dvi paskyras – Linux ir Embox. Tada komanda vykdoma Embox simple_pjsua_imported, Embox yra užregistruotas serveryje, po to mes skambiname Embox iš Linux. Prisijungimo momentu Asterisk serveryje patikriname, ar ryšys užmegztas, o po kurio laiko turėtume išgirsti garsą iš Linux Embox, o Linux išsaugome failą, kuris grojamas iš Embox.

Kai jis dirbo su QEMU, perėjome prie perkėlimo į STM32F7-Discovery. Pirmoji problema yra ta, kad jie netilpo į 1 MB ROM be įjungto kompiliatoriaus optimizavimo „-Os“ pagal vaizdo dydį. Štai kodėl įtraukėme „-Os“. Be to, pleistras išjungė C ++ palaikymą, todėl jis reikalingas tik pjsua, o mes naudojame simple_pjsua.

Įdėjus paprastas_pjsua, nusprendė, kad dabar yra galimybė jį paleisti. Tačiau pirmiausia reikėjo susitvarkyti su balso įrašymu ir atkūrimu. Klausimas kur rašyti? Pasirinkome išorinę atmintį – SDRAM (128 MB). Tai galite išbandyti patys:

Sukuria stereo WAV 16000 Hz dažniu ir 10 sekundžių trukme:


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

Mes netenkame:


play -m C0000000

Čia yra dvi problemos. Naudojamas pirmasis su kodeku - WM8994, kuris turi tokį dalyką kaip lizdas, o tokių lizdų yra 4. Taigi pagal nutylėjimą, jei tai nėra sukonfigūruota, tada grojant garsą, atkūrimas vyksta visuose keturiuose lizduose. . Todėl 16000 Hz dažniu gaudavome 8000 Hz, tačiau 8000 Hz atkūrimas tiesiog neveikė. Kai buvo pasirinkti tik 0 ir 2 lizdai, jis veikė kaip turėtų. Kita problema buvo garso sąsaja STM32Cube, kurioje garso išvestis veikia per SAI (Serial Audio Interface) sinchroniškai su garso įvestimi (detalių nesupratau, bet pasirodo, kad jie turi bendrą laikrodį ir kada garso išvestis inicijuojama, garsas kažkaip prijungtas prie įėjimo). Tai yra, jūs negalite jų paleisti atskirai, todėl padarėme taip - garso įvestis ir garso išvestis visada veikia (įskaitant generuojamus pertraukimus). Bet kai sistemoje niekas negroja, mes tiesiog įmetame tuščią buferį į garso išvestį, o prasidėjus atkūrimui, nuoširdžiai pradedame jį pildyti.

Be to, mes susidūrėme su tuo, kad garso įrašymo metu garsas buvo labai tylus. Taip yra dėl to, kad MEMS mikrofonai STM32F7-Discovery kažkaip neveikia gerai, kai dažnis mažesnis nei 16000 Hz. Todėl mes nustatome 16000 Hz, net jei ateina 8000 Hz. Tačiau norint tai padaryti, reikėjo pridėti programinės įrangos konvertavimą iš vieno dažnio į kitą.

Tada turėjau padidinti krūvos, esančios RAM, dydį. Mūsų skaičiavimais, pjsip reikėjo apie 190 KB, o mums liko tik apie 100 KB. Čia teko naudoti tam tikrą išorinę atmintį – SDRAM (apie 128 KB).

Po visų šių pakeitimų pamačiau pirmuosius paketus tarp Linux ir Embox ir išgirdau garsą! Bet garsas buvo baisus, visai ne toks kaip QEMU, nebuvo įmanoma nieko suprasti. Tada galvojome, kas gali būti. Derinimas parodė, kad „Embox“ tiesiog neturi laiko užpildyti / iškrauti garso buferių. Kol pjsip apdorojo vieną kadrą, dėl buferio apdorojimo pabaigos turėjo 2 pertraukimai, o tai yra per daug. Pirmoji mintis apie greitį buvo kompiliatoriaus optimizavimas, tačiau jis jau buvo įtrauktas į PJSIP. Antrasis yra aparatinės įrangos slankusis taškas, apie tai kalbėjome straipsnis. Tačiau, kaip parodė praktika, FPU žymiai nepadidėjo greičio. Kitas žingsnis buvo gijų prioritetų nustatymas. Embox turi skirtingas planavimo strategijas, ir aš įtraukiau vieną, kuri palaiko prioritetus ir nustato garso srautams aukščiausią prioritetą. Tai irgi nepadėjo.

Kita mintis buvo ta, kad mes dirbame su išorine atmintimi ir būtų malonu ten perkelti struktūras, kurios pasiekiamos itin dažnai. Atlikau preliminarią analizę, kada ir pagal ką paprastas_pjsua paskirsto atmintį. Paaiškėjo, kad iš 190 Kb pirmieji 90 Kb yra skirti vidiniams PJSIP poreikiams ir prie jų pasiekiama ne itin dažnai. Be to, įeinančio skambučio metu iškviečiama funkcija pjsua_call_answer, kurioje tada paskirstomi buferiai darbui su gaunamais ir išeinančiais kadrais. Tai vis dar buvo apie 100 Kb. Ir tada mes padarėme taip. Iki skambučio mes talpiname duomenis į išorinę atmintį. Kai tik skambiname, mes iš karto pakeičiame krūvą kita - RAM. Taigi visi „karšti“ duomenys buvo perkelti į greitesnę ir labiau nuspėjamą atmintį.

Dėl to visa tai kartu leido pradėti paprastas_pjsua ir skambinkite per savo serverį. Ir tada per kitus serverius, tokius kaip sip.linphone.org.

išvados

Dėl to buvo galima paleisti paprastas_pjsua su balso perdavimu į abi puses per serverį. Problemą dėl papildomai išleistos 128 KB SDRAM galima išspręsti naudojant šiek tiek galingesnį Cortex-M7 (pavyzdžiui, STM32F769NI su 512 KB RAM), tačiau tuo pačiu vis dar nepraradome vilties patekti į 256 KB 🙂 Džiaugsimės, jei kas susidomės, o dar geriau – išbandykite. Visi šaltiniai, kaip įprasta, yra mūsų saugyklos.

Šaltinis: www.habr.com

Добавить комментарий