cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_ADC_ConvCpltCallback optimized away

carlesls2
Associate III

Post edited to follow the community rules: Please review how to share a code in this post.

Using the stm32g030k8 and the Version: 1.18.1 STM32CubeIDE

 

I just recently applied an optimization in order to get more space for my application firmware. And then I realize that the HAL_ADC_ConvCpltCallback has been optimized away. I use the -Og (debug optimization) to use the less agressive and more debug friendly optimization. 

 

 
__attribute__((used)) void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1) { ADC_Average_Buff[CHANNEL_VREF] = ADC_DMA_Buff[CHANNEL_VREF]; ADC_Average_Buff[CHANNEL_VBAT] = ADC_DMA_Buff[CHANNEL_VBAT]; ADC_Average_Buff[CHANNEL_CURRENT] = ADC_DMA_Buff[CHANNEL_CURRENT]; ADC_Average_Buff[CHANNEL_TEMPERATURE] = ADC_DMA_Buff[CHANNEL_TEMPERATURE]; ADC_Average_Buff[CHANNEL_VREF] += ADC_DMA_Buff[CHANNEL_VREF]; ADC_Average_Buff[CHANNEL_VBAT] += ADC_DMA_Buff[CHANNEL_VBAT]; ADC_Average_Buff[CHANNEL_CURRENT] += ADC_DMA_Buff[CHANNEL_CURRENT]; ADC_Average_Buff[CHANNEL_TEMPERATURE] += ADC_DMA_Buff[CHANNEL_TEMPERATURE]; //------------------------------------------------------------- if (ADC_Samples >= ADC_SAMPLES - 1) { //------------------------------ // Voltage Reference calculation if (ADC_Average_Buff[CHANNEL_VREF] > 0) { VoltageReference_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_VREF] / ADC_SAMPLES; VoltageReference = (uint16_t) __LL_ADC_CALC_VREFANALOG_VOLTAGE( VoltageReference_Dig, LL_ADC_RESOLUTION_12B); } else { VoltageReference = VDDA_APPLI; // WARNING: Measure error, action: pending. } //------------------------------ // Voltage Battery calculation if (ADC_Average_Buff[CHANNEL_VBAT] > 0) { VoltageBattery_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_VBAT]/ ADC_SAMPLES; VoltageBattery_Pin = (uint16_t) __LL_ADC_CALC_DATA_TO_VOLTAGE( VoltageReference, VoltageBattery_Dig,LL_ADC_RESOLUTION_12B); ConversionFloat_Auxiliar = (float) (VoltageBattery_Pin); if (ConversionFloat_Auxiliar > 0) { ConversionFloat_Auxiliar = ((((ConversionFloat_Auxiliar / 1000) / ADC_VBAT_R2) * (ADC_VBAT_R2 + ADC_VBAT_R1)) * 1000)+ ADC_VBAT_OFFSET; //ConversionFloat_Auxiliar /= 1000; } else { ConversionFloat_Auxiliar = 0; } VoltageBattery = (uint16_t)ConversionFloat_Auxiliar; } else { // WARNING: Measure error, action: pending. } //------------------------------ // Current Motor calculation if (ADC_Average_Buff[CHANNEL_CURRENT] > 0) // index == 1 { VoltageMotorShunt_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_CURRENT] / ADC_SAMPLES; VoltageMotorShunt_Pin = (uint16_t) __LL_ADC_CALC_DATA_TO_VOLTAGE( VoltageReference, VoltageMotorShunt_Dig, LL_ADC_RESOLUTION_12B); ConversionFloat_Auxiliar = (float) (VoltageMotorShunt_Pin); if (ConversionFloat_Auxiliar > 0) { ConversionFloat_Auxiliar = (((ConversionFloat_Auxiliar / 1000)/ ADC_SHUNT) * 1000) + ADC_MOTOR_SHUNT_OFFSET; } else { ConversionFloat_Auxiliar = 0; } CurrentMotor = ConversionFloat_Auxiliar; } else { // WARNING: Measure error, action: pending. } //------------------------------ // Temperature calculation if (ADC_Average_Buff[CHANNEL_TEMPERATURE] > 0) { Temperature_Dig = (uint16_t) ADC_Average_Buff[CHANNEL_TEMPERATURE] / ADC_SAMPLES; Temperature = 100*(int16_t) __LL_ADC_CALC_TEMPERATURE(VoltageReference, Temperature_Dig, LL_ADC_RESOLUTION_12B); } else { // WARNING: Measure error, action: pending. } //------------------------------ // Initialization buffers ADC_Samples = 0; ADC_Average_Buff[CHANNEL_VREF] = 0; ADC_Average_Buff[CHANNEL_VBAT] = 0; ADC_Average_Buff[CHANNEL_CURRENT] = 0; ADC_Average_Buff[CHANNEL_TEMPERATURE] = 0; //------------------------------ //------------------------------ } else { ADC_Samples++; } } // End HAL_ADC_ConvCpltCallback
View more

As the reader can see, I have added the __attribute__((used)) but it is still being optimized away. I also check if the ADC_DMAConvCplt or HAL_ADC_IRQHandler or DMA1_Channel1_IRQHandler are being called, but they are not being called.  

what should I do next?

Thanks for all. 

18 REPLIES 18
Ozone
Principal

First, there is a "insert code sample" menu entry, which makes code snippets like yours much more readable.

Ozone_0-1750058081255.png

Second, declare your ADC_Average_Buff array volatile.
It is highly recommended (read: required) for variables changed in interrupt context anyway.

> __attribute__((used)) void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1)

