Teade

Collapse

Foorumi reeglid.

Foorumi reeglistik on uuendatud. Palume tutvuda ja arvesse võtta.
See more
See less

Katkestus funktsiooni täitmise ajal; AVRStudio, C

Collapse
X
 
  • Filter
  • Kellaaeg
  • Show
Clear All
new posts

    Katkestus funktsiooni täitmise ajal; AVRStudio, C

    Väike probleem C-keelse koodiga (ATmega644P, AVRStudio).

    Probleemi sisuline külg seisneb funktsiooni täitmise ajal katkestuse ilmnemises. Kui funktsioonis sisalduv aga main'i lahti kirjutada, töötab korralikult.

    Programmitekst.
    Kood:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    
    volatile unsigned char b;
    
    void punkt(unsigned char b)
    {
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 2 && b != 0)
        {
            PORTD |= (1 << 5);
        }
    }
    
    void kriips(unsigned char b)
    {
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 4 && b != 0)
        {
            PORTD |= (1 << 5);
        }
    }
    
    void paus(unsigned char b)
    {
        b = 0;
        while(b < 3)
        {
            PORTD &= ~(1 << 5);
        }
    }
    
    ISR(TIMER0_OVF_vect)
    {
        b++;
        sei();
    }
    
    int main(void)
    {
        DDRD = 0xFF;
        
        sei();
    
        TIMSK0 = 0b00000001;    // Taimer0 katkestused
        TCCR0A = 0x00;
        TCCR0B = 0b00000101;    // Taimer0 --> CK / 1024
        TCNT0 = 0;
        
        punkt(b);
        punkt(b);
        punkt(b);
        kriips(b);
        paus(b);
        
        /*
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 2 && b != 0)
        {
            PORTD |= (1 << 5);
        }
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 2 && b != 0)
        {
            PORTD |= (1 << 5);
        }
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 2 && b != 0)
        {
            PORTD |= (1 << 5);
        }
        b = 0;
        while(!b)
        {
            PORTD &= ~(1 << 5);
        }
        while(b < 4 && b != 0)
        {
            PORTD |= (1 << 5);
        }
        */
        
        asm volatile("Loop:"::);
        asm volatile("rjmp Loop"::);
    }
    Antud programm peaks väljastama viigule PD5 morsemärke (väike osa palju-palju mahukamast programmist). Kavatsus on pärast algväärtustamisi kutsuda välja mõni funktsioon ning püsida neis paiknevais while-tsüklites kuni tekib taimeri ületäitumine. Muutujaga unsigned char b määratakse, kas on pisike pausikene punktide-kriipsude vahel (PD5 madal) või "punkt/kriips kestab" (PD5 kõrge).

    Paraku ei teki soovitud tulemust ei reaalsuses ega AVRStudio simulaatoris (mõlemal juhul optimeerimata kood). Sisenedes "Step Into'ga" reale punkt(b);, peatub simulatsioon katkestusvektori alguses (Cycle Counter ca 262000), pärast katkestuse täitmist peatub simulatsioon uuesti samas kohas jne, jne. Mida aga ei juhtu, on muutus PD5-l.

    Kui kasutada maha kommenteeritud ridu (ja eemaldada funktsioonide kirjeldused ning väljakutsed), töötab kõik korralikult.

    Isegi kui viimase meetodi kasutamisel mälust puudu ei tule, pole kohane niisugust lahendust heaks kiita (ühest küljest on nimetatud funktsioone plaanis mitmeid kordi üha uuesti ja uuesti välja kutsuda, teisest küljest ei ole hea tehnikaalades niisuguseid "pisiasju" selgeks tegemata jätta).

    Karta on, et tegu võib olla mõne C ja AVRStudio omavahelise koostöö iseärasusega, kuid omal jõul, tundub, probleemist jagu ei saa.
    Öeldakse: "Esialgsed operatsioonilised testid olid ebaveenvad..."
    Seejuures mõeldakse: "Pauk käis, kui sisse lülitasime..."

    #2
    Re: Katkestus funktsiooni täitmise ajal; AVRStudio, C

    probleem ongi selles, et optimeerimata kood ei tööta alati nii nagu peab. proovi 0s optimisatsiooniga ja anna tulemustest teada

    Comment


      #3
      Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

      probleem selles et kasutad sama muutujanime "b" nii globaalsena kui funktsioonis . standard ütleb et funktsioonis defineeritu on eesõigusega, ja nii seal funktsioonis seisabki b väärtus alati null .
      tee funktsioonid ümber ilma sisendparameetrita kujule ntx: void punkt ( void )
      ja peaks töötama.
      viimati muutis kasutaja raivo; 15 m 2009, 11:31.

      Comment


        #4
        Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

        Mis puutub optimeerimisse, siis sai selle koha pealt veidi puusse pandud. Tont teab, mis ajast oligi jäänud AVRStudio'le -Os seade (üldiselt olen kasutanud vaid -O0 ja ei tulnud selle pealegi, et vahepeal seda muutnud olin). Siiski, vahet ei ole, kuna tulemus nii simulaatoris kui reaalsuses sama (vähemalt soovitud tulemuse puudumise põhjal). Samas tunduski imelik, miks hakkab simulaator järsku toimetama mitte "Step Into", vaid "Run" stiilis, nagu seda optimisatsiooni puhul ette tuleb.


        Globaalsena saigi char b deklareeritud, et oleks võimalik selle väärtust katkestuse korral muuta, olin ka eelnevalt kaalunud ilma sisendparameetriteta funktsioonide kasutamist, kuid ei suutnud välja mõelda sobivat algoritmi.

        Üritades vältida char b funktsioonisisest defineerimist alljärgnevalt:

        Kood:
        void punkt(unsigned char b)
        {
            //b = 0;
            while(!b)
            {
                PORTD &= ~(1 << 5);
            }
            while(b < 2 && b != 0)
            {
                PORTD |= (1 << 5);
            }
        }
        
        int main(void)
        {
        //...
            b = 0;
            punkt(b);
            b = 0;
            punkt(b);
            // jne
        //...
        }
        ei saa ka (vähemalt simulatsioonis) soovitud tulemust.

        Tagantjärele mõeldes võib ju kasutada muutuja asemel sobivat sisend-väljundregistrit, mida antud programmiosas niikuinii ei kasutata ja mille muutmine soovimatuid tagajärgi kaasa ei too. Samas on see ikkagi veidi kohatu lahendus.

        Teine võimalus näib olevat assemblerikeelseid käske kasutada "b väärtust" otse kindlasse registrisse kirjutades.
        Öeldakse: "Esialgsed operatsioonilised testid olid ebaveenvad..."
        Seejuures mõeldakse: "Pauk käis, kui sisse lülitasime..."

        Comment


          #5
          Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

          avr'i C'ga pole kokku puutund, aga nö tava C mõistes on asi vigane.
          void punkt(unsigned char b) asemel peaks olema ikka: void punkt(void) kui tahad globaalset muutujat näha funktsiooni sees või siis anna funktsioonile sisse pointer muutujale, mitte ära defineeri uut nagu praegu.

          edit: ja b=0; pole defineerimine vaid väärtuse omistamine, uue muutuja defineerimine on ikka: void punkt(unsigned char b), see tuleb asendada, (selle "unsigned char b" ütled ju, et nüüd on sul funktsiooni sees kasutusel uus lokaalne muutuja b ja globaalset sa ei näe niisama enam.)

          Comment


            #6
            Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

            Tänud, tundub, et nüüd peaks töötama.

            Kood:
            unsigned char b;
            unsigned char *p;
            
            void punkt(void)
            {
                *p = 0;
                while(!*p)
                {
                    PORTD &= ~(1 << 5);
                }
                while(*p < 2 && *p != 0)
                {
                    PORTD |= (1 << 5);
                }
            }
            
            ISR(TIMER0_OVF_vect)
            {
                (*p)++;
                sei();
            }
            
            int main(void)
            {
                //...
                p = &b;
                //...
                punkt();
                punkt();
                //...
            }
            Võttis küll teatava aja, kuna nullilähedaste kokkupuudetega viitadega pole just kerge leida üles viga *p++; ja (*p)++; põhjal.
            Öeldakse: "Esialgsed operatsioonilised testid olid ebaveenvad..."
            Seejuures mõeldakse: "Pauk käis, kui sisse lülitasime..."

            Comment


              #7
              Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

              Njah, ma pidasin silmas, et kood võiks näha välja umbes nii:

              Kood:
              volatile unsigned char b;
              
              void punkt(void)
              {
                  b = 0;
                  while(!b)
                  {
                      PORTD &= ~(1 << 5);
                  }
                  while(b < 2 && b != 0)
                  {
                      PORTD |= (1 << 5);
                  }
              }
              
              int main(void)
              {
                  ...
                  punkt();
                  ...
              
              }
              või siis umbes nii:

              Kood:
              volatile unsigned char b;
              
              void punkt(unsigned char *p)
              {
                  *p = 0;
                  while(!*p)
                  {
                      PORTD &= ~(1 << 5);
                  }
                  while(*p < 2 && *p != 0)
                  {
                      PORTD |= (1 << 5);
                  }
              }
              
              int main(void)
              {
                  ...
                  punkt(&b);
                  ...
              
              }

              Comment


                #8
                Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                optimaator on igas compileris saatanast, kui probleemid siis välja. See koristab osa su koodi nii ära et ise ei saa arugi. Optimeeri kui tõesti vajalik(miski ajakriitiline,koodi ruumi vähe vms), pigem tee ise manuaalselt(eeldab et oskad), võtab vähem aega kui optimaatorile selgeks tegemine mida teha tahad.
                Simulaator=ma pole ühtegi simulaatorit näinud mis töötaks, kõik mõnest kohast bugised. Risk et bug simulaatoris veel üks probleemne koht lisaks enda koodimis vigadele. Debuggerist saan veel aru kus saad mälus olevaid parameetreid jälgida. aga muidu reaalne raud siis töötab.
                Soovitan ka panna muutujatele vähe pikemad nimed ja vältida koopiaid siis pole ka muret et miskil funktsioonil eesõigus vms.

                Ma ei kasuta mitte ühtegi simulaatorit debug port on USART ja/või LCD kui see prjektis olemas. Ei pea debugima debuggerit või simulaatorit vaid juba reaalset asja. Proset ka ei vali hypersäästu, panen 2-3 eeka juurde saan rammusama.
                Kui prose hind pole teema ja jõudlust on jätangi debug info porti, siis ei pea service olukorras mõtlema hakkama, usb järgi ja kohe selge.
                Modelleerimises ja tootmises kehtivad:
                1. Avariikindel vooluring lühistab kõik teised.
                2. Transistor, millel on kiiresti toimiv kaitse, säästab kaitset, sulades kõigepealt ise.

                Comment


                  #9
                  Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                  Esmalt postitatud murphy poolt
                  optimaator on igas compileris saatanast, kui probleemid siis välja. See koristab osa su koodi nii ära et ise ei saa arugi. Optimeeri kui tõesti vajalik(miski ajakriitiline,koodi ruumi vähe vms), pigem tee ise manuaalselt(eeldab et oskad), võtab vähem aega kui optimaatorile selgeks tegemine mida teha tahad.
                  Ära nüüd optimeerijat päris maha ka tee, vahest on temast ikka abi. Mis kalad sul on sellega olnud?
                  If you think education is expensive, try ignorance.

                  Comment


                    #10
                    Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                    Jään vist oma viimase variandi juurde, kui sealt vigu ei leia. Tänud siiski Spiritile toodud näidete eest. Kuluvad ära, kui mitte mujal, siis C-ga suuremaks sõbraks saamisel.

                    Mis puutub optimeerimisse, siis kõnealust tegevust olengi üritanud vältida, kuid eelkõige seetõttu, et vähemalt AVRStudio võimaldab -O0-ga arusaadavamalt programmi tööd simuleerida (korra vist on esinenud registriga CLKPR probleeme – nõutud väärtuse kirjutamine 4 takti jooksul).

                    Simulaatori mittetöötamist olen ka ise näinud ATmega162 16-bitise taimeri puhul. Siiski on väheste kogemuste puhul simulaatorist pigem abi, kuna enamikel juhtudel leiab selle abil lihtsa koodi korral (keerulist veel ei kirjuta) vea üles. Korra vähemalt on tulnud ka "rauas" vigade otsimist ette stiilis "kui muutujal lõpuks kõigest hoolimata õiges kohas õige väärtus on, siis südamerahustuseks valgusdioodike põlema".
                    Öeldakse: "Esialgsed operatsioonilised testid olid ebaveenvad..."
                    Seejuures mõeldakse: "Pauk käis, kui sisse lülitasime..."

                    Comment


                      #11
                      Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                      Optimeerija koristab ära while asjad.
                      Teeb miskit maagiat sunktsiooni sisemiste muutujatega nii et asi ei tagasta enam õiget asja.
                      Koristab ära kindlale adrele määratud funktisoonid mida kood tegelt ei kasuta(Näiteks bootloader, mõned raua funktsioonid mis flashis kasutab neid pärast ramis käima tõmmatav exe.)
                      Neid kalasid on veel. Ma ei jõua alati talle ette sööta et ära nüüd seda või toda muutujat/funktsiooni näpi.
                      Tõsi võib ju igale poole kirjutada volatile. Lihtsam aga minu arust kood käsitsi ära optimeerida.
                      Need kogemused eelkõige WINARM nimelise compileriga.
                      Modelleerimises ja tootmises kehtivad:
                      1. Avariikindel vooluring lühistab kõik teised.
                      2. Transistor, millel on kiiresti toimiv kaitse, säästab kaitset, sulades kõigepealt ise.

                      Comment


                        #12
                        Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                        Esmalt postitatud murphy poolt
                        Optimeerija koristab ära while asjad.
                        86. oli meil 1. PC togida.
                        Kirjutasime masmis. Siis saime C translaatori.
                        Avastasime, et osa meie exe programme on samas C-s kirjutatud.
                        Hakkasime siis kirjutame exe to C disC-id.

                        Mäletan et While ja If (või oli ??, ikkagi üle 20 aastat tagasi)
                        olid täpselt ühesuguse binari koodiga.
                        Siis me jälgisime seda binarit juba disasm koodis.

                        Microdele oli ju ka disasm olemas.
                        Võib seda binkoodi vaadata ja vead ülesse otsida.
                        Ja siis translaator ära parandada.

                        Mina ise olen masmi juures tagasi. Vähemalt micro juures.

                        Comment


                          #13
                          Vs: Katkestus funktsiooni täitmise ajal; AVRStudio, C

                          Märgusõnaga "volatile" märgistatakse katkestusfunktsioonide ja peaprogrammi vahelise suhtlemise muutujad. Niiviisi on just asi selgem.

                          Kasutan kogu aeg optimeerimist (gcc-l võti -O2, microsofti kompilaatoritel omad) ja asjad toimivad, ei kurda üldse.
                          If you think education is expensive, try ignorance.

                          Comment

                          Working...
                          X