Below is the GPTimer ISR, where h4l() and h4h() are the gpio port h pin 4 toggles for the GPTimer trace in above logic analyzer figures. No FreeRTOS API references.
// TIMER2 ISR
// Manages and updates the 8 system software timers. If a system timer has not
// reached zero it is decremented.
// update the 8 system software timers
for(i = 0; i <= MAX_TIMERS; i++)
if(Timers[i] > 0) // if this timer is still counting down
--Timers[i]; // decrement this timer
--*Tstatus[i]; // and this timer`s status variable
if(Timers[i] == 0) // if this timer has reached zero
Tstatus[i] = 0; // NULL this timer`s status pointer
TIM2->SR &= ~BIT0; // reset TIM2 IRQ pending status
Okay. Let’s test the hypothesis of entry/exit stack issue. If we guard the entire call/return to CalcAuth(), we observe no hardfault. Now the next test might be to guard the entry or return instead of the entire function call and return. If it protects from the hardfault, then we are most likely getting a stack corruption from the interrupt somehow. This was also a speculated hypothesis from the ST FAE, so it is worth consideration.
Thank you for the reference. I am starting to grok the priorities. Though when I set the GPTimer to NVIC priority 1 (highest without going unmaskable), it runs all the time and on time. When it is 0xf, it does get blocked for a time and then eventually runs, though the timing is inconsistent. With a single FreeRTOS thread it seems odd. Not sure what to make of it given that it should “always” fire.
I assume you are not talking about the USART’s RX buffer here – your code already reads that buffer after the framing error and before the TX/RX packet exchange. Instead I assume you are talking about an RX queue in software. If you pull the errant
0 byte out of the software queue before the parser consumes it, and if that solves your problem, that is an excellent clue.
You are correct, I am talking about the circular buffer that DMA uses, not the hardware 1 byte buffer.
Notably, the compiler output for the C code of the function that handles those first two packets (and the null first byte) requires -O1 or lower to hardfault. -O2 and we see no hardfault. I’ll post the listings as screenshots of Ozone following this reply to see the differences which may be related to the hardfault.
My logic analyzer toggles for PH3 CalcAuth were supposed to be before/after the call/return of CalcAuth(). I discovered they were also before and after the calling function of CalcAuth(), so it could be either. Going high is the call, going low is the return.
CalcAuth() does not use hardware assist. It looks like this:
uint32_t CalcAuth(uint8_t dat)
// Calculates an ongoing CRC on the byte sent in 'dat' and returns the
// calculated value to the caller. Each successive byte sent to this
// function is calculated into CRC of the previous byte stream.
unsigned long crc;
crc = dat;
if((afbcount % nth_BYTE) == 0)
dat &= 0xfd;
for(i = 8; i > 0; i--)
if(crc & 1)
crc = ((crc >> 1) ^ CRC_POLYNOMIAL);
crc >>= 1;
I’ll review the hardfault FreeRTOS guidance and get back later.
EDIT: added rolling count code