AMcoder - javascript, python, java, html, php, sql

UART DMA Tx/Rx Architecture [կրկնօրինակ]

Հնարավոր կրկնօրինակ՝
UART ISR Tx Rx Architecture

Ես հենց հիմա աշխատում եմ TI micro-ի հետ, որը ներառում է DMA UART Driver և օպերացիոն համակարգ, որն աջակցում է զուգահեռ առաջադրանքներին: UART վարորդի գործառույթները ներառում են.

  • ստատիկ դատարկություն HalUARTInitDMA(void);
  • static void HalUARTOpenDMA(halUARTCfg_t *config);
  • ստատիկ uint16 HalUARTReadDMA(uint8 *buf, uint16 len);
  • ստատիկ uint16 HalUARTWriteDMA(uint8 *buf, uint16 len);
  • ստատիկ դատարկություն HalUARTPollDMA(անվավեր);
  • ստատիկ uint16 HalUARTRxAvailDMA(անվավեր);
  • static void HalUARTSuspendDMA(void);
  • static void HalUARTResumeDMA(void);

Ես փորձում եմ շփվել մեկ այլ ծայրամասային սարքի հետ, որն ընդունում է հաղորդագրությունները, որոնք ավարտվում են փոխադրման հետադարձով և այնուհետև պատասխանում է հաղորդագրություններով՝ փոխադրման վերադարձով:

Ինձ հետաքրքրում էր, թե որն է այս տեսակի կապի պետական ​​մեքենայի ճարտարապետության լավագույն միջոցը: Իմ խնդիրը UART նավահանգստի համար հետադարձ զանգի ֆունկցիան նախագծելն է այնպես, որ այն...

  1. չի կախում համակարգը՝ սպասելով պատասխանի: (Ինչ-որ ժամանակամիջոց)
  2. Եթե ​​պատասխանը շատ շուտ կարդացվի, այն կմիավորի պատասխանները
  3. Փոխադրման վերադարձը կնշանակի հաղորդագրության ավարտը

Հիմնական տեսությունը մոտավորապես այսպիսին է.

//send messsage to peripheral
HalUARTWriteDMA("tx\r",4);

//wait a little bit for the device to process the message

//start reading from the peripheral    
do {
    //how many bytes are at the RX port?
    int len = HalUARTRxAvailDMA();

    //Read those bytes
    HalUARTReadDMA(msg, len);

    //append the rx msg to the buffer
    strcat(rxbuf, msg)

    //does the response contain a CR?
} while(strchr(rxbuf, 0x0D));

Այս գաղափարի մեջ կան մի քանի ակնհայտ թերություններ. Ես հուսով էի, որ ինչ-որ մեկը կարող է կիսվել որոշ գաղափարներով, թե ինչպես է իրականացվում այս տեսակի հաղորդակցությունը:

Շնորհակալություն


  • Հիմնական ալգորիթմը լավ է, հատկապես այն գործարկելու համար (պահեք այն պարզ); Իդեալում, սա կիրականացվի որպես ISR, որը գործարկվում է UART-ում տվյալների ժամանման ժամանակ (գուցե դա այդպես է, չի կարելի ասել կոդից), այնպես որ դուք անընդհատ չեք պտտվում տվյալների ժամանման ժամանակ: Նույնիսկ եթե կա կանխարգելիչ ՕՀ, որը թույլ չի տալիս, որ շարանը չխոչընդոտի պրոցեսորին, դուք առնվազն անհրաժեշտից ավելի շատ էներգիա կծախսեք: Առնվազն, դուք կարող եք տեղադրել sleep() հանգույցում, որպեսզի նվազեցնեք պրոցեսորի/էլեկտրաէներգիայի օգտագործումը և մշակեք միայն 2-րդ 2 տողերը, եթե len › 0: Մի քանի տարվա ընթացքում ներկառուցված չէ, ուստի սա մեկնաբանություն չէ, պատասխան չէ: -) 22.10.2012
  • Այսպիսով, հենց հիմա, DMA վարորդի հետ, կա հետադարձ զանգի գործառույթ, որը կանչվում է UART հաղորդագրության ժամանումից հետո: Չնայած սա չի օգտագործում ISR-ը, ես զգում եմ, որ դա նման է այն բանին, թե ինչպես է ISR-ն իրականացվում: Դեռևս մտքումս է այն միտքը, թե արդյոք ես պետք է հրաժարվեմ DMA-ից և կիրառեմ ISR՝ հանուն պարզության: 22.10.2012
  • Ունե՞ք ՕՀ՝ թելերով և սեմաֆորներով: 23.10.2012
  • TI-ի կողմից տրամադրված ՕՀ-ն ունի թելեր, բայց չունի սեմաֆորներ կամ մուտեքսներ: Նրանք բացատրում են, որ ՕՀ-ն վարում է թելերը «կլոր ռոբին» մոտեցմամբ, այնպես որ, եթե դուք որոշ ժամանակ (1){} դնեք դրանցից մեկում, դա կհանգեցնի բոլոր շղթաների դադարեցմանը: Սա ստիպում է ինձ հավատալ, որ նոր թեմա չի սկսվի այնքան ժամանակ, քանի դեռ նախորդ թեմա չի ավարտվել: 23.10.2012
  • Այս հարցը տալուց շաբաթներ անց, ես վերջացրի այն վերափոխել եմ և դրա մասին հիանալի քննարկում ունեցա այստեղ՝ stackoverflow.com/questions/13520272/ 03.12.2012
  • Հարցը, որը նշված է որպես կրկնօրինակ, ոչ մի կապ չունի DMA-ի հետ, որն այստեղ հիմնական կետն է: 10.07.2013

