LPC546xx: lwip bare-metal (NO_SYS=1) and disabling interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC546xx: lwip bare-metal (NO_SYS=1) and disabling interrupts

878 Views
giusloq
Contributor III

If I understood well, ethernet driver is interrupt driven, so some critical lwip functions are called from interrupt context. This must be done with great care, because is not generally safe.

Indeed SDK code set LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT and defines sys_arch_protect() as:

sys_prot_t sys_arch_protect(void)
{
  sys_prot_t result;
  result = (sys_prot_t)DisableGlobalIRQ();
  return result;
}

In the end, interrupts are disabled frequently, mainly every time a dynamic allocation is needed, from the heap or from a memory pool.

Is there a way to avoid disabling interrupts so frequently?

 

Labels (2)
0 Kudos
3 Replies

860 Views
giusloq
Contributor III

I'm looking at the lwip porting function (sys_arch.c) for NO_SYS=0 too (FreeRTOS), starting from lpcxpresso54628_lwip_mqtt_freertos SDK example.

Here I found SYS_LIGHTWEIGHT_PROT=1, SYS_ARCH_PROTECT macro calls sys_arch_protect function that is implemented as:

sys_prot_t sys_arch_protect(void)
{
    sys_prot_t result = 0;

#ifdef __CA7_REV
    if (SystemGetIRQNestingLevel())
#else
    if (__get_IPSR())
#endif
    {
        result = portSET_INTERRUPT_MASK_FROM_ISR();
    }
    else
    {
        portENTER_CRITICAL();
    }
    return result;
}

What does it do? __get_IPSR() should returns 0 if the running context is not an interrupt, so this function seems to disable only lower priorities interrupts if an interrupt (whatever it is) is running, otherwise all the interrupts are globally disabled.

This isn't clear to me, I was expecting exactly the opposite. If an interrupt context is actually running, we can only disable all interrupts, otherwise we can disable only lower priorities interrupts.

Besides, I understood interrupts are disabled not only in bare-metal systems, but also with FreeRTOS. Why do we need to disable interrupts if we have mutexes? Does this depends from the Ethernet driver implementation that is interrupt driven and calls lwip function in ISR functions?

0 Kudos

861 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Regarding your question, for critical code execution which is not allowed to be interrupted, you have to use the LIST_ENTER_CRITICAL() /LIST_EXIT_CRITICAL() to disable/enable interrupt, I do not think there is the other way.

#define LIST_ENTER_CRITICAL() uint32_t regPrimask = DisableGlobalIRQ();
#define LIST_EXIT_CRITICAL() EnableGlobalIRQ(regPrimask);

 

Hope it can help you

BR

XiangJun Rong

0 Kudos

854 Views
giusloq
Contributor III

I'm studying NXP code examples. I don't need to add additional code.

When NO_SYS=1 (bare-metal), NXP code disables interrupts with sys_arch_protect() that calls DisableGlobalIRQ().

lwip calls sys_arch_protect() in many points, for example in mem_malloc. This means interrupts are disabled very frequently. I'd like to understand why this is necessary and if there's a solution to this, because disabling interrupts isn't a good practice.

I thought a solution could have been using FreeRTOS, but even in this case sys_arch_protect() disables interrupts. So the problem remains.

0 Kudos