ARM prekinitev

Vse kar je v povezavi z ARM-Cotrex-M procesorji. Sem spada tako HW kot SW.

Moderator: tilz0R

ARM prekinitev

OdgovorNapisal/-a zanka » 07 Avg 2019, 22:16

Na določenem kosu kode reden program dostopa do istih spominskih naslovov kot prekinitev, zato bi rad v tem kosu prekinitev izklopil. Sedaj me zanima, če se ob vklopu prekinitve izvajanje nadaljuje v prekinitvi, če je prišlo do pogojev za prekinitev, ko so bile te izklopljene. Po domače, ali prekinitev počaka?

Verjetno je dovolj, če izklopim zgolj nadležno prekinitev?
Uporabniški avatar
zanka
 
Prispevkov: 2257
Pridružen: 17 Mar 2016, 01:16
Kraj: Krško
Zahvalil se je: 101 krat
Prejel zahvalo: 199 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 38

Re: ARM prekinitev

OdgovorNapisal/-a Kroko » 07 Avg 2019, 23:13

Če lahko interupt preskočuš potem takole:

Koda: Izberi vse
volatile uint32_t data;
volatile bool lock;

void ISR (void)
{
  if(!lock)
  {
    data = 123456;
  }
}

void main (void)
{
  ...
  lock= true;
  data = 456789;
  lock= false;
  ...
}
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4368
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 635 krat
Prejel zahvalo: 1420 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a tilz0R » 08 Avg 2019, 10:35

zanka je napisal/-a:Na določenem kosu kode reden program dostopa do istih spominskih naslovov kot prekinitev, zato bi rad v tem kosu prekinitev izklopil. Sedaj me zanima, če se ob vklopu prekinitve izvajanje nadaljuje v prekinitvi, če je prišlo do pogojev za prekinitev, ko so bile te izklopljene. Po domače, ali prekinitev počaka?

Verjetno je dovolj, če izklopim zgolj nadležno prekinitev?


Imaš prav. Prekinitev bo počakala, torej lahko izklopiš interrupte (globalne), in narediš svoje. Vklopiš nazaj, in če je medtem prišla prekinitev, se sproži, ko vklopiš le-te nazaj.

Najbolj pravilen način za le-to bi bil z uporabo primask registra, a ne vem kateri core imaš. To bo interrupte vklopilo nazaj le, če so bili predhodno vklopljeni. To ti omogoča stacking funkcij.
Koda: Izberi vse
int main() {
...
uint32_t prim = __get_PRIMASK();
__disable_irq();

...
tvoja koda..
...


__set_PRIMASK( prim );
}


Če si pa v Cortex-M3/4/7/33 pa lahko uporabiš BASEPRI feature. Tukaj pa izklopiš interrupte, ki imajo nižji priority kot vrednost v BASEPRI. Če interruptu ki dostopa do tvojih spremenljivk nastaviš najnižno vrednosti, lahko v BASEPRI vpišeš najvišjo številko (višja številka pomeni nižji priority!!!) in bo ta interrupt izklopljen, ostali pa ne. Odvisno kako pomembni so ostali interrupti in koliko časa bi bili izklopljeni.

To bi potem izgledalo nekako tako:
Koda: Izberi vse
//Nastavi prio tvojemu interruptu na X, v tem primeru je X = 15

uint32_t basepri = __get_BASEPRI();
__set_BASEPRI(15); //Izklopi vse interrupte z logičnim prioritijem 15 ali manj (16, 17, 18, ...)

...tvoja koda

__set_BASEPRI(basepri); //Nastavi nazaj prejšnjo vrednost
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1691
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 220 krat
Prejel zahvalo: 441 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a Kroko » 08 Avg 2019, 11:56

Nenagradno vprašanje:

Recimo, da imam timer ki šteje nanosekunde. Ko pride do 1000ns sproži interupt. V interuptu imam uro, ki šteje milisekunde. Se pravi po eni sekundi bo ura kazala 1000ms.

Sedaj v main uporabim uporabim BASEPRI. Recimo, da je timer v tem trenutku preštel 400ns. Main počaka točno eno sekundo. Kaj se bo zgodilo z interuptom, ko ga spet vklopim? Kako bo štela ura?

A: 0 - ura se bo povečala šele ob naslenjem interuptu, se pravi šez 600 ns.
B: 1 - interupt se bo takoj sprožil in povečal uro, naslednjič se bo povečala čez 600ns.
C: 1 - interupt se bo takoj sprožil in povečal uro, naslednjič se bo povečala čez 1000ns.
D: 1000 - interupt se bo takoj sprožil tisočkrat - toliko časa je namreč bil onemogočen.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4368
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 635 krat
Prejel zahvalo: 1420 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a tilz0R » 08 Avg 2019, 12:18

