Kuinka saan tehtyä assemblerilla delay funktion (esim 200ms) c -ohjemaan?
delay funktio
12
2075
Vastaukset
- 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
Sannalla tänään vuorossa The Daily Show
Eli nyt mennään jo satiirin puolelle. Tuohan on vähän kuten Lindströmin ohjelma Suomessa.888077Tanskassa lain vaatimana Bovaer tappanut nautoja ja sairastuttanut
Samaa myrkkyä myös Suomen lehmiin ollut tuloillaan, miten teidän tilalla? https://www.agriland.ie/farming-news/bovaer-m906084Ruotsalaisuuden Päivän virallinen liputuspäivä poistettava VÄLITTÖMÄSTI!
Suomen valtion ja suomalaisuuden kannalta ei ole minkäänlaisia perusteita liputtaa virallisesti ruotsalaisuuden päivää,875567Täysi ryöpytys Sanna Marinille ulkomailla.
https://www.iltalehti.fi/ulkomaat/a/f699d84f-fa53-4dba-8718-2c395017fc55 Sanna Marinin kirja saa todella tylyn vastaanot685511Minja Koskelan "istumista" kertovassa uutisessa ei sanottu persuista mitään
eli jälleen kerran äärivasemmistolainen valehtelee, hän kun väittää että juuri persut ovat lähetelleet Koskelalle vähemm1134740Pekka Visuri: "Suomen on aika irrottautua Ukrainan sodasta"
Slava Ukraina-mölinät eivät enää auta. Ukraina on sotansa hävinnyt. Nyt tarvitaan poliittista selvänäköisyyttä, reaalipo1232508Mikaela Nylander: Jos pakkoruotsi poistetaan, niin ruotsin kielen asema romahtaa
(Nylander on vanha RKP:nen) Mutta niin heikossa vedossa muumiruotsi siis on Suomessa, että vain tekohengityksellä se pys362218Maajussi-Villen morsioehdokas Maarit ei halunnut Villeä - Tämä totuus valkeni kuvauksissa!
Ohhoh, tekikö Maarit mielestäsi oikean ratkaisun Villen suhteen? Maajussi-Ville on herättänyt voimakkaita tunteita puol71354Ei välimatka meitä erottanut
Vaan välirikko ja väärinymmärrykset. Oikeastaan henkinen välimatka on meidän välillä pieni, näin uskon. Näen koko ajan e51349Kohta taas mesikämmeneen
Onneksi kaupunki ostaa mesikämmenen, niin päästään taas tekemään rahaa441190