STM32F7-Discovery'de SIP telefonu

Herkese Merhaba.

Bir süre önce biz писали STM32F4-Discovery'de 1 MB ROM ve 192 KB RAM ile bir SIP telefonu başlatmayı nasıl başardığımız hakkında) em kutusu. Burada, bu sürümün minimum olduğu ve iki telefonu doğrudan sunucusuz ve tek yönde ses iletimi ile birbirine bağladığı söylenmelidir. Bu nedenle, sunucu üzerinden arama, her iki yönde ses iletimi ile daha eksiksiz bir telefon başlatmaya karar verdik, ancak aynı zamanda mümkün olan en küçük bellek boyutunu da koruyoruz.


Telefon için bir uygulama seçilmesine karar verildi. basit_pjsua PJSIP kitaplığının bir parçası olarak. Bu, sunucuya kayıt olabilen, aramaları cevaplayabilen ve cevaplayabilen minimal bir uygulamadır. Aşağıda hemen STM32F7-Discovery'de nasıl çalıştırılacağının bir açıklamasını vereceğim.

nasıl çalıştırılır

  1. Embox'ı Yapılandırma
    make confload-platform/pjsip/stm32f7cube
  2. conf/mods.config dosyasında gerekli SIP hesabını ayarlayın.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    nerede sunucu bir SIP sunucusudur (örneğin, sip.linphone.org), kullanıcı adı и şifre - hesap kullanıcı adı ve şifresi.

  3. Embox'ı ekip olarak bir araya getirme yapmak. Sahip olduğumuz kart yazılımı hakkında wiki ve Makale.
  4. Embox konsolunda "simple_pjsua_imported" komutunu çalıştırın
    
    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. Son olarak, ses çıkışına hoparlör veya kulaklık takmak ve ekranın yanındaki iki küçük MEMS mikrofonuna konuşmak kalır. Simple_pjsua, pjsua uygulaması aracılığıyla Linux'tan çağrı yapıyoruz. Peki, ya da başka herhangi bir hat telefonu kullanabilirsiniz.

Bütün bunlar bizim sayfamızda açıklanmıştır. wiki.

oraya nasıl gittik

Bu nedenle, başlangıçta bir donanım platformu seçme sorusu ortaya çıktı. STM32F4-Discovery'nin bellekten sığmayacağı açık olduğu için STM32F7-Discovery seçildi. 1 MB flash sürücüsü ve 256 KB RAM'i (ayrıca kullanacağımız + 64 özel hızlı bellek) var. Ayrıca sunucu üzerinden yapılan aramalar için pek bir şey yok, ancak uyum sağlamaya karar verdik.

Şartlı olarak kendileri için görev birkaç aşamaya ayrıldı:

  • PJSIP'i QEMU'da çalıştırma. Hata ayıklama için uygundu, ayrıca orada zaten AC97 codec'i için desteğimiz vardı.
  • QEMU ve STM32'de ses kaydı ve oynatma.
  • Uygulama taşıma basit_pjsua PJSIP'den. SIP sunucusuna kayıt olmanızı ve arama yapmanızı sağlar.
  • Kendi Asterisk tabanlı sunucunuzu konuşlandırın ve üzerinde test edin, ardından sip.linphone.org gibi harici sunucuları deneyin.

Embox'ta ses, PISIP'te de kullanılan Portaudio aracılığıyla çalışır. İlk sorunlar QEMU'da ortaya çıktı - WAV 44100 Hz'de iyi oynadı, ancak 8000'de açıkça bir şeyler ters gitti. Bunun bir frekans ayarlama meselesi olduğu ortaya çıktı - varsayılan olarak ekipmanda 44100'dü ve bu programlı olarak değişmedi.

