cancel
Showing results for 
Search instead for 
Did you mean: 

Compiler optimized program has errors

Tobe
Senior III

While trying to debug a problem, it seems that another one is giving me a hard time.

One function call is not shown, another has the wrong name ("writeFLASHDoubleWord" should be "waitForBusy").

The breakpoint is also missed.

 

Originally the code worked, but then i moved to the new prototype. I copied the project, and made a few minor changes. Mainly just the pins.

I had some hardfault before, which happend seemingly at "CLEAR_BIT(FLASH->CR, FLASH_CR_PG);" after writing FLASH. But after seeing the above, i doubt this!

37 REPLIES 37

I just found out, that the interrupt is fired twice. But i dont know why, it does not when there is no optimization. Placing breakpoints does not work at all!

This is quite a tough one.

Maybe this?

JW

No, there is a lot of code behind that part in the interrupt.

I have another finding: When the TFE flag is set, the interrupt is executed a second time, even tough, the interrupt enable IS NOT enabled. How in the world?

 

void newMessageIRQ() { unsigned long nowMicros = micros(); print(100); if(dataFlowControl() != 0) return; print(hfdcan1.Instance->IE >> 3*8); print(hfdcan1.Instance->IE >> 2*8); print(hfdcan1.Instance->IE >> 1*8); print(hfdcan1.Instance->IE >> 0*8); print(101); print((uint8_t) (hfdcan1.Instance->IR >> 3*8)); print((uint8_t) (hfdcan1.Instance->IR >> 2*8)); print((uint8_t) (hfdcan1.Instance->IR >> 1*8)); print((uint8_t) (hfdcan1.Instance->IR >> 0*8)); // TODO low prio: make another version of this, that filters out ids below x beforehand print(TK_FDCAN_GetRx0Message(&hfdcan1, &inputBuffer[inputWriteIndex])); print(102); print((uint8_t) (hfdcan1.Instance->IR >> 3*8)); print((uint8_t) (hfdcan1.Instance->IR >> 2*8)); print((uint8_t) (hfdcan1.Instance->IR >> 1*8)); print((uint8_t) (hfdcan1.Instance->IR >> 0*8)); SET_BIT(hfdcan1.Instance->IR, FDCAN_IR_TFE); // Clear bit // Bootloader does not use ids below ID_REQUEST and 1764 is from diagnose software (dont use it!) if(inputBuffer[inputWriteIndex].id < ID_REQUEST || inputBuffer[inputWriteIndex].id == 1764){ print(99); return; } print(103); // Control data if(inputBuffer[inputWriteIndex].id < ID_DATA_START) { lastControlID = (uint32_t) inputBuffer[inputWriteIndex].id; lastControlMode = (uint32_t) inputBuffer[inputWriteIndex].data[0]; lastAdditionalData = (uint32_t) inputBuffer[inputWriteIndex].data[3]; } print(104); lastBusActivityMicros = nowMicros; //TODO: DELETE VARIABLE (is not used) inputBuffer[inputWriteIndex].timeMicros= nowMicros; print(105); inputFrameCount++; inputWriteIndex++; print(106); delayMicroseconds(150); if(inputWriteIndex >= INPUT_BUFFER_SIZE){ inputWriteIndex = 0; inputOverFlow = true; } delayMicroseconds(150); print(inputReadIndex); print(inputWriteIndex); print(inputOverFlow); delayMicroseconds(150); }
View more

 

 It prints (for the registers (IE, IR, and IR after the FDCAN routin) only - decimal, one digit for each byte):

When TFE is set in IR:

0001 / 0021 / 0021 (*) / 0001 / 0020 / 0020 ( For every CAN frame)

When TFE is cleared in IR (in the interrupt):

0001 / 0021 / 0021 (First CAN frame)

0001 / 0003 / 0003 (Second CAN frame - 3 means new Message; buffer full)

 

How can this interrupt fire, when it is not enabled?

 


@Tobe wrote:

there is a lot of code behind that part in the interrupt.


That's generally a Bad Things - ISRs should generally be kept as short as possible.

 

Placing breakpoints does not work at all! This is quite a tough one.

Although, if it's timing-related, it's possible (likely?) that breakpoints wouldn't help anyhow.

Tough indeed!

Maybe try toggling some pins to observe on a scope or a logic analyser?

 


@Andrew Neil wrote:


That's generally a Bad Things - ISRs should generally be kept as short as possible.


I know, but my debugging efforts inflated it.

 

I just find out, that clearing another flag (that is even not set), seems to prevent a second run of the interrupt. I also verfied, that it is not a timing issue, with writing to another register where the bit was set anyway.

 

This is getting more and more strange!


@Tobe wrote:

I just find out, that clearing ANY flag, seems to prevent a second run of the interrupt.


Good - some progress, at least. :thumbs_up:

Does make it sound like @waclawek.jan could be onto something with his link ...

Do you have an ST or Distributor FAE who could give you more direct help with this?

I updated my answer above.

The link? I think no? they is plenty of time after the actual "hardware handling".

I dont think anyone would bother with a guy that hasnt had any training nor is a professional...

I have found out, that for clearing interrrupt flags, SET_BIT() would clear all the flags. Another thing that gets you confused/ off track... jeeeez.

 

Another interesting thing. In my routine, i dont even clear the newMessage flag, but it is cleared, when the second false interrupt fires.

 

HAL_StatusTypeDef TK_FDCAN_GetRx0Message( FDCAN_HandleTypeDef *hfdcan, struct can_frame *cFrame) { uint32_t *RxAddress; uint32_t GetIndex; // If no messages if ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0FL) == 0U) return HAL_TIMEOUT; /* Calculate Rx FIFO 0 element address */ GetIndex = ((hfdcan->Instance->RXF0S & FDCAN_RXF0S_F0GI) >> FDCAN_RXF0S_F0GI_Pos); RxAddress = (uint32_t *)(hfdcan->msgRam.RxFIFO0SA + (GetIndex * SRAMCAN_RF0_SIZE)); /* Retrieve Identifier */ cFrame->id = ((*RxAddress & FDCAN_ELEMENT_MASK_STDID) >> 18U); // /* Retrieve ErrorStateIndicator */ // pRxHeader->ErrorStateIndicator = (*RxAddress & FDCAN_ELEMENT_MASK_ESI); /* Increment RxAddress pointer to second word of Rx FIFO element */ RxAddress++; // USE EXTERNALLY! // /* Retrieve RxTimestamp */ // cFrame->timeMicros = micros(); /* Retrieve DataLength - Yes its weird (bitshift)! Just ignore it!*/ cFrame->count = (*RxAddress & FDCAN_ELEMENT_MASK_DLC) >> 16U; /* Increment RxAddress pointer to payload of Rx FIFO element */ RxAddress++; /* Retrieve Rx payload */ uint8_t *pData = (uint8_t *)RxAddress; for (uint32_t ByteCounter = 0; ByteCounter < cFrame->count; ByteCounter++) { cFrame->data[ByteCounter] = pData[ByteCounter]; } /* Acknowledge the Rx FIFO 0 that the oldest element is read so that it increments the GetIndex */ hfdcan->Instance->RXF0A = GetIndex; return HAL_OK; }
View more