Telepon SIP di STM32F7-Discovery

Halo.

Beberapa waktu lalu kita писали tentang bagaimana kami berhasil meluncurkan telepon SIP di STM32F4-Discovery dengan ROM 1 MB dan RAM 192 KB) berdasarkan kotak masuk. Di sini harus dikatakan bahwa versi itu minimal dan menghubungkan dua ponsel secara langsung tanpa server dan dengan transmisi suara hanya dalam satu arah. Oleh karena itu, kami memutuskan untuk meluncurkan ponsel yang lebih lengkap dengan panggilan melalui server, transmisi suara di kedua arah, tetapi pada saat yang sama tetap dalam ukuran memori sekecil mungkin.


Untuk ponsel, diputuskan untuk memilih aplikasi simple_pjsua sebagai bagian dari perpustakaan PJSIP. Ini adalah aplikasi minimal yang dapat mendaftar di server, menerima dan menjawab panggilan. Di bawah ini saya akan langsung memberikan gambaran cara menjalankannya di STM32F7-Discovery.

Bagaimana menjalankan

  1. Konfigurasi Embox
    make confload-platform/pjsip/stm32f7cube
  2. Tetapkan akun SIP yang diperlukan di file conf/mods.config.
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    dimana Server adalah server SIP (misalnya, sip.linphone.org), nama pengguna ΠΈ kata sandi - nama pengguna dan kata sandi akun.

  3. Merakit Embox sebagai sebuah tim membuat. Tentang firmware papan yang kita miliki wiki ΠΈ Π² Artikel.
  4. Jalankan perintah β€œsimple_pjsua_imported” di konsol Embox
    
    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. Terakhir, tinggal memasukkan speaker atau headphone ke output audio, dan berbicara ke dua mikrofon MEMS kecil di sebelah layar. Kami memanggil dari Linux melalui aplikasi simple_pjsua, pjsua. Nah, atau Anda bisa menggunakan jenis linphone lainnya.

Semua ini dijelaskan pada kami wiki.

Bagaimana kita sampai di sana

Jadi, awalnya muncul pertanyaan tentang memilih platform perangkat keras. Karena jelas bahwa STM32F4-Discovery tidak muat dari memori, STM32F7-Discovery dipilih. Dia memiliki flash drive 1 MB dan RAM 256 KB (+ 64 memori cepat khusus, yang juga akan kami gunakan). Juga tidak banyak panggilan melalui server, tetapi kami memutuskan untuk mencoba menyesuaikan diri.

Secara kondisional untuk diri mereka sendiri, tugas itu dibagi menjadi beberapa tahap:

  • Menjalankan PJSIP di QEMU. Itu nyaman untuk debugging, plus kami sudah memiliki dukungan untuk codec AC97 di sana.
  • Perekaman dan pemutaran suara di QEMU dan di STM32.
  • Mem-porting aplikasi simple_pjsua dari PJSIP. Ini memungkinkan Anda untuk mendaftar di server SIP dan melakukan panggilan.
  • Terapkan server berbasis Asterisk Anda sendiri dan uji di atasnya, lalu coba yang eksternal seperti sip.linphone.org

Suara di Embox bekerja melalui Portaudio, yang juga digunakan di PISIP. Masalah pertama muncul di QEMU - WAV diputar dengan baik pada 44100 Hz, tetapi pada 8000 jelas ada yang tidak beres. Ternyata ini masalah pengaturan frekuensi - secara default adalah 44100 di peralatan, dan ini tidak berubah secara terprogram.

Di sini, mungkin, ada baiknya menjelaskan sedikit bagaimana bunyi itu dimainkan secara umum. Kartu suara dapat diatur ke beberapa penunjuk ke bagian memori yang ingin Anda putar atau rekam pada frekuensi yang telah ditentukan. Setelah buffer berakhir, interupsi dihasilkan dan eksekusi dilanjutkan dengan buffer berikutnya. Faktanya adalah buffer ini perlu diisi terlebih dahulu saat buffer sebelumnya dimainkan. Kami akan menghadapi masalah ini lebih lanjut di STM32F7.

Selanjutnya, kami menyewa server dan memasang Asterisk di dalamnya. Karena perlu melakukan banyak debug, tetapi saya tidak ingin banyak berbicara ke mikrofon, maka perlu dilakukan pemutaran dan perekaman otomatis. Untuk melakukan ini, kami menambal simple_pjsua sehingga Anda dapat menyelipkan file alih-alih perangkat audio. Di PJSIP, ini dilakukan dengan cukup sederhana, karena mereka memiliki konsep port, yang bisa berupa perangkat atau file. Dan port ini dapat secara fleksibel dihubungkan ke port lain. Anda dapat melihat kodenya di pjsip kami repositori. Hasilnya, skemanya adalah sebagai berikut. Di server Asterisk, saya memulai dua akun - untuk Linux dan untuk Embox. Selanjutnya, perintah dijalankan di Embox simple_pjsua_imported, Embox terdaftar di server, setelah itu kami memanggil Embox dari Linux. Pada saat koneksi, kami memeriksa di server Asterisk apakah koneksi sudah dibuat, dan setelah beberapa saat kami akan mendengar suara dari Linux di Embox, dan di Linux kami menyimpan file yang diputar dari Embox.

Setelah berhasil di QEMU, kami beralih ke porting ke STM32F7-Discovery. Masalah pertama adalah bahwa mereka tidak cocok dengan ROM 1 MB tanpa pengoptimalan kompiler yang diaktifkan "-Os" untuk ukuran gambar. Itu sebabnya kami menyertakan "-Os". Selanjutnya, tambalan menonaktifkan dukungan untuk C ++, jadi hanya diperlukan untuk pjsua, dan kami menggunakan simple_pjsua.

