STM32F7-డిస్కవరీలో SIP ఫోన్

అందరికీ నమస్కారం.

కొంతకాలం క్రితం మేము రాశారు మేము STM32F4-డిస్కవరీలో 1 MB ROM మరియు 192 KB RAMతో SIP ఫోన్‌ను ఎలా ప్రారంభించగలిగాము అనే దాని ఆధారంగా ఎంబాక్స్. ఇక్కడ ఆ వెర్షన్ కనిష్టంగా ఉందని మరియు సర్వర్ లేకుండా నేరుగా రెండు ఫోన్‌లను ఒక దిశలో మాత్రమే వాయిస్ ట్రాన్స్‌మిషన్‌తో కనెక్ట్ చేసిందని చెప్పాలి. అందువల్ల, మేము సర్వర్ ద్వారా కాల్‌తో మరింత పూర్తి ఫోన్‌ను ప్రారంభించాలని నిర్ణయించుకున్నాము, రెండు దిశలలో వాయిస్ ట్రాన్స్‌మిషన్, కానీ అదే సమయంలో సాధ్యమైనంత చిన్న మెమరీ పరిమాణానికి సరిపోతుంది.


ఫోన్ కోసం అప్లికేషన్‌ను ఎంచుకోవాలని నిర్ణయించారు simple_pjsua PJSIP లైబ్రరీలో భాగంగా. ఇది సర్వర్‌లో నమోదు చేయగల, కాల్‌లను స్వీకరించగల మరియు సమాధానం ఇవ్వగల కనీస అప్లికేషన్. క్రింద నేను వెంటనే STM32F7-డిస్కవరీలో దీన్ని ఎలా అమలు చేయాలో వివరణ ఇస్తాను.

ఎలా లాంచ్ చేయాలి

  1. ఎంబాక్స్‌ని కాన్ఫిగర్ చేస్తోంది
    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), <span style="font-family: Mandali; "> యూజర్ పేరు </span> и <span style="font-family: Mandali; "> పాస్‌వర్డ్</span> - ఖాతా కోసం వినియోగదారు పేరు మరియు పాస్‌వర్డ్.

  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. చివరగా, ఆడియో అవుట్‌పుట్‌లో స్పీకర్‌లు లేదా హెడ్‌ఫోన్‌లను చొప్పించడం మరియు డిస్‌ప్లే పక్కన ఉన్న రెండు చిన్న MEMS మైక్రోఫోన్‌లలో మాట్లాడడం మాత్రమే మిగిలి ఉంది. మేము simple_pjsua, pjsua అప్లికేషన్‌ని ఉపయోగించి Linux నుండి కాల్ చేస్తాము. బాగా, లేదా మీరు ఏదైనా ఇతర రకమైన లిన్‌ఫోన్‌ను ఉపయోగించవచ్చు.

ఇవన్నీ మాపై వివరించబడ్డాయి వికీ.

మనం ఇక్కడికి ఎలా వచ్చాం

కాబట్టి, హార్డ్‌వేర్ ప్లాట్‌ఫారమ్‌ను ఎంచుకోవడం గురించి మొదట్లో ప్రశ్న తలెత్తింది. STM32F4-డిస్కవరీ మెమరీకి తగినది కాదని స్పష్టంగా ఉన్నందున, STM32F7-డిస్కవరీ ఎంపిక చేయబడింది. ఆమె 1 MB ఫ్లాష్ డ్రైవ్ మరియు 256 KB RAM (+ 64 ప్రత్యేక ఫాస్ట్ మెమరీ, మేము కూడా ఉపయోగిస్తాము). సర్వర్ ద్వారా కాల్‌ల కోసం ఇది చాలా ఎక్కువ కాదు, కానీ మేము ప్రవేశించడానికి ప్రయత్నించాలని నిర్ణయించుకున్నాము.

సాంప్రదాయకంగా, పని అనేక దశలుగా విభజించబడింది:

  • QEMUలో PJSIPని అమలు చేస్తోంది. ఇది డీబగ్గింగ్‌కు అనుకూలమైనది, అలాగే మేము ఇప్పటికే అక్కడ AC97 కోడెక్‌కు మద్దతునిచ్చాము.
  • QEMU మరియు STM32లో వాయిస్ రికార్డింగ్ మరియు ప్లేబ్యాక్.
  • అప్లికేషన్‌ను పోర్ట్ చేస్తోంది simple_pjsua PJSIP నుండి. ఇది SIP సర్వర్‌లో నమోదు చేసుకోవడానికి మరియు కాల్స్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది.
  • ఆస్టరిస్క్ ఆధారంగా మీ స్వంత సర్వర్‌ని అమలు చేయండి మరియు దానిపై పరీక్షించండి, ఆపై sip.linphone.org వంటి బాహ్య వాటిని ప్రయత్నించండి