Պատասխանները:


1

Դիզայնի հետ կապված մեկ անմիջական խնդիր կա, ինչպես նկարագրում եք այն, եթե մտադիր եք արգելափակել հաղորդագրությունների սպասող շարանը, որը փոփոխական չափի հաղորդագրությունների օգտագործումն է և CR որպես սահմանազատող:

Ես պատկերացնում եմ, որ HalUARTReadDMA()-ը նախատեսված է արգելափակելու կանչող շարանը մինչև len բայթ ստանալը, այնպես որ դուք ակնհայտորեն չեք կարող հուսալիորեն օգտագործել այն փոփոխական երկարությամբ հաղորդագրության արգելափակման համար:

Կոդը նման կլինի (մի քանի ենթադրություններ անելով).

while (1) 
{
    static const size_t bufferSize = sizeof(Message_t);
    uint8_t buffer[bufferSize];

    // blocks until message received 
    unsigned len = HalUARTReadDMA(buffer, bufferSize);

    if (len == bufferSize)
        processMessage(buffer);
}

Չկա առանձնապես գեղեցիկ կամ հուսալի լուծում DMA-ով փոփոխական չափերի հաղորդագրություններ օգտագործելու համար, որը չի ներառում հարցում, քանի դեռ DMA կարգավորիչը չի կարող ձեզ համար հայտնաբերել հաղորդագրության վերջի սահմանազատիչներ:
Եթե չեք կարող փոխել հաղորդագրությունը: ձևաչափով, ավելի լավ կլիներ ընդհատումների վրա հիմնված IO-ն, որտեղ դուք արգելափակում եք հաղորդագրության առանձին բայթերի ընդունումը, հատկապես UART-ի դեպքում, որն ունի տվյալների համեմատաբար ցածր արագություն:

22.10.2012
  • +1 - այո, DMA-ն առանձնապես օգտակար չի հնչում այս նպատակով, հատկապես այդ CR-ով ավարտված հաղորդագրությունների դեպքում :( 23.10.2012

  • 2

    Եթե ​​ձեր DMA դրայվերը չունի ֆունկցիոնալություն՝ ընդունելու բուֆերային ցուցիչների հերթ, կարող է ընդհատում առաջացնել, երբ CR ստացվում է և ինքնուրույն չի անցնում հաջորդ բուֆերային ցուցիչին, դուք ստիպված կլինեք կրկնել rx տվյալները՝ փնտրելով CR.

    Եթե ​​դուք պետք է կրկնեք տվյալները, դուք կարող եք դա անել նաև «դասական» ISR-ում՝ մեկ առ մեկ բերելով նիշերը rx FIFO-ից և դրանք դնելով բուֆերի մեջ, մինչև CR ստացվի:

    Այնուհետև կարող եք բուֆերային ցուցիչը հերթագրել համապատասխան շրջանաձև հերթի մեջ, հաջորդ հաղորդագրության համար մեկ այլ բուֆեր բերել «դատարկ» բուֆերների մեկ այլ շրջանաձև լողավազանի հերթից, ազդանշան տալ սեմաֆորին, որպեսզի այն շարանը, որը պետք է մշակի հաղորդագրությունը, գործարկվի և դուրս գա: ձեր ISR-ից ՕՀ-ի միջոցով, որպեսզի անմիջապես վերադասավորվի:

    Rx շարանը կարող է փակել հաղորդագրությունը, մշակել այն և այնուհետև ուղարկել այն լողավազանի հերթում՝ ISR-ի կողմից նորից օգտագործելու համար:

    Strchr()-ով CR-ի համար ամբողջական բուֆեր փնտրելը, ամենայն հավանականությամբ, առանձնապես արդյունավետ կամ հեշտ չէ. CR-ը կարող է լինել DMA բուֆերի մեջտեղում, և դուք ինքներդ ձեզ ներգրավում եք հիշող մասնակի բուֆերի տվյալների պատճենում:

    .

    22.10.2012
    Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..