error in struct decleration in header files - c

port_pin.h
#ifndef __PORT_PIN_H__
#define __PORT_PIN_H__
typedef enum
{
IO_PORT_A = ((uint16_t)0), /* IO Port A Selected */
IO_PORT_B = ((uint16_t)1), /* IO Port B Selected */
IO_PORT_NONE = ((uint16_t)0xFF) /* No IO Port Selected */
}PortName_t;
/* IO Driver GPIO Pin Numbers */
typedef enum
{
IO_PIN_0 = ((uint16_t)0), /* Pin 0 selected */
IO_PIN_1 = ((uint16_t)1), /* Pin 1 selected */
IO_PIN_2 = ((uint16_t)2), /* Pin 2 selected */
IO_PIN_3 = ((uint16_t)3), /* Pin 3 selected */
}PinNumber_t;
hal_io.h
#ifndef __HAL_IO_H__
#define __HAL_IO_H__
#ifdef DEF_HAL_IO
#define EXTERN_HAL_IO
#else
#define EXTERN_HAL_IO extern
#endif
EXTERN_HAL_IO void HalIo_fct(PortName_t, PinNumber_t);
#endif
drv_io.h
#ifndef __DRV_IO_H__
#define __DRV_IO_H__
#ifdef DEF_DRV_IO
#define EXTERN_DRV_IO
#else
#define EXTERN_DRV_IO extern
#endif
EXTERN_DRV_IO Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer);
#endif
board_cfg.h
#ifndef __BOARD_CFG_H__
#define __BOARD_CFG_H__
#ifdef DEF_BOARD_CFG
#define EXTERN_BOARD_CFG
#else
#define EXTERN_BOARD_CFG extern
#endif
/* IO driver Gpio Port and Pin Configuration */
typedef struct
{
PortName_t Name_en; /* Specifies the IO Port module */
/* This parameter can be a value of #ref */
/* GpioPort_t */
PinNumber_t PinNo_en; /* Specifies the IO Pin number */
/* This parameter can be a value of #ref */
/* PinNumber_t */
}BoardCfgPortPin_t;
EXTERN_BOARD_CFG const BoardCfgPortPin_t BoardCfgPortPin_sta[4];
EXTERN_BOARD_CFG void BoardCfg_fct();
#endif
main.c
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "board_cfg.h"
#include "drv_io.h"
int main()
{
BoardCfg_fct();
printf("\n\n");
return 0;
}
hal_io.c
#define DEF_HAL_IO
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "hal_io.h"
void HalIo_fct(PortName_t PortName_en, PinNumber_t PinNo_en)
{
printf("\nIN HAL\n");
printf("PORTNAME : %d, PIN NUMBER : %d", PortName_en, PinNo_en);
}
drv_io.c
#define DEF_DRV_IO
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "hal_io.h"
#include "board_cfg.h"
#include "drv_io.h"
Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer)
{
printf("\nin DRV IO \n");
HalIo_fct(pointer->Name_en, pointer->PinNo_en);
return (PASS);
}
board_cfg.c
#define DEF_BOARD_CFG
#include <stdio.h>
#include "common.h"
#include "port_pin.h"
#include "drv_io.h"
#include "board_cfg.h"
const BoardCfgPortPin_t BoardCfgPortPin_sta[4] =
{
{ IO_PORT_B, IO_PIN_0 }, /* SENSE_INV_TEMP */
{ IO_PORT_B, IO_PIN_1 }, /* SENSE_INV_AC */
{ IO_PORT_B, IO_PIN_2 }, /* BUZZER */
{ IO_PORT_B, IO_PIN_3 }, /* STAUS_230V_AC */
};
void BoardCfg_fct()
{
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[0]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[1]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[2]);
DDrvIOPinSet_fct(&BoardCfgPortPin_sta[3]);
}
Regarding the above files, when I try to compile the code I am getting the following errors:
drv_io.h(10): error C2143: syntax error : missing ')' before '*'
drv_io.h(10): error C2143: syntax error : missing '{' before '*'
drv_io.h(10): error C2059: syntax error : ')'
If I comment the code in board_cfg.h
/* IO driver Gpio Port and Pin Configuration */
typedef struct
{
PortName_t Name_en; /* Specifies the IO Port module */
/* This parameter can be a value of #ref */
/* GpioPort_t */
PinNumber_t PinNo_en; /* Specifies the IO Pin number */
/* This parameter can be a value of #ref */
/* PinNumber_t */
}BoardCfgPortPin_t;
and add it to port_pin.h, I could compile the code successfully.
But I need to have the struct in board_cfg.h only
Why am I getting this error?

