# ATMEL mikrokontrolleri >  AVR Studio un RESET vektors

## marcina

Diemžēl sarakstīta proga Atmegai8535 ir šausmīgi liela, bet īsumā kods apmēram šāds:


```
rjmp RESET
...

Interrupt1:
sei
...
reti

Inetrrupt2:
sei
...
reti

RESET:
...
MAIN:
rjmp MAIN
```

 Lieta tāda, ka ik pa laikam (un dažkārt tas var notikt pēc 10sekundēm, dažkārt pēc 5minūtēm) kods atgriežas atpakaļ RESET vektorā...
Jautājums: kā tas var notikt??? Kādi varbūt cēloņi? Platei viss ok!

----------


## M_J

Uz RESET procesors atgriežas, ja tam liek darīt kaut ko, ko tas nevar - piemēram kaut ko nolasīt vai ierakstīt neeksistējošā adresē. No savas pieredzes - tādam it kā neizskaidrojamam resetam var būt miljons iemeslu. Parasti jau kāda kļūda programmā. Man parasti ir bijušas kļūdas pārtraukumu apstrādē. Vai ieejot pārtraukumā saglabāji SREG un atgriežoties atjaunoji? Vai PUSH un POP skaits ieejot paartraukumā un atgriežoties sakrīt, vai pārtraukumā neizmanto kādu reģistru, kuram   esi aizmirsis iztaisīt PUSH un POP. Galu galā pārtraukums (ja nav aizliegts) var notikt starp jebkurām divām komandām, padomā, kas notiks, ja tas būs izmainījis kādu reģistru, kuru patreiz izmanto pārtrauktā programma. Piemēram - tu kaut ko iaraksti reģistru pārī ZH:ZL un pēc tam izmanto komandu IJMP, bet pa vidu ir bijis pārtraukums, kas izmainījis ZH. Un tādā garā...

----------


## M_J

p.s. sākumā nepamanīju - kāpēc ieejot pārtraukumā taisi SEI - tas ir atļauj pārtraukumus? Ne velti ieejot jebkurā pārtraukumā defaultā visi pārējie pārtraukumi defaultā tiek aizliegti. Ir vismaz viena lieta, kas ieejot pārtraukumā obligāti jāizdara, pirms taisa SEI - jāsaglabā SREG. Ir vēl citas lietas, bet tās - atkarībā no situācijas.

----------


## marcina

Jā - es atļauju pātraukumus, ja jau ir cits pātraukums - vairāki taimeri (un visi nozīmīgi   ::  )


```
ieejot pārtraukumā obligāti jāizdara, pirms taisa SEI - jāsaglabā SREG
```

 Ak tā? ... 
Rediģēts: a nu sapratu!  :: 
Es parasti SREG saglabāju vienā no reģistriem un tad pie pārtruakuma izejas no reģistra ielādēju atpakaļ SREGā.
Jā tos visus pārtraukumus esmu pārbaudījis - visi push un pop sakrituši.

Rediģēts: galu galā iznācis tā - ka viss darīts pareizi...

----------


## M_J

Iekš SREG taču ir nosacījumu biti C,Z,N utt. kurus izmanto Branch instrukcijas. Piemēram - Tu esi veicis salīdzināšanu CP XL,YL  aiz kuras seko instrukcija BRCC A, kura kā kritēriju izmanto bitu C reģistrā SREG. Ja pa vidu ir bijis pārtraukums, kurā arī ir bijušas komandas, kas izmaina bitu C, tad Tu vairs nezini, kāds tas būs pēc atgriešanās no pārtraukuma un rezultātā komandas BRCC A rezultāts nekādā veidā nebūs saistīts ar iepriekš veikto salīdzināšanu. Pieņemsim, ka Tu ieejot pārtraukumā SREG saglabā, bet pēc SEI. Tas nozīmē, ka pirms SREG saglabāšanas jau var būt bijis vēl viens pārtraukums, kas jau ir izmainījis SREG un tas kas tiek saglabāts jau nav vajadzīgais. Protams, pārtraukumi šādos bīstamos brīžos negadās vienmēr, bet laiku pa laikam, tāpēc arī RESETs notiek neregulāri. Es SREG saglabāšanai esmu noziedojis r3, kuru neizmantoju nekur citur un lietoju šādu konstrukciju:
interrupt:
 in r3,SREG
 push r3
 sei
.........
 cli
 pop r3
 out SREG,r3
 reti

----------


## marcina

