So I would recommend that you put in the ASSERT for the LDL_PEDANTIC()
macro.

Secondly, you need to be careful with PROGMEM, that is with AVR being a
Harvard machine you can burn up SRAM quickly by not using PROGMEM  for
constants.  For example with the LDL library you need to be sure
that LDL_ENABLE_AVR is defined.

Note the AVR is a great processor, however I have personally not used one
in about 15 years.  The price and ease of programming ARM Cortex M have
gotten such AVR are no longer viable for new development as I can develop
products so much faster with ARM Cortex M parts, and their power and price
is comparable to AVR.

Another trick you can do is inside a function do this:

void printMem(void) {
   uint8_t *ptr;
   printf("stack 0x%X\n", &ptr); //this will be address on stack where ptr
is.
   ptr=malloc(10);
   printf("heap 0x%X\n", ptr); //this will be address as to heap
   free(ptr);
}

This will help as you can do some rough tracking of stack and heap usage,
assuming the AVR linker script has stack growing from top of memory to end
of heap it will help you check for stack overflow.





On Tue, Jun 22, 2021 at 1:39 PM BERTRAND Joël <joel.bertr...@systella.fr>
wrote:

>         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
>
>
>

Reply via email to