SIP հեռախոս STM32F7-Discovery-ում

Բարեւ բոլորին

Քիչ առաջ մենք писали այն մասին, թե ինչպես մեզ հաջողվեց գործարկել SIP հեռախոս STM32F4-Discovery-ում 1 ՄԲ ROM-ով և 192 ԿԲ RAM-ով)՝ հիմնված Embox. Այստեղ պետք է ասել, որ այդ տարբերակը մինիմալ էր և միացնում էր երկու հեռախոս անմիջապես առանց սերվերի և ձայնի փոխանցմամբ միայն մեկ ուղղությամբ։ Հետևաբար, մենք որոշեցինք գործարկել ավելի ամբողջական հեռախոս՝ սերվերի միջոցով զանգով, ձայնի փոխանցում երկու ուղղություններով, բայց միևնույն ժամանակ պահպանելով հնարավոր ամենափոքր հիշողության չափը:


Հեռախոսի համար որոշվեց ընտրել հավելված պարզ_պջսուա որպես PJSIP գրադարանի մաս: Սա նվազագույն հավելված է, որը կարող է գրանցվել սերվերում, ստանալ և պատասխանել զանգերին: Ստորև ես անմիջապես կտամ նկարագրությունը, թե ինչպես գործարկել այն STM32F7-Discovery-ում:

