Reputation: 1234
I have a project written in C on STM32 platform. My project source code will be available for multiple hardware. I use CMakeLists
For example I have 2 header for the moment hardware1.h
and hardware2.h
I have file har_conf.f
and hard_conf.c
to init pin.
Let's take an example for my hardware1
I have PB2
used as OUTPUT
and for my hardware2
PB2
is not use. So my file looks like this:
CMakeList
add_definitions(-DDEBUG -DUSE_HAL_DRIVER -DSTM32F405xx -DHARDWARE1 //select hardware here
hardware1.h
#define NIT_GPIO_PORT GPIOB
#define NIT_GPIO_PIN GPIO_PIN_2
hardware2.h
nothing for PB2 pin because it will not be used.
hard_conf.h
#if defined(HARDWARE1)
#include "hardware1.h"
#endif
#if defined(HARDWARE2)
#include "hardware2.h"
#endif
void InitPinNit(void);
hard_conf.c
void InitPinNit(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(NIT_GPIO_PORT, NIT_GPIO_PIN, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = NIT_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(NIT_GPIO_PORT, &GPIO_InitStruct);
}
Ok so at this point I'd like to avoid to use #ifdef
#endif
in my function InitPinNit()
, how can I achieve this to avoid error when I compile for HARDWARE2 beacause NIT_GPIO_PORT
and NIT_GPIO_PIN
will not be define ?
Upvotes: 0
Views: 81
Reputation: 12708
Well you can write two versions of hard_conf.c
to handle the differences in hardware you are having. As you require constants that you have not defined for HARDWARE2
you will get compilation errors from the undefined macros you reference when compiling hardware2.
If you create two versions of hard_conf.c
(the one for HARDWARE2 will probably need a do nothing function, probably, but the function must be there if you want the linker not to shout at you.
A different approach (but used frequently) Is a table of constants (implemented as an array of structures) that includes values to initialize every device you can have, and then initialize the array contents with a flag that allows you to check if the device is present on the cpu or not. If you check the flag at function entry and simply return if the device is not configured, then you can run the full software, enabling the device if it is plugged (and of course you can detect it somehow) or not.
The number of entries in the array should match the number of different devices attached for the driver you use, and you configure the flag when the device is present (or when the program desires) and you allow/deny access if the flag states that the device is not configured.
To supply a complete example would require to know more about the kind of hardware you are using and the full set of possibilities that you are heading, because there can be the possibility that two different devices use the same GPIO pins, or the GPIO pin can enter in conflict with a PWM device or a serial port.
Normally a Hardware Abstract Layer (HAL) is built to describe the hardware connectivity possibilities, and this database helps you to decide about incompatibilities between devices to be attached to your processor. This will allow you to control a LCD display (which consumes plenty GPIO ports) with wired keyboard matrices (which also consume a lot of GPIO ports) without conflicting. This layer of software is built to say things like "you are trying to open the LCD display, but now you are in the process of reading the pressed key of the keyboard, so you cannot do it now".
Upvotes: 0
Reputation: 965
How to avoid an error because something is not defined?
Define it.
In your Pin example, the GPIO_PIN_x Defines start at 0x01 for Pin 0. Chances are good, that feeding 0x00 into the init function will do nothing. So your hardware2.h should look like:
#define NIT_GPIO_PORT GPIOB
#define NIT_GPIO_PIN 0x00 // no pin, not used
Another solution would be not only defining the hardware pins in your hardware.h files, but the whole initialization and control:
void InitNITPin();
void SetNITPin(bool bSet);
bool GetNITPin();
In General, if stuff like this comes up more often, or your hardware gets more diverse (maybe not only STM32 but some entirely different controller), creating a HAL (hardware abstraction layer) may be worthwile.
Upvotes: 0