delay funktio

C -ohjelma

Kuinka saan tehtyä assemblerilla delay funktion (esim 200ms) c -ohjemaan?

12

2125

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • tjooo...

      Loopissa vaan tarpeeksi monta kertaa esim NOP (No OPeration) käskyä. Sisäkkäisiäkin looppeja voi käyttää.

      Tietysti tällöin ohjelma jököttää 200ms tekemättä mitään hyödyllistä..

      • nop

        Paitsi että tuolla tavalla tehty 'hidastaja' vie eri ajan eritehoisilla prosessoreilla.


      • jooh
        nop kirjoitti:

        Paitsi että tuolla tavalla tehty 'hidastaja' vie eri ajan eritehoisilla prosessoreilla.

        oletetaan että kyseessä on joku sulautettu rauta jossa on vakio taajuinen kide

        tosin nuo looppaamalla tehdyt hidastajat on vähän kökköjä..mitä sitä suotta prosessoritehoa semmoiseen käyttämään? Löytyyhän niitä ajastimiakin.


    • keskytysaliohjelma

      RTC-keskeytykselle. Keskeytysaliohjelma laskee
      sopivan määrän tulleita keskeytyksiä ja nostaa
      lipun.
      Sitten asetat RTC:n keskeyttämään 1024
      kertaa sekunnissa ja keskeytysmaskin säädät
      niin, että RTC-keskeytykset sallitaan.
      Tuskin säästät kovin paljon tekemällä tämän
      assemblerilla.
      Tasan millisekunnin monikertaa tällä tavalla
      ei saada, mutta aika lähelle kuitenkin.

    • ...

      sleep(sekunteja) toimii unixilla (unistd.h?). windowsilla sitten..jotain muuta.

      • ...

        uhh, sori, assylla piti.. silmät ristissä..


    • Anonyymi

      Delay-funktio voidaan luoda kääntämällä assemblerilla yksinkertainen silmukka, joka odottaa tietyn ajanjakson ennen kuin se siirtyy eteenpäin ohjelmassa. Tässä esimerkissä luodaan 200ms viive käyttämällä x86-arkkitehtuurin NASM-assembleria:

      section .data

      delay_time equ 200      ; Viiveaika 200ms

      section .text
      global delay

      delay:
          mov ecx, delay_time   ; Aseta viiveaika rekisteriin
        delay_loop:
          dec ecx               ; Vähennä rekisterin arvoa yhdellä
          jnz delay_loop        ; Toista silmukka, kunnes rekisteri on 0
          ret                   ; Palauta ohjaus ohjelman päävaiheeseen


      Tässä assembler-koodissa delay-funktio luo 200ms viiveen suorittamalla silmukan, joka vähentää rekisterin arvoa yhdellä ja odottaa, kunnes rekisterin arvo on nolla. Sitten funktion ohjaus palautetaan takaisin C-ohjelmaan. Voit kutsua tätä delay-funktiota C-ohjelmassasi seuraavasti:

      extern void delay();    // Esittele delay-funktio

      int main() {
          // Aja delay-funktio viiveen luomiseksi
          delay();

          // Jatka ohjelman suorittamista
          return 0;
      }

      • Anonyymi

        Meinaatko että aloittaja odottelee vastaustasi 19 vuotta?


      • Anonyymi
        Anonyymi kirjoitti:

        Meinaatko että aloittaja odottelee vastaustasi 19 vuotta?

        No, hyvää kannattaa odottaa.


    • Anonyymi

      Ohjelmassa on / tulee olla jokin tick timer -keskeytys, josta viiveet ym. ajoitukset on helppo johtaa. PC-koneissa tällainen keskeytys tikitti aikoinaan n. 55 ms, nyttemmin 1 ms välein. Jossakin sulautetussa järjestelmässä keskeytysintervalli voi olla lyhyempikin, mutta sen kerrannaisten ja nanosekuntiluokan viiveiden (nop-luuppi tms.) väliin jää yleensä hankalasti toteutettava viiveen pituus, joka tyypillisesti ratkeaa vain omalla h/w-timerilla.

      • Anonyymi

        Erittäin lyhyet odottelut voi kannattaa tehdä nop-loopilla. Muistelisin, että avr:ssä nop-käsky on tasan 1 kellojakso ja hyppy siihen takaisn vie 3 kellojaksoa, siispä yksi kierros looppia vie 4 kellokiteen jaksoa. Hiukan pidemmät odottelut voi sitten tehdä h/w-timerilla ilman keskeytysrutiinia. Sitten kun aletaan puhua alle 100-200 keskeytyksestä sekunnissa voi ottaa keskeytysrutiinin käyttöön. Esimerkiksi avr:llä joskus tuli laskettua, että kääntäjä tunkee rutiiniin 68 kellojaksoa koodia ilman, että oma koodi vielä pyörähtää lainkaan: Tämä vie melkoisesti jo kellojaksoja. Nopean rutiinin teko vaatii siis koodin läpikäymistä ja kannattaa mitata rutiinin tyhjäkäyntinopeus eli kuinka nopea kello tarvitaan, jotta rutiinia voidaan kutsua ylipäätään x kertaa sekunnissa.
        http://www.rjhcoding.com/avr-asm-delay-subroutine.php

        avr-gcc toteutuksessa on valmiiksi assembler-toteutus uint8_t tyyppiselle viiveelle. Muistelisin, että tätä on käytetty uint16_t tyyppisessä hyväksi - joskaan rutiini ei ole enää kellojakson tarkka toisin kuin uint8_t:lle oleva rutiini. Tässäkin tosin on yllätyksiä: inline-koodi edellyttää, että ei käytetä size-optimointia, joka lisää viiveisiin funktiokutsujen ajat. Siispä uint16_t loopin pituus menee heti rikki, jos koodin optimointia muutetaan!
        https://www.nongnu.org/avr-libc/user-manual/group__util__delay__basic.html


      • Anonyymi
        Anonyymi kirjoitti:

        Erittäin lyhyet odottelut voi kannattaa tehdä nop-loopilla. Muistelisin, että avr:ssä nop-käsky on tasan 1 kellojakso ja hyppy siihen takaisn vie 3 kellojaksoa, siispä yksi kierros looppia vie 4 kellokiteen jaksoa. Hiukan pidemmät odottelut voi sitten tehdä h/w-timerilla ilman keskeytysrutiinia. Sitten kun aletaan puhua alle 100-200 keskeytyksestä sekunnissa voi ottaa keskeytysrutiinin käyttöön. Esimerkiksi avr:llä joskus tuli laskettua, että kääntäjä tunkee rutiiniin 68 kellojaksoa koodia ilman, että oma koodi vielä pyörähtää lainkaan: Tämä vie melkoisesti jo kellojaksoja. Nopean rutiinin teko vaatii siis koodin läpikäymistä ja kannattaa mitata rutiinin tyhjäkäyntinopeus eli kuinka nopea kello tarvitaan, jotta rutiinia voidaan kutsua ylipäätään x kertaa sekunnissa.
        http://www.rjhcoding.com/avr-asm-delay-subroutine.php

        avr-gcc toteutuksessa on valmiiksi assembler-toteutus uint8_t tyyppiselle viiveelle. Muistelisin, että tätä on käytetty uint16_t tyyppisessä hyväksi - joskaan rutiini ei ole enää kellojakson tarkka toisin kuin uint8_t:lle oleva rutiini. Tässäkin tosin on yllätyksiä: inline-koodi edellyttää, että ei käytetä size-optimointia, joka lisää viiveisiin funktiokutsujen ajat. Siispä uint16_t loopin pituus menee heti rikki, jos koodin optimointia muutetaan!
        https://www.nongnu.org/avr-libc/user-manual/group__util__delay__basic.html

        "Esimerkiksi avr:llä joskus tuli laskettua, että kääntäjä tunkee rutiiniin 68 kellojaksoa koodia ilman, että oma koodi vielä pyörähtää lainkaan"

        Enin osa tuosta 68 kellojaksosta lienee rekisterien talletusta ja palautusta. Jos keskeytyskoodista kutsuu mitä tahansa funktiota (toisessa moduulissa), kääntäjällä ei ole muuta vaihtoehtoa kuin työntää kaikki mahdollisesti muuttuvat rekisterit pinoon. Etenkin AVR:ssä työrekistereitä riittää.

        Keskeytyskoodit kannattaakin kirjoittaa mahdollisimman yksinkertaisiksi, mielellään ilman ensimmäistäkään funktiokutsua ja jättää varsinainen tekeminen "pääohjelmaan". Aina tämä ei ole mahdollista ja silloin tuo 68 kellojakson overhead on vain hyväksyttävä.

        Puheena olevassa tick timer -keskeytyksessä asialla on oleellinen merkitys. Esimerkiksi millisekunnin resoluutiolla ja 8 MHz kellotaajuudella pelkkä 68 kellojakson overhead käyttää lähes prosentin CPU-kapasiteetista.


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Vesikin maksaa, miksei hengitysilma?

      Jatkuvasti itketään ettei ole rahaa mihinkään, mutta tilastojen mukaan rahaa on enemmän kuin koskaan, joten miksei asial
      Maailman menoa
      20
      1791
    2. Satuolennoista tarinointi ei kuulu peruskoulun tehtäviin

      Opetustunteja on muutenkin käytössä vain rajallinen määrä. Eli nämä satuhommat koulun ulkopuolelle vapaaehtoisiin harras
      Maailman menoa
      156
      1789
    3. Suomalainen perheenisä vaatii Suvivirren esittämisestä hyvityksiä

      Itse lapsena uskonnonopetuksesta vissiin traumoja saanut ihka suomalainen (!) perheenisä vaatii Espoon kaupungilta korva
      Maailman menoa
      339
      1495
    4. Mies profiloin sinut

      Etsit täysin hallittavaa mutta samalla poikkeuksellista ihmistä. Etsit jotain mitä et koskaan tule saamaan.
      Ikävä
      209
      1122
    5. Lahkokasteen ja kristillisen kasteen erot

      Raamatun mukaan Kristillisessä yhdessä kasteessa Jumala pesee ja puhdistaa ihmisen sydämen ja poistaa perisynnin kirouks
      Kaste
      422
      1118
    6. Mitä haluaisit

      Tehdä kaivattusi kanssa?
      Ikävä
      142
      1106
    7. Salainen kastekoulutus

      Millainen on helluntailainen kastekoulutus ja kauanko se kestää ?
      Kaste
      285
      985
    8. Känsäkoura ja hotelli

      Tietoa kuka ostanut?
      Kuhmo
      11
      985
    9. Heikki Paasosen Marita-vaimo jätti tunteikkaat jäähyväiset: "Tällä kertaa me..."

      Heikki Paasonen on naimisissa Marita Paasosen (os. Alatalo) kanssa ja heillä on kaksi pientä lasta. Nyt koitti aika jätt
      Suomalaiset julkkikset
      4
      969
    10. Pirkanlinna yleisötapahtuma

      Oli todella hyvä tilaisuus. Ja EERO. L. Aivan mahtava tyyppi. Veti rennosti ja asiallisesti. Ja yleisöltä hyviä kysymyks
      Ähtäri
      49
      928
    Aihe