एसटीएम32एफ7-डिस्कवरी पर एसआईपी फोन

नमस्कार.

कुछ समय पहले हम писали हम कैसे STM32F4-Discovery पर 1 MB ROM और 192 KB RAM के साथ एक SIP फोन लॉन्च करने में कामयाब रहे) के आधार पर एमबॉक्स. यहाँ यह कहा जाना चाहिए कि वह संस्करण न्यूनतम था और बिना सर्वर के सीधे दो फोन से जुड़ा था और केवल एक दिशा में आवाज संचरण के साथ। इसलिए, हमने सर्वर के माध्यम से कॉल के साथ एक और पूर्ण फोन लॉन्च करने का फैसला किया, दोनों दिशाओं में वॉयस ट्रांसमिशन, लेकिन एक ही समय में सबसे छोटे संभव मेमोरी आकार के भीतर।


फोन के लिए, एक एप्लिकेशन चुनने का निर्णय लिया गया simple_pjsu PJSIP लाइब्रेरी के हिस्से के रूप में। यह एक न्यूनतम एप्लिकेशन है जो सर्वर पर रजिस्टर कर सकता है, कॉल प्राप्त कर सकता है और उत्तर दे सकता है। नीचे मैं तुरंत वर्णन करूंगा कि इसे STM32F7-डिस्कवरी पर कैसे चलाया जाए।

कैसे दौड़ें

  1. एमबॉक्स को कॉन्फ़िगर करना
    make confload-platform/pjsip/stm32f7cube
  2. आवश्यक SIP खाते को conf/mod.config फ़ाइल में सेट करें।
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    जहां सर्वर एक SIP सर्वर है (उदाहरण के लिए, sip.linphone.org), उपयोगकर्ता नाम и पासवर्ड - खाता उपयोगकर्ता नाम और पासवर्ड।

  3. एक टीम के रूप में एमबॉक्स को असेंबल करना बनाना. हमारे पास मौजूद बोर्ड फर्मवेयर के बारे में вики और लेख.
  4. Embox कंसोल में “simple_pjsua_imported” कमांड चलाएँ
    
    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. अंत में, यह ऑडियो आउटपुट में स्पीकर या हेडफ़ोन डालने और डिस्प्ले के बगल में दो छोटे एमईएमएस माइक्रोफ़ोन में बोलने के लिए बनी हुई है। हम लिनक्स से simple_pjsua, pjsua एप्लिकेशन के माध्यम से कॉल करते हैं। ठीक है, या आप किसी अन्य प्रकार के लिनफ़ोन का उपयोग कर सकते हैं।

यह सब हमारे पर वर्णित है вики.

हम वहां कैसे पहुंचे

इसलिए, शुरू में हार्डवेयर प्लेटफॉर्म चुनने के बारे में सवाल उठा। चूंकि यह स्पष्ट था कि STM32F4-डिस्कवरी मेमोरी से फिट नहीं होगी, इसलिए STM32F7-डिस्कवरी को चुना गया। उसके पास 1 एमबी फ्लैश ड्राइव और 256 केबी रैम (+ 64 विशेष फास्ट मेमोरी, जिसका हम उपयोग भी करेंगे) है। सर्वर के माध्यम से कॉल करने के लिए भी बहुत कुछ नहीं है, लेकिन हमने इसमें फिट होने का प्रयास करने का निर्णय लिया।

सशर्त रूप से स्वयं के लिए, कार्य को कई चरणों में विभाजित किया गया था:

  • QEMU पर PJSIP चला रहा है। यह डिबगिंग के लिए सुविधाजनक था, साथ ही हमारे पास पहले से ही AC97 कोडेक के लिए समर्थन था।
  • QEMU और STM32 पर वॉयस रिकॉर्डिंग और प्लेबैक।
  • किसी एप्लिकेशन को पोर्ट करना simple_pjsu पीजेएसआईपी से। यह आपको SIP सर्वर पर रजिस्टर करने और कॉल करने की अनुमति देता है।
  • अपने स्वयं के तारांकन-आधारित सर्वर को परिनियोजित करें और उस पर परीक्षण करें, फिर बाहरी लोगों जैसे कि sip.linphone.org का प्रयास करें

