EEVblog Electronics Community Forum

Products => Computers => Programming => Topic started by: TonyBe on April 03, 2020, 08:18:50 am

Title: Variable Declaration Issue in C (STM32 MCU)
Post by: TonyBe on April 03, 2020, 08:18:50 am
Hi Forum,

i've really run into a strange problem here. I'm trying to program the DMA for my STM32H750 MCU. When using the HAL Drivers from STM, everything is done by using peripheral handlers, which are declared in the source files generated by CubeMX.

When using the Timers and the UART, everything works fine. But now, i've get an "undeclared (first use in this function)" error when trying to call HAL_DMA_Start function with the "hdma_adc1" handler. When stepping through the code with the debugger, i can clearly see that the handler is declared and even initialized. And even more strange: when clicking on the hdma_adc1 in the function call (which is underlined red for being the error) i can jump to declaration without any problem. So why can i jump there when the compiler says, that it is not declared anywhere?

Here is some code:

This is the Init section at the beginning of my code. As seen with the HAL_TIM_OC_Start, the dereferenced handlers are used to call the functions f.ex. "&tim2".
Code: [Select]
/* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_ADC3_Init();
  MX_DAC1_Init();
  MX_SPI1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_UART4_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_ADC2_Init();
  MX_TIM1_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */

  HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_2); // Start timer for heartbeat LED
  USR_send_Board_Info();
  HAL_Delay(2000);
  HAL_DMA_Start(&hdma_adc1, (uint32_t)&(hadc1.Instance->DR), (uint32_t)&samples[0], 1999);
  HAL_ADC_Start(&hadc1);

The compiler marks the line which calls HAL_DMA_Start(&hdma_adc1,...).
hdma_adc1 gets declared in the source file, which includes the MX_ADC1_INIT():
Code: [Select]
/* Includes ------------------------------------------------------------------*/
#include "adc.h"

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc1;

/* ADC1 init function */
void MX_ADC1_Init(void)
{
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
.
.
.

The type of hdma_adc1 is (as seen) "DMA_HandleTypeDef". When checking the HAL_DMA_Start() function, this type should be totaly fine:
Code: [Select]
/**
  * @brief  Starts the DMA Transfer.
  * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
  *                     the configuration information for the specified DMA Stream.
  * @param  SrcAddress: The source memory Buffer address
  * @param  DstAddress: The destination memory Buffer address
  * @param  DataLength: The length of data to be transferred from source to destination
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
  HAL_StatusTypeDef status = HAL_OK;
.
.
.

So what is going on here? Is this a compiler bug? If there were some typos or anything similar, I shouldn't be able to jump to declaration, didn't I?

Please let me know if you need more code to get a better understanding.

Thanks in advance
Kind Regards
Tony
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: Siwastaja on April 03, 2020, 08:57:15 am
Just a guess,

It's not obvious from your excerpts, but the definition

DMA_HandleTypeDef hdma_adc1;

should come before accessing that variable:

HAL_DMA_Start(&hdma_adc1, (uint32_t)&(hadc1.Instance->DR), (uint32_t)&samples[0], 1999);


These should be in the same file, and in this order. Maybe the order is different? If this is the case, you can either move the definition above the code that uses the variable, or if you can't/don't want to do that, add a declaration:
extern DMA_HandleTypeDef hdma_adc1;
which tells the compiler the type of the variable, and that it will be defined somewhere else, let the linker figure that out.

The declaration is also handy when you define the variable in some other .c file; then you add the declaration to a .h file which you can include elsewhere.
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: TonyBe on April 03, 2020, 09:12:09 am
Thank you for your quick reply.
Well indeed, this declaration is done before the HAL_DMA_Start function is called, since the MX_ADC_Init() is called above and therefore the hdma_adc1 handler is initialized as well.

Regarding the declaration with the "extern" operator: i've also thought about that, but in every other case (UART, Timer) this isn't necessary at all and i really don't want to change the basic structure and idea of the HAL and MX Code just to build around the problem. There must be something else,..  with the compiler maybee?

Any other suggestions?

Thanks a lot
Regards
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: Siwastaja on April 03, 2020, 09:21:42 am
Any other warnings or errors? Full error message(s)?
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: TonyBe on April 03, 2020, 09:31:14 am
Any other warnings or errors? Full error message(s)?

../Core/Src/main.c: In function 'main':
../Core/Src/main.c:122:18: error: 'hdma_adc1' undeclared (first use in this function); did you mean 'hdac1'?
   HAL_DMA_Start(&hdma_adc1, (uint32_t)&(hadc1.Instance->DR), (uint32_t)&samples[0], 1999);
                           ^~~~~~~~~
                           hdac1
../Core/Src/main.c:122:18: note: each undeclared identifier is reported only once for each function it appears in
make: *** [Core/Src/subdir.mk:70: Core/Src/main.o] Error 1
make: *** Waiting for unfinished jobs....
"make -j8 all" terminated with exit code 2. Build might be incomplete.

10:49:16 Build Failed. 3 errors, 0 warnings. (took 10s.951ms)


That's all...

Regards
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: Siwastaja on April 03, 2020, 10:00:21 am
I don't get it. When in stuck in such a case which 99% likely is some super stupid mistake I'm unable to see, I try to narrow it down using things like:

1) Move the declaration just before the function call. Or make an extra declaration with the same type, different name, locally in that function. Doesn't need to be functional that way - it's enough to see if it passes the compiler.
2) Change the type of the variable to, for example, int. Now the error message should be about the wrong type.

Eventually you'll figure it out by narrowing it down by such tests.
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: greenpossum on April 03, 2020, 10:07:35 am
The error mentions a hdac1. I don't see that anywhere else, but there is a hadc1. Did your finger slip and type hdac1 for hadc1?

As for the debugger working it probably ran the last good executable generated before this error.
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: TonyBe on April 03, 2020, 10:52:28 am
Ok i found the problem with the help of some colleagues. In the adc.h file, the extern variable declaration for hdma_adc1 was missing. I've actually checked that yesterday and it was there,... somehow after genereating new code with CubeMX this line was deleted. :-//

Thank you anyway!

Have a good one
Regards
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: Siwastaja on April 03, 2020, 01:41:05 pm
Oh, so the definition was in a different file after all!

Autogenerating code carries risks such as this.
Title: Re: Variable Declaration Issue in C (STM32 MCU)
Post by: TonyBe on April 04, 2020, 09:46:49 am
Oh, so the definition was in a different file after all!

Autogenerating code carries risks such as this.

Yes, sorry that this wasn't clear after my description above.

I'm really trying to avoid auto generation of code,... but in this case, I had to go with it.

Thanks again
Regards!