delay funktio

C -ohjelma

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

12

2103

    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. Kelekkakisat

      Mikä vakava onnettomuus sattunut kisoissa. On peruttu koko kisat. Pelastuskopteri näytti käyvän paikalla.
      Nivala
      10
      5006
    2. Kuinka pitkä välimatka

      on teidän kotien välillä?
      Ikävä
      79
      2697
    3. Eikö me voitais

      Vaan harrastaa seksiä kun muusta ei tule mitään
      Ikävä
      46
      2632
    4. Pitäis vaan lopettaa

      Sinun kanssa yhteydenpito. Alkaa vaan haluamaan enemmän ja tuskin lopulta mikään kohtaisi. Ja ikävä vaan kasvaa ja lähei
      Ikävä
      13
      2010
    5. Ikävä uutinen uudesta Unelmia Italiassa -kaudesta

      Unelmia Italiassa -sarja on ollut supersuosittu ja uutta kautta on odotettu. Nyt on tullut se aika, että TV-katsojat pää
      Tv-sarjat
      7
      1743
    6. Onko kaivattusi

      …mielestäsi älykäs, tai kenties tyhmä? Oma mielipide.
      Ikävä
      47
      1740
    7. Epäilen ettet edes

      Kehtaisi liikkua kanssani.
      Ikävä
      42
      1695
    8. Oletko huomannut

      Yhden muutoksen?
      Ikävä
      22
      1666
    9. Salatut elämät: Lola Odusoga -paljastus - Tämä suosii tiettyjä Salkkarit-faneja!

      Salatut elämät vetää katsojia tv-ruudun äärelle jaksosta, kaudesta ja vuodesta toiseen. Tähän mennessä sarjaa on nähty j
      Salatut elämät
      7
      1651
    10. Lähtisitkö Erikoisjoukot-leirille? Yksi kokelas paljastaa karun totuuden kulissien takaa

      Erikoisjoukot realityssä kokelaat kohtaavat omat henkiset ja fyysiset rajansa. Nyt yksi kokelas paljastaa karun totuuden
      Tv-sarjat
      17
      1651
    Aihe