IS_ENABLED 函数详解
IS_ENABLED() 是 Linux 内核中一个非常重要的预处理宏,用于检查内核配置选项是否被启用。它定义在 include/linux/kconfig.h 文件中。
函数定义
/*
* IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm',
* 0 otherwise.
*/
#define IS_ENABLED(option) \
(__is_defined(option) || __is_defined(option##_MODULE))
工作原理
IS_ENABLED() 可以检查三种状态:
-
y:编译进内核(built-in)
-
m:编译为内核模块(module)
-
未设置:未启用
++当配置选项为 y 或 m 时返回 1,否则返回 0。++
使用示例
1. 基本用法
#include <linux/kconfig.h>
// 检查 CONFIG_USB 是否启用(无论是 y 还是 m)
if (IS_ENABLED(CONFIG_USB)) {
// USB 相关的代码
usb_init();
}
// 检查 CONFIG_DEBUG_FS 是否启用
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
debugfs_create_file("myfile", 0644, NULL, NULL, &my_fops);
}
2. 条件编译 vs 运行时检查
// 方式1:条件编译(预处理阶段)
#ifdef CONFIG_USB
usb_init(); // 如果未配置,这段代码完全不存在
#endif
// 方式2:运行时检查(编译阶段)
if (IS_ENABLED(CONFIG_USB)) {
usb_init(); // 代码总是存在,但可能不会执行
}
3. 实际驱动示例
static int my_driver_probe(struct platform_device *pdev)
{
int ret;
// 检查是否启用了调试功能
if (IS_ENABLED(CONFIG_MY_DRIVER_DEBUG)) {
dev_info(&pdev->dev, "Debug mode enabled\n");
my_driver_enable_debug();
}
// 检查是否支持电源管理
if (IS_ENABLED(CONFIG_PM)) {
device_init_wakeup(&pdev->dev, true);
}
// 根据配置决定使用哪种模式
if (IS_ENABLED(CONFIG_MY_DRIVER_DMA)) {
ret = my_driver_init_dma(pdev);
} else {
ret = my_driver_init_pio(pdev);
}
return ret;
}
与其他宏的区别
| 宏 | 检查范围 | 使用场景 | 示例 |
|---|---|---|---|
IS_ENABLED() |
y 或 m | 运行时检查配置是否可用 | if (IS_ENABLED(CONFIG_USB)) |
IS_BUILTIN() |
仅 y | 检查是否编译进内核 | if (IS_BUILTIN(CONFIG_USB)) |
IS_MODULE() |
仅 m | 检查是否编译为模块 | if (IS_MODULE(CONFIG_USB)) |
#ifdef |
任何定义 | 编译时条件包含代码 | #ifdef CONFIG_USB |
需求:找不到/dev/ttyS0 串口设备节点

原因是不同的板卡配置的时候,采用的是不同的需求,有些又需要/dev/ttyS2,所以同一份sdk中的串口驱动,得实现根据不同的板卡配置,给创建不同的串口节点。所以这时候IS_ENABLE()函数的作用就来了,
大概原理是在内核配置文件中增加宏定义,根据不同的板卡需要则打开那个即可,不需要的则采用用默认的即可,如下述代码demo,全部贴上来了,感觉还蛮实用的。
hzs@sr658:~/rk3562-v1.2.0-sdk/kernel$ git diff ./
diff --git a/arch/arm64/configs/rk3562_scd1_mono_defconfig b/arch/arm64/configs/rk3562_scd1_mono_defconfig
index 04c0afb9c95b..044b6c07d9b1 100644
--- a/arch/arm64/configs/rk3562_scd1_mono_defconfig
+++ b/arch/arm64/configs/rk3562_scd1_mono_defconfig
@@ -246,6 +246,7 @@ CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=10
CONFIG_SERIAL_8250_RUNTIME_UARTS=10
CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_8250_DW_TTYS0=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_ROCKCHIP=y
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 2aa42e1a85b3..e2bf6f372048 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -449,10 +449,14 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
/* get index of serial line, if found in DT aliases */
id = of_alias_get_id(np, "serial");
- if (id >= 0) {
+ if (IS_ENABLED(CONFIG_SERIAL_8250_DW_TTYS0)) {
+ printk("[%s]000 id = %d CONFIG_SERIAL_8250_DW_TTYS0 = %d \n", __func__, id, CONFIG_SERIAL_8250_DW_TTYS0);
+ p->line = 0;
+ }else{
+ printk("[%s]111 id = %d CONFIG_SERIAL_8250_DW_TTYS0 = %d \n", __func__, id, CONFIG_SERIAL_8250_DW_TTYS0);
p->line = id;
- // p->line = 0;
}
+
if (IS_ENABLED(CONFIG_ROCKCHIP_MINI_KERNEL))
return;
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index b7922c8da1e6..86dcc0963a82 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -376,6 +376,14 @@ config SERIAL_8250_DW
Selecting this option will enable handling of the extra features
present in the Synopsys DesignWare APB UART.
+config SERIAL_8250_DW_TTYS0
+ tristate "Support for Synopsys DesignWare 8250 quirks"
+ depends on SERIAL_8250
+ select SERIAL_8250_DWLIB
+ help
+ Selecting this option will enable handling of the extra features
+ present in the Synopsys DesignWare APB UART.
+
config SERIAL_8250_EM
tristate "Support for Emma Mobile integrated serial port"
depends on SERIAL_8250 && ARM && HAVE_CLK
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index a8bfb654d490..2e866fc1a8a6 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o
obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
+obj-$(CONFIG_SERIAL_8250_DW_TTYS0) += 8250_dw.o
obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o
obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o
hzs@sr658:~/rk3562-v1.2.0-sdk/kernel$