A odpade, ker pending status čaka
B, je pravi, ker timer je tisti, ki naredi trigger za interrupt. Če ga je naredil in je interrupt onemogočen, bo interrupt sprožen po 400ns ko bodo spet vklopljeni. Naslednjič bo trigger čez 600ns in bo pač takrat spet.
C odpade, ker pending čaka in timer bo naslednji trigger naredil čez 600ns...timer je neodvisen od interruptov
D odpade, če gledamo s stališča core-a. core ima samo flag (pending or not), 1 bit, tako da če ga 5x postaviš, ga še vedno samo 1x zbrišeš. Če pa gledamo s stališča periferije, je pa vendor specific. Mogoče je kakšna periferija sposobna šteti koliko pending interruptov se je zgodilo in temu primerno tolikokrat poslat trigger core-u, po tem, ko si v periferiji pobrisal flag (števec gre dol). A to ne verjamem da obstaja v timerjih, mogoče v UART-u, ki ima fifo.

Nauk zgodbe...če imaš periodic interrupt za štetje časa in če disable interrupt traja dlje kot ena perioda števca, boš zgubil štetje vsake x-krat.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1691
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 220 krat
Prejel zahvalo: 441 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a Kroko » 08 Avg 2019, 12:39

tilz0R je napisal/-a:Nauk zgodbe...če imaš periodic interrupt za štetje časa in če disable interrupt traja dlje kot ena perioda števca, boš zgubil štetje vsake x-krat.


Pa ne samo pri štetju časa. Tudi v komunikaciji so lahko problemi. Nima smisla, da komunikacija pade samo zato, ker je skupni spomin zaklenjen in podatkov nimamo kam dati.

Tako da je večkrat bolje interupte pustiti pri miru in ščititi samo resurse. To pa moja koda naredi povsem zadovoljivo (čeprav na prvi uč ne izgleda tako - volatile ni tu zaradi memory barrierja ampak zaradi optimizatorja).

Koda: Izberi vse
volatile uint32_t ura;
volatile uint32_t data;
volatile bool lock;

void ISR (void)
{
  ura++:
  if(!lock)
  {
    data = 123456;
  }
}

void main (void)
{
  ...
  lock= true;
  data = 456789;
  lock= false;
  ...
}
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4368
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 635 krat
Prejel zahvalo: 1420 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a tilz0R » 08 Avg 2019, 13:17

Po eni strani imaš prav. A po drugi, vsak operacijski sistem v neki točki vgasne interrupte, včasih za relativno dolgo časa, pa se zaradi tega ne izgublja komunikacije :D To se optimizira tako, da (če je možno) se uporabi BASEPRI register kot opisano zgoraj. Ali pač disable interrupt.

Pravilno je, da se omeni vse opcije.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1691
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 220 krat
Prejel zahvalo: 441 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a zanka » 09 Avg 2019, 12:41

Uporabljam škrt M0 procesor.

Si bom odgovoril na svoje vprašanje. Spomnim se, da sem prebral, da je potrebno programsko "skriti" zastavico. Zato se bo prekinitev sprožila takoj, ko bom jo vklopil nazaj.
Uporabniški avatar
zanka
 
Prispevkov: 2257
Pridružen: 17 Mar 2016, 01:16
Kraj: Krško
Zahvalil se je: 101 krat
Prejel zahvalo: 199 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 38

Re: ARM prekinitev

OdgovorNapisal/-a tilz0R » 09 Avg 2019, 13:15

zanka je napisal/-a:Uporabljam škrt M0 procesor.

Si bom odgovoril na svoje vprašanje. Spomnim se, da sem prebral, da je potrebno programsko "skriti" zastavico. Zato se bo prekinitev sprožila takoj, ko bom jo vklopil nazaj.


Ni res, Cortex-M sam pobrise zastavico za pending irq, ko se ta izvede. Moraš pa pobrisat zastavico od periferije, ki naredi trigger. A to je vendor specific in ni nujno vedno res.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1691
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 220 krat
Prejel zahvalo: 441 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: ARM prekinitev

OdgovorNapisal/-a zanka » 09 Avg 2019, 14:45

To je natančneje res, kajti prekinitev lahko sproži več dejavnikov in je potrebno zato znotraj nje še dodatno ugotoviti vzrok. Briše se nato te vzroke.
Uporabniški avatar
zanka
 
Prispevkov: 2257
Pridružen: 17 Mar 2016, 01:16
Kraj: Krško
Zahvalil se je: 101 krat
Prejel zahvalo: 199 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 38

Re: ARM prekinitev

OdgovorNapisal/-a MitjaN » 09 Avg 2019, 15:25

To pa moja koda naredi povsem zadovoljivo

Če je read in write dostop do tipa bool atomic
MitjaN
 
Prispevkov: 74
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 3 krat
Prejel zahvalo: 33 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 6

Re: ARM prekinitev

OdgovorNapisal/-a Kroko » 09 Avg 2019, 16:24

Ni treba, da je atomic.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4368
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 635 krat
Prejel zahvalo: 1420 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255


Vrni se na ARM-Cortex-M

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost