Kviz - podivna chovani programu pro 8bitove uP

Jan Waclawek wek@evona.sk
Pondělí Leden 8 12:38:35 CET 2007


Ahaho, problem "atomicity", v kombinacii s pouzitim nevhodneho datoveho 
typu v - s prepacenim - vyssom jazyku. Toto by sa malo rozdavat vsetkym 
adeptom programovania ako psia znamka na krk.

Toto je klasicky ucebnicovy priklad premennej (counter), ktora je v 
maine pouzita (tu: testovana, pouzita v odcitani) prerusitelnou 
sekvenciou instrukcii - a pouziva sa (tu: meni) aj v preruseni. Este 
dobre, ze s premenna counter sa v main-e nemeni, to by mohlo byt este 
zaujimavejsie :-) Ale existuju aj zakernejsie verzie, napr. ak su dve 
premenne sice pouzivane "atomicky" ale musia zachovat nejaky vzajomny 
vztah - klasicky priklad je obsah buffra a pointer nan...

Analyza:
counter na zaciatku zmeni stav postupne z -22 na -40, pricom sa v maine 
(pri counter=-30) nastavi result na 10 - to je napokon zamyslana funkcia 
  (dostatocne rychle vykonavanie cyklu zaruci, ze sa to aspon raz 
stane). potom counter nadobuda uz iba hodnoty 0 (= 0x0000), -1 (= 
0xFFFF), -2, -3, -4, -15, -16, -17, -18, -19 (= 0xFFED) a znova 0 atd. 
Ak nastane prerusenie "uprostred" pouzitia counter-a, main "vidi" bud 
predchadzajuce LSB a nasledujuce MSB alebo naopak v zavislosti od 
poradia pouzitia (pri kontrole zhody s konstantou to moze byt akokolvek, 
pri odcitani to bude zrejme LSB first aj ked to tiez nie je na 100%, 
prekladac si moze napr. odkopirovat hodnotu pre odcitanie aj v opacnom 
poradi). V prvom pripade moze teda main "vidiet" okrem uz uvedenych 
hodnot countera aj 0x00ED = 237 (pri prechode z -19 na 0) a 0xFF00 = 
-256 (pri prechode z 0 na -1); v druhom pripade sa moze vyskytnut 
"naviac" 0xFF00 = -256 a 0x00FF = 255.

Takze pripad A a B uz nenastane, prvy pripad C raz pravdepodobne nastane 
(zavisi to este od potencialneho synchronizmu prerusenia voci "main"-u) 
a druhy pripad C by tiez nemal nastat ("najzapornejsi" vysledok bude 
-256-100 = -356. -10 ani -30 sa uz nevyskytne.

Takze "konecny" vysledok je 100.

Mno samozrejme sa mozem mylit ako obvykle...

wek



Jan Kral wrote:
> Zdravim vespolek,
> 
> kazdy se jiz urcite setkal, ze jim napsany program do procesoru fungoval podivne a nekdy chybu najdeme a nekdy obcasne podivne chovani urcime jako vliv ruseni z vnejsku. Prave na tento typ chyby tady mam maly kviz, kdy je je problematika vysyntetizovana do nekolika malo radku kodu, tak aby to bylo patrne co nejdrive. Kod je urceny pro 8bitove uP typu AVR nebo 51. Rychlost procesoru je dostatecna, aby se stihla vykonavat smycka v main.
> 
> Jestli nekdo spravne pozna, jaka bude konecna hodnota promenne "result" a hlavne proc? Pro stouraly "konecnou" je mysleno dlouhe obdobi treba i nekolika dnu. 
> 
> Ja samozrejme reseni i duvod znam. Kdo prijde na spravnou odpoved, tak mu nektera podivna chovani nekterych programu budou jasnejsi.
> 
> S pozdravem Jan Kral
> 
> int    counter = -22;
> int    result = 1;
> 
> void timer0handler( void ) interrupt 1 {
>        counter --;
>        if (counter == -20 )
>           counter = 0;
>        if (counter == -5 )
>           counter -= 10;
>        if (counter <-40 )
>           counter = 0;
> }
> 
> void main( void ) {
>       Init_Timer;			// casovac 1000x/s
> 
>       while (1) {
>         if (counter == -10)
>            result = 5;             // A
>         if (counter == -30)
>            result = 10;            // B
>         if ((counter-result)>0)
>            result = 100;           // C
>         if ((counter-result)<-400)
>            result = 100;       }   // C
>   }



Další informace o konferenci Hw-list