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

Optimized code stops working

On the following code I have a packet of 6 bytes that I write to a buffer. I pass the buffer as read_packet function argument. When optimized, the code doesn't work. I only got noise on the UART and even with the debugger I coudn't see the correct values. After some hours of trial and error I decided to select the level 0 of optimization and it started working.

What is the compiler doing?

while (true)
{
    uint32_t received[6];
		
			//received
			read_packet(received);
			//nrf_gpio_pin_toggle(led1);
			//nrf_gpio_pin_toggle(led3);
			app_uart_put(received[1]);
			//app_uart_put(12);
    
    //printf("The contents of the package is %u\n\r", (unsigned int)received);
}

bool read_packet(uint32_t *buffer)
{
    //uint32_t *result = malloc(sizeof(uint32_t)*6);
		static uint32_t result[6];

    NRF_RADIO->EVENTS_READY = 0U;
    // Enable radio and wait for ready
    NRF_RADIO->TASKS_RXEN = 1U;

    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
    NRF_RADIO->EVENTS_END = 0U;
    // Start listening and wait for address received event
    NRF_RADIO->TASKS_START = 1U;

    // Wait for end of packet or buttons state changed
    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }

    if (NRF_RADIO->CRCSTATUS == 1U)
    {
      buffer[0] = packet[0];
			buffer[1] = packet[1];
			buffer[2] = packet[2];
			buffer[3] = packet[3];
			buffer[4] = packet[4];
			buffer[5] = packet[5];
    }
    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
    return 1;
}
Parents
  • What's result and what's packet? You define result but don't use it, you use packet but it's not defined in the code you posted. If you're using easyDMA where's the pointer reset before you send the START task?

    Do you know if CRCSTATUS is 1 or not? If it's not then buffer isn't re-filled and has whatever garbage was in it when you called the function. Perhaps a failure return from the read function would help in that case.

    None of that has anything to do with optimization, but it's hard to figure out what could even be happening without a bit of clarification.

    Have you looked at the compiled assembler to see what it's doing? You would hope the compiler is smart enough not to compile out the while loops as the fields are marked volatile but it's worth checking.

Reply
  • What's result and what's packet? You define result but don't use it, you use packet but it's not defined in the code you posted. If you're using easyDMA where's the pointer reset before you send the START task?

    Do you know if CRCSTATUS is 1 or not? If it's not then buffer isn't re-filled and has whatever garbage was in it when you called the function. Perhaps a failure return from the read function would help in that case.

    None of that has anything to do with optimization, but it's hard to figure out what could even be happening without a bit of clarification.

    Have you looked at the compiled assembler to see what it's doing? You would hope the compiler is smart enough not to compile out the while loops as the fields are marked volatile but it's worth checking.

Children
  • static uint8_t packet[6];

    and I set the pointer after radio_configure();

    radio_configure();
    NRF_RADIO->PACKETPTR = (uint32_t)packet;
    

    I'll set a bool to know if the CRCSTATUS is 1 or not.

    Only after change the optimization flag I got the same exact code working on the same exact condictions. Before the optimization flag I could see the data on the packet pointer but not on the buffer.

  • ok you have to reset the packetptr every time before you call start, but if you're only doing 1, not a problem. For code readability perhaps setting it right before the TASKS_START is good.

    Your second comment 'before the optimisation flag I could see the data on the packet pointer but not on the buffer'. Do you mean before you turned OFF optimisation? If you can see data in the packet pointer but not the buffer that would seem to indicate CRCSTATUS is zero so it didn't get copied into your buffer.

    I still don't know what this has to do with optimization - trying to rule out the obvious things first, then I suspect it's time to get into the assembler.

Related