cancel
Showing results for 
Search instead for 
Did you mean: 

Newbie struggling with .c .h and linking

BrianWhite
Associate II

Hello all

   I'm a hobbyist with experience as a java programmer and with simple embedded C and C++ experience who's working on a project for the Elektor Magazine STM32 contest and I'm finding myself in over my head and I'm wondering if any of you might be able to point me in the right direction.

  I'm building up a project that uses several of the capabilities of the STM32WB5MM-DK board that I'm working with. I decided to built it up step by step so I can understand what I'm doing.

   I began with a project that just reads the temperature sensor and outputs the data on the USART1 serial terminal. This was my first success. The next thing I'd like to add is the ability to use the RGB LED. I see that code is in stm32wb5mm_dk.c in one of the demo projects. So I put a copy of stm32wb5mm_dk.c into Core/Src and I put the corresponding .h file in Core/Inc. Since both Core/Src and Core/Inc already contain files that are part of the project, I assumed that I didn't need to change the build settings. Was this wrong?

  I was not able to call functions in the stm32wb5mm_dk.c file until I added #include "stm32wb5mm_dk.h" to main.c but then the related errors in main.c disappeared. I have a feeling that this isn't the right way to do this. Is there a better way to get access to those functions?

  However, errors appeared in the stm32wb5mm_dk.c file and this is what I'm going in circles to try to fix. There are only two functions that are a problem: HAL_TIM_Base_Init() and HAL_TIM_Base_Start() - the error is "undefined reference". I googled that and it suggests that this is a 'linker problem' - this may be confirmed by searching for the declaration of these functions which only turns up a stub in stm32wbxx_hal_tim.h (rather than a real declaration of code). The thing is, stm32wbxx_hal_tim.c is already in the project by default (in Drivers/STM32WBxx_HAL_Driver/Src/) and the corresponding .h is in Drivers/STM32WBxx_HAL_Driver/Inc. So, somehow, eclipse isn't seeing this .c file. 

  If I look in the properties for this project and Paths and Symbols and then Includes, I see

Core/Inc

Drivers/STM32WBxx_HAL_Driver/Inc

Drivers/STM32WBxx_HAL_Driver/Inc/Legacy

Drivers/CMSIS/Device/ST/STM32WBxx/Include

Drivers/CMSIS/Include

- so it looks like the files should be seen.

  It seems like there's something really simple I'm missing but while my grasp of .c vs .h and what the linker does is slowly coming into focus, I'm really at sea as to how to make eclipse do what I want. It feels like it has something to do with how you tell the compiler/linker to put all the pieces together but that part is really fuzzy for me. So please excuse my ignorance but any suggestions would help. 

  This may really be an eclipse question but I'm afraid that if I ask an eclipse forum they'll tell me they don't know what I'm referring to with the file and function names etc.

thanks to all.

Brian

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

EUREKA!

You folks are the best. Thanks a million. That Debugger is something else - a most awesome tool.

Hitting "suspend" was the key to success. As you know, it stops execution wherever it's stuck and you can see what's up.

I know this is technically off the topic that started this off but I figured you might want to know how I finally figured it out and got it working:

  1. When I hit suspend, it was in an infinite loop "that gets called when the processor receives an unexpected interrupt" - AHA
  2. I poked around in the SFRs (NVIC_IABR0) and found it to be interrupt #26 - the TIM17 interrupt
  3. so, the interrupt timer is being set up fine and interrupting as it should but the interrupt wasn't being caught
  4. I looked in the code and the ISR was missing
  5. replacing the ISR stopped it from freezing but it still didn't work - it would freeze at another place
  6. using 'suspend' I saw that it was always running in the ISR - so it was being called but somehow improperly
  7. I smelled a timing issue because the failure point was different if it was in run, breakpoint, or step by step (I gotta love those breakpoints, though)
  8. so I looked at the clock setup and, in the project I was modeling my work on, UART_Console, most of the clocks were 64MHz while in my current version, it was only 4MHz - HMMM
  9. changing the clock to 64MHz fixed it all

YAHOO! Now it's on to getting the BLE stack running.

Thanks for all your help. Have a great rest of your weekend.

Brian

View solution in original post

8 REPLIES 8

Check stm32wbxx_hal_conf.h in your project directory calls out the TIM module, and is not commented out

#define HAL_TIM_MODULE_ENABLED

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JTP1
Lead

Hello

I guess adding

#include "main.h" 

to the beginnig of stm32wb5mm_dk.c might help you forward.

Br JTP

Pavel A.
Evangelist III

> stm32wbxx_hal_tim.c is already in the project by default (in Drivers/STM32WBxx_HAL_Driver/Src/) and the corresponding .h is in Drivers/STM32WBxx_HAL_Driver/Inc. So, somehow, eclipse isn't seeing this .c file. 