ఎంబాక్స్‌లోని సౌండ్ పోర్టాడియో ద్వారా పని చేస్తుంది, ఇది PISIPలో కూడా ఉపయోగించబడుతుంది. QEMUలో మొదటి సమస్యలు కనిపించాయి - WAVలు 44100 Hz వద్ద బాగా ప్లే చేయబడ్డాయి, కానీ 8000 వద్ద ఏదో తప్పు జరుగుతోంది. ఫ్రీక్వెన్సీని సెట్ చేయడంలో సమస్య ఉందని తేలింది - డిఫాల్ట్‌గా పరికరాల్లో ఇది 44100, మరియు మేము దీన్ని సాఫ్ట్‌వేర్‌లో మార్చలేదు.

ఇక్కడ, సాధారణంగా ధ్వని ఎలా ప్లే చేయబడుతుందనే దాని గురించి కొంచెం వివరించడం విలువైనదే. సౌండ్ కార్డ్ కొంత పాయింటర్‌ను మెమరీ భాగానికి సెట్ చేయగలదు, దాని నుండి ముందుగా నిర్ణయించిన ఫ్రీక్వెన్సీలో ప్లే చేయబడాలి లేదా రికార్డ్ చేయాలి. బఫర్ అయిపోయిన తర్వాత, అంతరాయం ఏర్పడుతుంది మరియు తదుపరి బఫర్ నుండి అమలు కొనసాగుతుంది. విషయమేమిటంటే, మునుపటిది ప్లే అవుతున్నప్పుడు ఈ బఫర్‌లను ముందుగానే పూరించాలి. మేము ఈ సమస్యను STM32F7లో మరింతగా ఎదుర్కొంటాము.

తరువాత, మేము సర్వర్‌ని అద్దెకు తీసుకున్నాము మరియు దానిపై ఆస్టరిస్క్‌ని అమలు చేసాము. చాలా డీబగ్గింగ్ చేయాల్సి ఉంది మరియు నేను మైక్రోఫోన్‌లో ఎక్కువగా మాట్లాడాలనుకోలేదు కాబట్టి, ఆటోమేటిక్ ప్లేబ్యాక్ మరియు రికార్డింగ్ చేయడం అవసరం. దీన్ని చేయడానికి, మేము simple_pjsuaని ప్యాచ్ చేసాము, తద్వారా మేము ఆడియో పరికరాలకు బదులుగా ఫైల్‌లను చొప్పించగలము. PJSIPలో ఇది చాలా సరళంగా చేయబడుతుంది, ఎందుకంటే అవి పోర్ట్ యొక్క భావనను కలిగి ఉంటాయి, అది పరికరం లేదా ఫైల్ కావచ్చు. మరియు ఈ పోర్ట్‌లను ఇతర పోర్ట్‌లకు ఫ్లెక్సిబుల్‌గా కనెక్ట్ చేయవచ్చు. మీరు మా pjsipలో కోడ్‌ని చూడవచ్చు రిపోజిటరీలు. ఫలితంగా, పథకం క్రింది విధంగా ఉంది. నేను ఆస్టరిస్క్ సర్వర్‌లో - Linux మరియు Embox కోసం రెండు ఖాతాలను సృష్టించాను. తరువాత, ఆదేశం Emboxలో అమలు చేయబడుతుంది simple_pjsua_imported, Embox సర్వర్‌లో నమోదు చేయబడుతుంది, దాని తర్వాత మేము Linux నుండి Embox అని పిలుస్తాము. కనెక్షన్ సమయంలో, మొత్తం కనెక్షన్ ఏర్పాటు చేయబడిందని మేము ఆస్టరిస్క్ సర్వర్‌లో తనిఖీ చేస్తాము మరియు కొంత సమయం తర్వాత మేము Emboxలో Linux నుండి ధ్వనిని వినాలి మరియు Linuxలో మేము Embox నుండి ప్లే చేయబడిన ఫైల్‌ను సేవ్ చేస్తాము.

ఇది QEMUలో పనిచేసిన తర్వాత, మేము దానిని STM32F7-డిస్కవరీకి పోర్ట్ చేయడానికి వెళ్లాము. మొదటి సమస్య ఏమిటంటే, ఇమేజ్ సైజు కోసం “-Os” కంపైలర్ ఆప్టిమైజేషన్ ఎనేబుల్ చేయకుండా మనం 1 MB ROMకి సరిపోలేము. కాబట్టి, మేము "-Os"ని చేర్చాము. తరువాత, ప్యాచ్ C++కి మద్దతుని నిలిపివేసింది, కనుక ఇది pjsuaకి మాత్రమే అవసరమవుతుంది మరియు మేము simple_pjsuaని ఉపయోగిస్తాము.