Setelah ditempatkan simple_pjsua, memutuskan bahwa sekarang ada peluang untuk meluncurkannya. Tapi pertama-tama perlu berurusan dengan perekaman dan pemutaran suara. Pertanyaannya adalah menulis di mana? Kami memilih memori eksternal - SDRAM (128 MB). Anda dapat mencobanya sendiri:

Membuat WAV stereo dengan frekuensi 16000 Hz dan durasi 10 detik:


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

Kita kalah:


play -m C0000000

ada dua masalah disini. Yang pertama dengan codec - WM8994 digunakan, dan memiliki slot, dan slot ini ada 4. Jadi, secara default, jika ini tidak dikonfigurasi, maka saat memutar audio, pemutaran terjadi di keempat slot . Oleh karena itu, pada frekuensi 16000 Hz, kami menerima 8000 Hz, tetapi untuk 8000 Hz, pemutaran tidak berfungsi. Ketika hanya slot 0 dan 2 yang dipilih, itu berfungsi sebagaimana mestinya. Masalah lainnya adalah antarmuka audio di STM32Cube, di mana output audio bekerja melalui SAI (Serial Audio Interface) secara sinkron dengan input audio (saya tidak mengerti detailnya, tetapi ternyata mereka berbagi jam yang sama dan kapan output audio diinisialisasi, audio entah bagaimana terpasang ke pintu masuknya). Artinya, Anda tidak dapat menjalankannya secara terpisah, jadi kami melakukan hal berikut - input audio dan output audio selalu berfungsi (termasuk interupsi dihasilkan). Tetapi ketika tidak ada yang diputar di sistem, maka kami cukup menyelipkan buffer kosong ke dalam keluaran audio, dan saat pemutaran dimulai, kami dengan jujur ​​\uXNUMXb\uXNUMXbmulai mengisinya.

Selanjutnya, kami menemukan fakta bahwa suara selama perekaman suara sangat hening. Ini karena mikrofon MEMS pada STM32F7-Discovery tidak berfungsi dengan baik pada frekuensi di bawah 16000 Hz. Oleh karena itu, kami menyetel 16000 Hz, meskipun 8000 Hz datang. Namun, untuk melakukan ini, perlu menambahkan konversi perangkat lunak dari satu frekuensi ke frekuensi lainnya.

Selanjutnya, saya harus menambah ukuran heap, yang terletak di RAM. Menurut perhitungan kami, pjsip membutuhkan sekitar 190 KB, dan kami hanya memiliki sisa sekitar 100 KB. Di sini saya harus menggunakan beberapa memori eksternal - SDRAM (sekitar 128 KB).

Setelah semua pengeditan ini, saya melihat paket pertama antara Linux dan Embox, dan saya mendengar suaranya! Tapi suaranya sangat buruk, sama sekali tidak sama dengan di QEMU, tidak mungkin untuk melihat apapun. Kemudian kami berpikir tentang apa yang mungkin terjadi. Debugging menunjukkan bahwa Embox tidak punya waktu untuk mengisi / membongkar buffer audio. Sementara pjsip sedang memproses satu frame, 2 interupsi sempat terjadi tentang penyelesaian pemrosesan buffer, yang terlalu banyak. Pemikiran pertama untuk kecepatan adalah pengoptimalan kompiler, tetapi sudah termasuk dalam PJSIP. Yang kedua adalah floating point perangkat keras, kami membicarakannya Artikel. Namun seperti yang diperlihatkan oleh praktik, FPU tidak memberikan peningkatan kecepatan yang signifikan. Langkah selanjutnya adalah memprioritaskan utas. Embox memiliki strategi penjadwalan yang berbeda, dan saya telah menyertakan salah satu yang mendukung prioritas dan menyetel aliran audio ke prioritas tertinggi. Ini juga tidak membantu.

Gagasan selanjutnya adalah kami bekerja dengan memori eksternal dan akan menyenangkan untuk memindahkan struktur ke sana yang sangat sering diakses. Saya melakukan analisis awal tentang kapan dan di bawah apa simple_pjsua mengalokasikan memori. Ternyata dari 190 Kb, 90 Kb pertama dialokasikan untuk kebutuhan internal PJSIP dan tidak terlalu sering diakses. Selanjutnya, selama panggilan masuk, fungsi pjsua_call_answer dipanggil, di mana buffer kemudian dialokasikan untuk bekerja dengan frame masuk dan keluar. Itu masih sekitar 100 Kb. Dan kemudian kami melakukan hal berikut. Hingga saat panggilan, kami menempatkan data di memori eksternal. Begitu ada panggilan, kami langsung mengganti heap dengan yang lain - di RAM. Dengan demikian, semua data "panas" ditransfer ke memori yang lebih cepat dan lebih dapat diprediksi.

Hasilnya, semua ini bersama-sama memungkinkan untuk diluncurkan simple_pjsua dan menelepon melalui server Anda. Kemudian melalui server lain seperti sip.linphone.org.

Temuan

Akibatnya, dimungkinkan untuk diluncurkan simple_pjsua dengan transmisi suara di kedua arah melalui server. Masalah dengan tambahan SDRAM 128 KB yang dihabiskan dapat diselesaikan dengan menggunakan Cortex-M7 yang sedikit lebih bertenaga (misalnya, STM32F769NI dengan RAM 512 KB), tetapi pada saat yang sama, kami masih belum putus asa untuk masuk ke 256 KB πŸ™‚ Kami akan senang jika ada yang tertarik, Atau lebih baik lagi, coba saja. Semua sumber, seperti biasa, ada di kami repositori.

Sumber: www.habr.com

Tambah komentar