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

求教: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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版