هاتف SIP على STM32F7-Discovery

مرحبا بالجميع.

منذ بعض الوقت كتبنا عن كيف تمكنا من إطلاق هاتف SIP على STM32F4-Discovery مع 1 MB ROM و 192 KB RAM) استنادًا إلى Embox . هنا يجب أن أقول أن هذا الإصدار كان الحد الأدنى وربط هاتفين مباشرة بدون خادم ومع نقل الصوت في اتجاه واحد فقط. لذلك ، قررنا إطلاق هاتف أكثر اكتمالًا بمكالمة عبر الخادم ، ونقل الصوت في كلا الاتجاهين ، ولكن في نفس الوقت يبقى ضمن أصغر حجم ممكن للذاكرة.


بالنسبة للهاتف ، تقرر اختيار تطبيق simple_pjsua كجزء من مكتبة PJSIP. هذا هو تطبيق الحد الأدنى الذي يمكن التسجيل على الخادم ، وتلقي المكالمات والرد عليها. أدناه سأقدم على الفور وصفًا لكيفية تشغيل هذا على STM32F7-Discovery.

كيف تركض


  1. تكوين Embox
    make confload-platform/pjsip/stm32f7cube 
  2. في ملف conf / mods.config ، قم بتعيين حساب SIP المطلوب.

     include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password") 

    حيث الخادم هو خادم SIP (على سبيل المثال ، sip.linphone.org) ، اسم المستخدم وكلمة المرور هي اسم المستخدم وكلمة المرور للحساب.
  3. قم ببناء Embox باستخدام الأمر make . حول البرامج الثابتة للوحة لدينا في الويكي وفي المقالة .
  4. قم بتشغيل الأمر "simple_pjsua_imported" في وحدة تحكم 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:alexk2222@sip.linphone.org: 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. أخيرًا ، يبقى إدخال مكبرات الصوت أو سماعات الرأس في إخراج الصوت ، والتحدث في ميكروفونين MEMS صغيرين بالقرب من الشاشة. نتصل من Linux من خلال تطبيق simple_pjsua ، pjsua. حسنًا ، أو يمكنك أي نوع آخر من هاتف Linphone.

كل هذا موصوف في ويكي .

كيف وصلنا إلى هذا


لذلك ، نشأ السؤال في البداية حول اختيار منصة الأجهزة. نظرًا لأنه كان من الواضح أن STM32F4-Discovery لن تتناسب مع الذاكرة ، فقد تم اختيار STM32F7-Discovery. لديها محرك أقراص فلاش 1 ميجا بايت و 256 كيلوبايت من ذاكرة الوصول العشوائي (+ 64 ذاكرة سريعة خاصة ، والتي سنستخدمها أيضًا). أيضًا ليس كثيرًا للمكالمات من خلال الخادم ، لكنه قرر محاولة الدخول.

تقليديا ، تم تقسيم المهمة إلى عدة مراحل:

  • تشغيل PJSIP على QEMU. كان مناسبًا لتصحيح الأخطاء ، بالإضافة إلى أن لدينا بالفعل دعم ترميز AC97 هناك.
  • التسجيل الصوتي والتشغيل على QEMU و STM32.
  • نقل تطبيق simple_pjsua من داخل PJSIP. يسمح لك بالتسجيل على خادم SIP وإجراء مكالمات.
  • انشر خادمك القائم على العلامة النجمية واختبره ، ثم جرب الخوادم الخارجية مثل sip.linphone.org

يعمل الصوت في Embox من خلال Portaudio ، والذي يستخدم أيضًا في PISIP. ظهرت المشاكل الأولى على QEMU - WAV لعبت بشكل جيد عند 44100 هرتز ، ولكن حدث خطأ واضح عند 8000. اتضح أن الأمر كان يتعلق بتعيين التردد - بشكل افتراضي كان 44100 في المعدات ، وهذا لم يتغير برمجيًا معنا.

هنا ، ربما يجدر شرح القليل عن كيفية تشغيل الصوت بشكل عام. يمكن لبطاقة الصوت ضبط بعض المؤشر على جزء من الذاكرة تريد اللعب أو التسجيل منه بتردد محدد مسبقًا. بعد انتهاء المخزن المؤقت ، يتم إنشاء مقاطعة ويستمر التنفيذ من المخزن المؤقت التالي. والحقيقة هي أنه يجب ملء هذه المخازن المؤقتة مسبقًا قبل تشغيل السابق. هذه المشكلة سوف نواجه المزيد في STM32F7.

