Some news. In lorawan/ldl_mac.c is defined LDL_MAC_otaa :
enum ldl_mac_status LDL_MAC_otaa(struct ldl_mac *self) { enum ldl_mac_status retval; union ldl_mac_response_arg arg; LDL_PEDANTIC(self != NULL) if(self->ctx.joined){ retval = LDL_STATUS_JOINED; } else if(self->op == LDL_OP_NONE){ if(self->devNonce <= U32(UINT16_MAX)){ forgetNetwork(self); self->trials = 0; self->day = U32(60) * U32(60) * U32(24) * timeTPS; #if defined(LDL_ENABLE_L2_1_1) LDL_OPS_deriveJoinKeys(self); #endif fillJoinBuffer(self, U16(self->devNonce)); self->devNonce++; arg.dev_nonce_updated.nextDevNonce = self->devNonce; self->handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg); self->tx.power = 0; self->op = LDL_OP_JOINING; if(self->state == LDL_STATE_IDLE){ self->state = LDL_STATE_WAIT_OTAA; LDL_MAC_timerSet(self, LDL_TIMER_WAITA, 0); } retval = LDL_STATUS_OK; LDL_DEBUG("OTAA is pending") } else{ /* need to re-init with a different JoinEUI */ retval = LDL_STATUS_DEVNONCE; } } else{ retval = LDL_STATUS_BUSY; } return retval; } In this function, there is a call to self->handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg). If I comment out this line, firmware doesn't crash anymore. I think in a first time that self->handler is nullified by something. OK, I've checked and I have added just before self->handler() : if (self->handler == NULL) for(;;); After recompilation, firmware runs as expected (!) and doesn't enter in loop (!). I don't understand why this test fix this bug. I have tried to replace in a second time : self->handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg); by a direct call to app_handler function (and of course without previous test): app_handler(self->app, LDL_MAC_DEV_NONCE_UPDATED, &arg); Thus : - self->handler() triggers the bug ; - I'm not sure that self->handler is really nullified as execution doesn't enter in if (self->handler == NULL) for(;;); - why and how does the line if (self->handler == NULL) for(;;); fix this issue ? self->handler() seems to be modified by something or CPU is not able to jump to specified address. Is there a difference in generated asm code between a call to a function pointer and a direct call ? I can post three firmware.elf if required : - original that crashes ; - modified with if (self->handler == NULL) for(;;); that runs as expected : - modified without test but with direct call to app_handler() that runs. Best regards, JKB