So is the stm32wbxx_hal_tim.c file in the *project* (the Eclipse project view) or just in the subdirectory on the disk? It should be visible in the eclipse project tree view. If not - add it there.

> I was not able to call functions in the stm32wb5mm_dk.c file until I added #include "stm32wb5mm_dk.h" to main.c but then the related errors in main.c disappeared. I have a feeling that this isn't the right way to do this. Is there a better way to get access to those functions?

No better way. In C, in order to use a function, you should have it declared before use. #includ'ing the h file is the proper way to do this. The module where the function is defined must be compiled and linked too - else the linker error.

Unfortunately Eclipse is less friendly to beginner than it should be. Take your time to learn and good luck!

 

Thanks for the quick and helpful reply. And thank you for your time - I will try not to drive you crazy.

That stm32wbxx_hal_conf.h is a goldmine of information - I was wondering how various parts of the HAL got enabled and now I get it. Thanks for pointing that out.

So, I tried your suggestion of commenting out

#define HAL_TIM_MODULE_ENABLED

and now it compiles without errors but it does not run properly. 

I dug into debugging - that's a nice tool BTW - and it's freezing when it tries to call HAL_TIM_Base_Start() for the first time. All previous steps run AOK but the debugger stops with the "step" buttons grayed out and the only way to get it to snap out of it is to hit "Terminate" or "Terminate and Relaunch". Doing a little poking, it looks like there is assembly code for the function in the .list file and it seems to match the code in stm32wbxx_hal_tim.c 

here's a little from the .list file

08004374 <HAL_TIM_Base_Start>:
  * @brief  Starts the TIM Base generation.
  * @PAram  htim TIM Base handle
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
{
 8004374:	b480      	push	{r7}
 8004376:	b085      	sub	sp, #20
 8004378:	af00      	add	r7, sp, #0
 800437a:	6078      	str	r0, [r7, #4]

  /* Check the parameters */
  assert_param(IS_TIM_INSTANCE(htim->Instance));

BUT, when I mouse over the stub for HAL_TIM_Base_Start() in stm32wbxx_hal_tim.h, it suggests that I "Wrirte occurrence of 'HAL_TIM_Base_Start'" - this suggests to me that it's not finding the real function code. But maybe I'm reading too much into it.

In answer to Pavel A's comment, it looks to me like the files are in the right places. I attached a pdf of some hopefully relevant screenshots. 

I'm sorry this is so weird - I have this strong feeling that I've left out some super-important and also super-obvious-to-experts-but-not-to-me detail. Thanks again for all your help.

JTP1 - thanks. I tried that but it had no effect. 

What should it have done?

Brian

Pavel

Thanks for the reply and the encouragement. I will soldier on - ultimately, computers work for us so I just need to show it who's boss.

I think the files are in the right places - I put some hopefully relevant screen clips in the attached pdf.

Please let me know if I'm missing something.

thanks again

all the best

Brian

 

Pavel A.
Evangelist III

> "step" buttons grayed out and the only way to get it to snap out of it is to hit "Terminate" or "Terminate and Relaunch". 

Is the "pause" || button grayed out as well?

All parts of Eclipse GUI, including the debugger, are mildly confusing. Take your time and familiarize yourself.

 

 

EUREKA!

You folks are the best. Thanks a million. That Debugger is something else - a most awesome tool.

Hitting "suspend" was the key to success. As you know, it stops execution wherever it's stuck and you can see what's up.

I know this is technically off the topic that started this off but I figured you might want to know how I finally figured it out and got it working:

  1. When I hit suspend, it was in an infinite loop "that gets called when the processor receives an unexpected interrupt" - AHA
  2. I poked around in the SFRs (NVIC_IABR0) and found it to be interrupt #26 - the TIM17 interrupt
  3. so, the interrupt timer is being set up fine and interrupting as it should but the interrupt wasn't being caught
  4. I looked in the code and the ISR was missing
  5. replacing the ISR stopped it from freezing but it still didn't work - it would freeze at another place
  6. using 'suspend' I saw that it was always running in the ISR - so it was being called but somehow improperly
  7. I smelled a timing issue because the failure point was different if it was in run, breakpoint, or step by step (I gotta love those breakpoints, though)
  8. so I looked at the clock setup and, in the project I was modeling my work on, UART_Console, most of the clocks were 64MHz while in my current version, it was only 4MHz - HMMM
  9. changing the clock to 64MHz fixed it all

YAHOO! Now it's on to getting the BLE stack running.

Thanks for all your help. Have a great rest of your weekend.

Brian