Telefuninu SIP nantu à STM32F7-Discovery

Bonghjornu.

Tempi fà noi hà scrittu quantu avemu riisciutu à lancià un telefunu SIP in STM32F4-Discovery cù 1 MB ROM è 192 KB RAM) basatu annantu à Embox. Quì ci vole à dì chì quella versione era minima è cunnessu dui telefoni direttamente senza un servitore è cù a trasmissione di voce in una sola direzzione. Dunque, avemu decisu di lancià un telefuninu più cumpletu cù una chjama à traversu u servitore, a trasmissione di voce in i dui sensi, ma à u stessu tempu mantene a dimensione di memoria più chjuca pussibule.


Per u telefunu, hè statu decisu di sceglie una applicazione semplice_pjsua cum'è parte di a biblioteca PJSIP. Questa hè una applicazione minima chì pò registrà nantu à u servitore, riceve è risponde à e chjama. Sottu vi daraghju subitu una descrizzione di cumu eseguisce in STM32F7-Discovery.

Cumu curriri

  1. Configurazione di Embox
    make confload-platform/pjsip/stm32f7cube
  2. Pone u contu SIP necessariu in u schedariu conf/mods.config.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    induve servore hè un servitore SIP (per esempiu, sip.linphone.org), gatti и codice - nome d'utilizatore è password di u contu.

  3. Assemblamentu di Embox cum'è una squadra . À propositu di u firmware di u bordu chì avemu nantu wiki è in articulu.
  4. Eseguite u cumandimu "simple_pjsua_imported" in a cunsola Embbox
    
    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. Infine, resta à inserisce parlanti o cuffie in l'output audio, è parlà in dui picculi microfoni MEMS accantu à a visualizazione. Chjamemu da Linux attraversu l'applicazione simple_pjsua, pjsua. Ebbè, o pudete aduprà qualsiasi altru tipu di linphone.

Tuttu chistu hè discrittu nantu à u nostru wiki.

Cumu avemu ghjuntu quì

Allora, inizialmente, a quistione hè stata di sceglie una piattaforma hardware. Siccomu era chjaru chì STM32F4-Discovery ùn si mette micca da a memoria, STM32F7-Discovery hè statu sceltu. Hà una unità flash 1 MB è 256 KB di RAM (+ 64 memoria rapida speciale, chì avemu ancu aduprà). Ancu micca assai per e chjama à traversu u servitore, ma avemu decisu di pruvà à adattà.

Cundizionalmente per elli, u compitu hè statu divisu in parechje tappe:

  • Esecuzione di PJSIP nantu à QEMU. Era cunvenutu per debugging, in più avemu digià avutu supportu per u codec AC97 quì.
  • Registrazione è riproduzione di voce nantu à QEMU è STM32.
  • Portà una applicazione semplice_pjsua da PJSIP. Permette di registrà nantu à u servitore SIP è fà chjamate.
  • Implantate u vostru propiu servitore basatu in Asterisk è pruvate nantu à ellu, dopu pruvate esternu cum'è sip.linphone.org

U sonu in Embbox travaglia attraversu Portaudio, chì hè ancu usatu in PISIP. I primi prublemi apparsu in QEMU - WAV hà ghjucatu bè à 44100 Hz, ma à 8000 qualcosa chjaramente andò male. Risultava chì si trattava di stabilisce a freccia - per difettu in l'equipaggiu era 44100, è questu ùn hà micca cambiatu programmaticu.

Quì, forsi, vale a pena spiegà un pocu cumu u sonu hè ghjucatu in generale. A carta di sonu pò esse stallata à qualchì punteru à un pezzu di memoria da quale vulete ghjucà o arregistrà à una freccia predeterminata. Dopu chì u buffer finisci, una interruzzione hè generata è l'esekzione cuntinueghja cù u buffer prossimu. U fattu hè chì questi buffers deve esse cumpletu in anticipu mentre u precedente hè ghjucatu. Facemu stu prublema più in STM32F7.

Dopu, avemu allughjatu un servitore è implementatu Asterisk nantu à questu. Siccomu era necessariu di debug assai, ma ùn vulia micca parlà in u micrufonu assai, era necessariu di fà a riproduzione automatica è a registrazione. Per fà questu, avemu patched simple_pjsua in modu chì pudete slip files invece di i dispositi audio. In PJSIP, questu hè fattu abbastanza simplice, postu chì anu u cuncettu di un portu, chì pò esse un dispositivu o un schedariu. E sti porti ponu esse cunnessi in modu flexible à altri porti. Pudete vede u codice in u nostru pjsip repository. In u risultatu, u schema era cusì. In u servitore Asterisk, aghju cuminciatu dui cunti - per Linux è per Embbox. Dopu, u cumandamentu hè eseguitu nantu à Embox simple_pjsua_imported, Embbox registra nantu à u servitore, dopu chì chjamemu Embbox da Linux. À u mumentu di a cunnessione, cuntrollemu in u servitore Asterisk chì a cunnessione hè stabilita, è dopu un pocu tempu duvemu sente u sonu da Linux in Embox, è in Linux salvemu u schedariu chì hè ghjucatu da Embox.

Dopu avè travagliatu in QEMU, avemu passatu à u porting à STM32F7-Discovery. U primu prublema hè chì ùn anu micca intruduciutu in 1 MB di ROM senza l'optimizazione di compilatore attivata "-Os" per a dimensione di l'imaghjini. Hè per quessa chì avemu inclusu "-Os". In più, u patch hà disattivatu u supportu per C ++, cusì hè necessariu solu per pjsua, è usemu simple_pjsua.

