cancel
Showing results for 
Search instead for 
Did you mean: 

Compiling/Linking stm32h753xx.h with errors

jcbless-ga
Associate II

I am trying to compile in stm32h753xx.h into a project.  It has a number of lines like this:

#define SPI3                ((SPI_TypeDef *) SPI3_BASE)

I am getting this error on that line:

In file included from ../src/libraries/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h:124,
                 from ../src/rt-arm/STM32F4/i2cComm.hh:17,
                 from ../src/rt-arm/busses/i2c.cc:12:
../src/libraries/CMSIS/Device/ST/STM32H7xx/Include/stm32h753xx.h:2510:30: error: 'reinterpret_cast<SPI_TypeDef*>(1073757184)' is not a constant expression
 2510 | #define SPI3                ((SPI_TypeDef *) SPI3_BASE)
      |                             ~^~~~~~~~~~~~~~~~~~~~~~~~~~
../src/rt-arm/STM32F4/dma.hh:178:64: note: in expansion of macro 'SPI3'
  178 | plate<> struct dma_perph<1,0,0> { enum {addr =  (uint64_t)(&SPI3->RXDR)}; }; //"SPI3_Rx"
      |                                                             ^~~~

Other lines like that one also get a similar error.  What I don't understand is that the SPI3_BASE is a constant and therefore I would think everything in ((SPI_TypeDef *) SPI3_BASE) would be considered a constant.  This code is directly from STM and therefore I'd expect the code to be correct and compilable.  Is the fact that the compiler is trying to change the c style cast to a reinterpret_cast<SPI_TypeDef*> causing it to think that it is not really a constant expression?  If so, what can be done to deal with this?  Given that it is a #define it seems that there shouldn't even be the requirement that the substituted value is constant.  In any case, do you have any ideas about the core problem here and how to fix it?

Note that I am not compiling this within STM32CubeIDE.  I am compiling with the arm-none-eabi-g++ compiler with this version info:

arm-none-eabi-g++ (15:13.2.rel1-2) 13.2.1 20231009
Copyright (C) 2023 Free Software Foundation, Inc.

 

1 ACCEPTED SOLUTION

Accepted Solutions

The problem is not with the header.

The problem is that where you're using it requires a constexpr, but SPI3 is not a constexpr, so you can't use it in that manner.

A #define is just the preprocessor. It gets filtered out before compiling even takes place. Take out SPI3 and put in ((SPI_TypeDef *) SPI3_BASE) and you will get the same error.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

5 REPLIES 5
TDK
Super User

c++ - Why is reinterpret_cast not constexpr? - Stack Overflow

If you feel a post has answered your question, please click "Accept as Solution".

There's some aspects of that stack overflow article that don't seem to quite fit.  One is that the code I referenced uses a #define instead of a constexpr.  A #define shouldn't require a constant expression as I understand it.  Additionally, although the error calls out reinterpret_cast<>, the original code actually uses a c style cast in it.  I don't understand why it seems to be converting the c style cast into a reinterpret_cast in the error.  

The problem is not with the header.

The problem is that where you're using it requires a constexpr, but SPI3 is not a constexpr, so you can't use it in that manner.

A #define is just the preprocessor. It gets filtered out before compiling even takes place. Take out SPI3 and put in ((SPI_TypeDef *) SPI3_BASE) and you will get the same error.

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for the clarification, TDK.  That's what I needed.  How did you know from the error that the problem was where the #define's symbol got used rather than in the #define statement itself?  Was there information indicating location of usage in the error that I wasn't recognizing or was that just a case of experience and/or knowledge on your part?

> How did you know from the error that the problem was where the #define's symbol got used rather than in the #define statement itself?

The problem is never the fact that something is in a #define statement. They can't cause any problems by themselves because, unless they are used, the compiler doesn't even know about them. The C preprocessor removes them before it sends code to the compiler.

This is fine unless you have ASDF in your code somewhere:

#define ASDF invalid_code_here---212353;dsacsdac;q32c23r32c

 

> Was there information indicating location of usage in the error that I wasn't recognizing or was that just a case of experience and/or knowledge on your part?

It tells you where the error occurred. Line 12 of i2c.cc. In your enum, you're assigning an explicit value to the "addr" enum which (apparently) requires a constexpr expression.

../src/rt-arm/STM32F4/dma.hh:178:64: note: in expansion of macro 'SPI3'
  178 | plate<> struct dma_perph<1,0,0> { enum {addr =  (uint64_t)(&SPI3->RXDR)}; }; //"SPI3_Rx"

 

Just to keep in mind, header files by themselves aren't compiled. They are only part of a compilation unit when they are included from a source file. In this case, including it from i2c.cc causes the error.

If you feel a post has answered your question, please click "Accept as Solution".