I have been running in the an error in regards to creation of variables through the Preprocessor. AppObjdict is loaded with objdict_frm.h and AppObjdict.h together with a define that controls the behavior of macros in objdict_frm.h. AppObjdict.h is an separate addition to objdict_frm.h. But the IAR compilers throws: Error[Pe169] expected a declaration
**AppObjdict.c**
#define PROTOTYPES
#include "objdict_frm.h"
#include "AppObjdict.h"
#undef PROTOTYPES
s_List_Element OD_init[]=
{
#define SET_OD
#include "objdict_frm.h"
#include "AppObjdict.h"
#undef SET_OD
0xffff, 0, NULL
};
#define RESERVE_RAM
#include <objdict_frm.h>
#include "AppObjdict.h"
#undef RESERVE_RAM
void Init_Canop_Structures(int* pNetCfg_p)
{
pNetCfg_p=7;
#define INIT_RAM
#include <objdict_frm.h>
#include "AppObjdict.h"
#undef INIT_RAM
return;
}
The content is of objdict_frm.h is loaded correctly as well as all the macros that are used for creation of the variables.
Yet the content of AppObjdict.h is not loaded and throws and error on the SET_OD section of the initialization. Guards have been removed from both objdict_frm.h and AppObjdict.h, because the same file need to be ran through several times. Why can the data from AppObjdict.h not pass the compiler?
**objdict_frm.h**
#ifdef PROTOTYPES
#define CREATE(a,b) extern a b[];
#define CREATE_INDEX_VAR(a,b) extern u_Subindex_Value a[];
#define CREATE_INDEX_FULL(a,b) extern s_SubIndex_Element a[];
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef RESERVE_RAM
#define CREATE(a,b) a b[sizeof( b##_init ) / sizeof( a )];
#define CREATE_INDEX_VAR(a,b) u_Subindex_Value a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
#define CREATE_INDEX_FULL(a,b) s_SubIndex_Element a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef INIT_RAM
#define CREATE_INDEX_FULL(a,b) memcpy((BYTE*)a,(BYTE*)a##_init,sizeof(a));
#define CREATE_INDEX_VAR(a,b) initram_var_func(&a[0],&a##_init[0].Subindex_Value,sizeof(a##_init)/sizeof(s_SubIndex_Element));
#define CREATE(a,b) memcpy((BYTE*)b,(BYTE*)b##_init,sizeof(b));
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef SET_OD
#define CREATE(a,b)
#define CREATE_INDEX_FULL(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a,
#define CREATE_INDEX_VAR(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
#define CREATE_INDEX_ROM(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
#endif
CREATE_INDEX_FULL (s_dummy_8, 0x0005)
**AppObjdict.h**
CREATE_INDEX_FULL (s_boardId, 0x0012);
#undef CREATE
#undef CREATE_INDEX_VAR
#undef CREATE_INDEX_FULL
#undef CREATE_INDEX_ROM
Note: the amount of CREATE_INDEX_FULL has been reduced as the same operation is done hundreds of times
Thanks in advance
removed guards from the included files
changed marcos slightly and cleaned them up
There is something screwy about iar. I'm on a linux x86_64 PC and I'm unable to reproduce your problem.
I added some tracing with a SHOWME macro.
From the output (at the bottom), AppObjDict.h is being included multiple times (without any sort of #ifndef guard or #pragma once).
At a guess ... If you still have issues using my versions, iar defaults to adding an implicit #pragma once to each .h it tries to include. If so, that's [IMO] bad/dumb.
objdict_frm.h:
// **objdict_frm.h**
SHOWME(objdict_frm_h_ENTER)
#ifdef PROTOTYPES
SHOWME(objdict_frm_h_PROTO)
#define CREATE(a,b) extern a b[];
#define CREATE_INDEX_VAR(a,b) extern u_Subindex_Value a[];
#define CREATE_INDEX_FULL(a,b) extern s_SubIndex_Element a[];
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef RESERVE_RAM
SHOWME(objdict_frm_h_RESERVE)
#define CREATE(a,b) a b[sizeof( b##_init ) / sizeof( a )];
#define CREATE_INDEX_VAR(a,b) u_Subindex_Value a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
#define CREATE_INDEX_FULL(a,b) s_SubIndex_Element a[sizeof( a##_init ) / sizeof( s_SubIndex_Element)];
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef INIT_RAM
SHOWME(objdict_frm_h_INIT)
#define CREATE_INDEX_FULL(a,b) memcpy((BYTE*)a,(BYTE*)a##_init,sizeof(a));
#define CREATE_INDEX_VAR(a,b) initram_var_func(&a[0],&a##_init[0].Subindex_Value,sizeof(a##_init)/sizeof(s_SubIndex_Element));
#define CREATE(a,b) memcpy((BYTE*)b,(BYTE*)b##_init,sizeof(b));
#define CREATE_INDEX_ROM(a,b)
#endif
#ifdef SET_OD
SHOWME(objdict_frm_h_OD)
#define CREATE(a,b)
#define CREATE_INDEX_FULL(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a,
#define CREATE_INDEX_VAR(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
#define CREATE_INDEX_ROM(a,b) b,(sizeof(a##_init)/sizeof(s_SubIndex_Element)),a##_init,
#endif
CREATE_INDEX_FULL (s_dummy_8, 0x0005)
SHOWME(objdict_frm_h_EXIT)
AppObjdict.h:
// **AppObjdict.h**
SHOWME(AppObjdict_h_ENTER)
CREATE_INDEX_FULL (s_boardId, 0x0012);
SHOWME(AppObjdict_h_EXIT)
#undef CREATE
#undef CREATE_INDEX_VAR
#undef CREATE_INDEX_FULL
#undef CREATE_INDEX_ROM
AppObjdict.c:
// **AppObjdict.c**
#define SHOWME(_who) SHOWME_ ## _who
SHOWME(AppObjdict_c_ENTER)
#define PROTOTYPES
SHOWME(AppObjdict_c_PROTO)
#include "objdict_frm.h"
#include "AppObjdict.h"
#undef PROTOTYPES
s_List_Element OD_init[]=
{
#define SET_OD
SHOWME(AppObjdict_c_OD)
#include "objdict_frm.h"
#include "AppObjdict.h"
#undef SET_OD
0xffff, 0, NULL
};
#define RESERVE_RAM
SHOWME(AppObjdict_c_RESERVE)
#include <objdict_frm.h>
#include "AppObjdict.h"
#undef RESERVE_RAM
void Init_Canop_Structures(int* pNetCfg_p)
{
pNetCfg_p=7;
#define INIT_RAM
SHOWME(AppObjdict_c_INIT)
#include <objdict_frm.h>
#include "AppObjdict.h"
#undef INIT_RAM
return;
}
SHOWME(AppObjdict_c_EXIT)
I ran it through cpp with cpp -I. -P AppObjdict.c > out
Here is the output:
SHOWME_AppObjdict_c_ENTER
SHOWME_AppObjdict_c_PROTO
SHOWME_objdict_frm_h_ENTER
SHOWME_objdict_frm_h_PROTO
extern s_SubIndex_Element s_dummy_8[];
SHOWME_objdict_frm_h_EXIT
SHOWME_AppObjdict_h_ENTER
extern s_SubIndex_Element s_boardId[];;
SHOWME_AppObjdict_h_EXIT
s_List_Element OD_init[]=
{
SHOWME_AppObjdict_c_OD
SHOWME_objdict_frm_h_ENTER
SHOWME_objdict_frm_h_OD
0x0005,(sizeof(s_dummy_8_init)/sizeof(s_SubIndex_Element)),s_dummy_8,
SHOWME_objdict_frm_h_EXIT
SHOWME_AppObjdict_h_ENTER
0x0012,(sizeof(s_boardId_init)/sizeof(s_SubIndex_Element)),s_boardId,;
SHOWME_AppObjdict_h_EXIT
0xffff, 0, NULL
};
SHOWME_AppObjdict_c_RESERVE
SHOWME_objdict_frm_h_ENTER
SHOWME_objdict_frm_h_RESERVE
s_SubIndex_Element s_dummy_8[sizeof( s_dummy_8_init ) / sizeof( s_SubIndex_Element)];
SHOWME_objdict_frm_h_EXIT
SHOWME_AppObjdict_h_ENTER
s_SubIndex_Element s_boardId[sizeof( s_boardId_init ) / sizeof( s_SubIndex_Element)];;
SHOWME_AppObjdict_h_EXIT
void Init_Canop_Structures(int* pNetCfg_p)
{
pNetCfg_p=7;
SHOWME_AppObjdict_c_INIT
SHOWME_objdict_frm_h_ENTER
SHOWME_objdict_frm_h_INIT
memcpy((BYTE*)s_dummy_8,(BYTE*)s_dummy_8_init,sizeof(s_dummy_8));
SHOWME_objdict_frm_h_EXIT
SHOWME_AppObjdict_h_ENTER
memcpy((BYTE*)s_boardId,(BYTE*)s_boardId_init,sizeof(s_boardId));;
SHOWME_AppObjdict_h_EXIT
return;
}
SHOWME_AppObjdict_c_EXIT
I have the following source named lcd.c.
#include <stdio.h>
#include "lcd.h"
void print_mode(void)
{
printf("%d\n",LCD_MODE);
}
The header lcd.h contains the definition for LCD_MODE as follows.
#ifndef LCD_H
#define LCD_H
#include "util.h"
#ifndef LCD_MODE
#define LCD_MODE LCD_MODE_8BIT
#endif
void print_mode(void);
#endif /* LCD_H */
The file util.h contains
#ifndef UTIL_H
#define UTIL_H
#define LCD_MODE_8BIT 1
#define LCD_MODE_4BIT 0
#endif /* UTIL_H */
lcd.c will be compiled separately as part of some library. I want to use it with an application main.c as follows.
#include "util.h"
#define LCD_MODE LCD_MODE_4BIT
#include "lcd.h"
int main(void)
{
print_mode();
return 0;
}
The desired outcome is to print 0 as per the definition of LCD_MODE_4BIT in main.c. However, 1 is printed because the header file sees that LCD_MODE is not defined during the preprocessing for lcd.c. How should I go about passing the LCD_MODE option to print_mode() through the main application?
if you cannot recompile lcd.c you cannot use a macro in another source file, because lcd.o already has the value hardcoded.
You could create a static variable (which defaults to LCD_MODE) that you can change using a setter:
#include <stdio.h>
#include "lcd.h"
static int the_mode = LCD_MODE;
void print_mode(void)
{
printf("%d\n",the_mode);
}
void set_mode(int new_mode)
{
the_mode = new_mode;
}
lcd.h should contain the prototype for the new configuration function BTW:
void set_mode(int new_mode);
then in your main, you can:
set_mode(LCD_MODE);
(or drop that LCD_MODE macro everywhere because it solves nothing and adds to the confusion)
I have code that I can't compile on one computer. It works on my PC, but on another it doesn't work. The error is "redefinition of typdef cplx" even though I have guard on every header file and I have guard for every definition of typdef:
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
Why this problems occurs?
Here are two header files. blas.h:
#ifndef BLAS_H
#define BLAS_H
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declaration of functions
#endif
and lapack.h:
#ifndef LAPACK_H
#define LAPACK_H
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declarations of functions
#endif
The problem is when I include both, lapack.h and blas.h, I get this error?
Your guards protect against the same include file being included twice, but you have two different include files with two different guards, and you define cplx in each one.
You need a separate guard for that type in each include file, like this:
#ifndef CPLX
#define CPLX
#ifdef __cplusplus
#include <complex>
#include <cmath>
typedef std::complex<double> cplx;
#else
#include <tgmath.h>
typedef double complex cplx;
#endif
//declarations of functions
#endif
I haven't found any solution on internet and this is why I am asking here.
My Led_TypeDef variable is undefined in MyDriverConfig.h. First, I have definded in MyApplications.h:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MYAPPLICATIONS_H
#define __MYAPPLICATIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
typedef enum
{
LED1 = 0,
LED_GREEN = LED1
} Led_TypeDef;
#define LEDn 1
#define LED1_PIN GPIO_PIN_0
#define LED1_GPIO_PORT GPIOB
#define LED1_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
#define LED1_GPIO_CLK_DISABLE() __GPIOA_CLK_DISABLE()
#define LEDx_GPIO_CLK_ENABLE(__INDEX__) (((__INDEX__) == 0) ? LED1_GPIO_CLK_ENABLE() : 0)
#define LEDx_GPIO_CLK_DISABLE(__INDEX__) (((__INDEX__) == 0) ? LED1_GPIO_CLK_DISABLE() : 0)
void LED_On(Led_TypeDef Led);
void LED_Off(Led_TypeDef Led);
void LED_Toggle(Led_TypeDef Led);
void MCU_Configuration(void);
#endif /* __MYAPPLICATIONS_H */
Then, in MyConfigDriver.h:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MYCONFIG_H
#define __MYCONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
void SystemClock_Config(void);
void MX_LED_Init(Led_TypeDef Led);
void MX_CAN_Init(void);
void MX_I2C1_Init(void);
void MX_SPI1_Init(void);
void MX_USART2_UART_Init(void);
#endif /* __MYCONFIG_H */
I thought it was well definded because my main.h included all:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#include "stm32f0xx_hal.h"
#include "MyDriverConfig.h"
#include "MyApplications.h"
#endif /* __MAIN_H */
These are errors I get:
MyApplications.c
Error[Pe020]: identifier "Led_TypeDef" is undefined C:\Inc\MyDriverConfig.h 24
Error while running C/C++ Compiler
main.c
Error[Pe020]: identifier "Led_TypeDef" is undefined C:\Inc\MyDriverConfig.h 24
Error while running C/C++ Compiler
Total number of errors: 2
Total number of warnings: 0
When I include MyApplication.h in MyDriverConfig.h I get this:
Updating build tree...
MyApplications.c
Error[Pe020]: identifier "Led_TypeDef" is undefined C:\Users\Inc\MyDriverConfig.h 25
Error while running C/C++ Compiler
main.c
MyDriverConfig.c
Total number of errors: 1
Total number of warnings: 0
I don't understand why I have two errors when I am not including MyApplications while I use Led_TypDef once in MyDriverConfig.h.
I also have tried to add
extern Led_TypeDef Led;
in MyApplication.h without any results.
Ok, thank you. For people who could be interested this way is working well:
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#include "stm32f0xx_hal.h"
#include "MyDriverConfig.h"
#include "MyApplications.h"
#endif /* __MAIN_H */
Now in MyDriverConfig.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MYCONFIG_H
#define __MYCONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f0xx_hal.h"
#include "MyApplications.h"
extern GPIO_TypeDef* LED_PORT[LEDn];
extern const uint16_t LED_PIN[LEDn];
[...]
void MX_LED_Init(Led_TypeDef Led);
#endif /* __MYCONFIG_H */
Then, in MyDriverConfig.c
/* Includes ------------------------------------------------------------------*/
#include "MyDriverConfig.h"
[...]
void MX_LED_Init(Led_TypeDef Led)
{
[...]
}
Then, In MyApplications.h
#ifndef __MYAPPLICATIONS_H
#define __MYAPPLICATIONS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f0xx_hal.h"
typedef enum
{
LED1 = 0,
LED_GREEN = LED1
} Led_TypeDef;
[...]
void LED_On(Led_TypeDef Led);
#endif /* __MYAPPLICATIONS_H */
And finaly in MyApplications.c
#include "MyApplications.h"
#include "MyDriverConfig.h"
GPIO_TypeDef* LED_PORT[LEDn] = {LED1_GPIO_PORT};
const uint16_t LED_PIN[LEDn] = {LED1_PIN};
Code is not perfect because there are still some circular includes : stm32f0xx_hal.h but it is compiling well.
I made a template list with help of macroses. And I have an error, when I use it in more then one time in the code. There is a link error LNC2005 in MS VS.
I think, it happens, because bodies of functions are in the header, is there another way to keep them?
#define GENERIC_LIST_POSTFIX i
#define GENERIC_LIST_TYPE int
#define GENERIC_LIST_NAME list
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
If I can't change a language, what can You advice to me?
Thanks.
There is my code
#ifndef _GENERIC_LIST_H
#define _GENERIC_LIST_H
#define _CAT(x,y) x##y
#define CAT(x,y) _CAT(x,y)
#if !defined GENERIC_LIST_POSTFIX
# error("GENERIC_LIST_POSTFIX")
#endif
#if !defined GENERIC_LIST_TYPE
# error("GENERIC_LIST_TYPE")
#endif
#if !defined GENERIC_LIST_NAME
# error("GENERIC_LIST_NAME")
#endif
//-------------------------------------------------------------------------------
typedef struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) CAT(GENERIC_LIST_NAME,_node);
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node)
{ GENERIC_LIST_TYPE value;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *prev;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *next;
};
//typedef struct CAT(_list_,GENERIC_LIST_POSTFIX) GENERIC_LIST_NAME;
struct CAT(_list_,GENERIC_LIST_POSTFIX)
{ unsigned int len; // number of elements
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *first;
struct CAT(CAT(_list_,GENERIC_LIST_POSTFIX),_node) *last;
};
//-------------------------------------------------------------------------------
void CAT(CAT(list_,GENERIC_LIST_POSTFIX),_create )
(struct CAT(_list_,GENERIC_LIST_POSTFIX) *List);
{ List->len = 0; List->first = NULL; List->last = NULL; }
void CAT(CAT(list_,GENERIC_LIST_POSTFIX),_copy )
(struct CAT(_list_,GENERIC_LIST_POSTFIX) *scr, struct CAT(_list_,GENERIC_LIST_POSTFIX) *dest);
{ // ... }
// ... there are more code
#endif
All works, but there is another problem.
I can use this .h file only one time in a one .c file.
If I define GENERIC_LIST_TYPE firstly as int, than as int*, for example.
#define GENERIC_LIST_POSTFIX i
#define GENERIC_LIST_TYPE int
#define GENERIC_LIST_NAME list_i
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
#define GENERIC_LIST_POSTFIX pi
#define GENERIC_LIST_TYPE int*
#define GENERIC_LIST_NAME list_pi
#include "generic_list.h"
#undef GENERIC_LIST_POSTFIX
#undef GENERIC_LIST_TYPE
#undef GENERIC_LIST_NAME
I don't get 2 lists with list_i and list_pi names.
The second "list_pi" is "undeclared identifier".
Is there a solution for this?
Thank you twice.
If I read your question right, you have a header like this:
void doSomething()
{
printf("doing something");
}
Which causes link errors when you include the file multiple times.
However, if you make the function static:
static void doSomething()
{
printf("doing something");
}
The method will not be put to the linker, so you won't have to worry about linker errors.
Your other option is to put a method declaration in your header, and an implementation in a .c file elsewhere in your project.