It would be new to me that "__attribute__((used))" has any effect on functions.

 

Saket_Om
ST Employee

Hello @carlesls2 

Did you try to disable optimization for the callback function? 

#pragma GCC push_options #pragma GCC optimize ("O0") // Disable optimization for this function void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { // Your callback implementation } #pragma GCC pop_options
To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

what is push_options and pop_options?

 

#pragma GCC push_options

 

#pragma GCC pop_options

 Thank you.

Hello @carlesls2 

Please check the GCC manual

Saket_Om_0-1750065481181.png

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om
Andrew Neil
Super User

@carlesls2 wrote:

the HAL_ADC_ConvCpltCallback has been optimized away.


How are you sure that the function has been optimised away?

As @Ozone suggests, if you haven't qualified things which get modified in the callback as volatile, then accesses to those variables may get optimised-out.

 


@carlesls2 wrote:

I also check if the ADC_DMAConvCplt or HAL_ADC_IRQHandler or DMA1_Channel1_IRQHandler are being called, but they are not being called.  


Sounds like the hardware interrupts are not happening...

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

carlesls2_0-1750068065763.png

I does not seem optimized away... it exists in the .map file. I guess this is not discarted... it seems not optimized away but it is never called. Yet this occurs when the optimization is applied. 

These callbacks are called from within the interrupt handler - hence their name.
I don't use Cube/HAL code, so you would need to check the respective ADC interrupt handler implementation. But they are supposedly called from there.

Perhaps some conditional code, or some preprocessor conditions (#if <..>) applying.
You could set a debug breakpoint in the handler, and step through.
Only avoid opening a interrupt status register view.

TDK
Super User

> And then I realize that the HAL_ADC_ConvCpltCallback has been optimized away.

Why do you think it's optimized away? Convince us.

 

Ensure ADC_Average_Buff is set to volatile.

If you feel a post has answered your question, please click "Accept as Solution".

I am not sure but whenever the optimization is applied (when I apply the -Og optimization) the HAL_ADC_ConvCpltCallback is never triggered. The It may not be optimized away but this occurs because of the optimization. 

I created a new smaller project to see if the HAL_ADC_ConvCpltCallback is being optimized away and it is not.