بعد ذلك ، استأجرنا خادمًا ونشرنا العلامة النجمية عليه. نظرًا لأنه كان من الضروري تصحيح الكثير ، ولكن لم يكن يريد التحدث كثيرًا في الميكروفون ، كان من الضروري إجراء التشغيل والتسجيل التلقائي. للقيام بذلك ، قمنا بتصحيح simple_pjsua بحيث كان من الممكن أن تنزلق الملفات بدلاً من الأجهزة الصوتية. في PJSIP ، يتم ذلك ببساطة ، نظرًا لأن لديهم مفهوم المنفذ ، والذي يمكن أن يكون إما جهازًا أو ملفًا. ويمكن توصيل هذه المنافذ بمرونة بمنافذ أخرى. يمكنك رؤية الرمز في مستودع pjsip الخاص بنا. ونتيجة لذلك ، كان المخطط على النحو التالي. لقد أنشأت حسابين على خادم Asterisk - لنظامي التشغيل Linux و Embox. بعد ذلك ، يتم تنفيذ الأمر simple_pjsua_imported على Embox ، ويتم تسجيل Embox على الخادم ، وبعد ذلك نسمي Embox من Linux. في وقت الاتصال ، نتحقق على خادم النجمة من أنه تم تأسيس الاتصال بالكامل ، وبعد مرور بعض الوقت يجب أن يسمعوا صوتًا من Linux في Embox ، وفي Linux نحفظ الملف الذي يتم تشغيله من Embox.

بعد أن عمل على QEMU ، تحولنا إلى النقل إلى STM32F7-Discovery. المشكلة الأولى - أنهم لم يدخلوا في 1 ميغابايت من ذاكرة القراءة فقط بدون التحسين المضمّن للمترجم "-Os" من حيث حجم الصورة. لذلك تضمن "-Os". علاوة على ذلك ، قام التصحيح بتعطيل دعم C ++ ، لذلك فهو مطلوب فقط لـ pjsua ، ونحن نستخدم simple_pjsua.

بعد تركيب simple_pjsua ، قررنا أن هناك فرصًا الآن لإطلاقه. ولكن أولاً ، كان عليك التعامل مع التسجيل الصوتي والتشغيل. سؤال - أين تكتب؟ لقد اخترنا ذاكرة خارجية - SDRAM (128 ميجابايت). يمكنك تجربتها بنفسك:

ينشئ WAV ستيريو بتردد 16000 هرتز ومدة 10 ثوانٍ:

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

نفقد:

 play -m C0000000 

كانت هناك مشكلتان. الأول مع برنامج ترميز هو WM8994 ، ولديه مفهوم مثل فتحة ، وهذه الفتحات هي 4. لذلك ، بشكل افتراضي ، إذا لم يتم تكوين ذلك ، فعند تشغيل الصوت ، يحدث التشغيل في جميع الفتحات الأربعة. لذلك ، على تردد 16000 هرتز ، تلقينا 8000 هرتز ، ولكن لمدة 8000 هرتز لم يعمل التشغيل ببساطة. عندما تم اختيار الفتحتين 0 و 2 فقط ، كان يعمل كما ينبغي. كانت المشكلة الأخرى هي واجهة الصوت في STM32Cube ، حيث يعمل إخراج الصوت عبر SAI (واجهة صوت تسلسلية) بشكل متزامن مع إدخال الصوت (لم يفهم التفاصيل ، ولكن اتضح أنهما يشتركان في ساعة مشتركة ويتم توصيل الصوت بطريقة أو بأخرى عند تهيئة إخراج الصوت الإدخال). أي أنه لا يمكن إطلاقها بشكل منفصل ، لذلك قاموا بما يلي - يعمل إدخال الصوت وخرج الصوت دائمًا (بما في ذلك المقاطعات التي يتم إنشاؤها). ولكن عندما لا يتم فقدان أي شيء في النظام ، فإننا ببساطة ننزلق مخزنًا مؤقتًا فارغًا في إخراج الصوت ، وعندما يبدأ التشغيل ، نبدأ بصدق في ملئه.

