Strange. Following function runs as expected. 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; unsigned char t[80]; sprintf(t, "self->handler=%p\r\n", self->handler); 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; } If I comment out sprintf(), it crashes. If I deplace this debug trace before or _after_ self->handler call, firmware runs as expected. I don't understand. If there is a memory corruption somewhere, I could understand that a debug trace _before_ the line that triggers the bug can change something. But I don't understand why the following function runs as expected : 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; } unsigned char t[80]; sprintf(t, "self->handler=%p\r\n", self->handler); return retval; } Of course, if I comment out : unsigned char t[80]; sprintf(t, "self->handler=%p\r\n", self->handler); it crashes again : hilbert:[~/cvs/firmware-antivol] > simavr -t -vvv -m atmega1284 -f 16000000 firmware.elf Loaded 95670 .text at address 0x0 Loaded 5654 .data Loaded 2276 .eeprom 01.. .. =================.. Systella L100-A.. =================.. .. Booting firmware 2021062218.. SPI initialized.. Reset LORA.. Reset LORA done.. LoRaWAN 1.1.. Initialization SX1262.. Initialization SX1262 done.. 0000000000000000.. MAC initialization.. LDL_MAC_addChannel:790>chIndex=0 freq=868100000 minRate=0 maxRate=5.. LDL_MAC_addChannel:790>chIndex=1 freq=868300000 minRate=0 maxRate=5.. LDL_MAC_addChannel:790>chIndex=2 freq=868500000 minRate=0 maxRate=5.. cb type=11.. processInit:994>set radio reset: ticks=151.. processRadioReset:1009>clear radio reset: ticks=151.. MAC initialization done.. lora_send.. processStartRadioForEntropy:1061>listen for entropy: ticks=152.. processEntropy:1078>read entropy: ticks=152 entropy=0.. cb type=0.. LDL_MAC_ready.. LDL_MAC_otaa.. LDL_MAC_addChannel:790>chIndex=0 freq=868100000 minRate=0 maxRate=5.. LDL_MAC_addChannel:790>chIndex=1 freq=868300000 minRate=0 maxRate=5.. LDL_MAC_addChannel:790>chIndex=2 freq=868500000 minRate=0 maxRate=5.. avr_gdb_init listening on port 1234