delay funktio

C -ohjelma

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

12

1797

    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. Tähdet, tähdet -tippuja Kake Randelin tilittää avoimena: "Tämä on viihdyttämistä, eikä sitä..."

      ISO kiitos Kake lauluistasi!Nyt ei vaan studioyleisö lämmennyt. Olet legenda! Lue Kake Randelinin mietteet: https://w
      Tv-sarjat
      18
      946
    2. En koskaan

      Aliarvoinut, nauranut/pitänyt pilkkana, tai ajatellut mitään negatiivista sinusta. Jos nämä asiat uskot ja luotat sen v
      Ikävä
      49
      830
    3. Haistoin ensin tuoksusi

      Käännyin katsomaan oletko se todellakin sinä , otin askeleen taakse ja jähmetyin. Moikattiin naamat peruslukemilla. Tu
      Ikävä
      3
      743
    4. Martinasta kiva haastattelu Iltalehdessä

      Hyvän mielen haastattelu ja Martina kauniina ja raikkaan keväisenä kuvissa.
      Kotimaiset julkkisjuorut
      224
      731
    5. Nainen, olet kaipaillut seuraani

      Tiedän sen, kuulen sen. Sinulla ei ole muita joiden kanssa voisit niistä asioista keskustella joista keskustelet kanssan
      Ikävä
      76
      727
    6. Kirjoitit joskus minulle tietäen

      Että se olin minä.
      Ikävä
      46
      719
    7. Emme näe enää koskaan

      Näin ainakin uskon. Mutta ei hätää, et menetä yhtään mitään minussa. Sen kai jo tiesitkin. Hyvää vappua ja kesää. Toivon
      Ikävä
      34
      687
    8. Mitäs meinaatte vappuna

      ikävöivät ihmiset?
      Ikävä
      107
      673
    9. Vornanen alkaa olla kusessa

      Kaikki vanhat synnit on kaiveltu esiin ja niitä tosiaan näyttää olevan. Poliisin asussa esiintyminen vaaliteltalla, työt
      Joensuu
      82
      672
    10. Pistetään panokset

      Vielä korkeammalle! Eli mitäs numeroa kaipaat? Kaikki mukaan! Itse kaipaan 5
      Ikävä
      35
      610
    Aihe