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

compiler warning: pointer from integer without a cast

Hello,

Would appreciate some understanding of a compiler warning. Developing for nRF52832 using SDK 15.3.0 plus S112.

This code compiles without warning:

ret_code_t err_code;
err_code = nrfx_ppi_channel_assign(chan_0, nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN),nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START));
APP_ERROR_CHECK(err_code);

Then I switch from nrfx to sd calls:

ret_code_t err_code;
err_code = sd_ppi_channel_assign(chan_0, nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN),nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START));
APP_ERROR_CHECK(err_code);

and the following warnings:

passing argument 2 of 'sd_ppi_channel_assign' makes pointer from integer without a cast [-Wint-conversion]

passing argument 3 of 'sd_ppi_channel_assign' makes pointer from integer without a cast [-Wint-conversion]

All seems to work, but would appreciate understanding the warnings.

Many thanks,

Tim

Parents
  • Hi,

    Take a look at the API documentation for explanation:

    nrfx_ppi_channel_assign

    sd_ppi_channel_assign

    The second one takes a pointer to a variable, while the first one takes a value. I would have call nrfx_gpiote_in_event_addr_get and nrfx_timer_task_address_get first and saved the results in their own variables that you can then pass via a pointer (&) to the sd_ppi_channel_assign.

    It's a bit surprising that you were able to compile with the wrong argument type. Pointers are the numbers containing the memory address of a variable instead of being the variable themselves. Therefore it could technically work, but would be very likely to behave incorrectly or even crash due to wrong values. That's what the compiler is warning you about.

    Best regards,

    Marjeris

  • Thank you Marjeris. Makes sense. I incorrectly assumed the function parameters were the same.

    However, it's odd that it worked. Compiler warnings went away, but PPI stopped working when I changed the code to:

    ret_code_t err_code;
    uint32_t event_addr = nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN);
    uint32_t task_addr = nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START);
    err_code = sd_ppi_channel_assign(chan_0, &event_addr, &task_addr);
    APP_ERROR_CHECK(err_code);

    I need to debug and see if sd_ppi_channel_assign returns an error. Will do so, but thought to check if the above code looks correct to you.

    Many thanks,

    Tim

  • Also, when I search devzone, all posts with sd_ppi_channel_assign access peripherals (TIMER, GPIOTE, etc.) directly, except for this post, which casts nrf_drv_gpiote_in_event_addr_get and nrf_drv_timer_task_address_get to (const volatile void *). This resolves the compiler warnings, but would like to confirm this is correct code.

    Many thanks,

    Tim

  • Hi,

    The correct approach is to cast the type (const volatile void *) when providing the variables (or events/task addresses). The sd_ppi_channel_assign() function is taking pointers, but the event/task addresses can be seen as pointers itself. It is therefore not correct to pass a pointer to the variables, as this will lead to PPI endpoints being set to addresses in RAM, which are not supported.

    ret_code_t err_code;
    uint32_t event_addr = nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN);
    uint32_t task_addr = nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START);
    err_code = sd_ppi_channel_assign(chan_0, (const volatile void *)event_addr, (const volatile void *)task_addr);
    APP_ERROR_CHECK(err_code);

    Best regards,
    Jørgen

Reply
  • Hi,

    The correct approach is to cast the type (const volatile void *) when providing the variables (or events/task addresses). The sd_ppi_channel_assign() function is taking pointers, but the event/task addresses can be seen as pointers itself. It is therefore not correct to pass a pointer to the variables, as this will lead to PPI endpoints being set to addresses in RAM, which are not supported.

    ret_code_t err_code;
    uint32_t event_addr = nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN);
    uint32_t task_addr = nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START);
    err_code = sd_ppi_channel_assign(chan_0, (const volatile void *)event_addr, (const volatile void *)task_addr);
    APP_ERROR_CHECK(err_code);

    Best regards,
    Jørgen

Children
  • Thank you Jørgen. I think I understand.

    Am I correct to say that this:

    ret_code_t err_code;
    uint32_t event_addr = nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN);
    uint32_t task_addr = nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START);
    err_code = sd_ppi_channel_assign(chan_0, (const volatile void *)event_addr, (const volatile void *)task_addr);
    APP_ERROR_CHECK(err_code);

    is equivalent to:

    ret_code_t err_code;
    err_code = sd_ppi_channel_assign(chan_0, (const volatile void *)nrfx_gpiote_in_event_addr_get(COMPARATOR_PIN), (const volatile void *)nrfx_timer_task_address_get(&m_timer1,NRF_TIMER_TASK_START));

    Any advantages of one compared to the other?

    Thanks,

    Tim

  • Hi,

    From what I can tell, the two are equivalent (except for the second one missing the call to APP_ERROR_CHECK()). That is, both should compile to the same as long as the compiler does some minimal optimization.

    However I do find the first one easier to read and understand. It does fewer things per line, and also gives descriptive names to the arguments sent in to sd_ppi_channel_assign() by using temporary variables (event_addr and task_addr).

    When in doubt, use the one which is the easiest to understand for someone looking into this code in the future. That might be you, a couple of years from now.

    Regards,
    Terje

Related