ఉంచిన తర్వాత simple_pjsua, ఇప్పుడు దీన్ని ప్రారంభించే అవకాశం ఉందని నిర్ణయించుకున్నారు. అయితే ముందుగా మనం వాయిస్‌లను రికార్డ్ చేయడం మరియు ప్లే బ్యాక్ చేయడం ఎలాగో గుర్తించాలి. ప్రశ్న: ఎక్కడ వ్రాయాలి? మేము బాహ్య మెమరీని ఎంచుకున్నాము - SDRAM (128 MB). మీరు దీన్ని మీరే ప్రయత్నించవచ్చు:

16000 Hz ఫ్రీక్వెన్సీ మరియు 10 సెకన్ల వ్యవధితో స్టీరియో WAVని సృష్టిస్తుంది:


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

మేము ఓడిపోయము:


play -m C0000000

ఇక్కడ రెండు సమస్యలు వచ్చాయి. మొదటిది కోడెక్‌తో ఉంది - WM8994 ఉపయోగించబడుతుంది మరియు దీనికి స్లాట్ వంటిది ఉంది మరియు డిఫాల్ట్‌గా ఈ స్లాట్‌లలో 4 ఉన్నాయి, ఇది కాన్ఫిగర్ చేయకపోతే, ఆడియో ప్లే చేస్తున్నప్పుడు, ప్లేబ్యాక్ అన్నింటిలోనూ జరుగుతుంది నాలుగు స్లాట్లు. అందువలన, 16000 Hz ఫ్రీక్వెన్సీ వద్ద మేము 8000 Hz అందుకున్నాము, కానీ 8000 Hz కోసం ప్లేబ్యాక్ కేవలం పని చేయలేదు. మేము 0 మరియు 2 స్లాట్‌లను మాత్రమే ఎంచుకున్నప్పుడు, అది ఊహించిన విధంగా పని చేసింది. మరొక సమస్య STM32Cubeలోని ఆడియో ఇంటర్‌ఫేస్, దీనిలో ఆడియో అవుట్‌పుట్ SAI (సీరియల్ ఆడియో ఇంటర్‌ఫేస్) ద్వారా ఆడియో ఇన్‌పుట్‌తో సమకాలీకరించబడుతుంది (నాకు వివరాలు అర్థం కాలేదు, కానీ అవి సాధారణ గడియారాన్ని పంచుకుంటాయని మరియు ప్రారంభించేటప్పుడు ఆడియో అవుట్‌పుట్, ఆడియో ఏదో ఒకవిధంగా దాని ప్రవేశానికి కట్టుబడి ఉంటుంది). అంటే, వాటిని విడిగా అమలు చేయడం అసాధ్యం, కాబట్టి మేము ఈ క్రింది వాటిని చేసాము - ఆడియో ఇన్‌పుట్ మరియు ఆడియో అవుట్‌పుట్ ఎల్లప్పుడూ పని చేస్తాయి (అంతరాయాలతో సహా). కానీ సిస్టమ్‌లో ఏదీ ప్లే కానప్పుడు, మేము కేవలం ఆడియో అవుట్‌పుట్‌లోకి ఖాళీ బఫర్‌ను స్లిప్ చేస్తాము మరియు ప్లేబ్యాక్ ప్రారంభించినప్పుడు, మేము నిజాయితీగా దాన్ని పూరించడం ప్రారంభిస్తాము.

వాయిస్ రికార్డింగ్ చేసేటప్పుడు ధ్వని చాలా నిశ్శబ్దంగా ఉందనే వాస్తవాన్ని మేము ఎదుర్కొన్నాము. STM32F7-డిస్కవరీలోని MEMS మైక్రోఫోన్‌లు 16000 Hz కంటే తక్కువ పౌనఃపున్యాల వద్ద సరిగ్గా పని చేయకపోవడమే దీనికి కారణం. అందువల్ల, 16000 Hz వచ్చినప్పటికీ, మేము దానిని 8000 Hzకి సెట్ చేస్తాము. అయితే, దీన్ని చేయడానికి, ఒక ఫ్రీక్వెన్సీని మరొకదానికి సాఫ్ట్‌వేర్ మార్పిడిని జోడించడం అవసరం.

తరువాత, మేము RAM లో ఉన్న కుప్ప యొక్క పరిమాణాన్ని పెంచాలి. మా లెక్కల ప్రకారం, pjsipకి దాదాపు 190 KB అవసరం, మరియు మాకు 100 KB మాత్రమే మిగిలి ఉంది. ఇక్కడ మనం కొద్దిగా బాహ్య మెమరీని ఉపయోగించాల్సి వచ్చింది - SDRAM (సుమారు 128 KB).

