Hej alle.
For et stykke tid siden om hvordan vi formÄede at kÞre en SIP-telefon pÄ STM32F4-Discovery med 1 MB ROM og 192 KB RAM) baseret pÄ . Her skal det siges, at den version var minimal og kun forbandt to telefoner direkte uden server og med stemmeoverfÞrsel kun i én retning. Derfor besluttede vi at lancere en mere fuldgyldig telefon med opkald via server, stemmeoverfÞrsel i begge retninger, men samtidig holde os inden for sÄ lille hukommelsesstÞrrelse som muligt.

Til telefonen besluttede vi at vÊlge applikationen simple_pjsua som en del af PJSIP-biblioteket. Dette er en minimal applikation, som kan registrere sig pÄ serveren, modtage og besvare opkald. Nedenfor vil jeg straks give en beskrivelse af, hvordan man starter det op pÄ STM32F7-Discovery.
SÄdan starter du
- Konfigurerer Embox
make confload-platform/pjsip/stm32f7cube - I filen conf/mods.config angiver vi den Ăžnskede SIP-konto.
include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password")hvor server â dette er SIP-serveren (for eksempel sip.linphone.org), brugernavn og adgangskode â brugernavn og adgangskode til kontoen.
- Saml Embox med kommandoen make. Vi har information om flashen af kortet pÄ og i .
- KĂžr kommandoen âsimple_pjsua_importedâ i Embox-konsollen
00:00:12.870 pjsua_acc.c ....SIP outbound status for acc 0 is not active 00:00:12.884 pjsua_acc.c ....sip:alexk2222@sip.linphone.org: registration success, status=200 (Registration success 00:00:12.911 pjsua_acc.c ....Keep-alive timer started for acc 0, destination:91.121.209.194:5060, interval:15s - Endelig er det tilbage at tilslutte hÞjttalere eller hovedtelefoner til lydudgangen og tale ind i to smÄ MEMS-mikrofoner tÊt pÄ skÊrmen. Vi ringer fra Linux via applikationen simple_pjsua, pjsua. Eller man kan bruge en hvilken som helst anden som linphone.
Alt dette er beskrevet pÄ vores .
Hvordan vi kom hertil
SÄ i starten opstod spÞrgsmÄlet om valg af hardwareplatform. Da det blev klart, at STM32F4-Discovery ikke ville vÊre tilstrÊkkelig med hensyn til hukommelse, blev STM32F7-Discovery valgt. Den har 1 MB flash og 256 KB RAM (+ 64 KB speciel hurtig hukommelse, som vi ogsÄ vil bruge). Det er heller ikke meget til opkald gennem serveren, men vi besluttede at prÞve at presse det ind.
For os selv delte vi opgaven op i flere faser:
- KÞrsel af PJSIP pÄ QEMU. Det var praktisk til debugging, plus vi havde allerede support for AC97 codec der.
- Optagelse og afspilning af lyd pÄ QEMU og pÄ STM32.
- Portering af applikationen simple_pjsua fra PJSIP-biblioteket. Den gÞr det muligt at registrere sig pÄ SIP-serveren og ringe.
- OpsÊtning af vores egen server baseret pÄ Asterisk og teste pÄ den, hvorefter vi vil prÞve eksterne, sÄsom sip.linphone.org
Lyden i Embox fungerer gennem Portaudio, som ogsĂ„ anvendes i PISIP. PĂ„ QEMU opstod de fĂžrste problemer â WAV-filer ved 44100 Hz blev afspillet fint, men ved 8000 Hz gik noget tydeligvis galt. Det viste sig, at problemet lĂ„ i indstillingen af frekvensen â standarden i hardwaren var 44100, og det blev ikke ĂŠndret programmĂŠssigt.
Her er det mÄske vÊrd at forklare lidt om, hvordan lyden faktisk afspilles. Der kan sÊttes en indikator pÄ lydkortet til et hukommelsesomrÄde, hvorfra der skal afspilles eller optages ved en forudbestemt frekvens. NÄr bufferen er brugt op, genereres der et afbrydelse, og udfÞrelsen fortsÊtter fra den nÊste buffer. Problemet er, at disse buffere skal fyldes i forvejen, mens den tidligere afspilles. Denne udfordring vil vi ogsÄ stÞde pÄ senere med STM32F7.
Derefter lejede vi en server og installerede Asterisk pĂ„ den. Da vi mĂ„tte debugge meget, og det ikke var sjovt at tale ind i mikrofonen, besluttede vi at lave automatisk afspilning og optagelse. For at gĂžre dette patchede vi simple_pjsua, sĂ„ vi kunne indsĂŠtte filer i stedet for lydudstyr. I PJSIP er dette meget enkelt, da de har et begreb om port, som kan vĂŠre bĂ„de en enhed og en fil. Og disse porte kan fleksibelt tilsluttes til andre porte. Koden kan ses i vores pjsip. Sammenfattende var diagrammet som fĂžlger. PĂ„ Asterisk-serveren oprettede jeg to konti â en til Linux og en til Embox. DernĂŠst udfĂžres kommandoen pĂ„ Embox. simple_pjsua_imported, Embox registrerer sig pĂ„ serveren, hvorefter vi fra Linux ringer til Embox. I forbindelse med forbindelsen kontrollerer vi pĂ„ Asterisk-serveren, at forbindelsen er oprettet, og efter nogen tid skal vi hĂžre lyden fra Linux i Embox, og i Linux gemmer vi den fil, der bliver afspillet fra Embox.
Efter at dette fungerede pĂ„ QEMU, gik vi videre til porteringen til STM32F7-Discovery. Det fĂžrste problem var, at vi ikke kunne fĂ„ plads i 1 MB ROM uden at aktivere compilationsoptimeringen â-Osâ for billedstĂžrrelsen. Derfor aktiverede vi â-Osâ. DernĂŠst, med et patch, deaktiverede vi C++-support, da det kun er nĂždvendigt for pjsua, og vi bruger simple_pjsua.
Efter at vi fik plads simple_pjsua, besluttede vi, at der nu var chancer for at starte det. Men fĂžrst skulle vi finde ud af optagelse og afspilning af stemmen. SpĂžrgsmĂ„let var â hvor skulle vi optage? Vi valgte ekstern hukommelse â SDRAM (128 MB). Du kan prĂžve dette selv:
Opretter stereo WAV med en frekvens pÄ 16000 Hz og en varighed pÄ 10 sekunder:
record -r 16000 -c 2 -d 10000 -m C0000000
Afspiller:
play -m C0000000
Her opstod der to problemer. Det fĂžrste med codec'en â WM8994 bruges, og der er noget, der hedder slot, og der er 4 slotter. Som standard, hvis man ikke konfigurerer det, sĂ„ afspilles lyd i alle fire slotter. Derfor fik vi ved 16000 Hz 8000 Hz, og for 8000 Hz fungerede afspilningen bare ikke. Da vi valgte kun slottene 0 og 2, sĂ„ fungerede det som det skulle. Et andet problem var lydinterfacet i STM32Cube, hvor lydudgangen fungerer via SAI (Serial Audio Interface) synkront med lydindgangen (jeg har ikke undersĂžgt detaljerne, men det ser ud til, at de deler fĂŠlles clock, og ved initialisering af lydudgangen binds lydindgangen eller lignende). Det vil sige, at man ikke kan starte dem separat, derfor gjorde vi fĂžlgende â bĂ„de lydindgang og lydudgang fungerer altid (herunder genereres afbrydelser). Men nĂ„r der ikke afspilles noget i systemet, indsĂŠtter vi bare en tom buffer til lydudgangen, og nĂ„r afspilningen starter, sĂ„ begynder vi ĂŠrligt at fylde den.
Derefter stÞdte vi pÄ, at lyden ved optagelse af stemmen var meget lav. Dette skyldes, at MEMS mikrofonerne pÄ STM32F7-Discovery fungerer dÄrligt ved frekvenser under 16000 Hz. Derfor indstiller vi 16000 Hz, selv hvis der kommer 8000 Hz. Faktisk var det nÞdvendigt at tilfÞje en softwarekonvertering af en frekvens til en anden.
DernĂŠst var vi nĂždt til at Ăžge stĂžrrelsen pĂ„ bunken, der ligger i RAM. IfĂžlge vores beregninger krĂŠvede pjsip omkring 190 KB, men vi havde kun omkring 100 KB tilbage. Her mĂ„tte vi bruge lidt ekstern hukommelse â SDRAM (omkring 128 KB).
Efter alle disse ĂŠndringer sĂ„ jeg de fĂžrste pakker mellem Linux og Embox og hĂžrte lyd! Men lyden var forfĂŠrdelig, slet ikke som pĂ„ QEMU, intet kunne forstĂ„s. SĂ„ begyndte vi at undre os over, hvad der kunne vĂŠre galt. Debugging viste, at Embox simpelthen ikke kunne nĂ„ at fylde/udlevere lydbufferne. Mens pjsip behandlede en ramme, skete der to afbrydelser om afslutningen af bufferbehandlingen, hvilket var for meget. Den fĂžrste tanke til at fremskynde var compileroptimering, men det var allerede aktiveret i PJSIP. Det andet â hardware flydende punkt, om det fortalte vi i . Men som praksis har vist, gav FPU ikke en betydelig stigning i hastighed. NĂŠste skridt var at prioritere trĂ„de. I Embox er der forskellige planlĂŠgningsstrategier, og jeg aktiverede den, der understĂžtter prioriteter, og gav lyden den hĂžjeste prioritet. Dette hjalp heller ikke.
NÊste idé var, at vi arbejder med ekstern hukommelse, og det ville vÊre godt at flytte strukturer derhen, som der er meget hyppig adgang til. Jeg udfÞrte en forudgÄende analyse af, hvornÄr og til hvad simple_pjsua hukommelse bliver tildelt. Det viste sig, at ud af 190 Kb blev de fÞrste 90 Kb tildelt til interne behov i PJSIP, og adgangen til dem sker ikke sÊrlig ofte. Derefter, under et indgÄende opkald, kaldes funktionen pjsua_call_answer, hvor der derefter tildeles buffere til behandling af indgÄende og udgÄende rammer. Det var omkring 100 Kb mere. Og her gjorde vi det pÄ fÞlgende mÄde. Indtil opkaldet placerer vi data i den eksterne hukommelse. SÄ snart opkaldet er modtaget - sÄ skifter vi hurtigt til en anden stak - i RAM. PÄ denne mÄde blev alle "hot" data flyttet til hurtigere og mere forudsigelig hukommelse.
Samlet set gjorde alt dette det muligt at starte simple_pjsua og ringe gennem vores server. Og derefter ogsÄ gennem andre servere som sip.linphone.org.
Konklusioner
Resultatet blev, at vi fik startet simple_pjsua med stemmeoverfĂžrsel i begge retninger gennem serveren. Problemet med de ekstra brugte 128 Kb SDRAM kan lĂžses ved at bruge en lidt mere kraftfuld Cortex-M7 (for eksempel STM32F769NI med 512 Kb RAM), men vi har stadig ikke mistet hĂ„bet om at fĂ„ det til at passe ind i 256 Kb đ Vi vil vĂŠre glade, hvis nogen er interesseret, og endnu bedre - prĂžver det. Alle kildekoder er, som sĂŠdvanligt, tilgĂŠngelige i vores .
Kilde: habr.com
