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

Using Optimisation in nrf51 Keil

Hi, I have the following piece of code.

nrf_gpio_cfg_output(PIN_EN_BSTR);

for(int i=0;i<300;i++)

{

	nrf_gpio_pin_clear(PIN_EN_BSTR);

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();

	__NOP();	

	nrf_gpio_pin_set(PIN_EN_BSTR);

	nrf_delay_us(100);

}

nrf_gpio_pin_clear(PIN_EN_BSTR);

With Optimisation level O0, the off time is 2usec and with O3, the off time is 1.4usec. Will __NOPs have different cycle time for different optimisation levels? I thought they should be the same? Thanks.

  • __NOP() can be optimized by compiler, instead use inline assembly instructions that you can find in nrf_delay.h

      __ASM volatile (
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t"
           " NOP\n\t");
    

    Inline assembly is not optimized.

  • Hi Aryan, Thanks for your reply. With O0, even without adding any nops(whether inline or not), there is a delay of 1usec between nrf_gpio_pin_clear and nrf_gpio_pin_set. With O3, there is 320nsec between nrf_gpio_pin_clear and nrf_gpio_pin_set. So, if I add nops(inline or not), this is further going to add delay in the O0. I want the delay to be the same irrespective whether it is O0 or O3. Is it possible? Thanks. THis is my code:

    nrf_gpio_cfg_output(PIN_EN_BSTR);
    
    for(int i=0;i<300;i++)
    
    {
    
    	nrf_gpio_pin_clear(PIN_EN_BSTR);
    
    
    	nrf_gpio_pin_set(PIN_EN_BSTR);
    
    	nrf_delay_us(100);
    
    }
    
    nrf_gpio_pin_clear(PIN_EN_BSTR);
    
  • I tested it myself on nRF51

    int main(void)
    {
    nrf_gpio_cfg_output(11);
    
        while(1)
    
        {
    
            nrf_gpio_pin_clear(11);
            nrf_gpio_pin_set(11);
    
        }
    }
    

    with -O0 it is 0.36us
    with -O3 it is 0.12us

    considering 1 cpu cycle is 0.062us I think it is doing excellent job with -O3 only two cycles and with -O0 it is taking 6 cpu cycles which is reasonable because of many debug NOPS and unoptimized reads and writes.

    inside the nrf_delay_us you also have C logic to to compare if number_of_us is positive or not, this compare logic will generate different type of code with different optimization level and will run in a loop to the number of us you give in the argument. I am not sure if we can create a software emulated delay accurate to nano seconds at different optimizations.

    I Suggest you use hardware timer for it.

  • Thanks Aryan. Bascally I am looking for a code where I can do PWM of a gpio pin with on period (1usec) and off period as 100usec : The main point would be the on and off time of PWM should be the same for all optimisation levels, O0 to O3. Thanks

  • Then use PWM library provided by the SDK instead of creating your own delays. PWM library will create same delays and will be same of all optimizations and with or without softdevice.

Related