In the file board_cfg.c, it has drv_io.h first followed by board_cfg.h. However, the delaration of DDrvIOPinSet_fct has an argument of type BoardCfgPortPin_t which is defined in board_cfg.h. Since drv_io.h is listed first, BoardCfgPortPin_t hasn't been declared yet. This is what is causing the error.
Your header files are dependent on each other. Rather than depending on the files that include them to put things in the right order, each header file needs to include the other headers they depend on.
In port_pin.h, add #include <stdint.h>
In hal_io.h, add #include "port_pin.h"
In drv_io.h, add #include "board_cfg.h" and #include "common.h"
In board_cfg.h add #include "port_pin.h"
By doing this, each header has everything it needs. Then it doesn't matter in which order they are included by source files.
Also, you don't need any of the defines related to extern. Function declarations are extern by default.

In line 10 of drv_io.h you have
EXTERN_DRV_IO Status_t DDrvIOPinSet_fct(const BoardCfgPortPin_t *pointer);
So you are using BoardCfgPortPin_t which means that the compiler has to know at this point what BoardCfgPortPin_t is. There are several ways to achieve this:
#include board_cfg.h in drv_io.h before line 10
use a forward declaration: put typedef struct BoardCfgPortPin_t; before line 10
make sure all .c files include board_cfg.h before drv_io.h; this is already the case for all but board_cfg.c

Related

Can't find 'FD_SET' function declaration in `select.h`

I'm learning unix network programming. I include #include <sys/select.h> and call FD_SET function. The code can compile successfully when I run gcc manually.
The problem is my IDE Clion can not recognize FD_SET, so it can not help me auto-complete the rest code when I type FD_. So I check the select.h file, I can not find FD_SET declaration in the file.
Here is the source code of select.h on my Mac:
#ifndef _SYS_SELECT_H_
#define _SYS_SELECT_H_
#include <sys/appleapiopts.h>
#include <sys/cdefs.h>
#include <sys/_types.h>
/*
* [XSI] The <sys/select.h> header shall define the fd_set type as a structure.
* The timespec structure shall be defined as described in <time.h>
* The <sys/select.h> header shall define the timeval structure.
*/
#include <sys/_types/_fd_def.h>
#include <sys/_types/_timespec.h>
#include <sys/_types/_timeval.h>
/*
* The time_t and suseconds_t types shall be defined as described in
* <sys/types.h>
* The sigset_t type shall be defined as described in <signal.h>
*/
#include <sys/_types/_time_t.h>
#include <sys/_types/_suseconds_t.h>
#include <sys/_types/_sigset_t.h>
/*
* [XSI] FD_CLR, FD_ISSET, FD_SET, FD_ZERO may be declared as a function, or
* defined as a macro, or both
* [XSI] FD_SETSIZE shall be defined as a macro
*/
/*
* Select uses bit masks of file descriptors in longs. These macros
* manipulate such bit fields (the filesystem macros use chars). The
* extra protection here is to permit application redefinition above
* the default size.
*/
#include <sys/_types/_fd_setsize.h>
#include <sys/_types/_fd_set.h>
#include <sys/_types/_fd_clr.h>
#include <sys/_types/_fd_isset.h>
#include <sys/_types/_fd_zero.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#include <sys/_types/_fd_copy.h>
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
__BEGIN_DECLS
#ifndef __MWERKS__
int pselect(int, fd_set * __restrict, fd_set * __restrict,
fd_set * __restrict, const struct timespec * __restrict,
const sigset_t * __restrict)
#if defined(_DARWIN_C_SOURCE) || defined(_DARWIN_UNLIMITED_SELECT)
__DARWIN_EXTSN_C(pselect)
#else /* !_DARWIN_C_SOURCE && !_DARWIN_UNLIMITED_SELECT */
# if defined(__LP64__) && !__DARWIN_NON_CANCELABLE
__DARWIN_1050(pselect)
# else /* !__LP64__ || __DARWIN_NON_CANCELABLE */
__DARWIN_ALIAS_C(pselect)
# endif /* __LP64__ && !__DARWIN_NON_CANCELABLE */
#endif /* _DARWIN_C_SOURCE || _DARWIN_UNLIMITED_SELECT */
;
#endif /* __MWERKS__ */
#include <sys/_select.h> /* select() prototype */
__END_DECLS
#endif /* !_SYS_SELECT_H_ */
So, where can I find FD_SET declaration? And how should I configure my clion so it can recognize it?

dereferencing pointer to incomplete type ‘struct tcphdr’?

