ARM:0016 pertraukimai WTF?

Kartas nuo karto, kai būna laiko vis paknibinėju ARM procesoriuką. Bet kuo toliau, tuo labiau jis mane nervuoja. Šį kartą pašnekėsim apie pertraukimus dėl PIO kojų lygio pasikeitimo…

Biški veikia ir biški veikia keistai…

Susikonfiguruoji koją kaip input:

AT91F_PIO_CfgInput( AT91C_BASE_PIOA, RTC_INT );

Pagalvoji, kad kojai reikėtu pull-up:

AT91F_PIO_CfgPullup( AT91C_BASE_PIOA, RTC_INT );

… pyst neveikia iškarto. Nebereaguoja. Tai šitą eilutę užkomentuojam.

Dėl šito nežinau ar reikia, bet eksperimente panaudojau:

AT91F_PIO_CfgInputFilter( AT91C_BASE_PIOA, RTC_INT );

Dabar konfiguruojam pačio pertraukimo valdymą:

//* configure PIO interrupt and handler
AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC,
AT91C_ID_PIOA,	// pertraukimo tipas.
INT_LEVEL,	// pertraukimo lygis
//AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL , 	// nesuprantu kas sukelia pertraukima
AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE , // nes visi sitie veikia vienodai
//AT91C_AIC_SRCTYPE_POSITIVE_EDGE, // visiskai. Nesamone.
ISR_PIO_handler); // paprograme atliekanti INT apdorojimą

Ir kaip parašyta komentaruose, visiškai pofig ką ten konfiguruoji- ar low_level ar external negative edge ar positive edge pertraukimas iššauna visada. Į RTC_INT koją padaviau 1Hz signalą kuris ateina iš nepriklausomo šaltinio. Taigis pertraukimas šaudo ir kai būna LH ir HL perjungimas. Ir visiškai dzin ką ten rašai.

Kita pastebėta nesamonė- nesugebu išjungti pertraukimo. Pas AVR procesoriuką, vieną asemblerio komanda ir pertraukimai išjungti. Čia jau ne. Tačiau yra “makro” komandos:

//AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);
//AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_PIOA);

Atrodo kaip tik tas- išjungia pertraukimus pagal PIO. Praktiškai viskas žymiai blogiau. Ta išjungimo komanda susideda iš kelių komandų. O procesorius taigi dirba “asinchroniškai” (pipeline). Ir taip gaunasi, kad kažkuriuo momentu kažkas susimaišo protelyje pas ARMą ir pertraukimas nebeveikia.
Programa tokia: sukasi amžinas ciklas kuris ant spalvoto LCD ekranėlio paišo mažus kvadratėlius ar linijas (tai ne žaidimas), o pertraukimas, kas 1 sekundę parašo- atnaujiną laiką ant to pačio ekrano. Grafinio ekrano paišymo subtilybė- kad nupaišyti primityva atliekamos kelios komandos. Ir jų seka svarbi. Todėl, teoriškai grafinio paišymo metu pertraukimas turi būti išjungtas. Išjungia pertraukimą, nupaiš0 kvadratėlį, įjungia pertraukimą. Ir kai pertraukimas suveikia, ant to pačio ekrano parašo laiką. Ką jus manot? Ogi figuški- per mažiausiai 10 sekundžių, daugiausiai per porą minučių pertraukimas sugenda. Jei nejungti pertraukimo blokavimo, viskas veikia ilgai, tik ant ekrano atsiranda artefaktų dėl nekorektiško valdymo. Programėlę reikia rašyti kitaip, nei įprasta pas ATMEGAs…

Laukių komentarų žmonių kurie žaidė su SAM7 čipu.

Beja, int handleris:

__ramfunc void ISR_PIO_handler(void)
{
volatile unsigned int pin_mask = AT91C_BASE_PIOA->PIO_ISR;
// Int patvirtinimas-isvalymas. Be jo neveikia.

	if(pin_mask & RTC_INT)
	{
	if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & RTC_INT) == 0 )
		{
			AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, _BV(15));
			AT91F_PIO_SetOutput( AT91C_BASE_PIOA,_BV(15));
		}
	}
AT91F_AIC_ClearIt(AT91C_BASE_AIC,AT91C_ID_PIOA); // clear interrupt
AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);	// acknowledge interrupt
}

gal čia kažką neteisingai parašiau?

7 replies on “ARM:0016 pertraukimai WTF?”

  1. Aš dar su savo STM32F103 procesoriuku iki pertraukimų nedaėjau, tik pradėjau skaitinėtis… tai supratau, kad paprasta nebus. Kažkoks ten organas raibas su pertraukimų vektoriais ir dar bbž kuo.

  2. Beje, radau, kad teoriškai visai Cortex-M šeimynai turėtų ir asembleris padėti:
    Išjungti pertraukimus: __asm(“cpsid i”)
    Įjungti: __asm(“cpsie i”)

    Turėtų nepriklausomai nuo gamintojo veikti.

  3. Ar šitas užkeikimas tik ARM7TDMI® ARM® Thumb® procesoriukui… 🙂
    Ten kažkaip kitaip padaryta. Kol kas guglinu, bet normalaus užkeikimo nerandu.

  4. Jei yra toks svarbus momentas, kai ekraniuke yra vykdomas piešimas, tai kodėl nepadarius antreip,
    t. y. ekraniuko paišymo algoritmą įdėti i kokią vieną iš vidinių laikrodzio pertrauktį ir jai suteikti aukščiausią levelį.
    O išorinį kloką ir laiką vykdyti pagrindiniame kode arba pertrauktyje su jai nustatytu žemiausiu leveliu.

  5. Čia šiaip ekraniukas panaudotas kaip iliustracija. Esmė straipsnio, kaip suvaldyti pertraukimus, kad jie veiktu bent jau panašiai kaip aš įsivaizduoju.

  6. Aš tai su Microchip karts nuo karto eksperimentuoju. Asembleryje tiktai.
    Kartais irgi vyksta procesai nesuprantami. Bet kai isigilinu,tai tik žinių stoka…
    Paskutinis eksperimentas su PIC18F46K22. Tai ir pertarukimai, adc, dac,PWM – moduliuotam garso pyptelejimui ir t.t. .Tai pradžioje buvau kapitališkai striges su adresacija, nes ten naudojama tokia bent jau man sonevinė ir naujovinė. Tai Li-Ion 18560 testeris- na, šiuo metu gražiai veikia…

  7. Tokie “subrende” procesoriukai kaip PIC ar AVR jau ištobulinti iki galo. O štai nauji procesoriukai dar “žali” ir juose dar pilna klaidų. Užtenka pažiūrėti datasheeto “errata” skyriu. Kai kurios pastraipos užmuša: tipo tas ir tas užlenkia procesorių. Solution: none.

    Ir kai oficialiuose failuose-pavyzdukuose būna: padarykit tuščią ciklą, nes tas ar kitas modulis iš pirmo karto nesuveikia…

Leave a Reply

Your email address will not be published. Required fields are marked *