C MEX Bug: String Preprocessor Concatenation Not Working?
1 view (last 30 days)
Show older comments
I am working on an STM32 Simulink library for a host of projects. The user #defines the chipset they are working on when they reference the library, and the library #includes the right files. There are a number of S-Functions that have been created, and they rely on the STM32 firmware packages to access the microcontroller's various peripherals. Let me give an example:
In stm32_config.h:
#define STM32_CHIPSET stm32l4
#define STM32_CHIP stm32l433
In our library's S-Function wrapper, say "ADC_StartConversion_wrapper.c":
#include "stm32_config.h"
#include "../STM32_Drivers/" #STM32_CHIPSET "/HAL_Driver/Inc/" #STM32_CHIPSET "xx_hal_adc.h"
The above is perfectly legal C code. The STM32_Drivers folder referenced contains every chipset we have implemented for our library, and everything underneath it is the same folder structure exactly as the files are downloaded from ST Microelectronics' website. The ability to use macros as part of the #include directive is called "Computed Includes" and is written about in the gcc online manual. The C preprocessor takes adjacent strings and concatenates them at compile time, and the #[macro] stringizes it. In a regular C compiler, this would automatically get translated to:
#include "../STM32_Drivers/stm32l4/HAL_Driver/Inc/stm32l4xx_hal_adc.h"
But when I try to build the mex file
mex ADC_StartConversion.c ADC_StartConversion_wrapper.c
I get the error "fatal error C1083: Cannot open include file: '../STM32_Drivers/': No such file or directory".
If I try to either use a helper macro so the string gets expanded early, or break the string manually into multiple quotes, like this:
#define ADC_INC_HELPER "../STM32_Drivers/" #STM32_CHIPSET "/HAL_Driver/Inc/" #STM32_CHIPSET "xx_hal_adc.h"
#define ADC_INC ADC_INC_HELPER
#include ADC_INC
...
#include "../STM32_Drivers/" "stm32l4" "/HAL_Driver/Inc/" "stm32l4" "xx_hal_adc.h"
same error. Only when I make it a single quote
#include "../STM32_Drivers/stm32l4/HAL_Driver/Inc/stm32l4xx_hal_adc.h"
does it work.
So basically, is this a bug or a feature oversight by MATLAB? Is there a way to accomplish what I want other than to make a separate header file that has a million #ifdef switches for every STM32 chip we support?
0 Comments
Accepted Answer
Varun
on 31 Aug 2023
Hi Dana,
I understand that you are trying to include “../STM32_Drivers/stm32l4/HAL_Driver/Inc/stm32l4xx_hal_adc.h” by following method:
#define STM32_CHIPSET stm32l4
#define STM32_CHIP stm32l433
#include "../STM32_Drivers/" #STM32_CHIPSET "/HAL_Driver/Inc/" #STM32_CHIPSET "xx_hal_adc.h"
Actually, your assumption that C preprocessor takes adjacent strings and concatenates them at compile time is wrong, if you use above method to include then compiler will just see "../STM32_Drivers/" as including header and ignore what is written after it. So, compiler will try to find only "../STM32_Drivers/" as header file which will result in the error you mentioned.
Your 2nd approach of using
#include "../STM32_Drivers/" "stm32l4" "/HAL_Driver/Inc/" "stm32l4" "xx_hal_adc.h"
will be treated the same as above, the compiler will ignore what is written after "../STM32_Drivers/" and will result in same error.
So, the correct way to include this header is:
#include "../STM32_Drivers/stm32l4/HAL_Driver/Inc/stm32l4xx_hal_adc.h"
3 Comments
Varun
on 31 Aug 2023
Edited: Varun
on 31 Aug 2023
In the CPP documentation which has an example:
#define WARN_IF(EXP) \
do { if (EXP) \
fprintf (stderr, "Warning: " #EXP "\n"); } \
while (0)
Here, EXP is a input parameter, and with input parameter of a macro this concatenation is allowed. But you cannot use this directly with your macros :
#define STM32_CHIPSET stm32l4
#define STM32_CHIP stm32l433
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!