साउंड इन एमबॉक्स पोर्टऑडियो के माध्यम से काम करता है, जिसका उपयोग पीआईएसआईपी में भी किया जाता है। QEMU पर पहली समस्याएँ दिखाई दीं - WAV ने 44100 हर्ट्ज पर अच्छा बजाया, लेकिन 8000 पर कुछ स्पष्ट रूप से गलत हो गया। यह पता चला कि यह आवृत्ति सेट करने का मामला था - डिफ़ॉल्ट रूप से यह उपकरण में 44100 था, और यह प्रोग्रामेटिक रूप से नहीं बदला।

यहाँ, शायद, यह थोड़ा समझाने लायक है कि सामान्य रूप से ध्वनि कैसे बजाई जाती है। साउंड कार्ड को मेमोरी के एक टुकड़े के लिए कुछ पॉइंटर पर सेट किया जा सकता है जिससे आप पूर्व निर्धारित आवृत्ति पर खेलना या रिकॉर्ड करना चाहते हैं। बफ़र समाप्त होने के बाद, एक व्यवधान उत्पन्न होता है और अगले बफ़र के साथ निष्पादन जारी रहता है। तथ्य यह है कि इन बफ़र्स को पहले से भरने की आवश्यकता होती है जबकि पिछले एक को खेला जा रहा है। हम आगे इस समस्या का सामना STM32F7 पर करेंगे।

अगला, हमने एक सर्वर किराए पर लिया और उस पर तारांकन चिह्न लगाया। चूंकि यह बहुत डिबग करने के लिए आवश्यक था, लेकिन मैं माइक्रोफ़ोन में ज्यादा नहीं बोलना चाहता था, स्वचालित प्लेबैक और रिकॉर्डिंग करना आवश्यक था। ऐसा करने के लिए, हमने simple_pjsua को पैच किया ताकि आप ऑडियो डिवाइस के बजाय फ़ाइलों को स्लिप कर सकें। PJSIP में, यह काफी सरलता से किया जाता है, क्योंकि उनके पास एक पोर्ट की अवधारणा है, जो एक डिवाइस या फ़ाइल हो सकती है। और इन पोर्ट्स को लचीले ढंग से अन्य पोर्ट्स से जोड़ा जा सकता है। आप हमारे pjsip में कोड देख सकते हैं खजाने. नतीजतन, योजना इस प्रकार थी। तारांकन चिह्न सर्वर पर, मैंने दो खाते शुरू किए - लिनक्स के लिए और एमबॉक्स के लिए। इसके बाद, आदेश को Embox पर निष्पादित किया जाता है simple_pjsua_imported, Embox सर्वर पर पंजीकृत है, जिसके बाद हम Linux से Embox को कॉल करते हैं। कनेक्शन के क्षण में, हम एस्टरिस्क सर्वर पर जांच करते हैं कि कनेक्शन स्थापित हो गया है, और थोड़ी देर के बाद हमें एम्बॉक्स में लिनक्स से ध्वनि सुननी चाहिए, और लिनक्स में हम उस फ़ाइल को सहेजते हैं जो एमबॉक्स से खेली जाती है।

इसके QEMU पर काम करने के बाद, हम STM32F7-डिस्कवरी में पोर्टिंग के लिए आगे बढ़े। पहली समस्या यह है कि वे छवि के आकार के लिए सक्षम संकलक अनुकूलन "-Os" के बिना 1 एमबी रोम में फिट नहीं हुए। इसलिए हमने "-Os" को शामिल किया। इसके अलावा, पैच ने C ++ के लिए समर्थन को अक्षम कर दिया है, इसलिए इसकी आवश्यकता केवल pjsua के लिए है, और हम simple_pjsua का उपयोग करते हैं।

