C MEX Bug: String Preprocessor Concatenation Not Working?

조회 수: 1 (최근 30일)
Dana Schwanke
Dana Schwanke 2022년 11월 28일
댓글: Dana Schwanke 2023년 11월 21일
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?

채택된 답변

Varun
Varun 2023년 8월 31일
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
Varun
Varun 2023년 8월 31일
편집: Varun 2023년 8월 31일
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
Dana Schwanke
Dana Schwanke 2023년 11월 21일
Yeah, I see that I had this somewhat backwards. The C language itself does the concatenation, but this is not supported inside of #includes the way I had assumed. The answers on this StackOverflow page gave me some better ideas on how to tackle this. I think I was pretty close with the helper #defines:
#define STM32_CHIPSET stm32l4
#define STM32_CHIP stm32l433
#define ADC_INC_HELPER(CHIPSET) "../STM32_Drivers/" #CHIPSET "/HAL_Driver/Inc/" #CHIPSET "xx_hal_adc.h"
#define ADC_INC(CHIPSET) ADC_INC_HELPER(CHIPSET)
#define ADC_INC_STR ADC_INC(STM32_CHIPSET)
#include ADC_INC_STR

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

제품


릴리스

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by