你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

求教:sw4stm32编译C++工程 Link的时候出错,请大神帮忙看看

[复制链接]
jjbboox 提问时间:2018-3-12 14:55 /
是用STM32CubeMX生成的sw4stm32工程。
然后在sw4中转换为C++工程
建立了一个Source Folder 叫做user_libs,在该目录下添加了自定义的类。
该类中有一个public的function定义如下
void HW_SteerEngine::init(TIM_HandleTypeDef        *htim, uint32_t tim_channel, int angle)
C和C++编译设置中都已经把user_libs目录添加到include路径中。
代码编译都过了,最后在link的时候出现下列错误。

Building target: SteerEngine.elf
Invoking: MCU G++ Linker
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -mfloat-abi=soft -specs=nosys.specs -specs=nano.specs -T"../STM32F103C8Tx_FLASH.ld" -Wl,-Map=output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "SteerEngine.elf" @"objects.list"   -lm
Src/user_main.o: In function `user_setup':
D:\jinbin\单片机\MyProject\STM32\AC6 WorkSpace\SteerEngine\Debug/../Src/user_main.cpp:18: undefined reference to `HWSteerEngine::HW_SteerEngine::init(TIM_HandleTypeDef*, unsigned long, int)'
collect2.exe: error: ld returned 1 exit status
make: *** [SteerEngine.elf] Error 1
makefile:51: recipe for target 'SteerEngine.elf' failed


问题是,如果将该方法中的第一个参数类型改为 void *htim的话,link就不出错,能正常生成.bin文件。
类似的问题已经遇到好几次了,一旦在自定义类的函数定义中使用到hal库的变量类型就会出现连接错误。但是使用普通的变量类型就完全OK。
是不是那里设置上遗漏了什么?


收藏 评论4 发布时间:2018-3-12 14:55

举报

4个回答
maxtch 回答时间:2018-3-12 15:34:11
这个应该是 HAL 的暗病,头文件没做 C++ 兼容。试试看往 HAL 的头文件里面加上 __BEGIN_DECLS 和 __END_DECLS 能不能解决。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

jjbboox 回答时间:2018-3-12 17:29:15
maxtch 发表于 2018-3-12 15:34
这个应该是 HAL 的暗病,头文件没做 C++ 兼容。试试看往 HAL 的头文件里面加上 __BEGIN_DECLS 和 __END_DEC ...

看过头文件。
HAL的头文件中都有

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

__BEGIN_DECLS是一个意思吗?
编译的时候也没出错啊!
maxtch 回答时间:2018-3-12 22:25:46
  1. __BEGIN_DECLS
复制代码


  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
复制代码

是一回事。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

jjbboox 回答时间:2018-3-20 16:21:01
本帖最后由 jjbboox 于 2018-3-20 16:22 编辑

问题原因找到了

不是__cplusplus的问题。
之所以编译出错是HAL的头文件存在bug。

经过仔细调查,发现 TIM_HandleTypeDef是不会出错的,只有SPI_HandelTypeDef类型会出错。
跑到头文件中去查看,发现该类型结构的定义存在问题。定义代码如下:
  1. /**
  2.   * @brief  SPI handle Structure definition
  3.   */
  4. typedef struct __SPI_HandleTypeDef
  5. {
  6.   SPI_TypeDef                *Instance;    /*!< SPI registers base address */

  7.   SPI_InitTypeDef            Init;         /*!< SPI communication parameters */

  8.   uint8_t                    *pTxBuffPtr;  /*!< Pointer to SPI Tx transfer Buffer */

  9.   uint16_t                   TxXferSize;   /*!< SPI Tx Transfer size */

  10.   __IO uint16_t              TxXferCount;  /*!< SPI Tx Transfer Counter */

  11.   uint8_t                    *pRxBuffPtr;  /*!< Pointer to SPI Rx transfer Buffer */

  12.   uint16_t                   RxXferSize;   /*!< SPI Rx Transfer size */

  13.   __IO uint16_t              RxXferCount;  /*!< SPI Rx Transfer Counter */

  14.   void                       (*RxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Rx ISR */

  15.   void                       (*TxISR)(struct __SPI_HandleTypeDef * hspi); /*!< function pointer on Tx ISR */

  16.   DMA_HandleTypeDef          *hdmatx;      /*!< SPI Tx DMA Handle parameters   */

  17.   DMA_HandleTypeDef          *hdmarx;      /*!< SPI Rx DMA Handle parameters   */

  18.   HAL_LockTypeDef            Lock;         /*!< Locking object                 */

  19.   __IO HAL_SPI_StateTypeDef  State;        /*!< SPI communication state */

  20.   __IO uint32_t              ErrorCode;    /*!< SPI Error code */

  21. }SPI_HandleTypeDef;
复制代码


通常我们在用typedef定义一个类型的时候 typedef struct后面是不带名称的,只会在结构体最后起名,
但是该类型定义却在typedef struct 后定义为 [__SPI_HandleTypeDef],而在结构体定义最后又起名为[SPI_HandleTypeDef],导致编译器无法将[SPI_HandleTypeDef]识别为一个有效的变量类型。

现在通过将参数类型更改为 struct __SPI_HandleTypeDef后问题解决。
该问题在编译器中貌似不会出问题,但是如果是C++编译器就会出错了。
可能是HAL库的bug。

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版