लगाए जाने के बाद simple_pjsu, फैसला किया कि अब इसे लॉन्च करने का मौका है। लेकिन पहले आवाज की रिकॉर्डिंग और प्लेबैक से निपटना जरूरी था। सवाल यह है कि कहां लिखें? हमने बाहरी मेमोरी - एसडीआरएएम (128 एमबी) को चुना। आप इसे स्वयं आजमा सकते हैं:

16000 हर्ट्ज की आवृत्ति और 10 सेकंड की अवधि के साथ एक स्टीरियो WAV बनाता है:


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

हम हारॆ:


play -m C0000000

यहां पर दो समस्याएं हैं। कोडेक के साथ पहला - WM8994 का उपयोग किया जाता है, और इसमें एक स्लॉट जैसी चीज होती है, और इनमें से 4 स्लॉट होते हैं। इसलिए, डिफ़ॉल्ट रूप से, यदि यह कॉन्फ़िगर नहीं किया गया है, तो ऑडियो चलाते समय, सभी चार स्लॉट में प्लेबैक होता है . इसलिए, 16000 हर्ट्ज की आवृत्ति पर, हमें 8000 हर्ट्ज प्राप्त हुआ, लेकिन 8000 हर्ट्ज के लिए, प्लेबैक बस काम नहीं करता था। जब केवल स्लॉट 0 और 2 का चयन किया गया था, तो यह उसी तरह काम करता था जैसा इसे करना चाहिए। एक अन्य समस्या STM32Cube में ऑडियो इंटरफ़ेस थी, जिसमें ऑडियो आउटपुट SAI (सीरियल ऑडियो इंटरफ़ेस) के माध्यम से ऑडियो इनपुट के साथ सिंक्रोनस रूप से काम करता है (मुझे विवरण समझ में नहीं आया, लेकिन यह पता चला कि वे एक सामान्य घड़ी साझा करते हैं और जब ऑडियो आउटपुट को इनिशियलाइज़ किया जाता है, ऑडियो किसी तरह इसके एंट्रेंस से जुड़ा होता है)। यही है, आप उन्हें अलग से नहीं चला सकते हैं, इसलिए हमने निम्नलिखित किया - ऑडियो इनपुट और ऑडियो आउटपुट हमेशा काम करते हैं (इंटरप्ट उत्पन्न होते हैं)। लेकिन जब सिस्टम में कुछ भी नहीं चल रहा होता है, तो हम बस एक खाली बफर को ऑडियो आउटपुट में खिसका देते हैं, और जब प्लेबैक शुरू होता है, तो हम ईमानदारी से इसे भरना शुरू करते हैं।

इसके अलावा, हमने इस तथ्य का सामना किया कि वॉयस रिकॉर्डिंग के दौरान ध्वनि बहुत शांत थी। यह इस तथ्य के कारण है कि STM32F7-डिस्कवरी पर MEMS माइक्रोफोन किसी तरह 16000 हर्ट्ज से कम आवृत्तियों पर अच्छी तरह से काम नहीं करते हैं। इसलिए हम 16000 हर्ट्ज़ सेट करते हैं, भले ही 8000 हर्ट्ज़ आ जाए। ऐसा करने के लिए, हालांकि, एक आवृत्ति के सॉफ़्टवेयर रूपांतरण को दूसरे में जोड़ना आवश्यक था।

अगला, मुझे हीप का आकार बढ़ाना था, जो रैम में स्थित है। हमारी गणना के अनुसार, pjsip को लगभग 190 KB की आवश्यकता है, और हमारे पास केवल लगभग 100 KB शेष है। यहाँ मुझे कुछ बाहरी मेमोरी - SDRAM (लगभग 128 KB) का उपयोग करना था।