ఈ సవరణలన్నిటి తర్వాత, నేను Linux మరియు Embox మధ్య మొదటి ప్యాకేజీలను చూశాను మరియు ధ్వనిని విన్నాను! కానీ ధ్వని భయంకరంగా ఉంది, QEMUలో లాగా లేదు, ఏమీ వినబడలేదు. అప్పుడు విషయం ఏమిటని మేము ఆలోచించాము. ఆడియో బఫర్‌లను పూరించడానికి/అన్‌లోడ్ చేయడానికి Emboxకి సమయం లేదని డీబగ్గింగ్ చూపింది. pjsip ఒక ఫ్రేమ్‌ను ప్రాసెస్ చేస్తున్నప్పుడు, బఫర్ ప్రాసెసింగ్ పూర్తి చేయడం గురించి 2 అంతరాయాలు సంభవించాయి, ఇది చాలా ఎక్కువ. స్పీడప్ కోసం నా మొదటి ఆలోచన కంపైలర్ ఆప్టిమైజేషన్, కానీ అది ఇప్పటికే PJSIPలో చేర్చబడింది. రెండవది హార్డ్‌వేర్ ఫ్లోటింగ్ పాయింట్, మేము దాని గురించి మాట్లాడాము వ్యాసం. కానీ ఆచరణలో చూపినట్లుగా, FPU వేగంలో గణనీయమైన పెరుగుదలను అందించలేదు. తదుపరి దశ థ్రెడ్ ప్రాధాన్యతలను సెట్ చేయడం. Embox విభిన్న షెడ్యూలింగ్ వ్యూహాలను కలిగి ఉంది మరియు నేను ప్రాధాన్యతలను సపోర్ట్ చేసేదాన్ని ఎనేబుల్ చేసాను మరియు ఆడియో స్ట్రీమ్‌లకు అత్యధిక ప్రాధాన్యత ఇచ్చాను. ఇది కూడా సహాయం చేయలేదు.

తదుపరి ఆలోచన ఏమిటంటే, మేము బాహ్య మెమరీతో పని చేస్తున్నాము మరియు చాలా తరచుగా యాక్సెస్ చేయబడిన నిర్మాణాలను అక్కడికి తరలించడం మంచిది. నేను ఎప్పుడు మరియు దేని క్రింద ప్రాథమిక విశ్లేషణ నిర్వహించాను simple_pjsua జ్ఞాపకశక్తిని కేటాయిస్తుంది. 190 KBలో, మొదటి 90 KB PJSIP యొక్క అంతర్గత అవసరాల కోసం కేటాయించబడింది మరియు చాలా తరచుగా యాక్సెస్ చేయబడదు. తర్వాత, ఇన్‌కమింగ్ కాల్ సమయంలో, pjsua_call_answer ఫంక్షన్ అంటారు, దీనిలో ఇన్‌కమింగ్ మరియు అవుట్‌గోయింగ్ ఫ్రేమ్‌లతో పని చేయడానికి బఫర్‌లు కేటాయించబడతాయి. ఇది ఇంకా 100 KB ఉంది. ఆపై మేము ఈ క్రింది వాటిని చేసాము. కాల్ చేసే వరకు, డేటా బాహ్య మెమరీలో నిల్వ చేయబడుతుంది. కాల్ రింగ్ అయిన వెంటనే, మేము వెంటనే RAMలో మరొకదానితో కుప్పను భర్తీ చేస్తాము. అందువలన, అన్ని "హాట్" డేటా వేగంగా మరియు మరింత ఊహాజనిత మెమరీకి బదిలీ చేయబడింది.

ఫలితంగా, ఇవన్నీ కలిసి మాకు లాంచ్ చేయడానికి అనుమతించాయి simple_pjsua మరియు మీ సర్వర్ ద్వారా కాల్ చేయండి. ఆపై sip.linphone.org వంటి ఇతర సర్వర్‌ల ద్వారా.

కనుగొన్న

చివరికి లాంచ్ చేయడం సాధ్యమైంది simple_pjsua సర్వర్ ద్వారా రెండు దిశలలో వాయిస్ ట్రాన్స్‌మిషన్‌తో. అదనపు 128 KB SDRAMతో ఉన్న సమస్యను కొంచెం శక్తివంతమైన Cortex-M7 (ఉదాహరణకు, 32 KB RAMతో STM769F512NI) ఉపయోగించడం ద్వారా పరిష్కరించవచ్చు, కానీ మేము ఇంకా 256 KBలో అమర్చాలనే ఆశను వదులుకోలేదు :) ఎవరైనా ఆసక్తి కలిగి ఉంటే సంతోషించండి లేదా ఇంకా మెరుగ్గా ప్రయత్నించండి. అన్ని మూలాధారాలు, ఎప్పటిలాగే, మాలో ఉన్నాయి రిపోజిటరీలు.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి