Locking External Interrupts

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
yiancar
Posts: 14
Joined: Fri Jan 04, 2019 11:26 am
Has thanked: 1 time

Locking External Interrupts

Post by yiancar »

Hello there!

I would like to have multiple EXT interrupts all of which call the same callback. However I would like to disable any interrupt from being executed (or going to the "queue", if that is a thing) while the interrupt happens.

I tried using chSysLockFromISR() but it doesnt seem to be doing what I described above.

Thank you,
Yiangos

My config looks like :

Code: Select all

static const EXTConfig extcfg = {
    {
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 },
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 },
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 },
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL}
    },
};


My callback looks like:

Code: Select all

static void extcb1(EXTDriver *extp, expchannel_t channel) {
    (void)extp;
    (void)channel;
    chSysLockFromISR();
   
    porta_buffer = palReadPort(GPIOA);
    portb_buffer = palReadPort(GPIOB);

    chSysUnlockFromISR();
}
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Locking External Interrupts

Post by Giovanni »

Hi,

Those lock/unlock functions do not disable all interrupts, only those with priorities from 2 to 15, levels 0 and 1 are not disabled. Check your priority settings.

Note that interrupts are not queued, there is a single level of buffering. If you get the same interrupts repeatedly while interrupts are disabled then you get a single ISR call when interrupts are enabled again.

In that code port A and B would not be read atomically anyway, values could change in between the two read operations.

Giovanni
yiancar
Posts: 14
Joined: Fri Jan 04, 2019 11:26 am
Has thanked: 1 time

Re: Locking External Interrupts

Post by yiancar »

Thanks Giovanni,

Yes they are at priority level 6 and I see exactly what you mention.

Interrupt gets triggered, ISR is dissabled, correct values get stored (I know ports are not read atomically but in this case luckily they are asserted for long enough to be sampled correctly) ISR gets triggered again, ISR is enabled values get overwritten with the wrong value. Is there a way to disable the second interrupt execution?

My crude way for now is to set a flag on the first ISR
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Locking External Interrupts

Post by Giovanni »

There are extChannelEnable() and extChannelDisable().

Note that EXT has been removed in recent versions, now PAL has callback capability.

Giovanni
Post Reply