Is there a Linux Kernel #ifdef directive for conditional compilation available, which is set by the kernel build system (kbuild)?
Usecase:
I have a source code file with register map entries for a SoC and with functions used by a Kernel driver. This file shall be includable by userspace programs as well to use the register map entries:
myheader.h:
...
#define REGENTRY1 0x0001
#define REGENTRY2 0x0002
.....
#ifdef ANY_KERNEL_DIRECTIVE???
firstkernelspacefunc();
....
#endif
Or maybe there are other solutions to this usecase?
Related
When setting up the GPIO on my STM32 Processor I want to check and make sure two different GPIOs are on the same port.
So, I added this macro:
#if (USART2_TX_GPIO_Port != USART2_RX_GPIO_Port)
#error "USART TX and RX on different ports!!!"
#endif
It won't compile, this is the error:
../Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7a3xxq.h:2419:45: error: operator '*' has no right operand
2419 | #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
No idea what the issue is.
Anyone have an idea?
I am trying to make the following code work on both Linux and FreeBSD based system, Is it a valid usage of macros __GLIBC__ and __USE_XOPEN2K8?
#include <stdio.h>
#include <langinfo.h>
#include <locale.h>
#include <xlocale.h>
int main(void) {
//#if defined(__GLIBC__) && defined (__USE_XOPEN2K8)
locale_t loc;
char *locale_messages = "en-US.utf-8";
loc = newlocale(LC_ALL_MASK, locale_messages, (locale_t)0);
if (loc != NULL)
{
char result[256];
sprintf(result, "%s_%s.%s",
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
nl_langinfo_l(CODESET, loc));
}
//#endif
}
If I don't use those directives, I get the following error on mac OS. I want to disable that code to avoid the following errors.
error: use of undeclared identifier '_NL_IDENTIFICATION_LANGUAGE'
nl_langinfo_l(_NL_IDENTIFICATION_LANGUAGE, loc),
^
error: use of undeclared identifier '_NL_IDENTIFICATION_TERRITORY'
nl_langinfo_l(_NL_IDENTIFICATION_TERRITORY, loc),
I have found one thread recommending use _GNU_SOURCE and _XOPEN_SOURCE, but as result above code is disabled on my linux system too. It seems I need to define _GNU_SOURCE before using it, but before proceding with this idea, can we work with __GLIBC__ and __USE_XOPEN2K8.
You can use
#indef __FreeBSD__
#endif
preprocessor directives to ignore the code that shouldn't be built on FreeBSD. However man nl_langinfo_l on FreeBSD says that this function is present on FreeBSD, so you shouldn't have any problems with it.
The best way is to use a build system to detect if that option is available and then conditionally enable that part of code depending of the detection result. This is how autotools project came to be - to detect differences between operating systems.
In cmake you could:
include(CheckCSourceCompiles)
check_c_source_compiles("
#define _GNU_SOURCE
#define _SOMETHING_READ_FEATURE_TEST_MACROS
#include <something something that is needed.h>
int main() { return _NL_IDENTIFICATION_TERRITORY; }
" WE_HAVE_NL_IDENTIFICATION_TERRITORY)
if(WE_HAVE_NL_IDENTIFICATION_TERRITORY)
target_add_definitions(your_target PUBLIC LIB_HAS_NL_IDENTIFICATION_TERRITORY)
endif()
and then use your own LIB_HAS_NL_IDENTIFICATION_TERRITORY macro that detect if that option is available or not. Such solution is stable, easy to port and dynamically reacts to environment changes.
On Ubuntu 17.04, with aarch64-linux-gnu-as installed, compile the following assembly code:
# code.s
_start:
mrs x0,icc_igrpen0_el1
with
aarch64-linux-gnu-as code.s
gives the following error:
as.s: Assembler messages:
as.s:3: Error: unknown or missing system register name at operand 2 -- `mrs x0,icc_igrpen0_el1'
However, icc_igrpen0_el1 is described in documentation of ARMv8 profile,cortext-a53 TRM and GICv3 specification.
And the same error applies to registers starts with ICC_.Why gnu assembler does not recognize those ICC_* registers?
Apparently, you are supposed to use a header file with the register definitions as macros, mapping them to the generic system register names, perhaps like this:
#define ICC_IGRPEN0_EL1 S3_0_C12_C12_6
#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
#define ICC_IGRPEN1_EL3 S3_6_C12_C12_7
I don't think there is any expectation that the non-generic names will be added to GAS proper.
I want to check HZ value of the Kernel running in my board.
Can you please guide me how to check. I want confirm what is configured in .config is same while running.
I could see following config parameters from .config
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NO_HZ=y
CONFIG_HZ_FIXED=0
CONFIG_HZ_100=y
CONFIG_HZ=100
I am using TI's ARM based board and checked include/asm-generic/param.h file initially for HZ value then I checked .config file. I could see following lines in param.h. Please let me know If I the file "include/asm-generic/param.h" which I am checking is not correct.
#define HZ CONFIG_HZ
#define USER_HZ 100
#define CLOCKS_PER_SEC (USER_HZ)
Inside a Linux kernel module, using the macro KERNEL_VERSION, how I can use
either of the create_proc_entry or proc_create ?
Exactly in which kernel version, the interface got changed ?
I see that in kernel version 3.9, in the file proc_fs.h both the APIs are present under
different #ifdef's. Basically I want to check kernel version and depending on that
call the correct API.
#include <linux/version.h> /* For LINUX_VERSION_CODE */
#if ( LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0) )
/*
* Do This
*/
#else
/*
* Do This
*/
#endif
Seems it is available - I just tried on Linux 3.2.0-80-generic (Ubuntu 12.04)
if LINUX_VERSION_CODE < VERSION(3,11,0) && defined(CONFIG_PROC_FS)
and when this condition is met I use create_proc_entry() otherwise proc_create().