> Pieņemsim, ka Tu ieejot pārtraukumā SREG saglabā, bet pēc SEI. Tas nozīmē, ka pirms SREG saglabāšanas jau var būt bijis vēl viens pārtraukums, kas jau ir izmainījis SREG un tas kas tiek saglabāts jau nav vajadzīgais.


 Paldies, vērtīgs padoms - iespējams ka tā arī ir mana problēma  :: 
Vienīgais - nākamā problēma - tas pātraukums var vienkārši izslīdēt man no rokām   ::  Iznāk, ka vēl papildus jāskatās pātraukumu flagi...

----------


## M_J

Kā Tu to domā - izslīdēt no rokām? Ja Tu domā, ka pārtraukums pazudīs, ja attiecīgais notikums notiks laika intervālā, kamēr visi pārtraukumi aizliegti - bažām nav pamata, tā izsaukšana tikai tiks atlikta līdz brīdim, kad pārtraukumi atkal būs atļauti. Pēc savas pieredzes varu teikt, ka drīzāk jāuzmanās no pretējā: ja kādu pārtraukumu aizliedz, bet pēc tam atļauj, tad rēķinies - ja pa aizliegto laiku ir bijis notikums, tad tad brīdī kad pārtraukumu atļauj, tas tiks izģenerēts. Tāpēc, ja pa aizliegto laiku saskrējušie pārtraukumi nav vajadzīgi - pirms pārtraukumu atļaut, drošības pēc attiecīgajā reģistrā nometu karogu, kurš atbild par attiecīgā pārtraukuma ģenerēšanu un, kurš atļauta pārtraukuma gadījuma tiek nomests brīdī kad procesors dodas apstrādāt pārtraukumu. Pretējā gadījumā var sanākt, ka atļaujot kādu pārtraukumu procesors uzreiz dosies apstrādāt fig viņu zin kad notikušu, absolūti nevajadzīgu notikumu. Samudžināti teikumi sanāca, bet ceru, ka domu varēs saprast.

----------


## marcina

10 reizes analizējot teikto, sapratu, ka:
Kad pienācis laiks pātraukumam, pārtraukumu karogu reģistrā tiek uzstādīts tā notikuma karogs, un kad sākas pātraukuma apstrāde, karogs tiek nomests. Tāpēc, ja pātraukums uz šo mirkli aizliegts, tad to atļaujot un, ja uzstādīts šī pātraukuma karogs, procesors steigsies apstrādāt pārtraukumu un nomest tā karogu.

Mja... vajadzēs gan pierediģēt kodu...   ::

----------


## Velko

Nu, bet ja par resetošanos - kā ir ar Watchdog taimeri? Neesi jamo ieslēdzis?

----------


## marcina

> Nu, bet ja par resetošanos - kā ir ar Watchdog taimeri? Neesi jamo ieslēdzis?


 Ne - nav vajadzības to vispār lietot...

----------


## M_J

Manuprāt, ja jau viss notiek, kā paredzēts, tas Watchdog taimeris vispār nav vajadzīgs. Tas ir kā drošības pedālis vilcienu mašīnistiem, ja to regulāri nenospiež tad ieslēdzas bremzes (notiek Resets). Ja programma ir pareizi uzrakstīta un shēma pareizi izprojektēta līdz tam nedrīkstētu nonākt. Un ja nu tomēr kaut kādu pilnīgi neparedzētu iemeslu dēļ kontrolieris tomēr iebrauc galīgās auzās, tad tas ir pēdējais glābiņš, kā vest pie sajēgas ierīci, kura nedrīkst pārstāt funkcionēt.

----------


## Velko

Manas domas par WDT ir tādas pašas - ja viss ir pareizi, tad nav vajadzības izmantot. Doma bija - vai marcina nav nejauši to aktivizējis?

Vēl iespējams iemesls - vai steks "nelien virsū" mainīgajiem atmiņā? Tad var gadīties, ka pārraksti return adresi ar nullēm.

----------


## marcina

> Vēl iespējams iemesls - vai steks "nelien virsū" mainīgajiem atmiņā? Tad var gadīties, ka pārraksti return adresi ar nullēm.


 Diezvai... 512 baiti, nu kuriem tik vien kā 50baiti manīgajiem un pāŗejais stekam  ::  Nelien nelien  :: 
Strap citu - to flagu attīrīšana pirms pārtraukuma atļaušanas iespējams palīdzējusi.. vismaz kamēr strādā gludi

----------

