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