Burada belki de genel olarak sesin nasıl çalındığını biraz açıklamaya değer. Ses kartı, önceden belirlenmiş bir frekansta çalmak veya kaydetmek istediğiniz bir hafıza parçasına bir işaretçi olarak ayarlanabilir. Arabellek sona erdikten sonra bir kesme oluşturulur ve yürütme bir sonraki arabellekte devam eder. Gerçek şu ki, bir önceki oynatılırken bu arabelleklerin önceden doldurulması gerekiyor. Bu problemle STM32F7'de daha fazla karşılaşacağız.

Ardından, bir sunucu kiraladık ve üzerine Asterisk yerleştirdik. Çok fazla hata ayıklamak gerektiğinden, ancak mikrofona çok fazla konuşmak istemediğimden, otomatik oynatma ve kayıt yapmak gerekiyordu. Bunu yapmak için, ses cihazları yerine dosyaları kaydırabilmeniz için simple_pjsua'ya yama uyguladık. PJSIP'de, bir cihaz veya bir dosya olabilen bir bağlantı noktası kavramına sahip oldukları için bu oldukça basit bir şekilde yapılır. Ve bu bağlantı noktaları diğer bağlantı noktalarına esnek bir şekilde bağlanabilir. Kodu pjsip'imizde görebilirsiniz. depolar. Sonuç olarak, şema aşağıdaki gibiydi. Asterisk sunucusunda iki hesap başlattım - Linux ve Embox için. Ardından, komut Embox'ta yürütülür basit_pjsua_imported, Embox sunucuda kayıtlıdır, bundan sonra Linux'tan Embox diyoruz. Bağlantı anında Asterisk sunucusunda bağlantının kurulduğunu kontrol ediyoruz ve bir süre sonra Embox'ta Linux'tan ses duymamız gerekiyor ve Linux'ta Embox'tan oynatılan dosyayı kaydediyoruz.

QEMU üzerinde çalıştıktan sonra, STM32F7-Discovery'ye taşıma işlemine geçtik. İlk sorun, görüntünün boyutu için etkinleştirilen derleyici optimizasyonu "-Os" olmadan 1 MB ROM'a sığmamasıdır. Bu yüzden "-Os" ekledik. Ayrıca, yama C++ desteğini devre dışı bıraktı, bu nedenle yalnızca pjsua için gerekli ve biz simple_pjsua kullanıyoruz.

yerleştirildikten sonra basit_pjsua, şimdi onu başlatma şansı olduğuna karar verdi. Ama önce sesin kaydedilmesi ve çalınması ile uğraşmak gerekiyordu. Soru nereye yazılacağıdır. Harici belleği seçtik - SDRAM (128 MB). Bunu kendiniz deneyebilirsiniz:

16000 Hz frekans ve 10 saniye süreli bir stereo WAV oluşturur:


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

Kaybettik:


play -m C0000000

Burada iki problem mevcut. Codec bileşeni olan ilki - WM8994 kullanılır ve bir yuva gibi bir şeye sahiptir ve bu yuvalardan 4 tane vardır.Bu nedenle, varsayılan olarak, bu yapılandırılmamışsa, o zaman ses çalarken dört yuvada da oynatma gerçekleşir . Bu nedenle, 16000 Hz frekansında 8000 Hz aldık, ancak 8000 Hz için oynatma işe yaramadı. Yalnızca yuva 0 ve 2 seçildiğinde olması gerektiği gibi çalıştı. Diğer bir sorun da STM32Cube'deki ses arabirimiydi, burada ses çıkışı SAI (Seri Ses Arabirimi) aracılığıyla ses girişiyle senkron olarak çalışıyor (ayrıntıları anlamadım ama ortak bir saati paylaştıkları ortaya çıktı ve ne zaman ses çıkışı başlatılır, ses bir şekilde girişine eklenir). Yani, bunları ayrı ayrı çalıştıramazsınız, bu yüzden aşağıdakileri yaptık - ses girişi ve ses çıkışı her zaman çalışır (oluşturulan kesintiler dahil). Ancak sistemde hiçbir şey oynatılmadığında, ses çıkışına boş bir arabellek kaydırırız ve oynatma başladığında, onu dürüstçe doldurmaya başlarız.