Dopu à esse postu semplice_pjsua, hà decisu chì avà ci hè una chance di lancià. Ma prima era necessariu di trattà cù a registrazione è a riproduzione di a voce. A quistione hè induve scrive? Avemu sceltu memoria esterna - SDRAM (128 MB). Pudete pruvà questu stessu:

Crea un WAV stereo cù una frequenza di 16000 Hz è una durata di 10 seconde:


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

Perdemu:


play -m C0000000

Ci sò dui prublemi quì. U primu cù u codec - WM8994 hè utilizatu, è hà una tale cosa cum'è un slot, è ci sò 4 di questi slots. Allora, per difettu, se questu ùn hè micca cunfiguratu, allora quandu si riproduce l'audio, a riproduzione si trova in tutti i quattru slot. . Dunque, à una freccia di 16000 Hz, avemu ricevutu 8000 Hz, ma per 8000 Hz, a riproduzione simpricimenti ùn hà micca travagliatu. Quandu solu i slots 0 è 2 sò stati selezziunati, hà travagliatu cumu si deve. Un altru prublema era l'interfaccia audio in u STM32Cube, in quale l'output audio travaglia via SAI (Serial Audio Interface) in sincronia cù l'input audio (ùn aghju micca capitu i dettagli, ma risulta chì sparte un clock cumunu è quandu u L'output audio hè inizializatu, l'audio hè in qualchì modu attaccatu à l'entrata). Vale à dì, ùn pudete micca eseguisce separatamente, cusì avemu fattu u seguitu - l'ingressu audio è l'output audio sempre funzionanu (cumprese l'interruzioni sò generate). Ma quandu nunda ùn hè ghjucatu in u sistema, allora simpricimenti sbulicà un buffer viotu in l'output audio, è quandu a riproduzione principia, sinceramente cumminciamu à riempia.

In più, avemu scontru u fattu chì u sonu durante a registrazione di voce era assai tranquillu. Questu hè duvuta à u fattu chì i microfoni MEMS nantu à u STM32F7-Discovery in qualchì manera ùn funziona micca bè à frequenze sottu 16000 Hz. Dunque, avemu stabilitu 16000 Hz, ancu s'ellu vene 8000 Hz. Per fà questu, però, era necessariu aghjunghje una cunversione di software di una frequenza à l'altru.

In seguitu, aghju avutu à aumentà a dimensione di u munzeddu, chì si trova in RAM. Sicondu i nostri calculi, pjsip necessitava circa 190 KB, è avemu solu circa 100 KB. Quì aghju avutu aduprà qualchì memoria esterna - SDRAM (circa 128 KB).

Dopu à tutti questi editi, aghju vistu i primi pacchetti trà Linux è Embbox, è aghju intesu u sonu! Ma u sonu era terribili, micca uguale à u QEMU, ùn era impussibile di fà qualcosa. Allora avemu pensatu à ciò chì puderia esse a materia. A debugging hà dimustratu chì Embox simpricimenti ùn hà micca tempu per riempie / scaricate i buffer audio. Mentre pjsip elaborava un quadru, 2 interruzioni anu avutu u tempu di accade à a fine di u prucessu di buffer, chì hè troppu. U primu pensamentu per accelerà era l'ottimisazione di compilatore, ma era digià inclusu in PJSIP. U sicondu hè un puntu flottante di hardware, avemu parlatu in questu articulu. Ma cum'è a pratica hà dimustratu, FPU ùn hà micca datu un aumentu significativu di a velocità. U passu prossimu era di priorità i fili. Embox hà diverse strategie di pianificazione, è aghju inclusu una chì sustene e priorità è stabilisce i flussi audio à a più alta priorità. Questu ùn hà micca aiutu ancu.

A prossima idea era chì avemu travagliatu cù memoria esterna è saria bellu di spustà e strutture quì chì sò accede assai spessu. Aghju fattu un analisi preliminare di quandu è sottu à chì semplice_pjsua attribuisce memoria. Hè risultatu chì fora di 190 Kb, i primi 90 Kb sò attribuiti per i bisogni interni di PJSIP è ùn sò micca accessu assai spessu. In più, durante una chjama in entrata, a funzione pjsua_call_answer hè chjamata, in quale i buffers sò allora attribuiti per travaglià cù frames in entrata è in uscita. Era sempre circa 100 Kb. E dopu avemu fattu u seguitu. Finu à u mumentu di a chjama, mettimu i dati in memoria esterna. Appena a chjama, rimpiazzà immediatamente u munzeddu cù un altru - in RAM. Cusì, tutti i dati "caldi" sò stati trasferiti in memoria più veloce è più prevedibile.

In u risultatu, tuttu questu inseme hà permessu di lancià semplice_pjsua è chjamate attraversu u vostru servitore. E poi attraversu altri servitori cum'è sip.linphone.org.

scuperti

In u risultatu, era pussibule di lancià semplice_pjsua cù trasmissione di voce in e duie direzzione attraversu u servitore. U prublema cù 128 KB in più di SDRAM pò esse risolta cù un Cortex-M7 un pocu più putente (per esempiu, STM32F769NI cù 512 KB di RAM), ma à u stessu tempu, ùn avemu micca rinunciatu a speranza per entra in 256. KB 🙂 Seremu cuntenti se qualcunu hè interessatu, O megliu ancu, pruvate. Tutte e fonti, cum'è di solitu, sò in u nostru repository.

Source: www.habr.com

Add a comment