Ինչպես վազել

  1. Embox-ի կարգավորում
    make confload-platform/pjsip/stm32f7cube
  2. Սահմանեք անհրաժեշտ SIP հաշիվը conf/mods.config ֆայլում:
    
    include platform.pjsip.cmd.simple_pjsua_imported(
        sip_domain="server", 
        sip_user="username",
        sip_passwd="password")
    

    որտեղ սերվեր SIP սերվեր է (օրինակ՝ sip.linphone.org), օգտագործողի անունը и Գաղտնաբառ - հաշվի օգտանունը և գաղտնաբառը:

  3. Embox-ի թիմային հավաքում անել. Տախտակի որոնվածի մասին, որը մենք ունենք վիքի իսկ Հոդված.
  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:[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 խոսափողերի մեջ: Մենք զանգում ենք Linux-ից simple_pjsua, pjsua հավելվածի միջոցով։ Դե, կամ կարող եք օգտագործել ցանկացած այլ տեսակի հեռախոս:

Այս ամենը նկարագրված է մեր վիքի.

Ինչպես հասանք այնտեղ

Այսպիսով, ի սկզբանե հարց էր ծագում ապարատային հարթակ ընտրելու մասին։ Քանի որ պարզ էր, որ STM32F4-Discovery-ը հիշողությունից չի տեղավորվի, ընտրվեց STM32F7-Discovery-ը: Նա ունի 1 ՄԲ ֆլեշ կրիչ և 256 ԿԲ RAM (+ 64 հատուկ արագ հիշողություն, որը մենք նույնպես կօգտագործենք): Նաև շատ չէ սերվերի միջոցով զանգերի համար, բայց մենք որոշեցինք փորձել տեղավորվել:

Պայմանականորեն իրենց համար առաջադրանքը բաժանվեց մի քանի փուլերի.

  • PJSIP-ի գործարկում QEMU-ում: Դա հարմար էր վրիպազերծման համար, գումարած, մենք այնտեղ արդեն աջակցություն ունեինք AC97 կոդեկի համար:
  • Ձայնի ձայնագրում և նվագարկումը QEMU-ում և STM32-ում:
  • Հավելվածի տեղափոխում պարզ_պջսուա PJSIP-ից: Այն թույլ է տալիս գրանցվել SIP սերվերում և զանգեր կատարել:
  • Տեղադրեք ձեր սեփական Asterisk վրա հիմնված սերվերը և փորձարկեք դրա վրա, այնուհետև փորձեք արտաքինը, ինչպիսին է sip.linphone.org-ը:

Embox-ում ձայնն աշխատում է Portaudio-ի միջոցով, որն օգտագործվում է նաև PISIP-ում: Առաջին խնդիրները հայտնվեցին QEMU-ում. WAV-ը լավ էր խաղում 44100 Հց հաճախականությամբ, բայց 8000-ում ինչ-որ բան ակնհայտորեն սխալ էր: Պարզվեց, որ խոսքը հաճախականությունը դնելու մասին է - սարքավորման մեջ լռելյայն 44100 էր, ու սա ծրագրային առումով չէր փոխվում։

Այստեղ, թերեւս, արժե մի փոքր բացատրել, թե ընդհանրապես ինչպես է հնչում ձայնը։ Ձայնային քարտը կարող է սահմանվել հիշողության մի հատվածի ինչ-որ ցուցիչի վրա, որտեղից ցանկանում եք նվագարկել կամ ձայնագրել կանխորոշված ​​հաճախականությամբ: Բուֆերի ավարտից հետո ստեղծվում է ընդհատում և կատարումը շարունակվում է հաջորդ բուֆերի հետ: Փաստն այն է, որ այս բուֆերները պետք է նախապես լրացվեն, մինչ նախորդը խաղարկվում է: Մենք այս խնդրին հետագայում կբախվենք STM32F7-ում:

Հաջորդը, մենք վարձեցինք սերվեր և տեղադրեցինք Asterisk-ը դրա վրա: Քանի որ անհրաժեշտ էր շատ կարգաբերել, բայց ես չէի ուզում շատ խոսել խոսափողի մեջ, անհրաժեշտ էր ավտոմատ նվագարկում և ձայնագրում: Դա անելու համար մենք կարկատեցինք simple_pjsua-ն, որպեսզի ձայնային սարքերի փոխարեն կարողանաք սայթաքել ֆայլեր: PJSIP-ում դա արվում է բավականին պարզ, քանի որ նրանք ունեն պորտի գաղափարը, որը կարող է լինել կամ սարք կամ ֆայլ: Եվ այս նավահանգիստները կարող են ճկուն միանալ այլ նավահանգիստների հետ: Կոդը կարող եք տեսնել մեր pjsip-ում պահոցներ. Արդյունքում սխեման հետևյալն էր. Asterisk սերվերի վրա ես բացեցի երկու հաշիվ՝ Linux-ի և Embox-ի համար: Հաջորդը, հրամանը կատարվում է Embox-ում simple_pjsua_imported, Embox-ը գրանցված է սերվերի վրա, որից հետո մենք զանգում ենք Embox-ը Linux-ից։ Միացման պահին Asterisk սերվերում ստուգում ենք, որ կապը հաստատված է, և որոշ ժամանակ անց Embox-ում պետք է ձայն լսենք Linux-ից, իսկ Linux-ում պահպանում ենք Embox-ից նվագարկվող ֆայլը։

Այն բանից հետո, երբ այն աշխատեց QEMU-ի վրա, մենք անցանք STM32F7-Discovery-ի տեղափոխմանը: Առաջին խնդիրն այն է, որ դրանք չեն տեղավորվում 1 ՄԲ ROM-ի մեջ՝ առանց նկարի չափի համար միացված կոմպիլյատորների օպտիմալացման «-Os»: Դրա համար մենք ներառել ենք «-Os»-ը։ Ավելին, կարկատումն անջատեց C ++-ի աջակցությունը, ուստի այն անհրաժեշտ է միայն 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-ի (Serial Audio Interface) միջոցով՝ համաժամանակյա աուդիո մուտքի հետ (ես չհասկացա մանրամասները, բայց պարզվում է, որ նրանք կիսում են ընդհանուր ժամացույցը և երբ աուդիո ելքը սկզբնավորվում է, աուդիոն ինչ-որ կերպ կցված է դրա մուտքին): Այսինքն, դուք չեք կարող դրանք գործարկել առանձին, ուստի մենք արեցինք հետևյալը. աուդիո մուտքը և աուդիո ելքը միշտ աշխատում են (ներառյալ ընդհատումները ստեղծվում են): Բայց երբ համակարգում ոչինչ չի նվագարկվում, մենք պարզապես դատարկ բուֆեր ենք մտցնում աուդիո ելքի մեջ, և երբ նվագարկումը սկսվում է, մենք անկեղծորեն սկսում ենք լրացնել այն:

Ավելին, մենք հանդիպեցինք այն փաստին, որ ձայնի ձայնագրման ժամանակ ձայնը շատ հանգիստ էր։ Դա պայմանավորված է նրանով, որ STM32F7-Discovery-ի MEMS խոսափողները լավ չեն աշխատում 16000 Հց-ից ցածր հաճախականություններում: Հետեւաբար, մենք սահմանում ենք 16000 Հց, նույնիսկ եթե 8000 Հց է գալիս: Դա անելու համար, սակայն, անհրաժեշտ էր ավելացնել մեկ հաճախականության ծրագրային փոխակերպում մյուսին:

Հաջորդը, ես ստիպված էի մեծացնել կույտի չափը, որը գտնվում է RAM-ում: Ըստ մեր հաշվարկների, pjsip-ը պահանջում էր մոտ 190 ԿԲ, իսկ մեզ մնում է մոտ 100 ԿԲ: Այստեղ ես ստիպված էի օգտագործել որոշ արտաքին հիշողություն՝ SDRAM (մոտ 128 ԿԲ):

Այս բոլոր խմբագրումներից հետո ես տեսա առաջին փաթեթները Linux-ի և Embox-ի միջև և լսեցի ձայնը: Բայց ձայնը սարսափելի էր, ամենևին էլ նույնը չէր, ինչ QEMU-ում, անհնար էր որևէ բան պարզել։ Հետո մտածեցինք, թե ինչ կարող էր լինել։ Վրիպազերծումը ցույց տվեց, որ Embox-ը պարզապես ժամանակ չունի աուդիո բուֆերները լցնելու/բեռնաթափելու համար: Մինչ pjsip-ը մշակում էր մեկ կադր, բուֆերային մշակման ավարտի համար 2 ընդհատում էր առաջացել, ինչը չափազանց շատ է: Արագության առաջին միտքը կոմպիլյատորների օպտիմալացումն էր, բայց այն արդեն ներառված էր PJSIP-ում: Երկրորդը ապարատային լողացող կետն է, մենք դրա մասին խոսեցինք Հոդված. Բայց ինչպես ցույց է տվել պրակտիկան, FPU-ն արագության զգալի աճ չի տվել: Հաջորդ քայլը թելերի առաջնահերթություն տալն էր: Embox-ն ունի պլանավորման տարբեր ռազմավարություններ, և ես ներառել եմ մեկը, որն աջակցում է առաջնահերթություններին և սահմանում է աուդիո հոսքերը ամենաբարձր առաջնահերթության վրա: Սա էլ չօգնեց։

Հաջորդ գաղափարն այն էր, որ մենք աշխատում ենք արտաքին հիշողության հետ, և լավ կլիներ այնտեղ տեղափոխել այնպիսի կառույցներ, որոնց հասանելի են չափազանց հաճախ: Նախնական վերլուծություն եմ արել, թե երբ և ինչի տակ պարզ_պջսուա հատկացնում է հիշողություն. Պարզվեց, որ 190 ԿԲ-ից առաջին 90 Կբ-ը հատկացվում է PJSIP-ի ներքին կարիքներին և դրանց հասանելիությունը այնքան էլ հաճախ չէ: Ավելին, մուտքային զանգի ժամանակ կանչվում է pjsua_call_answer ֆունկցիան, որում բուֆերներն այնուհետև հատկացվում են մուտքային և ելքային շրջանակների հետ աշխատելու համար: Այն դեռ մոտ 100 Կբ էր։ Եվ հետո մենք արեցինք հետևյալը. Մինչև զանգի պահը տվյալները տեղադրում ենք արտաքին հիշողության մեջ։ Զանգի անմիջապես կույտը փոխարինում ենք մեկ այլով՝ RAM-ով: Այսպիսով, բոլոր «թեժ» տվյալները փոխանցվեցին ավելի արագ և կանխատեսելի հիշողություն:

Արդյունքում այս ամենը միասին հնարավոր դարձրեց գործարկել պարզ_պջսուա և զանգահարեք ձեր սերվերի միջոցով: Եվ հետո այլ սերվերների միջոցով, ինչպիսիք են sip.linphone.org-ը:

Արդյունքները

Արդյունքում հնարավոր եղավ գործարկել պարզ_պջսուա սերվերի միջոցով երկու ուղղություններով ձայնի փոխանցմամբ: Լրացուցիչ ծախսված 128 ԿԲ SDRAM-ի հետ կապված խնդիրը կարող է լուծվել՝ օգտագործելով մի փոքր ավելի հզոր Cortex-M7 (օրինակ՝ STM32F769NI 512 ԿԲ օպերատիվ հիշողությամբ), բայց միևնույն ժամանակ, մենք դեռ հույս չենք կորցրել 256-ի մեջ մտնելու համար: KB 🙂 Մենք ուրախ կլինենք, եթե ինչ-որ մեկին հետաքրքրի, Կամ ավելի լավ է, փորձեք: Բոլոր աղբյուրները, ինչպես միշտ, մեր մեջ են պահոցներ.

Source: www.habr.com

Добавить комментарий