Hej alla.
För en tid sedan pratade vi om hur vi lyckades köra en SIP-telefon pÄ STM32F4-Discovery med 1 MB ROM och 192 KB RAM baserat pÄ . HÀr mÄste jag nÀmna att den versionen var minimal och kopplade samman tvÄ telefoner direkt utan server och med röstöverföring endast i en riktning. DÀrför beslutade vi oss för att starta en mer fullstÀndig telefon som skulle ringa genom servern, med röstöverföring i bÄda riktningarna, men samtidigt hÄlla oss till sÄ liten minnesstorlek som möjligt.

För telefonen beslutade vi att vÀlja applikationen simple_pjsua i PJSIP-biblioteket. Det hÀr Àr en minimal applikation som kan registrera sig pÄ en server, ta emot och svara pÄ samtal. Nedan ska jag omedelbart ge en beskrivning av hur man startar den pÄ STM32F7-Discovery.
Hur man startar
- Konfigurera Embox
make confload-platform/pjsip/stm32f7cube - I filen conf/mods.config anger vi det önskade SIP-kontot.
include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password")w server â detta Ă€r SIP-servern (till exempel sip.linphone.org), username och password â anvĂ€ndarnamn och lösenord för kontot.
- Bygg Embox med kommandot make. Om firmware för kortet har vi pÄ och i .
- Kör kommandot âsimple_pjsua_importedâ i Embox-konsolen
00:00:12.870 pjsua_acc.c ....SIP outbound status för acc 0 Àr inte aktiv 00:00:12.884 pjsua_acc.c ....sip:alexk2222@sip.linphone.org: registrering lyckades, status=200 (Registrering lyckades 00:00:12.911 pjsua_acc.c ....Keep-alive-timer startad för acc 0, destination: 91.121.209.194:5060, intervall: 15s - Till slut ÄterstÄr det att sÀtta in högtalare eller hörlurar i ljuduttaget och prata i tvÄ smÄ MEMS-mikrofoner nÀra skÀrmen. Vi ringer frÄn Linux via applikationen simple_pjsua, pjsua. Eller sÄ kan man anvÀnda vilket annat alternativ som helst, som linphone.
Allt detta beskrivs pÄ vÄr .
Hur vi kom dit
SÄ, inledningsvis uppstod frÄgan om att vÀlja hÄrdvaruplattform. Eftersom det stod klart att STM32F4-Discovery inte skulle passa för minnet, valdes STM32F7-Discovery. Den har 1 MB flash och 256 KB RAM (+ 64 snabb minne, som vi ocksÄ kommer att anvÀnda). Inte mycket för samtal genom servern, men vi beslutade att försöka fÄ plats.
Villkorligt delade vi upp uppgiften i flera steg:
- Kör PJSIP pÄ QEMU. Det var bekvÀmt för felsökning, plus att vi redan hade stöd för AC97-codec dÀr.
- Inspelning av röst och uppspelning pÄ QEMU och pÄ STM32.
- Portering av applikationen simple_pjsua frÄn PJSIP. Den möjliggör registrering pÄ SIP-servern och samtal.
- SÀtta upp en egen server baserad pÄ Asterisk och testa pÄ den, och sedan prova externa, som sip.linphone.org.
Ljud i Embox fungerar genom Portaudio, vilket ocksĂ„ anvĂ€nds i PISIP. PĂ„ QEMU uppstod de första problemen â WAV-filer spelades upp korrekt vid 44100 Hz, men vid 8000 var det uppenbart nĂ„got som gick fel. Det visade sig att det berodde pĂ„ instĂ€llningen av frekvensen â som standard var den instĂ€lld pĂ„ 44100 i hĂ„rdvaran, och vi Ă€ndrade inte detta programmerat.
HÀr kanske det Àr vÀrt att förklara hur ljuduppspelning överhuvudtaget gÄr till. Ljudkortet kan fÄ en pekare till en minnesbit som ska spelas upp eller spelas in vid en förutbestÀmd frekvens. NÀr bufferten tar slut genereras ett avbrott, och exekveringen fortsÀtter med nÀsta buffert. Problemet Àr att dessa buffertar mÄste fyllas i förvÀg medan den föregÄende spelas upp. Vi kommer att stöta pÄ detta problem lÀngre fram pÄ STM32F7.
DĂ€refter hyrde vi en server och installerade Asterisk pĂ„ den. Eftersom det krĂ€vdes mycket felsökning och vi inte ville prata mycket i mikrofonen behövde vi automatisera uppspelning och inspelning. För detta patchade vi simple_pjsua sĂ„ att vi kunde mata in filer istĂ€llet för ljudenheter. I PJSIP görs detta ganska enkelt, eftersom de har begreppet port som kan vara bĂ„de en enhet och en fil. Dessa portar kan kopplas flexibelt till andra portar. Koden kan ses i vĂ„r pjsip. . Resultatet blev följande. PĂ„ Asterisk-servern skapade jag tvĂ„ konton â för Linux och för Embox. DĂ€refter utförs kommandot simple_pjsua_imported, Embox registreras pĂ„ servern, och efter det ringer vi frĂ„n Linux till Embox. NĂ€r anslutningen har upprĂ€ttats kontrollerar vi pĂ„ Asterisk-servern att hela anslutningen Ă€r etablerad, och efter en stund ska vi höra ljudet frĂ„n Linux i Embox, medan vi pĂ„ Linux sparar den fil som spelas upp frĂ„n Embox.
Efter att detta fungerade pĂ„ QEMU gick vi vidare till porteringen pĂ„ STM32F7-Discovery. Det första problemet var att vi inte fick plats inom 1 MB ROM utan att aktivera kompileringsoptimeringen â-Osâ för bildstorleken. SĂ„ vi aktiverade â-Osâ. DĂ€refter stĂ€ngde vi av C++-stödet med en patch eftersom det bara behövs för pjsua, och vi anvĂ€nder simple_pjsua.
NĂ€r vi vĂ€l fick plats simple_pjsua, beslutade vi att chansen att fĂ„ detta att fungera nu fanns. Men först behövde vi reda ut inspelning och uppspelning av rösten. FrĂ„gan var â vart ska vi spela in? Vi valde extern minne â SDRAM (128 MB). Du kan försöka detta sjĂ€lv:
Skapar stereo WAV med en frekvens pÄ 16000 Hz och en lÀngd pÄ 10 sekunder:
record -r 16000 -c 2 -d 10000 -m C0000000
Spelar upp:
play -m C0000000
HĂ€r uppstod tvĂ„ problem. Det första med codecâen â WM8994 anvĂ€nds, och det finns ett begrepp som kallas slot, och det finns fyra sĂ„dana slots. SĂ„, om man inte konfigurerar detta, sĂ„ kommer uppspelning av ljud att ske i alla fyra slots. DĂ€rför fick vi 8000 Hz vid 16000 Hz, och för 8000 Hz fungerade inte uppspelningen alls. NĂ€r vi valde endast slots 0 och 2, fungerade det som det skulle. Ett annat problem var ljudgrĂ€nssnittet i STM32Cube, dĂ€r ljudutgĂ„ngen arbetar via SAI (Serial Audio Interface) synkront med ljudingĂ„ngen (jag har inte gĂ„tt in i detaljerna, men det verkar som om de delar en gemensam klocka och vid initialisering av ljudutgĂ„ngen kopplas den pĂ„ nĂ„got sĂ€tt till ljudingĂ„ngen). Det innebĂ€r att de inte kan startas separat, sĂ„ vi gjorde följande â ljudingĂ„ng och ljudutgĂ„ng fungerar alltid (inklusive avbrott genereras). Men nĂ€r inget spelas i systemet, sĂ„ skickar vi en tom buffert till ljudutgĂ„ngen, och nĂ€r uppspelningen startas, börjar vi fylla den pĂ„ riktigt.
DÀrefter stötte vi pÄ att ljudet vid röstinspelning var vÀldigt tyst. Detta beror pÄ att MEMS mikrofonerna pÄ STM32F7-Discovery fungerar dÄligt vid frekvenser under 16000 Hz. SÄ vi stÀller in 16000 Hz, Àven om 8000 Hz tas emot. För detta behövdes dock ett programvaruomvandling av en frekvens till en annan.
DĂ€refter var vi tvungna att öka storleken pĂ„ minnet som finns i RAM. Enligt vĂ„ra berĂ€kningar krĂ€vde pjsip cirka 190 kB, och vi hade bara cirka 100 kB kvar. HĂ€r var vi tvungna att anvĂ€nda lite extern minne â SDRAM (cirka 128 kB).
Efter alla dessa justeringar sĂ„g jag de första paketen mellan Linux och Embox, och hörde ljud! Men ljudet var fruktansvĂ€rt, inte alls som pĂ„ QEMU, och ingenting kunde sĂ€rskiljas. DĂ„ började vi undra vad som kunde vara fel. Debugging visade att Embox sannerligen inte hĂ€ngde med i att fylla/tömma ljudbuffrarna. Medan pjsip bearbetade ett ram, intrĂ€ffade tvĂ„ avbrott om avslutning av buffertbehandling, vilket Ă€r för mycket. Den första tanken för att snabba pĂ„ processen var att optimera kompilatorn, men den var redan aktiverad i PJSIP. Det andra â hĂ„rdvaru-flytpunkt, om den pratar vi i . Men som praktiken har visat, gav FPU ingen betydande ökning av hastigheten. NĂ€sta steg var att stĂ€lla in prioriteringar för flöden. I Embox finns det olika schemalĂ€ggningsstrategier, och jag aktiverade den som stödjer prioriteringar och satte ljudflödena till högsta prioritet. Detta hjĂ€lpte inte heller.
NĂ€sta idĂ© var att vi arbetar med extern minne och det skulle vara bra att flytta strukturer dit som det ofta görs hĂ€nvisningar till. Jag genomförde en preliminĂ€r analys av nĂ€r och under vad simple_pjsua minnet allokeras. Det visade sig att av 190 Kb allokeras de första 90 Kb för interna behov av PJSIP och att hĂ€nvisningarna till dem sker inte sĂ„ ofta. Vid ett inkommande samtal anropas funktionen pjsua_call_answer, dĂ€r buffrar sedan allokeras för att arbeta med inkommande och utgĂ„ende ramar. Det var ytterligare cirka 100 Kb. Och hĂ€r gjorde vi pĂ„ följande sĂ€tt. Fram till samtalet placerade vi data i det externa minnet. SĂ„ snart samtalet kom â bytte vi omgĂ„ende ut heapen mot en annan â i RAM. PĂ„ sĂ„ sĂ€tt flyttades alla "heta" data till ett snabbare och mer förutsĂ€gbart minne.
Slutresultatet av allt detta möjliggjorde lanseringen simple_pjsua och att ringa via vÄr server. Och sedan Àven genom andra servrar som sip.linphone.org.
Slutsatser
Resultatet blev en fungerande lösning simple_pjsua med röstöverföring i bĂ„da riktningarna via servern. Problemet med de ytterligare 128 Kb SDRAM kan lösas genom att anvĂ€nda en nĂ„got kraftfullare Cortex-M7 (till exempel STM32F769NI med 512 Kb RAM), men vi har fortfarande inte gett upp hoppet att fĂ„ plats med 256 Kb đ Vi skulle vara glada om nĂ„gon Ă€r intresserad, eller Ă€nnu bĂ€ttre â testar. Alla kĂ€llkoder finns som vanligt i vĂ„r .
KĂ€lla: habr.com