علاوة على ذلك ، واجهوا حقيقة أن الصوت عند تسجيل الصوت كان هادئًا جدًا. هذا يرجع إلى حقيقة أن ميكروفونات MEMS على STM32F7-Discovery بطريقة ما لا تعمل بشكل جيد في الترددات أقل من 16000 هرتز. لذلك ، قمنا بتعيين 16000 هرتز ، حتى إذا جاء 8000 هرتز. للقيام بذلك ، كانت الحقيقة هي إضافة تحويل برنامج من تردد إلى آخر.

بعد ذلك ، اضطررت إلى زيادة حجم كومة الذاكرة المؤقتة الموجودة في ذاكرة الوصول العشوائي. وفقًا لتقديراتنا ، تطلب pjsip حوالي 190 كيلوبايت ، وكان لدينا حوالي 100 كيلوبايت فقط. هنا اضطررت لاستخدام جزء صغير من الذاكرة الخارجية - SDRAM (حوالي 128 كيلوبايت).

بعد كل هذه التعديلات ، رأيت الحزم الأولى بين Linux و Embox ، وسمعت صوتًا! لكن الصوت كان فظيعًا ، ليس على الإطلاق مثل QEMU ، لا يمكن عمل أي شيء. ثم فكرنا في ما يمكن أن يكون الأمر. أظهر التصحيح أن Embox ببساطة ليس لديه الوقت لملء / إلغاء تحميل المخازن المؤقتة الصوتية. أثناء معالجة pjsip لإطار واحد ، حدثت مقاطعتان قبل الانتهاء من معالجة المخزن المؤقت ، وهو عدد كبير جدًا. كان أول ما تم تسريعه هو تحسين المترجم ، ولكن تم تضمينه بالفعل في PJSIP. والثاني هو نقطة عائمة للأجهزة ، تحدثنا عنها في المقالة . ولكن كما أظهرت الممارسة ، لم تقدم FPU زيادة كبيرة في السرعة. كانت الخطوة التالية تحديد أولويات المواضيع. لدى Embox إستراتيجيات جدولة مختلفة ، وقمت بتضمين إستراتيجية تدعم الأولويات وتعيين التدفقات الصوتية إلى الأولوية القصوى. لم يساعد أيضا.

كانت الفكرة التالية هي أننا نعمل مع الذاكرة الخارجية وسيكون من الجيد نقل الهياكل هناك ، والتي يتم الوصول إليها في كثير من الأحيان. لقد أجريت تحليلاً أوليًا لموعد وتحت أي شيء يخصصه simple_pjsua للذاكرة. اتضح أنه من 190 كيلوبايت يتم تخصيص أول 90 كيلوبايت للاحتياجات الداخلية لـ PJSIP ولا يتم الوصول إليها كثيرًا. بعد ذلك ، أثناء مكالمة واردة ، يتم استدعاء وظيفة pjsua_call_answer ، والتي يتم بعد ذلك تخصيص المخازن المؤقتة للعمل مع الإطارات الواردة والصادرة. كان حوالي 100 كيلو بايت. وهنا تصرفنا على النحو التالي. قبل المكالمة ، يتم وضع البيانات في ذاكرة خارجية. بمجرد المكالمة - استبدال الكومة على الفور بأخرى - في ذاكرة الوصول العشوائي. وهكذا ، تم نقل جميع البيانات "الساخنة" إلى ذاكرة أسرع وأكثر قابلية للتنبؤ.

ونتيجة لذلك ، سمح كل هذا معًا ببدء simple_pjsua وإجراء مكالمة من خلال خادمه . ثم من خلال خوادم أخرى مثل sip.linphone.org.

الاستنتاجات


ونتيجة لذلك ، اتضح تشغيل simple_pjsua مع الإرسال الصوتي في كلا الاتجاهين من خلال الخادم. يمكن حل المشكلة مع SDRAM 128 Kb التي تم إنفاقها أيضًا باستخدام Cortex-M7 أقوى قليلاً (على سبيل المثال ، STM32F769NI مع 512 كيلوبايت من ذاكرة الوصول العشوائي) ، ولكن في الوقت نفسه لا يزال لدينا أمل في احتواء 256 كيلوبايت :) سنكون سعداء إذا كان شخص ما مهتمًا ، وحتى أفضل - حاول. جميع المصادر ، كالعادة ، موجودة في مستودعنا .

Source: https://habr.com/ru/post/ar431134/


All Articles