Products > Programming
Variable Declaration Issue in C (STM32 MCU)
TonyBe:
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: ---/* 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);
--- End code ---
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: ---/* 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;
.
.
.
--- End code ---
The type of hdma_adc1 is (as seen) "DMA_HandleTypeDef". When checking the HAL_DMA_Start() function, this type should be totaly fine:
--- Code: ---/**
* @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;
.
.
.
--- End code ---
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
Siwastaja:
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.
TonyBe:
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
Siwastaja:
Any other warnings or errors? Full error message(s)?
TonyBe:
--- Quote from: Siwastaja on April 03, 2020, 09:21:42 am ---Any other warnings or errors? Full error message(s)?
--- End quote ---
../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
Navigation
[0] Message Index
[#] Next page
Go to full version