This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Dynamic change of Interrupt priority (sd_nvic_SetPriority)

Hi everyone,

Device : nRF52832

SDK version : 14.2

Softdevice : S132 v5.0

I am facing a problem when changing the interrupt priority dynamically. Let me explain the context of my application. My BLE module is basically a bridge between BLE and UART. I am a slave for the BLE and master for the UART.

I would like to have UART priority set to 2 when I am waiting for an answer from the nested device over UART, and UART priority set to 7 when I am not waiting for an answer (since I am the master for that communication).

The code was already developped for another application using a cortex-M4 from NXP and works perfectly fine.

Below you can see the intruction used for that:

void RS485ManageIRQ(){       
    //Timeout when finished receiving bytes
    //Currently the priority is 2
    //Now set the priority to 7 for the next interrupt
            
     __disable_irq();											    // Avoid irq restart at priority change
    NVIC_SetPriority(pRS485Vars->UART_IRQn, RS485_INTP_NEWPACK);	// Set priority under real time
    __enable_irq();
    
    
}

Now I am facing a problem since Nordic does not recommend (forbid?) to disable IRQ using __disable_irq() since it blocks the time-critical operation of the softdevice.

But in all documentation I found, it is strongly recommended to disable all IRQ before using the function NVIC_SetPriority.

Actually now my code looks like this :

void RS485ManageIRQ(){       
    //Timeout when finished receiving bytes
    //Currently the priority is 2
    //Now set the priority to 7 for the next interrupt
            
    //__disable_irq();	//cannot disable all IRQ
    sd_nvic_SetPriority(nrf_drv_get_IRQn((void *)pRS485Vars->Reg.pUart), RS485_INTP_CALLBACK);	// Set priority under real time
    //__enable_irq();
    
    
}

I am actually using the sd_ wrapper function for the NVIC_SetPriority, since no SVC calls are made inside it I assume that this should not be a problem calling it from interrupt level 2.

Using sd_nvic_critical_region_enter/exit function instead of __disable_irq() is not sufficient if I want to follow the recommendation since it disable only the application interruption.

Do you recommend a workaround to dynamically change the interrupt priority?

This is my first message on the DevZone, I hope that I explained my issue well enough.

Best regards,

  • Hey Kevin,

    To say that you absolutely cannot use __disable_irq() is probably erroneous, but I will still not recommend using it. This is because we can only test on our own codebase and the improper use of __disable_irq() is guaranteed to crash the SoftDevice.

    That being said, I believe you can safely use __disable_irq() given that you extensively test the stability of your application, and that is most likely what you've been doing already. 

    The risk of a crash is a function of how often you disable interrupts, for how long, and how often the SoftDevice will need to execute timing-critical interrupts. 

    I think you should also assume that you WILL crash "once in a blue moon" and handle that scenario, though that is true for all SW.  

    Cheers,

    Håkon.

Related