इन सभी संपादनों के बाद, मैंने Linux और Embox के बीच पहला पैकेज देखा, और मैंने आवाज़ सुनी! लेकिन आवाज भयानक थी, क्यूईएमयू के समान बिल्कुल नहीं, कुछ भी बनाना असंभव था। फिर हमने सोचा कि क्या बात हो सकती है। डिबगिंग से पता चला कि Embox के पास ऑडियो बफ़र्स को भरने/अनलोड करने का समय नहीं है। जबकि pjsip एक फ्रेम को प्रोसेस कर रहा था, बफर प्रोसेसिंग के पूरा होने के बारे में 2 इंटरप्ट होने का समय था, जो बहुत अधिक है। गति के लिए पहला विचार संकलक अनुकूलन था, लेकिन यह पहले से ही PJSIP में शामिल था। दूसरा हार्डवेयर फ़्लोटिंग पॉइंट है, हमने इसके बारे में बात की थी लेख. लेकिन जैसा कि अभ्यास से पता चला है, एफपीयू ने गति में उल्लेखनीय वृद्धि नहीं की। अगला कदम थ्रेड्स को प्राथमिकता देना था। Embox की अलग-अलग शेड्यूलिंग रणनीतियाँ हैं, और मैंने एक को शामिल किया है जो प्राथमिकताओं का समर्थन करता है और ऑडियो स्ट्रीम को सर्वोच्च प्राथमिकता पर सेट करता है। इससे भी मदद नहीं मिली।

अगला विचार यह था कि हम बाहरी मेमोरी के साथ काम कर रहे हैं और वहां संरचनाओं को स्थानांतरित करना अच्छा होगा जो बहुत बार एक्सेस किए जाते हैं। मैंने कब और किसके तहत इसका प्रारंभिक विश्लेषण किया simple_pjsu स्मृति आवंटित करता है। यह पता चला कि 190 केबी में से, पहले 90 केबी पीजेएसआईपी की आंतरिक जरूरतों के लिए आवंटित किए गए हैं और उन्हें अक्सर एक्सेस नहीं किया जाता है। इसके अलावा, आने वाली कॉल के दौरान, pjsua_call_answer फ़ंक्शन को कॉल किया जाता है, जिसमें आने वाले और बाहर जाने वाले फ्रेम के साथ काम करने के लिए बफर आवंटित किए जाते हैं। यह अभी भी लगभग 100 Kb था। और फिर हमने निम्नलिखित किया। कॉल के क्षण तक, हम डेटा को बाहरी मेमोरी में रखते हैं। जैसे ही कॉल आती है, हम तुरंत ढेर को दूसरे से बदल देते हैं - रैम में। इस प्रकार, सभी "हॉट" डेटा को तेज और अधिक अनुमानित मेमोरी में स्थानांतरित कर दिया गया।

नतीजतन, यह सब एक साथ लॉन्च करना संभव बना दिया simple_pjsu और अपने सर्वर के माध्यम से कॉल करें। और फिर अन्य सर्वर जैसे कि sip.linphone.org के माध्यम से।

निष्कर्ष

नतीजतन, लॉन्च करना संभव हो गया simple_pjsu सर्वर के माध्यम से दोनों दिशाओं में ध्वनि संचरण के साथ। एसडीआरएएम के अतिरिक्त 128 केबी खर्च करने की समस्या को थोड़ा अधिक शक्तिशाली कॉर्टेक्स-एम 7 (उदाहरण के लिए, 32 केबी रैम के साथ एसटीएम 769 एफ 512 एनआई) का उपयोग करके हल किया जा सकता है, लेकिन साथ ही, हमने अभी भी 256 में आने की उम्मीद नहीं छोड़ी है केबी 🙂 अगर कोई दिलचस्पी लेता है, या बेहतर अभी तक, इसे आजमाएं तो हमें खुशी होगी। सभी स्रोत, हमेशा की तरह, हमारे में हैं खजाने.

स्रोत: www.habr.com

एक टिप्पणी जोड़ें