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

Setting up APP_TIMER results in hardware fault

I started with the ble_app_template example. This example uses the Button event and notifies it. I modified the project to send some other data as notification, instead of the button state. And for the data to be read an transmitted, I initialized a timer. My timer_init looks like this,

static void timers_init(void)
{
	uint32_t err_code;
    // Initialize timer module, making it use the scheduler
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS,     APP_TIMER_OP_QUEUE_SIZE, true);
	
	err_code = app_timer_create(&m_ldc_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                data_timeout_handler);
    APP_ERROR_CHECK(err_code);
}

where data_time_handler is the event handler for the timer.

My timer_start looks like this:

static void timers_start(void)
{
	  uint32_t err_code = app_timer_start(m_timer_id, HEART_RATE_MEAS_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
}

Why would I be going in to a hard fault ?

  • I see that the debugger goes in to data_timeout_handler once and thereafter it does not. And it also seems like the debugger does not get into data_event_handler.

  • I am just starting out, and decided the best approach for me would be to start from scratch as you might say. The first thing I noticed was in code, here and there, was the line:

      APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS,     APP_TIMER_OP_QUEUE_SIZE, false);
    

    and in one place (as in the question above) I found a true (==> HARD FAULT)

      APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS,     APP_TIMER_OP_QUEUE_SIZE, true);
    

    A true will lead to m_evt_schedule_func being set to 1 and thus the code at
    ...\components\libraries\timer\app_timer.c(355) will call a function at address 0x00000001

    if (m_evt_schedule_func != NULL) 
    {
        uint32_t err_code = m_evt_schedule_func(p_timer->p_timeout_handler, p_timer->p_context);
        ..DEATH..
    }
    

    On investigating the parameters, I discovered that for the use of true / false , one should be using

    APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, true);
    

    Please, everyone, check in the header files app_timer.h and app_timer_appsh.h yourselves.

    I am currently working with SDK8.0.0, so I don't know if these 'typos' have been corrected in the latest release, but if not I would strongly recommend that the false be changed to a NULL, to avoid headaches in the future.

  • This is just code which hasn't been properly updated for the change in APP_TIMER_INIT() between SDK7 and SDK8. The parameter to that used to be a bool, it was changed to a function pointer but not much of the example code has been updated and in most cases you don't notice because false == 0 and it doesn't make a difference.

    Using GCC with a reasonable set of warnings turned on I get a warning if I try compiling something like that. I don't know if Keil is just not very good at warning about such things or the warnings are turned off by default. I always turn warning levels way up to catch all these things.

    I agree all the example code, most of which is 'wrong' should be properly updated for SDK8.

Related