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

Hard fault SD132 with timers and ble rwauth

Hi,

i'm testing an application on nRF52, with nRF5_SDK_11.0.0-2.alpha and SoftDevice 132.

I took the ble_uart example and added a custom service with some characteristics with various permissions. Everything seems to work well, i then decided to add a timer for system tick tracking and i'm stuck in a hard fault i get when performing SD calls.

In main.c i defined a timer for system tick management

APP_TIMER_DEF(system_timer);
volatile uint32_t systemTick;
...
int main(int)
{ 
    ...
    services_init();
    ... 
    err_code = app_timer_create(&system_timer, APP_TIMER_MODE_REPEATED , systemtimer_timeout_callback);
    err_code = app_timer_start(system_timer, APP_TIMER_TICKS(1, 0), NULL);
    ...
    for(;;){
    }
}

void systemtimer_timeout_callback(void *p_context)
{
	systemTick++;
	return;
}

What happens it that, if i perform authorized read on my characteristic, the system crashes without recovering. For example if i do authorized read from nRF Master tool, the system enters BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, but when i perform sd_ble_gatts_rw_authorize_reply, it doesn't exit from the function. If i debug and pause after that i can see

HardFault_Handler() at 0x24022
<signal handler called>() at 0xfffffff1	
on_rwauth() at ble_myservice.c:575 0x21444	
ble_myservice_on_ble_evt() at ble_myservice.c:672 0x21614
...

on the call stack.

If i comment timer section, everything works. Do you have any idea what could be the issue?

Thank you

EDIT 1:

This is a snippet of the function on_rwauth() i call inside BLE_GATT_RW_AUTHORIZE_REQUEST:

static void on_rwauth(ble_gate_t * p_gate, ble_evt_t * p_ble_evt){
	uint8_t result;
	uint8_t ledstate;
	uint32_t err_code;
	ble_gatts_rw_authorize_reply_params_t    reply_params;
	if (p_ble_evt->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_READ){
		//Authorized Read
		if(p_ble_evt->evt.gatts_evt.params.authorize_request.request.read.handle == p_myservice->state_handle.value_handle){
			SEGGER_RTT_WriteString(0, "READ AUTH IN\r\n");
			//retrieve global state of myservice
			result = p_myservice->mysrv_globalstate_handler(p_myservice);
			if(result == INIT_STATE){
				strncpy((char *)user_data, "HELLO", sizeof(user_data) -1);
			}
			else{
				//return state of LED
				ledstate = mysrv_ledstate_handler(p_myservice);
				if(ledstate == LED_ON){
					strncpy((char *)user_data, "ON", sizeof(user_data) -1);
				}
				else if(ledstate == LED_OFF){
					strncpy((char *)user_data, "OFF", sizeof(user_data) -1);
				}
			}

			memset(&reply_params, 0, sizeof(reply_params));

			reply_params.type                       = BLE_GATTS_AUTHORIZE_TYPE_READ;
			reply_params.params.read.p_data 		= (uint8_t *)&user_data[0];
			reply_params.params.read.len        	= strlen((char *)user_data);
			reply_params.params.read.offset 		= 0;
			reply_params.params.read.update 		= 1;

			SEGGER_RTT_WriteString(0, "ENTER SD_BLE_GATTS:....\r\n");
			
			err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gattc_evt.conn_handle, &reply_params);
			APP_ERROR_CHECK(err_code);
			
			SEGGER_RTT_WriteString(0, "READ AUTH OUT\r\n");
		}
	}
Parents
  • Sorry for not responding sooner. I does sound like the stack frame may have gotten corrupted somehow, but don't see why this would happen only after you added the timer instance. It could however explain why the same code works when built in Keil. Difference between these two is that Keil places the call stack just above the globals whereas GCC places it in top of RAM. In other words, it is possible that the same thing is happening in your Keil project, but it doesn't corrupt the stack since it's placed lower in RAM.

    I would suggest to try to move the stack upwards in RAM to see if this potential corruption is happening at a particular address in your current stack area. You can do that by increasing the RAM size in the linker script so that the total including softdevice is 64KB instead of 32K. Note that this will not work on the engineering A part (PCA10036) as the second RAM block was mapped to a different address range.

  • Hi, i submitted a new case with the project. Thank you

Reply Children
No Data
Related