delay funktio

C -ohjelma

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

12

2030

    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. Kokoomus haluaa leikata vielä lisää sosiaaliturvasta

      Kokoomuksen Sanni-Granhn Laasonen pyytänyt KELA:aa selvittämään mistä leikataan vähäosaisilta vielä lisää sosiaaliturvas
      Maailman menoa
      269
      1637
    2. Oletko pitkävihainen ja onko sinulla " huono muisti muisti "?

      Mitä asioita et unohda tai anna anteeksi ? Mitä asioita voit " unohtaa" tai unohtaa? Vastaa koskien kaivattuasi tai yle
      Ikävä
      37
      1512
    3. Mitä tapahtuu

      Syksyllä?
      Ikävä
      96
      1316
    4. Huomenet naiselle

      Harmittaa ettei ehkä nähdä enää koskaan. Näillä mennään sitten.
      Ikävä
      18
      1300
    5. Ikävöin sua

      Sä vaan pyörit mun mielessä, en saa sua unohdettua. Tilanteesta tekee vaikean sen kun molemmat ollaan varattuja ja tilan
      Ikävä
      6
      1217
    6. Neljä kuukautta vankeutta, kenelle?

      Kuka tuomittiin ehdottomaan neljän kuukauden vankeustuomioon ja korvauksiin?
      Suomussalmi
      10
      1037
    7. Minä täällä vaan

      Ukko jota oot joutunu joskus sietämään työnpuolesta. Toivottelen kauniita unia💛
      Ikävä
      86
      950
    8. Jos haluat jatkaa tutustumista

      Pyydä mut suoraan kunnon treffeille. En lähde mihinkään epämääräiseen viestittelyyn enää.
      Ikävä
      66
      925
    9. T, miten mun pitäis toimia

      Olen niin toivottoman ihastunut suhun...ollut jo liian,monta,vuotta. Lähestynkö viestillä? Miten? Sun katse...mä en kest
      Ikävä
      43
      901
    10. Olet huippunainen

      Ja onneksi tiedät sen itsekin.
      Ikävä
      32
      890
    Aihe