Ayrıca ses kaydı sırasında sesin çok kısık olduğu gerçeğiyle karşılaştık. Bunun nedeni, STM32F7-Discovery'deki MEMS mikrofonlarının 16000 Hz'nin altındaki frekanslarda bir şekilde iyi çalışmamasıdır. Bu nedenle 16000 Hz gelse de 8000 Hz ayarladık. Ancak bunu yapmak için, bir frekansın diğerine yazılım dönüşümünü eklemek gerekliydi.

Ardından, RAM'de bulunan yığının boyutunu artırmam gerekiyordu. Hesaplamalarımıza göre, pjsip yaklaşık 190 KB gerektiriyor ve elimizde sadece yaklaşık 100 KB kaldı. Burada biraz harici bellek kullanmak zorunda kaldım - SDRAM (yaklaşık 128 KB).

Tüm bu düzenlemelerden sonra Linux ve Embox arasındaki ilk paketleri gördüm ve sesini duydum! Ancak ses korkunçtu, QEMU'dakiyle hiç aynı değildi, hiçbir şey anlamak imkansızdı. Sonra sorunun ne olabileceğini düşündük. Hata ayıklama, Embox'ın ses arabelleklerini doldurmak / boşaltmak için zamana sahip olmadığını gösterdi. Pjsip bir çerçeveyi işlerken, arabellek işlemenin tamamlanmasıyla ilgili olarak 2 kesintinin gerçekleşmesi için çok fazla zaman vardı. Hız için ilk düşünce derleyici optimizasyonuydu, ancak bu zaten PJSIP'ye dahil edilmişti. İkincisi, bir donanım kayan noktasıdır, bundan daha önce bahsetmiştik. Makale. Ancak uygulamanın gösterdiği gibi, FPU hızda önemli bir artış sağlamadı. Bir sonraki adım, iş parçacıklarına öncelik vermekti. Embox'ın farklı zamanlama stratejileri vardır ve öncelikleri destekleyen ve ses akışlarını en yüksek önceliğe ayarlayan bir strateji ekledim. Bu da yardımcı olmadı.

Bir sonraki fikir, harici bellekle çalıştığımız ve son derece sık erişilen yapıları oraya taşımanın iyi olacağıydı. Ne zaman ve ne altında bir ön analiz yaptım. basit_pjsua bellek ayırır. 190 Kb'nin ilk 90 Kb'sinin PJSIP'in dahili ihtiyaçları için ayrıldığı ve bunlara çok sık erişilmediği ortaya çıktı. Ayrıca, gelen bir arama sırasında, gelen ve giden çerçevelerle çalışmak için arabelleklerin tahsis edildiği pjsua_call_answer işlevi çağrılır. Hala yaklaşık 100 Kb idi. Ve sonra şunları yaptık. Arama anına kadar verileri harici belleğe yerleştiriyoruz. Arama yapılır yapılmaz, yığını hemen RAM'de başka bir yığınla değiştiririz. Böylece, tüm "sıcak" veriler daha hızlı ve daha öngörülebilir belleğe aktarıldı.

Sonuç olarak, tüm bunlar birlikte lansmanı mümkün kıldı. basit_pjsua ve sunucunuz üzerinden arayın. Ve sonra sip.linphone.org gibi diğer sunucular aracılığıyla.

Bulgular

Sonuç olarak, başlatmak mümkün oldu basit_pjsua sunucu üzerinden her iki yönde ses iletimi ile. Ek olarak harcanan 128 KB SDRAM ile ilgili sorun, biraz daha güçlü bir Cortex-M7 kullanılarak çözülebilir (örneğin, 32 KB RAM ile STM769F512NI), ancak aynı zamanda 256'ya girme umudumuzu hala kaybetmedik. KB 🙂 İlgilenen olursa seviniriz, Ya da daha iyisi deneyin. Tüm kaynaklar, her zamanki gibi, bizim depolar.

Kaynak: habr.com

Yorum ekle