I'm trying to compile "Example 11-9. Source code to the SYNplescan tool" from this NetworkSecurityTools book on Ubuntu 18.04:
http://books.gigatux.nl/mirror/networksecuritytools/0596007949/networkst-CHP-11-SECT-4.html
But it says
error: dereferencing pointer to incomplete type ‘struct tcphdr’
if (tcp->th_flags == 0x14)
^~
How do I fix this?
People change and includes come and go, after the following changes:
## -1,9 +1,12 ##
+#define _DEFAULT_SOURCE 1
#define _BSD_SOURCE 1
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <libnet.h>
#include <pcap.h>
+#include <netinet/tcp.h>
+#include <netinet/ip.h>
int answer = 0; /* flag for scan timeout */
## -42,7 +45,7 ##
int
main (int argc, char *argv[])
{
- char *device = NULL; /* device for sniffing/sending */
+ const char *device = NULL; /* device for sniffing/sending */
char o; /* for option processing */
in_addr_t ipaddr; /* ip address to scan */
u_int32_t myipaddr; /* ip address of this host */
I was able to compile with:
gcc -Wall 1.c -lnet -lpcap
with no compiler messages. I guess that once netinet/tcp.h was included by libnet.h or maybe by pcap.h - seems not be the case anymore and you have to include netinet/tcp.h yourself for struct tcphdr.

stm32 c, export prototype to rest of project

I'm developing a little project (c) in stm32f407vg and following the UART tutorial in:
http://letanphuc.net/2015/09/stm32f0-uart-tutorial-5/#comment-346
My problem is with the function prototype:
/* Includes ——————————————————————*/
#include “usart.h”
#include “gpio.h”
/* Private function prototypes ———————————————–*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to ‘Yes’) calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* #brief Retargets the C library printf function to the USART.
* #param None
* #retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
/* USER CODE END PFP */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
…
..
..
How I have to do the declaration in usart.h so I can use printf() the rest of the project?
Thanks.
EDIT: 2017/01/20 response to Guillaume Michel
I've put in usart.h
#ifndef __usart_H
#define __usart_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "globals.h"
extern UART_HandleTypeDef huart1;
/* **********************************************
*
* **********************************************/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
and the PUTCHAR_PROTOTYPE at usart.c:
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
#include "gpio.h"
#include "string.h"
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
/* USER CODE END PFP */
//UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void){
..
..
}
And in main.c:
/* Includes ------------------------------------------------------------------*/
#include "globals.h"
#include "stm32f4xx_hal.h"
#include "syscfg.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
#include "kernel.h"
#include <stdio.h>
int main(void){
SysIniCfg();
printf("Hola");
while (1){
//kernelMotor();
HAL_GPIO_TogglePin(LED_G_GPIO_Port,LED_G_Pin);
}
}
I have tried other places to put the two sections of the code but this is the only one I don't get warnings or errors
I am pretty sure there is a catch, otherwise you wouldn't ask the question, but I think that if you cut and paste the code below in your uart.h, that should work.
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to ‘Yes’) calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
Don't forget to include uart.h everywhere you call printf
if you are using Newlib libc in your project (STM32Cube generated) you just need to implement int __io_putchar(int ch) any where in the project (main.c if you like), this implementation is used for to outputting characters to the standard output (by printf).
notice that extern int __io_putchar(int ch) __attribute__((weak)); is weakly linked in syscalls.c.
during compilation only the prototype of the function is used, and during the linking of the project, the user defined function is used.
including uart.h all over your project is not a neat solution. make sure you have the rest of Newlib files included.

getting Error[Pe020]: identifier "" is undefined in IAR with an typedef enum

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.

Arduino expected ')' before '*' token

I was trying to seperate my old working code in modules but I got always this error.
"nfc_read.h:24: error: expected ')' before '*' token"
this is line 24:
void read_card(boolean *success,uint8_t *uid,uint8_t *uidLength);
not sure what is wrong in the code...
In my header nfc_read.h:
#ifndef _nfc_read_h_
#define _nfc_read_h_
//Libarys
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
void setup_adafruit(int mode);
void read_card(boolean *success,uint8_t *uid,uint8_t *uidLength);//<--here is the error
#endif
Maybe here is the mistake somewhere:
#include "nfc_read.h"
#define IRQ (2) // IRQ = Interrupt request uint8 (input)
#define RESET (3) // Not connected by default on the NFC Shield uint8 (output)
void setup_adafruit(int mode)
{
Adafruit_NFCShield_I2C nfc(IRQ, RESET); //Funktionspointer....Pins konfigurieren IRQ => input ,RESET => output
Serial.println("Welcome this application will read your UID of your ISO14443A-Card"); //Willkommens Text
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find Arduino board");
while (1); // halt
}
nfc.setPassiveActivationRetries(0xFF);
// configure board to read RFID tags
nfc.SAMConfig();
Serial.println("Waiting for an ISO14443A card");
}
void read_card(boolean *success,uint8_t *uid,uint8_t *uidLength)
{
*success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);
}
Perhaps this will help?
#ifndef _nfc_read_h_
#define _nfc_read_h_
//Libarys
#include <Wire.h>
#include <Adafruit_NFCShield_I2C.h>
Add the following lines:
#include <stdint.h>
#ifndef boolean
#define boolean int
#endif
The above lines will ensure that the proper types are defined.
void setup_adafruit(int mode);
void read_card(boolean *success,uint8_t *uid,uint8_t *uidLength);//<--here is the error
#endif

Resources